diff --git a/docs/re/structures/xbg7-mesh.md b/docs/re/structures/xbg7-mesh.md index 1046158..b372790 100644 --- a/docs/re/structures/xbg7-mesh.md +++ b/docs/re/structures/xbg7-mesh.md @@ -426,12 +426,36 @@ now collected regardless of the filter, but only the asked-for ones and their ± neighbours are decoded in pass 1, so a filtered decode stays proportional to what was asked for. -**51 remain**, and they cluster: `_l` (LOD) and `_dead` variants — -`e001_l`, `e010_bdy_01_l`, `e011_bdy_01_l`, `e016_l`, `e104_bdy_05_l`, -`e106_eng_02_l`, `e501_01_l`, `_rou_f301_base_dead`, `_rou_f302_base_dead`, -`e303_base_dead`. 🟡 A plausible reading is that a variant shares its base's -vertex and index counts, so the two are mutually confusable and the neighbourhood -cannot separate them — untested. The ignored test +**51 remain**, and they cluster in `_l` (LOD) and `_dead` variants — `e001_l`, +`e010_bdy_01_l`, `e011_bdy_01_l`, `e016_l`, `e104_bdy_05_l`, `e106_eng_02_l`, +`e501_01_l`, `_rou_f301_base_dead`, `_rou_f302_base_dead`, `e303_base_dead`. + +**A tempting explanation, tested and false.** The obvious reading is that a +variant shares its base's vertex and index counts, so the two are mutually +confusable *and* adjacent, defeating locality. Checked across every container: +**2 714 variant/base pairs, and exactly zero share identical counts.** + +**What is actually happening: one region is a universal false positive.** +`e010_bdy_01_l` is 171 verts / 90 tris and **no other resource in its container +shares those counts** — yet in `Stage_S02` and `S26` it decodes to +**1600 × 2100 × 4800**, the *same* bounds `e303_wep_01` (172 verts / 110 tris) +produced before the fix. Differently-shaped resources are landing on the same +place. So the attractor is not "another mesh with my shape" but a region of +**round, axis-aligned box data** that validates for many different `(vtx, idx)` +shapes at once — every index lands in range and the triangles are coherent boxes. + +That also explains why the neighbourhood fix helped so broadly: it steers +resources away from a single strong attractor rather than resolving many +pairwise confusions. + +🟡 **Candidate next step, with its risk stated:** reject (or de-prefer) a +candidate whose sampled positions are *all* multiples of 50 with a large span — +the attractor's signature. The risk is real: an earlier sweep for exactly that +signature also flagged legitimate `e_rou_*` composite proxies, so it must be a +**tiebreak between validating candidates**, never an outright rejection, and it +needs the same before/after gate (decoded must not fall from 5 480). + +The ignored test [`mesh_consistency_disc.rs`](../../crates/sylpheed-formats/tests/mesh_consistency_disc.rs) still asserts the target state and now records 63 rather than 125; the remaining cases are where the neighbourhood is itself wrong or absent.