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
00060
00061
00062
00063
00064
00065 LLTargetingMotion::~LLTargetingMotion()
00066 {
00067 }
00068
00069
00070
00071
00072 LLMotion::LLMotionInitStatus LLTargetingMotion::onInitialize(LLCharacter *character)
00073 {
00074
00075 mCharacter = character;
00076
00077 mPelvisJoint = mCharacter->getJoint("mPelvis");
00078 mTorsoJoint = mCharacter->getJoint("mTorso");
00079 mRightHandJoint = mCharacter->getJoint("mWristRight");
00080
00081
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
00093 mTorsoState.setUsage(LLJointState::ROT);
00094 addJointState( &mTorsoState );
00095
00096 return STATUS_SUCCESS;
00097 }
00098
00099
00100
00101
00102 BOOL LLTargetingMotion::onActivate()
00103 {
00104 return TRUE;
00105 }
00106
00107
00108
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
00130
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
00151 new_torso_rot = new_torso_rot * ~cur_torso_rot;
00152
00153
00154 new_torso_rot = nlerp(slerp_amt, mTorsoState.getRotation(), new_torso_rot);
00155
00156
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
00168
00169 void LLTargetingMotion::onDeactivate()
00170 {
00171 }
00172
00173
00174