Gyro: byte-exact re-enable -- ctor map, integrators, jointeye writers (task #56)
The Gyroscope subsystem is LIVE again (was a stub since the NaN revert).
Reconstructed byte-exact from @004b3778 / @004b2ec0 / @004b30ec / @004b33e0 /
@004b34ec + the byte-verified dispatch in the unexported Mech performance
FUN_004a9b5c (calls @0x4aaf74/0x4aaf83):
- ctor field map corrected: springConstant@0x1E8 / dampingConstant@0x1F4 were
mislabelled (the old 'eyeOrientation = r->springConstant' poison line), the
0x254-0x2B3 block (externalPitchPtr, work matrix, placement) was missing so
everything after was mis-offset, and clamps/accumulators were 0xCD fill --
every field now initialised per the binary; 33 offsets static_assert-locked,
sizeof == 0x3D0 exact
- integrators: state-minus-target displacements, componentwise damping
OVERWRITE (FUN_004086d0 is a component multiply, not a cross), position step
without dt, clamp to [posSpring, negSpring]; IntegrateBody's X/Z-crossed
force + integration terms
- writers: WriteMechJoint drives ONE node ('jointeye', type 5): TRANSLATION =
eyePosition spring, ROTATION = bodyOrientation spring; WriteEyeJoint is a
multiplicative sway attenuator on 'jointlocal' (post-anim only)
- dispatch moved out of GyroscopeSimulation into the Mech performance tail
(GyroFrameJointWrite bridge, mech4.cpp) with the binary gates; gyro<->torso
pitch link wired (gyro+0x258 = &torso currentTwist) via complete-type-TU
bridges, retiring the SubProxy::linkTarget landmine
- Mech ctor: deathAnimationLatched/legResetLatch were never initialised --
0xCDCDCDCD gated the writers off silently
Runtime-verified: joints resolve (both BallTranslation), Performance installs,
WriteMechJoint finite from frame 0 (no NaN), Madcat cockpit un-regressed,
combat targeting healthy. Empirical: spring targets are SYMMETRIC -> eye
equilibrium (0,0,0), clamps +/-0.1-0.15u -- the gyro is the hit-BOUNCE
mechanism, not a steady eye offset (hypothesis disproven, recorded in KB).
Pending (task #56 tail): the damage->gyro fan-out FUN_004b2980 (unexported
gap) so hits actually kick the springs; the mech+0x3F0 overspeed sway model;
the torso-pitch EyepointRotation writer (FUN_004b66b4) + glance-look states.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
abaa145b6f
commit
cb85517ede
@@ -3147,6 +3147,39 @@ void
|
||||
<< " present / roster " << subsystemCount << "\n" << std::flush;
|
||||
}
|
||||
|
||||
//
|
||||
// GYRO JOINT-WRITE DISPATCH (task #56, byte-verified @0x4aaf18-0x4aaf89):
|
||||
// the binary Mech master performance tail pushes the gyro's integrated state
|
||||
// into the skeleton every frame AFTER the animation pass + subsystem tick:
|
||||
// gyro->swayBias = mech sway accumulator (the mech+0x3F0 overspeed model is
|
||||
// NOT yet reconstructed -- feed 0, flagged);
|
||||
// if (!deathAnimationLatched) { if (legAnimationState != 0) WriteEyeJoint();
|
||||
// WriteMechJoint(); }
|
||||
// WriteMechJoint drives 'jointeye' (translation = the eye spring offset +
|
||||
// hit bounce, rotation = body tip); siteeyepoint rides that joint, so this
|
||||
// IS what moves the cockpit eye. Runs after the roster tick above (the gyro
|
||||
// Performance integrated this frame) and after the gait channel wrote the
|
||||
// joints (WriteEyeJoint is multiplicative on the animated rotation).
|
||||
//
|
||||
if (GetInstance() == MasterInstance)
|
||||
{
|
||||
extern void GyroFrameJointWrite(Subsystem *, Scalar, int, int);
|
||||
static int s_gyrodbg = 0;
|
||||
if (getenv("BT_GYRO_LOG") && s_gyrodbg++ == 0)
|
||||
DEBUG_STREAM << "[gyro] dispatch: gyro=" << (void *)gyroSubsystem
|
||||
<< " legAnim=" << legAnimationState
|
||||
<< " death=" << deathAnimationLatched << "\n" << std::flush;
|
||||
GyroFrameJointWrite(gyroSubsystem, 0.0f /* mech+0x3F0 model TBD */,
|
||||
legAnimationState, deathAnimationLatched);
|
||||
}
|
||||
else if (getenv("BT_GYRO_LOG"))
|
||||
{
|
||||
static int s_gyrodbg2 = 0;
|
||||
if (s_gyrodbg2++ == 0)
|
||||
DEBUG_STREAM << "[gyro] dispatch SKIPPED: instance=" << (int)GetInstance()
|
||||
<< " != master\n" << std::flush;
|
||||
}
|
||||
|
||||
// Keep the simulation/networking bookkeeping consistent (this is exactly
|
||||
// what the base "no time / stasis" early-out does).
|
||||
WriteSimulationUpdate(update_stream);
|
||||
|
||||
Reference in New Issue
Block a user