ship_capture: bake e106 COMPLETE from the 2026-07-26 F10 capture — all 8 parts
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>
This commit is contained in:
@@ -3992,6 +3992,12 @@ fn build_ship_model(
|
||||
let Some(src) = base.iter().find(|m| m.name == p.resource) else {
|
||||
continue;
|
||||
};
|
||||
// A captured mirror placement (det < 0 — the engine X-reflects the
|
||||
// second of a port/starboard pair) flips triangle winding; reverse each
|
||||
// triangle's index order so front faces stay outward.
|
||||
let det = p.m[0][0] * (p.m[1][1] * p.m[2][2] - p.m[1][2] * p.m[2][1])
|
||||
- p.m[0][1] * (p.m[1][0] * p.m[2][2] - p.m[1][2] * p.m[2][0])
|
||||
+ p.m[0][2] * (p.m[1][0] * p.m[2][1] - p.m[1][1] * p.m[2][0]);
|
||||
let mut m = src.clone();
|
||||
for sub in &mut m.meshes {
|
||||
for v in &mut sub.positions {
|
||||
@@ -4000,6 +4006,11 @@ fn build_ship_model(
|
||||
for nrm in &mut sub.normals {
|
||||
*nrm = rot(&p.m, nrm);
|
||||
}
|
||||
if det < 0.0 {
|
||||
for tri in sub.indices.chunks_exact_mut(3) {
|
||||
tri.swap(1, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
models.push(m);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user