re: monotone assignment refuted again -- box identity needs descriptor data
XBG7_MONOTONE=1 enforces descriptor order per (stride, vtx, idx) signature: 89 minority decodes, unchanged. Monotonicity constrains order WITHIN a container while the disagreement is BETWEEN containers, which hold different numbers of these boxes in different arrangements. The remaining 89 are bounding-box identity ambiguities needing descriptor-level information, not another anchoring heuristic. Knob kept, default off, measurement recorded; suites green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -583,6 +583,7 @@ impl Xbg7Model {
|
||||
&r.decl,
|
||||
min_consistency,
|
||||
&empty_taken,
|
||||
0,
|
||||
)
|
||||
.into_iter()
|
||||
.collect()
|
||||
@@ -607,6 +608,7 @@ impl Xbg7Model {
|
||||
&r.decl,
|
||||
min_consistency,
|
||||
&empty_taken,
|
||||
0,
|
||||
)
|
||||
.into_iter()
|
||||
.collect()
|
||||
@@ -650,10 +652,39 @@ impl Xbg7Model {
|
||||
// (the adjacency-anchor path) take part; grouped-pool models are left
|
||||
// exactly as they were.
|
||||
let mut taken: std::collections::HashSet<usize> = std::collections::HashSet::new();
|
||||
// Opt-in monotone pass: the last offset handed to each (stride, vtx, idx)
|
||||
// signature. Resources that share a signature are interchangeable to the
|
||||
// validator — many containers hold dozens of identical 24-vertex bound
|
||||
// boxes — so file order is the only thing that can pin which is which.
|
||||
let monotone = std::env::var("XBG7_MONOTONE").is_ok();
|
||||
let mut last_by_sig: std::collections::HashMap<(usize, usize, usize), usize> =
|
||||
std::collections::HashMap::new();
|
||||
let mut models: Vec<Xbg7Model> = Vec::with_capacity(decoded.len());
|
||||
for (i, mut m) in decoded {
|
||||
let r = &resources[i];
|
||||
let starts = &starts_by_stride[&r.decl.stride];
|
||||
if monotone && m.meshes.len() == 1 && r.markers.len() == 1 {
|
||||
let (vc, ic) = r.markers[0];
|
||||
let sig = (r.decl.stride, vc, ic);
|
||||
let floor = last_by_sig.get(&sig).map_or(0, |o| o + 1);
|
||||
if m.meshes[0].vbuf_offset.map_or(false, |o| o < floor) {
|
||||
if let Some(alt) = anchor_pool_mesh(
|
||||
bytes,
|
||||
starts,
|
||||
ic,
|
||||
vc,
|
||||
&r.decl,
|
||||
min_consistency,
|
||||
&taken,
|
||||
floor,
|
||||
) {
|
||||
m.meshes[0] = alt;
|
||||
}
|
||||
}
|
||||
if let Some(o) = m.meshes[0].vbuf_offset {
|
||||
last_by_sig.insert(sig, o);
|
||||
}
|
||||
}
|
||||
if let Some(vb) = m.meshes[0].vbuf_offset {
|
||||
if taken.contains(&vb) {
|
||||
if m.meshes.len() == 1 && r.markers.len() == 1 {
|
||||
@@ -666,6 +697,7 @@ impl Xbg7Model {
|
||||
&r.decl,
|
||||
min_consistency,
|
||||
&taken,
|
||||
0,
|
||||
) {
|
||||
m.meshes[0] = alt;
|
||||
}
|
||||
@@ -1169,9 +1201,15 @@ fn anchor_pool_mesh(
|
||||
decl: &VertexDecl,
|
||||
min_consistency: f32,
|
||||
taken: &std::collections::HashSet<usize>,
|
||||
min_vb: usize,
|
||||
) -> Option<GameMesh> {
|
||||
let idx_bytes = index_count * 2;
|
||||
for &vb in starts {
|
||||
// Monotone assignment (opt-in): resources of one signature are laid out
|
||||
// in descriptor order, so a later one may not take an earlier block.
|
||||
if vb < min_vb {
|
||||
continue;
|
||||
}
|
||||
// A buffer another resource already claimed is not a candidate: the
|
||||
// engine draws each part from its own buffer (proved for the mirrored
|
||||
// `e106_bdy_0{1,2}_l` twins by a runtime capture), so two resources
|
||||
|
||||
@@ -1128,10 +1128,21 @@ rather than being the "one real disagreement" first written here.
|
||||
different containers.** What remains is 24-vertex boxes swapping identities: many
|
||||
of them exist, they are structurally identical, and distinct assignment gives each
|
||||
a *distinct* block without pinning *which* block belongs to which name. Fixing
|
||||
that needs an ordering rule (descriptor order ↔ ascending offset). Monotone
|
||||
anchoring was refuted once before, but that was measured under a decoder with
|
||||
several other defects, so it is worth re-testing — and it is now cheap to judge,
|
||||
because the target is a single number: 89 → 0.
|
||||
that needs an ordering rule (descriptor order ↔ ascending offset).
|
||||
|
||||
**Re-tested, and refuted again.** `XBG7_MONOTONE=1` adds exactly that rule: per
|
||||
`(stride, vtx_count, idx_count)` signature, a later resource may not take an
|
||||
earlier block than the previous one of the same signature. Result: **89 minority
|
||||
decodes — unchanged.** The reason is structural. Monotonicity constrains the
|
||||
order *within* a container, but the disagreement is *between* containers, which
|
||||
hold different numbers of these boxes in different arrangements; a consistent
|
||||
within-container order does not force a consistent name↔box mapping across them.
|
||||
|
||||
So the remaining 89 are **bounding-box identity ambiguities**, and pinning them
|
||||
needs information from the descriptor itself (a composite's own bounds or node
|
||||
data), not another anchoring heuristic. The knob stays, default off, with this
|
||||
measurement recorded so the idea is not tried a third time. Defaults verified
|
||||
unchanged: all ten test suites green.
|
||||
|
||||
(The boxes are harmless in themselves — nothing draws them. But no consistency
|
||||
figure should be quoted without saying whether it counts them; the ignored
|
||||
|
||||
Reference in New Issue
Block a user