//===========================================================================// // File: torso.cpp // // Project: BattleTech Brick: Mech subsystems // // Contents: Torso -- torso twist / weapon elevation // //---------------------------------------------------------------------------// // Copyright (C) 1995, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include #pragma hdrstop #if !defined(TORSO_HPP) # include #endif #if !defined(MECH_HPP) # include #endif #if !defined(JOINT_HPP) # include #endif Derivation Torso::ClassDerivations( PowerWatcher::ClassDerivations, "Torso" ); Torso::SharedData Torso::DefaultData( Torso::ClassDerivations, Subsystem::MessageHandlers, Subsystem::AttributeIndex, Subsystem::StateCount ); Torso::Torso( Mech *owner, int subsystem_ID, SubsystemResource *r, SharedData &shared_data ): PowerWatcher(owner, subsystem_ID, r, shared_data) { Check(owner); Check_Pointer(r); isDamagedCopy = (owner->GetInstance() == Entity::ReplicantInstance); statusFlags = 0; buttonAccelerationPerSecond = r->buttonAccelerationPerSecond; buttonAccelerationStart = r->buttonAccelerationStartValue; baseTwistRate = r->horizontalRotationPerSecond * RAD_PER_DEG; baseElevationRate = r->verticalRotationPerSecond * RAD_PER_DEG; horizontalLimitRight= r->horizontalLimitRight * RAD_PER_DEG; horizontalLimitLeft = r->horizontalLimitLeft * RAD_PER_DEG; verticalLimitTop = r->verticalLimitTop * RAD_PER_DEG; verticalLimitBottom = r->verticalLimitBottom * RAD_PER_DEG; twistCenterHigh = verticalLimitTop; twistCenterLow = verticalLimitBottom; elevationCenter = verticalLimitTop; elevationHalfBottom = verticalLimitBottom * 0.5f; buttonRampActive = 0; buttonRamp = 0.0f; horizontalEnabled = r->torsoHorizontalEnabled; // // Resolve the named torso-twist skeleton joints (twist body + shadow) from // the mech skeleton (now live). A mech with a fixed torso, or one whose // joint name is absent from the skeleton, resolves NULL and simply never // twists. // horizontalJointNode = owner->ResolveJoint(r->torsoHorizontalJoint); horizontalShadowJointNode = owner->ResolveJoint(r->torsoHorizontalShadowJoint); if (getenv("BT_MECH_LOG")) { DEBUG_STREAM << "[torso] horizJoint '" << r->torsoHorizontalJoint << "' -> " << (void *)horizontalJointNode; if (horizontalJointNode != NULL) { DEBUG_STREAM << " type=" << (int)horizontalJointNode->GetJointType(); } DEBUG_STREAM << " enabled=" << (int)horizontalEnabled << endl << flush; } currentTwist = 0.0f; currentElevation = 0.0f; analogElevationAxis = 0.0f; analogTwistAxis = 0.0f; for (int i = 0; i < 22; ++i) { dynamicsState[i] = 0.0f; } // // Install the per-frame twist/elevation Performance (the replicant copy is // driven by console updates via TorsoCopySimulation instead, still staged). // if (owner->GetInstance() != Entity::ReplicantInstance) { SetPerformance(&Torso::TorsoSimulation); } Check_Fpu(); } Torso::~Torso() { } Logical Torso::TestClass(Mech &) { return True; } Logical Torso::TestInstance() const { return IsDerivedFrom(ClassDerivations); } // //############################################################################# // TorsoSimulation -- per-frame torso twist / weapon-elevation integration. // // Slews the current elevation/twist toward the analog aim axes (written by // MechControlsMapper::InterpretControls) at the resource base rates, clamped to // the resource limits. Authentic core (torso.cpp @004b6xxx): current += axis * // baseRate * dt. APPLYING the resolved angles onto the skeleton torso/gun // joints (horizontalJointNode / the elevation joint) is deferred with the // skeleton-link + render wave; here we advance the scalar aim state (read by the // HUD reticle / weapon aim and, once wired, the joints). //############################################################################# // void Torso::TorsoSimulation(Scalar time_slice) { Check(this); // // Elevation (weapon pitch): slew toward the analog axis, clamp to limits. // currentElevation += analogElevationAxis * baseElevationRate * time_slice; { Scalar lo = (verticalLimitBottom < verticalLimitTop) ? verticalLimitBottom : verticalLimitTop; Scalar hi = (verticalLimitBottom < verticalLimitTop) ? verticalLimitTop : verticalLimitBottom; if (currentElevation < lo) currentElevation = lo; if (currentElevation > hi) currentElevation = hi; } // // Twist (horizontal torso rotation): only mechs with an enabled torso joint. // if (horizontalEnabled) { currentTwist += analogTwistAxis * baseTwistRate * time_slice; Scalar lo = (horizontalLimitLeft < horizontalLimitRight) ? horizontalLimitLeft : horizontalLimitRight; Scalar hi = (horizontalLimitLeft < horizontalLimitRight) ? horizontalLimitRight : horizontalLimitLeft; if (currentTwist < lo) currentTwist = lo; if (currentTwist > hi) currentTwist = hi; // // Push the twist onto the skeleton torso joint so the upper body rotates // on the model. Hinge joints take the scalar angle about their axis; // ball joints take it as the yaw component. // if (horizontalJointNode != NULL) { Joint::JointType jt = horizontalJointNode->GetJointType(); if (jt == Joint::HingeXJointType || jt == Joint::HingeYJointType || jt == Joint::HingeZJointType) { horizontalJointNode->SetRotation(Radian(currentTwist)); } else if (jt == Joint::BallJointType) { horizontalJointNode->SetRotation(EulerAngles(0.0f, currentTwist, 0.0f)); } } } Check_Fpu(); } void Torso::TorsoCopySimulation(Scalar) { Fail("Torso::TorsoCopySimulation -- torso.cpp not yet reconstructed"); }