00001
00032
00033
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
00044
00045 const F32 TORSO_TARGET_HALF_LIFE = 0.25f;
00046 const F32 MAX_TIME_DELTA = 2.f;
00047 const F32 TARGET_PLANE_THRESHOLD_DOT = 0.6f;
00048 const F32 TORSO_ROT_FRACTION = 0.5f;
00049
00050
00051
00052
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
00065
00066
00067 LLTargetingMotion::~LLTargetingMotion()
00068 {
00069 }
00070
00071
00072
00073
00074 LLMotion::LLMotionInitStatus LLTargetingMotion::onInitialize(LLCharacter *character)
00075 {
00076
00077 mCharacter = character;
00078
00079 mPelvisJoint = mCharacter->getJoint("mPelvis");
00080 mTorsoJoint = mCharacter->getJoint("mTorso");
00081 mRightHandJoint = mCharacter->getJoint("mWristRight");
00082
00083
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
00095 mTorsoState->setUsage(LLJointState::ROT);
00096 addJointState( mTorsoState );
00097
00098 return STATUS_SUCCESS;
00099 }
00100
00101
00102
00103
00104 BOOL LLTargetingMotion::onActivate()
00105 {
00106 return TRUE;
00107 }
00108
00109
00110
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
00132
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
00153 new_torso_rot = new_torso_rot * ~cur_torso_rot;
00154
00155
00156 new_torso_rot = nlerp(slerp_amt, mTorsoState->getRotation(), new_torso_rot);
00157
00158
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
00170
00171 void LLTargetingMotion::onDeactivate()
00172 {
00173 }
00174
00175
00176