fix(mesh): filtered decode must not depend on the requested subset
models_named pruned to the wanted set BEFORE distinct assignment, so collision resolution saw a different resource population and returned different offsets: 27 of 356 resources in Stage_S02 decoded differently when asked for alone, including real geometry (f001_bdy_30, f106_sld_02_l/m/d, f101_wep_01_l). Both the viewer and assemble_ship decode subsets, so both could disagree with the container's own answer. This was a regression from distinct assignment itself. Fixed by filtering the OUTPUT: the assignment always runs over the whole container. One-name, three-name and full decodes now agree exactly. Cost: a single-resource query on a 50MB container goes from near-instant to ~15s; per-container caching is the follow-up. Ten suites green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -523,11 +523,13 @@ impl Xbg7Model {
|
||||
}
|
||||
let name = read_cstr(bytes, e.name_offset as usize + DIR_BASE)
|
||||
.unwrap_or_else(|| "XBG7".to_string());
|
||||
if let Some(w) = wanted {
|
||||
if !w.contains(&name) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// NOTE: `wanted` is NOT applied here. Distinct assignment resolves
|
||||
// collisions against the whole set of resources, so pruning first
|
||||
// made a filtered decode depend on *which* subset was asked for —
|
||||
// measured 2026-08-12: 27 of 356 resources in `Stage_S02` came out
|
||||
// at a different offset when requested alone. The filter is applied
|
||||
// to the OUTPUT instead, so a subset is always a subset of the
|
||||
// container's own answer.
|
||||
resources.push(Res {
|
||||
name,
|
||||
markers,
|
||||
@@ -722,6 +724,9 @@ impl Xbg7Model {
|
||||
}
|
||||
models.push(m);
|
||||
}
|
||||
if let Some(w) = wanted {
|
||||
models.retain(|m| w.contains(&m.name));
|
||||
}
|
||||
out = models;
|
||||
out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user