72 lines
3.5 KiB
Markdown
72 lines
3.5 KiB
Markdown
# Handoff — capital-ship placement: static assembly EXACT (2026-07-26)
|
||
|
||
Branch `feature/ipfb-idxd-parser`, commits `c6ca5ce..ea32e77`. Canary fork
|
||
branch `capture-ship-placement`, tip `877163792`.
|
||
|
||
## Outcome
|
||
|
||
**Capital ships assemble exactly from the ISO alone — no captures needed.**
|
||
Runtime captures served as the oracle that cracked the static encoding and now
|
||
remain as verification tooling only.
|
||
|
||
## The two format discoveries (docs/re/ship-placement-runtime-capture.md)
|
||
|
||
1. **Node-TRS off-by-one** (`mesh.rs::read_trs9`): an XBG7 scene-graph node's
|
||
joint table holds NINE keyframe channels `[TX TY TZ RY RX RZ SX SY SZ]`
|
||
behind EIGHT pointer slots shifted one track forward — channel k+1 =
|
||
`f64@(ptr[k]+8)`, channel 0 (TX) = `f64@(ptr[0]−0x48)`. The old read never
|
||
saw TX (why hulls stacked on the centreline) and misassigned TY/RY.
|
||
2. **Euler order** (`mesh.rs::node_rotation`): `Ry(ch3)·Rx(ch4)·Rz(ch5)`,
|
||
angles direct — pinned by decomposing the captured engine-nacelle rotation
|
||
`Rx(−15°)·Rz(30°)` element-for-element.
|
||
|
||
## assemble_ship (ship.rs) — fully static, capture-validated
|
||
|
||
- Every composite-node instance (alias duplicates collapsed), including
|
||
cross-id turret mounts (`rou_e303_wep_01_root` ×2 on e106; e108 places 7).
|
||
- Engine cluster rig `e_rou_<id>_eng` mounts at `GN_Engine_01`
|
||
(two mirrored nacelles + centre engine).
|
||
- `brg`/`sld` at their exact GN frames (frames were always exact).
|
||
- Shared-geometry ±TX twins: the instance whose offset opposes the geometry's
|
||
dominant side draws X-reflected (viewer reverses winding on det<0).
|
||
- `exhaust_frames()`: the `GN_Jet`/`GN_SJet` frames — the game renders its
|
||
engine-exhaust FX there; the viewer draws marker cones at them (the engine
|
||
GEOMETRY is recessed in the hull by design; without the FX ships read
|
||
engine-less — that was the "engines inside the hull" report).
|
||
|
||
## Validation chain (all green)
|
||
|
||
- `ship::tests::static_assembly_matches_runtime_capture` (SYLPHEED_ISO): static
|
||
== the baked e106 capture, all 8 parts, T<1.0 R<0.02, nacelles ×2, turrets
|
||
×2, starboard mirror.
|
||
- `examples/capture_verify.rs` over the user's 5 multi-angle snapshots
|
||
(43 e106 instances): dominant clusters match static to ~1 unit on every part
|
||
incl. both nacelles. Run:
|
||
`cargo run --release --example capture_verify -- <Stage.xpr> e106 <logs…>`
|
||
- Offline audit (`examples/ship_audit.rs`) across all stages: no outliers among
|
||
composite ships; composite-less families (fighter morph sets, turret/prop
|
||
parts) are filtered from the viewer's Ships catalog.
|
||
- 81 formats-lib + all disc tests; viewer builds.
|
||
|
||
## Canary instrumentation (branch `capture-ship-placement`)
|
||
|
||
F10 → `xenia_ship_capture_NN.log` per press (multi-angle in one run), de-duped
|
||
by (vertex-buffer, c0..c2 WVP hash) so every instance of every part is
|
||
recorded. Launch:
|
||
```
|
||
cd xenia-canary/build/bin/Linux/Release
|
||
./xenia_canary "<…/Project Sylpheed - Arc of Deception (USA, Europe) (En,Ja).iso>"
|
||
```
|
||
|
||
## Open / next
|
||
|
||
- Verify remaining capital ships against the existing 5 snapshots (they contain
|
||
every on-screen ship): e105 (its engine block assembles dorsally — the one
|
||
placement to confirm), f105/f106/f101, e102. Same capture_verify invocation
|
||
with the other ship id.
|
||
- AA-gun models at `GN_AAGun*` frames need the Vessel recipe binding.
|
||
- SJet (maneuvering-vernier) marker orientation is approximate; main aft plumes
|
||
verified.
|
||
- `_mov` node animation keys (hull-opening sequences) — rest pose rendered now.
|
||
- Viewer GUI verification by the user (exhaust cones, catalog cleanup).
|