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 
00060 
00061 //-----------------------------------------------------------------------------
00062 // ~LLTargetingMotion()
00063 // Class Destructor
00064 //-----------------------------------------------------------------------------
00065 LLTargetingMotion::~LLTargetingMotion()
00066 {
00067 }
00068 
00069 //-----------------------------------------------------------------------------
00070 // LLTargetingMotion::onInitialize(LLCharacter *character)
00071 //-----------------------------------------------------------------------------
00072 LLMotion::LLMotionInitStatus LLTargetingMotion::onInitialize(LLCharacter *character)
00073 {
00074         // save character for future use
00075         mCharacter = character;
00076 
00077         mPelvisJoint = mCharacter->getJoint("mPelvis");
00078         mTorsoJoint = mCharacter->getJoint("mTorso");
00079         mRightHandJoint = mCharacter->getJoint("mWristRight");
00080 
00081         // make sure character skeleton is copacetic
00082         if (!mPelvisJoint ||
00083                 !mTorsoJoint ||
00084                 !mRightHandJoint)
00085         {
00086                 llwarns << "Invalid skeleton for targeting motion!" << llendl;
00087                 return STATUS_FAILURE;
00088         }
00089 
00090         mTorsoState.setJoint( mTorsoJoint );
00091 
00092         // add joint states to the pose
00093         mTorsoState.setUsage(LLJointState::ROT);
00094         addJointState( &mTorsoState );
00095 
00096         return STATUS_SUCCESS;
00097 }
00098 
00099 //-----------------------------------------------------------------------------
00100 // LLTargetingMotion::onActivate()
00101 //-----------------------------------------------------------------------------
00102 BOOL LLTargetingMotion::onActivate()
00103 {
00104         return TRUE;
00105 }
00106 
00107 //-----------------------------------------------------------------------------
00108 // LLTargetingMotion::onUpdate()
00109 //-----------------------------------------------------------------------------
00110 BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask)
00111 {
00112         F32 slerp_amt = LLCriticalDamp::getInterpolant(TORSO_TARGET_HALF_LIFE);
00113 
00114         LLVector3 target;
00115         LLVector3* lookAtPoint = (LLVector3*)mCharacter->getAnimationData("LookAtPoint");
00116 
00117         BOOL result = TRUE;
00118 
00119         if (!lookAtPoint)
00120         {
00121                 return TRUE;
00122         }
00123         else
00124         {
00125                 target = *lookAtPoint;
00126                 target.normVec();
00127         }
00128         
00129         //LLVector3 target_plane_normal = LLVector3(1.f, 0.f, 0.f) * mPelvisJoint->getWorldRotation();
00130         //LLVector3 torso_dir = LLVector3(1.f, 0.f, 0.f) * (mTorsoJoint->getWorldRotation() * mTorsoState.getRotation());
00131 
00132         LLVector3 skyward(0.f, 0.f, 1.f);
00133         LLVector3 left(skyward % target);
00134         left.normVec();
00135         LLVector3 up(target % left);
00136         up.normVec();
00137         LLQuaternion target_aim_rot(target, left, up);
00138 
00139         LLQuaternion cur_torso_rot = mTorsoJoint->getWorldRotation();
00140 
00141         LLVector3 right_hand_at = LLVector3(0.f, -1.f, 0.f) * mRightHandJoint->getWorldRotation();
00142         left.setVec(skyward % right_hand_at);
00143         left.normVec();
00144         up.setVec(right_hand_at % left);
00145         up.normVec();
00146         LLQuaternion right_hand_rot(right_hand_at, left, up);
00147 
00148         LLQuaternion new_torso_rot = (cur_torso_rot * ~right_hand_rot) * target_aim_rot;
00149 
00150         // find ideal additive rotation to make torso point in correct direction
00151         new_torso_rot = new_torso_rot * ~cur_torso_rot;
00152 
00153         // slerp from current additive rotation to ideal additive rotation
00154         new_torso_rot = nlerp(slerp_amt, mTorsoState.getRotation(), new_torso_rot);
00155 
00156         // constraint overall torso rotation
00157         LLQuaternion total_rot = new_torso_rot * mTorsoJoint->getRotation();
00158         total_rot.constrain(F_PI_BY_TWO * 0.8f);
00159         new_torso_rot = total_rot * ~mTorsoJoint->getRotation();
00160 
00161         mTorsoState.setRotation(new_torso_rot);
00162 
00163         return result;
00164 }
00165 
00166 //-----------------------------------------------------------------------------
00167 // LLTargetingMotion::onDeactivate()
00168 //-----------------------------------------------------------------------------
00169 void LLTargetingMotion::onDeactivate()
00170 {
00171 }
00172 
00173 
00174 // End

Generated on Thu Jul 1 06:09:15 2010 for Second Life Viewer by  doxygen 1.4.7