re: the break-composite alarm is false -- the container stores 3-6 copies of each buffer
locate_draw counts copies of a captured buffer. The f105 parts _rou_f105_break claims exist 3-6 times over (the 2336-vert one: 6 direct AND 6 mirrored), and every live LOD checked is anchored on a direct, byte-identical copy -- so the composite taking the drawn copy costs nothing. This also calibrates the oracle: 'exact' (anchored at the drawn offset) is stricter than correct, so 45/46 is a lower bound. Open: a resource landing on a MIRRORED copy would be a real defect invisible to every count-based metric. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
53
crates/sylpheed-formats/examples/locate_draw.rs
Normal file
53
crates/sylpheed-formats/examples/locate_draw.rs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//! How many copies of a captured buffer does a container hold?
|
||||||
|
//!
|
||||||
|
//! The twins showed that two resources decoding to one buffer can mean the
|
||||||
|
//! container really holds two (mirrored) copies and our scan found only one.
|
||||||
|
//! This asks that question for any draw: give it a `vbase`, and it reports every
|
||||||
|
//! offset whose leading vertices match the draw's dumped positions — directly, and
|
||||||
|
//! X-mirrored.
|
||||||
|
//!
|
||||||
|
//! Usage: locate_draw <container.xpr> <capture.log> <vbase-hex>...
|
||||||
|
use sylpheed_formats::ship_capture::{parse_capture, parse_drawlog};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let a: Vec<String> = std::env::args().collect();
|
||||||
|
let bytes = std::fs::read(&a[1]).expect("container");
|
||||||
|
let text = std::fs::read_to_string(&a[2]).expect("log");
|
||||||
|
let mut draws = parse_capture(&text);
|
||||||
|
if draws.is_empty() {
|
||||||
|
draws = parse_drawlog(&text);
|
||||||
|
}
|
||||||
|
let be = |at: usize| f32::from_be_bytes(bytes[at..at + 4].try_into().unwrap());
|
||||||
|
|
||||||
|
for want in &a[3..] {
|
||||||
|
let vb = u32::from_str_radix(want.trim_start_matches("0x"), 16).expect("hex vbase");
|
||||||
|
let Some(d) = draws.iter().find(|d| d.vbase == vb) else {
|
||||||
|
println!("vbase 0x{vb:08X}: not in this log");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let n = d.pos.len().min(8);
|
||||||
|
let mut direct = Vec::new();
|
||||||
|
let mut mirror = Vec::new();
|
||||||
|
for o in (0..bytes.len().saturating_sub(12 + 64 * 24)).step_by(4) {
|
||||||
|
for (flip, out) in [(1.0f32, &mut direct), (-1.0f32, &mut mirror)] {
|
||||||
|
let hit = (0..n).all(|k| {
|
||||||
|
let at = o + k * 24;
|
||||||
|
(be(at) - flip * d.pos[k][0]).abs() <= 1e-4
|
||||||
|
&& (be(at + 4) - d.pos[k][1]).abs() <= 1e-4
|
||||||
|
&& (be(at + 8) - d.pos[k][2]).abs() <= 1e-4
|
||||||
|
});
|
||||||
|
if hit {
|
||||||
|
out.push(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!(
|
||||||
|
"vbase 0x{vb:08X} vcount={}: {} direct copy/copies {:x?}, {} mirrored {:x?}",
|
||||||
|
d.vcount,
|
||||||
|
direct.len(),
|
||||||
|
&direct[..],
|
||||||
|
mirror.len(),
|
||||||
|
&mirror[..]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -898,14 +898,37 @@ systematic mis-anchor is invisible to it because it is consistent. Where the two
|
|||||||
disagree, the capture wins. Full suite green including the disc- and ISO-gated
|
disagree, the capture wins. Full suite green including the disc- and ISO-gated
|
||||||
ship tests.
|
ship tests.
|
||||||
|
|
||||||
❔ **Still open — grouped composites.** `_rou_f105_break` (the f105 destruction
|
✅ **Closed — the grouped composite is a false alarm.** `_rou_f105_break` (the
|
||||||
model) claims **twelve consecutive** drawn buffers, each matching one of its
|
f105 destruction model) claims **twelve consecutive** drawn buffers while
|
||||||
sub-mesh vertex counts exactly, while `f105_bdy_01_m`, `f105_bdy_03_m`,
|
`f105_bdy_01_m`, `f105_bdy_03_m` and `f105_eng_01_m` sit elsewhere, which looked
|
||||||
`f105_eng_01_m` — resources of exactly those sizes — are anchored elsewhere.
|
like the twins' bug in the grouped-pool path. It is not.
|
||||||
Distinct assignment does not touch this: the grouped-pool path is excluded. The
|
`examples/locate_draw.rs` counts how many copies of a captured buffer a container
|
||||||
question is the twins' question again — does the container hold two copies of
|
holds, directly and X-mirrored:
|
||||||
each of those buffers, or one that both names should share? The same
|
|
||||||
mirror/duplicate test would answer it.
|
| drawn buffer | vcount | direct copies | mirrored copies |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `0x1bf596c` | 2446 | **3** | 0 |
|
||||||
|
| `0x1c0fe2c` | 2336 | **6** | **6** |
|
||||||
|
| `0x1c211cc` | 1402 | **4** | 0 |
|
||||||
|
| `0x1bf40f4` | 261 | 1 | 0 |
|
||||||
|
|
||||||
|
The container stores these parts several times over, and every live LOD checked
|
||||||
|
(`f105_bdy_01_m` at `0x1ecb4c0`, `f105_bdy_03_m` at `0x1f902a4`, `f105_eng_01_m`
|
||||||
|
at `0x1ffb884`) is anchored on a **direct** copy — byte-identical geometry to the
|
||||||
|
one the engine drew. So the composite taking "the drawn" copy costs nothing: the
|
||||||
|
decode is the same vertices either way. (The draws use the ordinary ship shader
|
||||||
|
`0xEEA84C59D7F95371`, the same one as the validated e106 hull draws, so these are
|
||||||
|
intact-ship draws, not debris.)
|
||||||
|
|
||||||
|
⚠️ **This also calibrates the oracle metric.** "Exact" in the tables above means
|
||||||
|
*anchored at the offset the engine drew from*, which is stricter than correct: a
|
||||||
|
resource anchored on an identical copy is equally right. The 45/46 figure stands
|
||||||
|
as a lower bound, and an "unclaimed" row is not automatically a defect.
|
||||||
|
|
||||||
|
❔ What the copy counts *do* leave open: with six direct and six mirrored copies
|
||||||
|
of one buffer, a resource landing on a **mirrored** copy would be a real defect
|
||||||
|
and would look identical to a correct decode in every count-based metric. Only a
|
||||||
|
capture (or the twin-pair invariant) can catch it.
|
||||||
|
|
||||||
Not settled: `e106_brg_01_b_02` ≡ `e106_brg_01_l` (51 verts). A second 51-vertex
|
Not settled: `e106_brg_01_b_02` ≡ `e106_brg_01_l` (51 verts). A second 51-vertex
|
||||||
`vbase` exists in the logs but is **not** from this container, and the container
|
`vbase` exists in the logs but is **not** from this container, and the container
|
||||||
|
|||||||
Reference in New Issue
Block a user