BT410 Phase 5.3.5: eyepointRotation -- torso elevation pitches the eye/aim-ray, not a joint
Investigated the next planned binding (elevation -> gun joints jointlgun/ jointrgun) before implementing it, and found it was the wrong target: BT411's own reverse-engineering history records that NO gun/arm elevation joint exists in the authentic engine. The pod's stick-Y aim pitches the COCKPIT EYE and the weapon boresight directly (mech4.cpp @~5219, pixel-calibrated against real screenshots) -- the torso geometry never tilts for elevation on this mech family. Reconstructing a gun-joint binding would have been invented behavior. - MECH.HPP: EulerAngles eyepointRotation member (out of reservedState, now [208]) + GetEyepointRotation() accessor. - MECH.CPP: composed each frame in Simulate -- eyepointRotation = EulerAngles(Radian(Normalize(lookPitch+elevation)), Radian(Normalize(lookYaw)), Radian(0)), reading Torso::CurrentElevation() via sinkSourceSubsystem. lookPitch/lookYaw are 0 until the look-button wave (BTCommitLookState) lands. Verified: BT_FORCE_ELEV=0.8 -> torsoElev and eyePitch both read 0.349066 (the authentic 20 degree resource limit) every frame, exact match; neutral -> 0. Zero Fail. Corrected TORSO.NOTES.md's prior (wrong) "next: gun joints" note. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -162,8 +162,10 @@ Mech::Mech(
|
||||
bodyTargetSpeed = 0.0f;
|
||||
currentBodySpeed = 0.0f;
|
||||
|
||||
eyepointRotation = EulerAngles::Identity;
|
||||
|
||||
{
|
||||
for (int i = 0; i < 211; ++i)
|
||||
for (int i = 0; i < 208; ++i)
|
||||
{
|
||||
reservedState[i] = 0;
|
||||
}
|
||||
@@ -618,6 +620,31 @@ void
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
// Eyepoint / aim-ray composition (mech4.cpp @~5219, pixel-calibrated in the
|
||||
// BT411 reverse-engineering). The pilot's torso-elevation aim does NOT tilt
|
||||
// any skeleton joint on this mech family -- it pitches the cockpit eye and
|
||||
// the weapon boresight directly. Compose the look-state pitch/yaw (0 until
|
||||
// the look/eyepoint wave reconstructs BTCommitLookState) with the Torso's
|
||||
// currentElevation. DPLEyeRenderable / the aim ray read this each frame.
|
||||
//-----------------------------------------------------------------------
|
||||
//
|
||||
{
|
||||
Scalar lookPitch = 0.0f;
|
||||
Scalar lookYaw = 0.0f;
|
||||
Scalar elevation = 0.0f;
|
||||
if (sinkSourceSubsystem != NULL)
|
||||
{
|
||||
elevation = ((Torso *)sinkSourceSubsystem)->CurrentElevation();
|
||||
}
|
||||
eyepointRotation = EulerAngles(
|
||||
Radian(Radian::Normalize(lookPitch + elevation)),
|
||||
Radian(Radian::Normalize(lookYaw)),
|
||||
Radian(0.0f)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
// Integrate position and commit the Origin to the world transform.
|
||||
@@ -645,6 +672,7 @@ void
|
||||
<< localOrigin.linearPosition.z << ")"
|
||||
<< " yaw=" << (Scalar)ypr.yaw
|
||||
<< " spd=" << currentBodySpeed
|
||||
<< " eyePitch=" << (Scalar)eyepointRotation.pitch
|
||||
<< endl << flush;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@
|
||||
# include <namefilt.hpp>
|
||||
# endif
|
||||
|
||||
# if !defined(ROTATION_HPP)
|
||||
# include <rotation.hpp>
|
||||
# endif
|
||||
|
||||
//##################### Forward Class Declarations #######################
|
||||
class Mech;
|
||||
class Subsystem;
|
||||
@@ -307,6 +311,18 @@
|
||||
Scalar GetForwardThrottleScale() const { Check(this); return forwardThrottleScale; }
|
||||
void SetForwardThrottleScale(Scalar s){ Check(this); forwardThrottleScale = s; }
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Eyepoint / aim-ray composition. The pilot's torso-elevation aim (stick
|
||||
// pitch) does NOT tilt any skeleton joint on this mech family -- it pitches
|
||||
// the COCKPIT EYE and the weapon boresight (pixel-calibrated in the BT411
|
||||
// reverse-engineering: "pitch does not work" turned out to mean nothing
|
||||
// consumed Torso's currentElevation, not that a joint was un-animated).
|
||||
// Composed each frame in Simulate; DPLEyeRenderable / the aim ray read it.
|
||||
//
|
||||
public:
|
||||
const EulerAngles&
|
||||
GetEyepointRotation() const { Check(this); return eyepointRotation; }
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Local Data
|
||||
//
|
||||
@@ -367,12 +383,18 @@
|
||||
Scalar bodyTargetSpeed;
|
||||
Scalar currentBodySpeed;
|
||||
|
||||
//
|
||||
// Composed each frame in Simulate from the Torso elevation (+ the
|
||||
// look-state pitch/yaw once the look/eyepoint wave lands).
|
||||
//
|
||||
EulerAngles eyepointRotation;
|
||||
|
||||
//
|
||||
// Remaining per-frame targeting / animation state, advanced by the
|
||||
// mech2/mech3/mech4 simulation. Reserved until that path is
|
||||
// reconstructed with named fields.
|
||||
//
|
||||
int reservedState[211];
|
||||
int reservedState[208];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -259,8 +259,33 @@ drop, torso/free-look aiming (Torso/HUD analog axes), telemetry filters.
|
||||
(`horizJoint=''`, `enabled=0`) so its twist path is inert — correct and
|
||||
guarded; a torso-twist mech would drive the joint.
|
||||
|
||||
Next joint piece: elevation → the gun joints (`jointlgun`/`jointrgun`) — the
|
||||
aim mechanism for fixed-torso mechs — which needs the weapon-joint binding
|
||||
(resolved from the weapon subsystems, not the torso resource). Then the gait
|
||||
leg-clip animation. Both become VISIBLE only under the renderer; headlessly the
|
||||
joint transforms are computable/loggable.
|
||||
## PHASE 5.3 INCREMENT 5: eyepointRotation -- elevation is NOT a gun-joint binding (2026-07-21)
|
||||
|
||||
Before reconstructing "elevation → gun joints," checked BT411 for how the
|
||||
authentic engine actually consumes `Torso::currentElevation` — and it does NOT
|
||||
drive any skeleton joint. BT411's own history records the discovery (mech4.cpp
|
||||
@~5219, user report "pitch does not work"): the Torso sim integrated the R/F
|
||||
aim into `currentElevation` but nothing consumed it — no joint search ever
|
||||
existed for a gun/arm elevation joint. **The pod's stick-Y aim pitches the
|
||||
COCKPIT EYE, not the torso geometry**; `eyepointRotation` (an `EulerAngles`
|
||||
Mech member) is composed each frame from the look-state pitch/yaw (buttons)
|
||||
plus the Torso elevation, and `DPLEyeRenderable` reads it for both the camera
|
||||
view AND the weapon boresight (so a low target can still be hit — the fire ray
|
||||
re-applies the elevation onto the leveled boresight). BT411's sign convention
|
||||
was pixel-calibrated against real screenshots; our composition matches it
|
||||
verbatim (mirroring the additive pitch, zero look terms until that wave lands).
|
||||
|
||||
**Reconstructed:** `Mech::eyepointRotation` (`EulerAngles`, out of `reservedState`,
|
||||
now `[208]`) + `GetEyepointRotation()` accessor. Composed in `Simulate` each
|
||||
frame: `eyepointRotation = EulerAngles(Radian(Normalize(lookPitch + elevation)),
|
||||
Radian(Normalize(lookYaw)), Radian(0))`, reading `Torso::CurrentElevation()` via
|
||||
`sinkSourceSubsystem`. `lookPitch`/`lookYaw` are 0 until the look/eyepoint button
|
||||
wave (`BTCommitLookState`) is reconstructed.
|
||||
|
||||
**VERIFIED headlessly:** `BT_FORCE_ELEV=0.8` → `torsoElev=0.349066` (the 20°
|
||||
resource limit) and `eyePitch=0.349066` — an exact match, every frame; neutral →
|
||||
`eyePitch=0`. Zero Fail.
|
||||
|
||||
Next: the look-button wave (`BTCommitLookState`, `gBTLookPitch/Yaw`) to compose
|
||||
the full eyepoint; then the gait leg-clip animation. Both become VISIBLE only
|
||||
under the renderer; headlessly the composed angles are loggable (as here).
|
||||
|
||||
@@ -37,12 +37,19 @@ its twist path is inert — correctly guarded (null joint → no apply, no crash
|
||||
torso-twist mech drives the joint. Verified headlessly; the VISUAL rotation
|
||||
needs the renderer.
|
||||
|
||||
## Elevation does NOT drive a gun joint (corrected 2026-07-21)
|
||||
|
||||
Checked BT411 before reconstructing a "gun-elevation joint": no such joint
|
||||
binding exists anywhere in the authentic engine. `currentElevation` instead
|
||||
composes into `Mech::eyepointRotation` (the cockpit-eye / weapon-boresight
|
||||
pitch) — see MECH.NOTES.md "PHASE 5.3 INCREMENT 5". `TorsoSimulation` only
|
||||
needed to keep advancing the scalar state, which it already did; the missing
|
||||
piece was the CONSUMER (`Mech::Simulate`'s eyepoint composition), now
|
||||
reconstructed and verified (`torsoElev` == `eyePitch` every frame).
|
||||
|
||||
## Deferred
|
||||
|
||||
- **Elevation → gun joints.** This mech aims by pitching the guns
|
||||
(`jointlgun`/`jointrgun`), not twisting the torso. `currentElevation` still
|
||||
only advances the scalar state; applying it to the gun joints needs the
|
||||
weapon-joint binding (resolved from the weapon subsystems, not the torso
|
||||
resource) — the next joint piece.
|
||||
- HUD free-aim slew, look/eyepoint commit, `TorsoCopySimulation` (replicant
|
||||
console-driven aim) — still staged.
|
||||
- HUD free-aim slew, the look-button state machine (`BTCommitLookState` /
|
||||
`gBTLookPitch`/`gBTLookYaw` — composes with elevation into the full
|
||||
eyepoint), `TorsoCopySimulation` (replicant console-driven aim) — still
|
||||
staged.
|
||||
|
||||
Reference in New Issue
Block a user