re: ROOT CAUSE of the silent XBG7 mis-decodes -- the candidate list is container-global
anchor_pool_mesh walks candidates from vertex_run_starts(bytes, data_base, stride): ONE scan of the whole container per stride, shared by every resource of that stride, and it accepts the first candidate that validates. Nothing ties the chosen block to the resource it belongs to, so two resources sharing (stride, vertex count, index count) are interchangeable to this search. The wrong block is not distinguishable by quality. Tracing the accept for e303_wep_01: Stage_S01 vb=4600480 span 49 x 23 x 42 passes 0.85 = true Stage_S02 vb=18403456 span 1600 x 2100 x 4800 passes 0.85 = true Both clear the strict winding gate, because the wrongly-taken block IS real coherent geometry -- another resource's. That rules out a family of fixes: no threshold, scoring, or best-of-N selection can help, which is exactly why the previous iteration's attempt changed nothing. The search space must be constrained instead. Two candidates recorded, ordered by how much new format knowledge they need: per-resource data extents from the XPR2 resource table, or monotonic anchoring (resource k's vb after resource k-1's) if data blocks follow descriptor order -- testable against the 556 resources that already decode consistently. Instrumentation reverted; only docs land here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -339,6 +339,43 @@ majority is the turret the render and the runtime capture both support.
|
|||||||
15) and nothing yet says which is right. Use the detector to flag; do not silently
|
15) and nothing yet says which is right. Use the detector to flag; do not silently
|
||||||
rewrite geometry on a vote.
|
rewrite geometry on a vote.
|
||||||
|
|
||||||
|
### ROOT CAUSE: the candidate list is container-global
|
||||||
|
|
||||||
|
Traced 2026-08-12. `anchor_pool_mesh` (the **per-block** path, which is the one
|
||||||
|
that handles single-sub-mesh resources like `e303_wep_01`) walks a candidate list
|
||||||
|
built by `vertex_run_starts(bytes, data_base, stride)` — **one scan of the whole
|
||||||
|
container per stride**, shared by every resource of that stride. It accepts the
|
||||||
|
**first** candidate that validates.
|
||||||
|
|
||||||
|
So a resource is anchored to *whatever block matches its signature first in file
|
||||||
|
order*, and nothing ties that block to the resource it belongs to. Two resources
|
||||||
|
sharing `(stride, vertex count, index count)` are interchangeable to this search.
|
||||||
|
|
||||||
|
**The wrong block is not distinguishable by quality.** Tracing the accept for
|
||||||
|
`e303_wep_01`:
|
||||||
|
|
||||||
|
```
|
||||||
|
Stage_S01 ACCEPT vb=4600480 pad=0 span= 49 × 23 × 42 passes 0.85 = true
|
||||||
|
Stage_S02 ACCEPT vb=18403456 pad=0 span=1600 × 2100 × 4800 passes 0.85 = true
|
||||||
|
```
|
||||||
|
|
||||||
|
Both clear the strict winding-consistency gate, because the wrongly-taken block
|
||||||
|
**is** real, coherent geometry — just another resource's. That rules out a whole
|
||||||
|
family of fixes: no threshold, no scoring, no "pick the best candidate" changes
|
||||||
|
this, and the earlier attempt to add best-of-N selection in the grouped-pool
|
||||||
|
anchor duly changed nothing.
|
||||||
|
|
||||||
|
**The search space has to be constrained instead.** Two candidates, in order of
|
||||||
|
how much new format knowledge they need:
|
||||||
|
|
||||||
|
1. **Per-resource data extents.** The XPR2 resource table gives each resource a
|
||||||
|
descriptor; if the geometry extent can be derived from it, restrict `starts`
|
||||||
|
to that range and the theft becomes impossible.
|
||||||
|
2. **Monotonic anchoring.** If resources' data blocks follow descriptor order,
|
||||||
|
then resource *k*'s `vb` must lie after resource *k−1*'s — a cheap constraint
|
||||||
|
needing no new format knowledge. Testable against the 556 resources that
|
||||||
|
already decode consistently across containers.
|
||||||
|
|
||||||
### Where the mis-decode is *not*: the grouped-pool anchor
|
### Where the mis-decode is *not*: the grouped-pool anchor
|
||||||
|
|
||||||
An attempt to fix it by making `anchor_grouped_meshes` choose the **best-scoring**
|
An attempt to fix it by making `anchor_grouped_meshes` choose the **best-scoring**
|
||||||
|
|||||||
Reference in New Issue
Block a user