The second F10 capture (ship at _m LOD distance) closes e106 entirely: all 8 parts placed including the bridge both earlier captures missed, cross-validating the doc's 7 known translations to 0.1 units and adding brg_01 at the exact centreline (0, 153.3, -164.0). Matching hardened by what the real capture taught us: - LOD-aware: each part tries every variant vcount (base/_m/_l/_d) — a distant ship draws its LOD copies, same local frame. - Position-validated, SET-based, against the UNION of a part's variants: buffer order != decode order, and one draw's vcount equalled the _m count while its buffer held the FULL 1633-vert geometry. A coincidental vcount (foreign 51-vert mesh vs the bridge) is rejected by geometry. - Runtime mirror handled: twins share one file geometry; the engine uploads the starboard copy X-reflected. Mirror-validated draws bake diag(-1,1,1) and the viewer reverses triangle winding for det<0 so front faces stay outward. - Near-axis rotation entries snapped to exact 0/+-1 for a clean table; eng_01 keeps its genuine 30-degree nacelle rotation. data/ship_placements.txt now ships e106 (viewer renders via the captured table); embedded_e106_is_complete locks the baked data. part_pos + capture_match helper examples added. 10 ship_capture tests; 80 formats-lib tests green; viewer builds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
21 lines
856 B
Rust
21 lines
856 B
Rust
//! Print a resource's first N decoded positions (buffer order), for matching a
|
|
//! capture draw's `pos:` dump to a part:
|
|
//! cargo run --release --example part_pos -- <xpr path> <resource> [n]
|
|
use std::collections::HashSet;
|
|
use sylpheed_formats::mesh::Xbg7Model;
|
|
|
|
fn main() {
|
|
let a: Vec<String> = std::env::args().collect();
|
|
let bytes = std::fs::read(&a[1]).unwrap();
|
|
let n: usize = a.get(3).and_then(|s| s.parse().ok()).unwrap_or(4);
|
|
let want: HashSet<String> = [a[2].clone()].into();
|
|
for m in Xbg7Model::models_named(&bytes, &want, &|| false) {
|
|
let vc: usize = m.meshes.iter().map(|s| s.positions.len()).sum();
|
|
print!("{} vtx={}:", m.name, vc);
|
|
for p in m.meshes.iter().flat_map(|s| &s.positions).take(n) {
|
|
print!(" ({:.4},{:.4},{:.4})", p[0], p[1], p[2]);
|
|
}
|
|
println!();
|
|
}
|
|
}
|