re: eng_02_l's real block is adjacent -- the connectivity heuristic rejects it
debug_find_index_buffer scans the container for an index buffer that validates against a capture-proven vertex buffer. For eng_02_l nothing validates with the connectivity test on; with it off the nearest hit is exact pad-0 adjacency (vb-ib = 144 = 72*2). The block's mean_edge/diag is 0.417 against a 0.28 cap -- the documented false positive for coarse LODs, now caught with ground truth. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -714,6 +714,40 @@ sub-range, a different unit, or a Xenia-side artifact is unknown — it may matt
|
||||
for `eng_02_l`, whose block validation is exactly what an index-count mismatch
|
||||
would break.
|
||||
|
||||
**6. Why `eng_02_l`'s real block is rejected: the connectivity heuristic.**
|
||||
`mesh::debug_find_index_buffer` scans the *whole container* for an index buffer
|
||||
that validates against a known vertex buffer, instead of assuming adjacency
|
||||
(`examples/find_ib.rs`). For `e106_eng_02_l` at the capture-proven `0x44a32c`,
|
||||
with the connectivity test on, **nothing in the container validates**. With it
|
||||
off (`SOFT_IB=1`) the nearest hit is `ib 0x44a29c` — `vb − ib = 144 = 72 × 2`,
|
||||
i.e. **exact pad-0 adjacency**. So the index buffer is exactly where the decoder
|
||||
assumes it is; the block is thrown out by one heuristic.
|
||||
|
||||
That heuristic is `mean_edge / bbox_diag > 0.28 → reject`. Measured on the real
|
||||
blocks:
|
||||
|
||||
| block | mean edge | bbox diagonal | ratio | verdict |
|
||||
|---|---|---|---|---|
|
||||
| `eng_02_l` (24 tris) `ib 0x44a29c → vb 0x44a32c` | 109.21 | 261.96 | **0.417** | rejected (cap 0.28) |
|
||||
| `bdy_02_l` (82 tris) `ib 0x3c53ec → vb 0x3c55d8` | 131.70 | 786.66 | 0.167 | passes |
|
||||
| `bdy_01_l` (82 tris) `ib 0x3b3cfc → vb 0x3b3ee8` | 131.70 | 786.66 | 0.167 | passes |
|
||||
|
||||
This is precisely the false positive the check's own comment predicts — "a small
|
||||
flat sub-mesh legitimately has large edges relative to its own diagonal" — caught
|
||||
in the wild for the first time, with the runtime naming the block it rejects. A
|
||||
24-triangle engine LOD is coarse by construction, so its edges *are* a large
|
||||
fraction of its size.
|
||||
|
||||
(The twins' two real blocks having **identical** mean edge and diagonal is a free
|
||||
corroboration that they are mirror images: reflection preserves lengths.)
|
||||
|
||||
So the residual class is not one bug. `eng_02_l` has its vertex start in the
|
||||
candidate list *and* its index buffer exactly adjacent, and still fails — a
|
||||
**validator** problem, not a scan or selection one. Raising the cap is not the
|
||||
fix to reach for blind: the threshold trades against false anchors, and now that
|
||||
a capture can name true blocks, it can be **calibrated** against them rather than
|
||||
guessed. Not changed here.
|
||||
|
||||
Not settled: `e106_brg_01_b_02` ≡ `e106_brg_01_l` (51 verts). A second 51-vertex
|
||||
`vbase` exists in the logs but is **not** from this container, and the container
|
||||
holds three near-identical 51-vertex runs, so the pair has no oracle yet.
|
||||
|
||||
Reference in New Issue
Block a user