BT410 5.3.79: the twist is live in the sim and absent from the wire

pod_render_twist.conf isolates it -- throttle and turn zero, torso sweeping,
[sim] confirming spd=0, so only the torso joint can move the view.  Five
frames across a full sweep differ by 0-74 pixels: the view does not move.
The same run's telemetry has the twist sweeping the full authored range
(-0.895 to -0.022 rad, cmdL/cmdR alternating, joint resolved) and the bridge
reports anim_abs=1, joints=0 -- only the root articulates.

The cause: RecurseSKLFile builds each skeleton node's DCS with a baked matrix
and flushes it once at build time, and nothing re-flushes a node when its
joint angle changes.  TorsoSimulation faithfully calls SetRotation() every
frame, updating the Joint object, but no renderable reads that back into the
node's dpl_DCS.  The simulation twists; the board never hears.

The missing piece is the per-frame joint renderable -- the engine's
ChildOffsetRenderable family (L4VIDRND.CPP:930) exists for exactly this, and
our RootRenderable already proves the pattern for the hull.  That one brick
unlocks the torso twist (and the cockpit eye panning with it, since the eye
hangs off that chain), the leg gait, and weapon-pod aim.  Until then the mech
translates through the world as a rigid body -- which is what every frame so
far has shown.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-29 20:13:12 -05:00
co-authored by Claude Fable 5
parent 3c289ff10a
commit 8769dae0ac
4 changed files with 1387 additions and 715 deletions
@@ -1826,3 +1826,44 @@ and the mapper one is four bytes into adjacent heap. But both were real
corruption running in every mission, and the Torso one was introduced by the
very fix that cut the fault rate -- worth remembering when a rate MOVES
instead of going to zero.)
--------------------------------------------------------------------------------
THE TWIST IS LIVE IN THE SIM AND ABSENT FROM THE WIRE -- JOINT ARTICULATION IS
THE NEXT BRICK
--------------------------------------------------------------------------------
pod_render_twist.conf isolates it: throttle and turn forced to zero, torso
sweeping. [sim] confirms spd=0, so the only thing that can move the view is
the torso joint the cockpit eye hangs off. Five frames captured across a
full sweep:
tt1 vs tt2..tt5: ~1370 differing pixels (0.3%%)
tt2..tt5 vs each other: 0-74 pixels (0.0%%)
The view does not move. Meanwhile the same run's telemetry has the twist
sweeping the full authored range (-0.895 -> -0.022 rad, cmdL/cmdR
alternating, joint resolved), and the bridge reports:
anim_abs=1 joints=0
Only the ROOT articulates. That is the whole story: RecurseSKLFile builds
each skeleton node's DCS with a baked matrix and flushes it ONCE at build
time, and nothing re-flushes a node when its joint angle changes.
Torso::TorsoSimulation faithfully calls horizontalJointNode->SetRotation()
every frame -- updating the Joint OBJECT -- but no renderable reads that back
into the node's dpl_DCS and re-flushes it. So the simulation twists and the
board never hears about it.
THE MISSING PIECE is the per-frame JOINT RENDERABLE: the engine's
ChildOffsetRenderable family (L4VIDRND.CPP:930) exists exactly for this --
each carries its own offset DCS under a parent joint's DCS, and its Execute
re-flushes when the joint moves, which is what fills vr_flush_dcs_artic
(0x1f) with more than one node. Our RootRenderable already proves the
pattern end to end for the hull; the skeleton nodes need the same treatment
per articulated joint.
That single brick unlocks three things at once, which is why it is the right
next one: the torso twist (and with it the cockpit eye panning, since the eye
hangs off that chain), the LEG GAIT (the 12-joint flurry the real-pod capture
shows while walking), and weapon-pod aim. Until then the mech translates
through the world as a rigid body -- which is exactly what every frame so far
has shown.