//===========================================================================// // File: EyePointManager.hpp // Project: MechWarrior 4 // Contents: // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 03/20/00 JSE Initial coding, //---------------------------------------------------------------------------// // Copyright (C) 2000, Microsoft Corp. // All Rights reserved worldwide // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //===========================================================================// #include "MW4Headers.hpp" #include "EyePointManager.hpp" #include "mech.hpp" //############################################################################# //########################### EyePointManager ############################### //############################################################################# EyePointManager::ClassData* EyePointManager::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EyePointManager::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( EyePointManagerClassID, "MechWarrior4::EyePointManager", Receiver::DefaultData, 0, NULL ); Check_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EyePointManager::TerminateClass() { Check_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EyePointManager::EyePointManager(Mech *parent) : Adept::Receiver(DefaultData) { m_parentMech = parent; initilized = false; m_eyeJoint = NULL; m_jointWorld = NULL; m_eyeParent = NULL; m_springOffset = LinearMatrix4D::Identity; m_eyeDirection = LinearMatrix4D::Identity; m_originalEyeToParent = LinearMatrix4D::Identity; m_originalEyeToTorso = LinearMatrix4D::Identity; m_originalTorsoToRoot = LinearMatrix4D::Identity; m_torsoRotation = LinearMatrix4D::Identity; eyeState = StabalizedMode; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EyePointManager::~EyePointManager() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EyePointManager::Stabalize(Stuff::Scalar time) { if (eyeState == ToFollowMode || eyeState == FollowMode) { eyeState = ToStabalizedMode; transitionTimer = 0.0f; transitionTime = time; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EyePointManager::Follow(Stuff::Scalar time) { if (eyeState == ToStabalizedMode || eyeState == StabalizedMode) { eyeState = ToFollowMode; transitionTimer = 0.0f; transitionTime = time; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EyePointManager::PostCollisionExecute(Stuff::Scalar time_slice) { POSTCOLLISION_LOGIC("EyePoint Manager"); if (!initilized) { initilized = true; m_jointWorld = m_parentMech->FindChildMover("joint_WORLD"); Check_Object(m_jointWorld); m_eyeJoint = m_parentMech->FindChildMover("site_eyepoint"); Check_Object(m_eyeJoint); MWMover *torso_joint = m_parentMech->FindChildMover("joint_torso"); Check_Object(torso_joint); m_eyeParent = Cast_Object(MWMover *, m_eyeJoint->GetParentEntity()); m_springOffset = LinearMatrix4D::Identity; m_eyeDirection = LinearMatrix4D::Identity; m_originalEyeToParent = m_eyeJoint->GetLocalToParent(); LinearMatrix4D world_to_root; world_to_root.Invert(m_jointWorld->GetLocalToWorld()); LinearMatrix4D world_to_torso; world_to_torso.Invert(torso_joint->GetLocalToWorld()); m_originalEyeToTorso.Multiply(m_eyeJoint->GetLocalToWorld(), world_to_torso); m_originalTorsoToRoot.Multiply(torso_joint->GetLocalToWorld(), world_to_root); } if (!m_parentMech->usingEyeSpring) { POSTCOLLISION_LOGIC("EyePoint Manager::External"); LinearMatrix4D eye_to_parent; eye_to_parent.Multiply(m_eyeDirection, m_originalEyeToParent); m_eyeJoint->SetNewLocalToParent(eye_to_parent); m_eyeJoint->SyncMatrices(true); return; } switch(eyeState) { case StabalizedMode: { POSTCOLLISION_LOGIC("EyePoint Manager::Stabalized Mode"); LinearMatrix4D eye_to_parent; CalculateStabalizedEye(eye_to_parent); m_eyeJoint->SetNewLocalToParent(eye_to_parent); m_eyeJoint->SyncMatrices(true); } break; case FollowMode: { POSTCOLLISION_LOGIC("EyePoint Manager::Follow Mode"); LinearMatrix4D eye_to_parent; CalculateFollowEye(eye_to_parent); m_eyeJoint->SetNewLocalToParent(eye_to_parent); m_eyeJoint->SyncMatrices(true); } break; case ToFollowMode: { POSTCOLLISION_LOGIC("EyePoint Manager::To Follow Mode"); transitionTimer += time_slice; if (transitionTimer > transitionTime) { eyeState = FollowMode; LinearMatrix4D eye_to_parent; CalculateFollowEye(eye_to_parent); m_eyeJoint->SetNewLocalToParent(eye_to_parent); m_eyeJoint->SyncMatrices(true); time_slice = transitionTime; } else { LinearMatrix4D stab_eye_to_parent; CalculateStabalizedEye(stab_eye_to_parent); LinearMatrix4D fol_eye_to_parent; CalculateFollowEye(fol_eye_to_parent); Scalar lerp = transitionTimer/transitionTime; UnitQuaternion start_rot; start_rot = stab_eye_to_parent; UnitQuaternion stop_rot; stop_rot = fol_eye_to_parent; UnitQuaternion lerp_rot; lerp_rot.Lerp(start_rot, stop_rot, lerp); Point3D start_pos(stab_eye_to_parent); Point3D end_pos(fol_eye_to_parent); Point3D lerp_pos; lerp_pos.Lerp(start_pos, end_pos, lerp); LinearMatrix4D eye_to_parent; eye_to_parent.BuildRotation(lerp_rot); eye_to_parent.BuildTranslation(lerp_pos); m_eyeJoint->SetNewLocalToParent(eye_to_parent); m_eyeJoint->SyncMatrices(true); } } break; case ToStabalizedMode: { POSTCOLLISION_LOGIC("EyePoint Manager::To Stabalized Mode"); transitionTimer += time_slice; if (transitionTimer > transitionTime) { eyeState = StabalizedMode; LinearMatrix4D eye_to_parent; CalculateStabalizedEye(eye_to_parent); m_eyeJoint->SetNewLocalToParent(eye_to_parent); m_eyeJoint->SyncMatrices(true); time_slice = transitionTime; } else { LinearMatrix4D stab_eye_to_parent; CalculateStabalizedEye(stab_eye_to_parent); LinearMatrix4D fol_eye_to_parent; CalculateFollowEye(fol_eye_to_parent); Scalar lerp = transitionTimer/transitionTime; UnitQuaternion start_rot; start_rot = fol_eye_to_parent; UnitQuaternion stop_rot; stop_rot = stab_eye_to_parent; UnitQuaternion lerp_rot; lerp_rot.Lerp(start_rot, stop_rot, lerp); Point3D start_pos(fol_eye_to_parent); Point3D end_pos(stab_eye_to_parent); Point3D lerp_pos; lerp_pos.Lerp(start_pos, end_pos, lerp); LinearMatrix4D eye_to_parent; eye_to_parent.BuildRotation(lerp_rot); eye_to_parent.BuildTranslation(lerp_pos); m_eyeJoint->SetNewLocalToParent(eye_to_parent); m_eyeJoint->SyncMatrices(true); } } break; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EyePointManager::CalculateStabalizedEye(LinearMatrix4D &eye_to_parent) { // build the matrix for the eye to root matrix POSTCOLLISION_LOGIC("EyePoint Manager::Calc Stabalized"); LinearMatrix4D eye_to_root; LinearMatrix4D temp1; LinearMatrix4D temp2; // move to the torso and rotate temp1.Multiply(m_torsoRotation, m_originalTorsoToRoot); // move up the chain to the eye temp2.Multiply(m_originalEyeToTorso, temp1); // put in the spring temp1.Multiply(m_springOffset, temp2); // put in the eye direction eye_to_root.Multiply(m_eyeDirection, temp1); // move the eye into world space LinearMatrix4D eye_to_world; eye_to_world.Multiply(eye_to_root, m_jointWorld->GetLocalToWorld()); // make the matrix to move the world point into parent space LinearMatrix4D world_to_parent; world_to_parent.Invert(m_eyeParent->GetLocalToWorld()); // move the world eye point into eye space eye_to_parent.Multiply(eye_to_world, world_to_parent); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EyePointManager::CalculateFollowEye(LinearMatrix4D &eye_to_parent) { POSTCOLLISION_LOGIC("EyePoint Manager::Calc Follow"); LinearMatrix4D temp1; LinearMatrix4D temp2; //start with the generic position temp1 = m_originalEyeToParent; // put in the spring temp2.Multiply(m_springOffset, temp1); // put in the eye direction eye_to_parent.Multiply(m_eyeDirection, temp2); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EyePointManager::Reuse() { Check_Object(this); m_springOffset = LinearMatrix4D::Identity; m_eyeDirection = LinearMatrix4D::Identity; m_torsoRotation = LinearMatrix4D::Identity; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EyePointManager::TestInstance() { Verify(IsDerivedFrom(DefaultData)); }