re: exact anchor offsets (GameMesh.vbuf_offset) -- correcting yesterday's defect table
The first read of the capture-truth table located our resources by searching the container for their leading vertices, which reads much worse than reality: the same leading run occurs at several offsets in one container. GameMesh now carries the offset the anchor scan actually chose, so the comparison is exact -- 4 of the ship's drawn buffers are anchored correctly, 2 are the twin collapse, and 2 are real mis-anchors of a size we do decode (brg 51 verts, eng_02_l 44). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -117,15 +117,27 @@ fn main() {
|
||||
// scan chose for each resource — a direct read-out of what we got wrong.
|
||||
if let Some(a) = args.iter().find_map(|a| a.strip_prefix("--truth=")) {
|
||||
let base = u32::from_str_radix(a.trim_start_matches("0x"), 16).expect("base");
|
||||
// Where the anchor scan actually put each sub-mesh — exact, from the
|
||||
// decoder, not inferred by searching for its leading vertices (the same
|
||||
// leading run occurs at several offsets in a container, so a search
|
||||
// cannot tell where a resource was anchored).
|
||||
let mut ours: BTreeMap<usize, Vec<(String, usize)>> = BTreeMap::new();
|
||||
for m in &models {
|
||||
let pos: Vec<[f32; 3]> =
|
||||
m.meshes.iter().flat_map(|s| s.positions.iter().copied()).take(8).collect();
|
||||
let n: usize = m.meshes.iter().map(|s| s.positions.len()).sum();
|
||||
for (o, _) in locate_run(&bytes, &pos) {
|
||||
ours.entry(o).or_default().push((m.name.clone(), n));
|
||||
for sub in &m.meshes {
|
||||
if let Some(o) = sub.vbuf_offset {
|
||||
ours.entry(o).or_default().push((m.name.clone(), sub.positions.len()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if args.iter().any(|a| a == "--anchors") {
|
||||
println!("{:<12} where our decode put each resource", "file offset");
|
||||
for (o, v) in &ours {
|
||||
for (n, c) in v {
|
||||
println!("0x{o:<10x} {n} ({c} verts)");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
let mut drawn: BTreeMap<usize, u32> = BTreeMap::new();
|
||||
for (_, draws) in &logs {
|
||||
for d in draws {
|
||||
@@ -135,7 +147,14 @@ fn main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("{:<12} {:>7} claimed by our decode", "file offset", "vcount");
|
||||
// Which resources have the drawn vertex count, wherever we put them?
|
||||
// Right size + wrong place is a different bug from never finding it.
|
||||
let mut by_count: BTreeMap<usize, Vec<String>> = BTreeMap::new();
|
||||
for m in &models {
|
||||
let n: usize = m.meshes.iter().map(|s| s.positions.len()).sum();
|
||||
by_count.entry(n).or_default().push(m.name.clone());
|
||||
}
|
||||
println!("{:<12} {:>7} {:<44} our resources with that vcount", "file offset", "vcount", "claimed by our decode");
|
||||
for (off, vcount) in &drawn {
|
||||
let who = ours
|
||||
.get(off)
|
||||
@@ -143,7 +162,18 @@ fn main() {
|
||||
v.iter().map(|(n, c)| format!("{n}({c})")).collect::<Vec<_>>().join(", ")
|
||||
})
|
||||
.unwrap_or_else(|| "— NOBODY".into());
|
||||
println!("0x{off:<10x} {vcount:>7} {who}");
|
||||
let same = by_count
|
||||
.get(&(*vcount as usize))
|
||||
.map(|v| v.join(", "))
|
||||
.unwrap_or_else(|| "— none".into());
|
||||
// Nearest resource we anchored at or before this offset — the
|
||||
// likely owner of a buffer nobody claims.
|
||||
let near = ours
|
||||
.range(..=*off)
|
||||
.next_back()
|
||||
.map(|(o, v)| format!("{} @ -0x{:x}", v[0].0, off - o))
|
||||
.unwrap_or_default();
|
||||
println!("0x{off:<10x} {vcount:>7} {who:<44} {same:<34} {near}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user