fix(mesh): distinct anchor assignment -- no two resources may claim one buffer
Selection was per-resource and greedy, so two resources could take one vertex buffer while a valid one sat unused. A runtime capture proved that wrong for the mirrored e106 hull twins: the container holds both halves and the engine draws each from its own address. Now the first claimant keeps a buffer and later resources re-anchor past everything already claimed (coverage can never regress; grouped-pool models untouched). Against the 46 capture-named Stage_S02 buffers: exact anchors 29 -> 40, unclaimed 12 -> 4. Disc-wide: 5480 resources decoded (unchanged), cross-container inconsistency 125 -> 46. The twins' mirror therefore lives in the DATA, not in the placement matrix: the embedded e106_bdy_02 row and the two assertions encoding the old convention are updated, each with the reason recorded. Full suite green incl. disc/ISO gates. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -842,6 +842,38 @@ fixes the twins but cannot reach blocks the validator still rejects. The pair of
|
||||
changes is the fix; either alone is a half-measure, which is why neither has been
|
||||
made yet.
|
||||
|
||||
### ✅ Fixed: distinct anchor assignment (2026-08-12)
|
||||
|
||||
The selection is no longer per-resource-greedy. After the parallel decode, the
|
||||
models are walked in container order: the first claimant keeps a buffer, and any
|
||||
later resource that chose the same one is **re-anchored past every buffer already
|
||||
claimed**. A resource that finds no free candidate keeps its collided decode, so
|
||||
coverage can never regress. Grouped-pool models are untouched.
|
||||
|
||||
Measured against the 46 capture-named `Stage_S02` buffers, and disc-wide:
|
||||
|
||||
| | exact anchors | unclaimed | resources decoded | shared inconsistent |
|
||||
|---|---|---|---|---|
|
||||
| greedy, cap 0.28 (before) | 29 | 12 | 5 480 | 125 |
|
||||
| **distinct, cap 0.28 (now)** | **40** | **4** | 5 480 | **46** |
|
||||
| distinct, cap 0.42 | 45 | 0 | 6 069 | 62 |
|
||||
|
||||
Nothing decodes that did not decode before, cross-container inconsistency drops
|
||||
by **63 %**, and 11 more of the ship's drawn buffers get exactly the right
|
||||
resource. The cap stays at its shipped 0.28 — that is a separate change with its
|
||||
own evidence (section 9), and this one is worth being able to revert alone.
|
||||
|
||||
**One convention changed, and it is the point of the fix.** With the twins
|
||||
sharing a buffer, the reflection had to be synthesised downstream:
|
||||
`ship::apply_twin_mirrors` flipped one hull, and `correlate` baked an X-flip into
|
||||
`e106_bdy_02`'s captured matrix (`diag(-1,1,1)`). Now each twin decodes to its
|
||||
own, already-mirrored buffer, so **the mirror lives in the data** and both
|
||||
placements are proper rotations. Re-emitting the block from the capture confirms
|
||||
it independently (`1 0 0 0 1 0 0 0 1 264.04343 …`). The embedded placement row
|
||||
and the two assertions that encoded the old convention were updated, each with
|
||||
the reason in place; the full suite including the disc- and ISO-gated ship tests
|
||||
is green.
|
||||
|
||||
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