lltargetingmotion.cpp

Go to the documentation of this file.
00001 
00032 //-----------------------------------------------------------------------------
00033 // Header Files
00034 //-----------------------------------------------------------------------------
00035 #include "linden_common.h"
00036 
00037 #include "lltargetingmotion.h"
00038 #include "llcharacter.h"
00039 #include "v3dmath.h"
00040 #include "llcriticaldamp.h"
00041 
00042 //-----------------------------------------------------------------------------
00043 // Constants
00044 //-----------------------------------------------------------------------------
00045 const F32 TORSO_TARGET_HALF_LIFE = 0.25f;
00046 const F32 MAX_TIME_DELTA = 2.f; //max two seconds a frame for calculating interpolation
00047 const F32 TARGET_PLANE_THRESHOLD_DOT = 0.6f;
00048 const F32 TORSO_ROT_FRACTION = 0.5f;
00049 
00050 //-----------------------------------------------------------------------------
00051 // LLTargetingMotion()
00052 // Class Constructor
00053 //-----------------------------------------------------------------------------
00054 LLTargetingMotion::LLTargetingMotion(const LLUUID &id) : LLMotion(id)
00055 {
00056         mCharacter = NULL;
00057         mName = "targeting";
00058 
00059         mTorsoState = new LLJointState;
00060 }
00061 
00062 
00063 //-----------------------------------------------------------------------------
00064 // ~LLTargetingMotion()
00065 // Class Destructor
00066 //-----------------------------------------------------------------------------
00067 LLTargetingMotion::~LLTargetingMotion()
00068 {
00069 }
00070 
00071 //-----------------------------------------------------------------------------
00072 // LLTargetingMotion::onInitialize(LLCharacter *character)
00073 //-----------------------------------------------------------------------------
00074 LLMotion::LLMotionInitStatus LLTargetingMotion::onInitialize(LLCharacter *character)
00075 {
00076         // save character for future use
00077         mCharacter = character;
00078 
00079         mPelvisJoint = mCharacter->getJoint("mPelvis");
00080         mTorsoJoint = mCharacter->getJoint("mTorso");
00081         mRightHandJoint = mCharacter->getJoint("mWristRight");
00082 
00083         // make sure character skeleton is copacetic
00084         if (!mPelvisJoint ||
00085                 !mTorsoJoint ||
00086                 !mRightHandJoint)
00087         {
00088                 llwarns << "Invalid skeleton for targeting motion!" << llendl;
00089                 return STATUS_FAILURE;
00090         }
00091 
00092         mTorsoState->setJoint( mTorsoJoint );
00093 
00094         // add joint states to the pose
00095         mTorsoState->setUsage(LLJointState::ROT);
00096         addJointState( mTorsoState );
00097 
00098         return STATUS_SUCCESS;
00099 }
00100 
00101 //-----------------------------------------------------------------------------
00102 // LLTargetingMotion::onActivate()
00103 //-----------------------------------------------------------------------------
00104 BOOL LLTargetingMotion::onActivate()
00105 {
00106         return TRUE;
00107 }
00108 
00109 //-----------------------------------------------------------------------------
00110 // LLTargetingMotion::onUpdate()
00111 //-----------------------------------------------------------------------------
00112 BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask)
00113 {
00114         F32 slerp_amt = LLCriticalDamp::getInterpolant(TORSO_TARGET_HALF_LIFE);
00115 
00116         LLVector3 target;
00117         LLVector3* lookAtPoint = (LLVector3*)mCharacter->getAnimationData("LookAtPoint");
00118 
00119         BOOL result = TRUE;
00120 
00121         if (!lookAtPoint)
00122         {
00123                 return TRUE;
00124         }
00125         else
00126         {
00127                 target = *lookAtPoint;
00128                 target.normVec();
00129         }
00130         
00131         //LLVector3 target_plane_normal = LLVector3(1.f, 0.f, 0.f) * mPelvisJoint->getWorldRotation();
00132         //LLVector3 torso_dir = LLVector3(1.f, 0.f, 0.f) * (mTorsoJoint->getWorldRotation() * mTorsoState->getRotation());
00133 
00134         LLVector3 skyward(0.f, 0.f, 1.f);
00135         LLVector3 left(skyward % target);
00136         left.normVec();
00137         LLVector3 up(target % left);
00138         up.normVec();
00139         LLQuaternion target_aim_rot(target, left, up);
00140 
00141         LLQuaternion cur_torso_rot = mTorsoJoint->getWorldRotation();
00142 
00143         LLVector3 right_hand_at = LLVector3(0.f, -1.f, 0.f) * mRightHandJoint->getWorldRotation();
00144         left.setVec(skyward % right_hand_at);
00145         left.normVec();
00146         up.setVec(right_hand_at % left);
00147         up.normVec();
00148         LLQuaternion right_hand_rot(right_hand_at, left, up);
00149 
00150         LLQuaternion new_torso_rot = (cur_torso_rot * ~right_hand_rot) * target_aim_rot;
00151 
00152         // find ideal additive rotation to make torso point in correct direction
00153         new_torso_rot = new_torso_rot * ~cur_torso_rot;
00154 
00155         // slerp from current additive rotation to ideal additive rotation
00156         new_torso_rot = nlerp(slerp_amt, mTorsoState->getRotation(), new_torso_rot);
00157 
00158         // constraint overall torso rotation
00159         LLQuaternion total_rot = new_torso_rot * mTorsoJoint->getRotation();
00160         total_rot.constrain(F_PI_BY_TWO * 0.8f);
00161         new_torso_rot = total_rot * ~mTorsoJoint->getRotation();
00162 
00163         mTorsoState->setRotation(new_torso_rot);
00164 
00165         return result;
00166 }
00167 
00168 //-----------------------------------------------------------------------------
00169 // LLTargetingMotion::onDeactivate()
00170 //-----------------------------------------------------------------------------
00171 void LLTargetingMotion::onDeactivate()
00172 {
00173 }
00174 
00175 
00176 // End

Generated on Fri May 16 08:32:00 2008 for SecondLife by  doxygen 1.5.5