fix(mesh): require exact pool coverage -- found by rendering, not by a metric
Rendering assembled e106 from Stage_S02 showed the old slab: e106_bdy_03 spanning 600x1600x998 where three other containers give 276x236x941. Its anchor had slack 3, and the coverage gate tolerated up to three unreferenced tail vertices -- tolerance that was hiding a mis-anchor, since real blocks reach their last vertex exactly (8580 of 8629). Requiring exact coverage moves it to the block the other containers agree on and the slab disappears. Costs 3 resources (6212 -> 6209), inconsistency 39 -> 38, capture oracle unchanged at 46/46, suite green. Evidence: captures/e106-cover-slack-before-after.png Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,13 +11,23 @@ fn main() {
|
||||
println!("{} — {} sub-meshes decoded, {} markers declared", m.name, m.meshes.len(), markers.len());
|
||||
for (i, s) in m.meshes.iter().enumerate() {
|
||||
let max_idx = s.indices.iter().max().copied().unwrap_or(0) as usize;
|
||||
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
|
||||
for q in &s.positions {
|
||||
for k in 0..3 {
|
||||
lo[k] = lo[k].min(q[k]);
|
||||
hi[k] = hi[k].max(q[k]);
|
||||
}
|
||||
}
|
||||
println!(
|
||||
" #{i:<2} at 0x{:<9x} verts {:<6} idx {:<6} max_idx {:<6} slack {}",
|
||||
" #{i:<2} at 0x{:<9x} verts {:<6} idx {:<6} max_idx {:<6} slack {} span [{:.0} {:.0} {:.0}]",
|
||||
s.vbuf_offset.unwrap_or(0),
|
||||
s.positions.len(),
|
||||
s.indices.len(),
|
||||
max_idx,
|
||||
s.positions.len() as i64 - 1 - max_idx as i64
|
||||
s.positions.len() as i64 - 1 - max_idx as i64,
|
||||
hi[0] - lo[0],
|
||||
hi[1] - lo[1],
|
||||
hi[2] - lo[2]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -976,6 +976,21 @@ fn grouped_consistency() -> f32 {
|
||||
std::env::var("XBG7_GROUPED_CONSISTENCY").ok().and_then(|v| v.parse().ok()).unwrap_or(0.85)
|
||||
}
|
||||
|
||||
/// Coverage requirement, as `max_index + N >= vtx_count`. **`1` since
|
||||
/// 2026-08-12** — i.e. the indices must reach the pool's last vertex exactly.
|
||||
///
|
||||
/// The old `4` tolerated three unreferenced tail vertices, and that slack was a
|
||||
/// mis-anchor tell rather than a real variation: 8 580 of 8 629 decoded
|
||||
/// sub-meshes cover their pool exactly, and `e106_bdy_03` in `Stage_S02` was one
|
||||
/// of the few that did not — slack 3, decoding to a 600×1600×998 slab visible in
|
||||
/// a render, where three other containers give 276×236×941. Requiring exact
|
||||
/// coverage moves it onto the block those containers agree on. Costs 3 resources
|
||||
/// disc-wide; capture oracle unchanged at 46/46. `XBG7_COVER_SLACK` overrides
|
||||
/// (note `0` rejects everything — the comparison is `max_idx + N >= vtx_count`).
|
||||
fn cover_slack() -> usize {
|
||||
std::env::var("XBG7_COVER_SLACK").ok().and_then(|v| v.parse().ok()).unwrap_or(1)
|
||||
}
|
||||
|
||||
/// Smallest bounding-box extent a block may have (default `0.5`). An absolute
|
||||
/// floor on a format with no unit convention is a scale assumption, so it is a
|
||||
/// knob: `XBG7_MIN_EXTENT`.
|
||||
@@ -1262,7 +1277,7 @@ fn validate_block_report(
|
||||
}
|
||||
max_idx = max_idx.max(i);
|
||||
}
|
||||
if (max_idx as usize) + 4 < vtx_count {
|
||||
if (max_idx as usize) + cover_slack() < vtx_count {
|
||||
return Err(format!(
|
||||
"indices reach only {max_idx} of {vtx_count} vertices (buffer not covered)"
|
||||
));
|
||||
@@ -1525,7 +1540,7 @@ fn anchor_grouped_meshes(
|
||||
max_idx = max_idx.max(i);
|
||||
i < vc
|
||||
});
|
||||
if in_range && max_idx + 4 >= vc {
|
||||
if in_range && max_idx + cover_slack() >= vc {
|
||||
meshes.push(read_pool_mesh(bytes, ib, vb, ic, vc, decl));
|
||||
}
|
||||
vb += vc * stride;
|
||||
|
||||
BIN
docs/re/captures/e106-cover-slack-before-after.png
Normal file
BIN
docs/re/captures/e106-cover-slack-before-after.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
@@ -1042,6 +1042,35 @@ not obviously right, and both points are one env var apart
|
||||
(`XBG7_PAD0_CONSISTENCY`, `XBG7_EDGE_CAP`) for anyone who wants the conservative
|
||||
end.
|
||||
|
||||
### ✅ Fixed by *looking* at the output: exact pool coverage (2026-08-12)
|
||||
|
||||
Rendering the assembled `e106` from `Stage_S02` — something no metric had done —
|
||||
showed the old slab back: `e106_bdy_03` spanning **600×1600×998**, a blocky mass
|
||||
beside the hull. The same resource decodes to **276×236×941** in `Stage_S01`,
|
||||
`Stage_S03` and `Stage_S04`. The tell was already in the data:
|
||||
|
||||
| container | anchor | slack | span |
|
||||
|---|---|---|---|
|
||||
| `Stage_S01` | `0x3c9b7c` | 0 | 276×236×941 |
|
||||
| **`Stage_S02`** | `0x12d1d44` | **3** | **600×1600×998** |
|
||||
| `Stage_S03` | `0x1e07b7c` | 0 | 276×236×941 |
|
||||
| `Stage_S04` | `0x164337c` | 0 | 276×236×941 |
|
||||
| `Stage_S06` | `0x1f05298` | 0 | 414×636×1121 |
|
||||
|
||||
The coverage gate tolerated up to **three** unreferenced tail vertices, and that
|
||||
tolerance was hiding a mis-anchor: real blocks reach their pool's last vertex
|
||||
exactly (8 580 of 8 629). Requiring exact coverage moves `Stage_S02`'s
|
||||
`e106_bdy_03` to `0x2d35b7c`, slack 0, **276×236×941** — the block three other
|
||||
containers agree on — and the slab disappears from the render
|
||||
([`captures/e106-cover-slack-before-after.png`](../captures/e106-cover-slack-before-after.png)).
|
||||
|
||||
Cost: **3** resources disc-wide (6 212 → 6 209); cross-container inconsistency
|
||||
39 → 38; capture oracle unchanged at 46/46 claimed, 0 unclaimed; suite green.
|
||||
|
||||
(`Stage_S06` still gives a third answer at slack 0, so `e106_bdy_03` is not fully
|
||||
settled — but it is now consistent across four of the six containers that carry
|
||||
it instead of three.)
|
||||
|
||||
### The anchor work has plateaued at 98.7 % — state and what is left
|
||||
|
||||
Four evidence-driven changes took the decoder from 5 480 to **6 212 of 6 294**
|
||||
|
||||
Reference in New Issue
Block a user