00001
00032
00033
00034
00035 #include "linden_common.h"
00036
00037 #include "lleditingmotion.h"
00038 #include "llcharacter.h"
00039 #include "llhandmotion.h"
00040 #include "llcriticaldamp.h"
00041
00042
00043
00044
00045 const LLQuaternion EDIT_MOTION_WRIST_ROTATION(F_PI_BY_TWO * 0.7f, LLVector3(1.0f, 0.0f, 0.0f));
00046 const F32 TARGET_LAG_HALF_LIFE = 0.1f;
00047 const F32 TORSO_LAG_HALF_LIFE = 0.2f;
00048 const F32 MAX_TIME_DELTA = 2.f;
00049
00050 S32 LLEditingMotion::sHandPose = LLHandMotion::HAND_POSE_RELAXED_R;
00051 S32 LLEditingMotion::sHandPosePriority = 3;
00052
00053
00054
00055
00056
00057 LLEditingMotion::LLEditingMotion( const LLUUID &id) : LLMotion(id)
00058 {
00059 mCharacter = NULL;
00060
00061
00062 mParentJoint.addChild( &mShoulderJoint );
00063 mShoulderJoint.addChild( &mElbowJoint );
00064 mElbowJoint.addChild( &mWristJoint );
00065
00066 mName = "editing";
00067
00068 mParentState = new LLJointState;
00069 mShoulderState = new LLJointState;
00070 mElbowState = new LLJointState;
00071 mWristState = new LLJointState;
00072 mTorsoState = new LLJointState;
00073 }
00074
00075
00076
00077
00078
00079
00080 LLEditingMotion::~LLEditingMotion()
00081 {
00082 }
00083
00084
00085
00086
00087 LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *character)
00088 {
00089
00090 mCharacter = character;
00091
00092
00093 if (!mCharacter->getJoint("mShoulderLeft") ||
00094 !mCharacter->getJoint("mElbowLeft") ||
00095 !mCharacter->getJoint("mWristLeft"))
00096 {
00097 llwarns << "Invalid skeleton for editing motion!" << llendl;
00098 return STATUS_FAILURE;
00099 }
00100
00101
00102 mParentState->setJoint( mCharacter->getJoint("mShoulderLeft")->getParent() );
00103 mShoulderState->setJoint( mCharacter->getJoint("mShoulderLeft") );
00104 mElbowState->setJoint( mCharacter->getJoint("mElbowLeft") );
00105 mWristState->setJoint( mCharacter->getJoint("mWristLeft") );
00106 mTorsoState->setJoint( mCharacter->getJoint("mTorso"));
00107
00108 if ( ! mParentState->getJoint() )
00109 {
00110 llinfos << getName() << ": Can't get parent joint." << llendl;
00111 return STATUS_FAILURE;
00112 }
00113
00114 mWristOffset = LLVector3(0.0f, 0.2f, 0.0f);
00115
00116
00117 mShoulderState->setUsage(LLJointState::ROT);
00118 mElbowState->setUsage(LLJointState::ROT);
00119 mTorsoState->setUsage(LLJointState::ROT);
00120 mWristState->setUsage(LLJointState::ROT);
00121 addJointState( mShoulderState );
00122 addJointState( mElbowState );
00123 addJointState( mTorsoState );
00124 addJointState( mWristState );
00125
00126
00127 mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() );
00128 mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() );
00129 mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() );
00130 mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset );
00131
00132
00133 mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() );
00134 mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() );
00135 mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() );
00136
00137
00138 mIKSolver.setPoleVector( LLVector3( -1.0f, 1.0f, 0.0f ) );
00139
00140
00141 mIKSolver.setBAxis( LLVector3( -0.682683f, 0.0f, -0.730714f ) );
00142 mIKSolver.setupJoints( &mShoulderJoint, &mElbowJoint, &mWristJoint, &mTarget );
00143
00144 return STATUS_SUCCESS;
00145 }
00146
00147
00148
00149
00150 BOOL LLEditingMotion::onActivate()
00151 {
00152
00153 mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() );
00154 mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() );
00155 mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() );
00156 mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset );
00157
00158
00159 mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() );
00160 mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() );
00161 mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() );
00162
00163 return TRUE;
00164 }
00165
00166
00167
00168
00169 BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)
00170 {
00171 LLVector3 focus_pt;
00172 LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint");
00173
00174
00175 BOOL result = TRUE;
00176
00177 if (!pointAtPt)
00178 {
00179 focus_pt = mLastSelectPt;
00180 result = FALSE;
00181 }
00182 else
00183 {
00184 focus_pt = *pointAtPt;
00185 mLastSelectPt = focus_pt;
00186 }
00187
00188 focus_pt += mCharacter->getCharacterPosition();
00189
00190
00191 mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() );
00192 mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() );
00193 mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() );
00194 mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset );
00195
00196
00197 mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() );
00198 mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() );
00199 mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() );
00200
00201
00202 LLVector3 target = focus_pt - mParentJoint.getPosition();
00203 F32 target_dist = target.normVec();
00204
00205 LLVector3 edit_plane_normal(1.f / F_SQRT2, 1.f / F_SQRT2, 0.f);
00206 edit_plane_normal.normVec();
00207
00208 edit_plane_normal.rotVec(mTorsoState->getJoint()->getWorldRotation());
00209
00210 F32 dot = edit_plane_normal * target;
00211
00212 if (dot < 0.f)
00213 {
00214 target = target + (edit_plane_normal * (dot * 2.f));
00215 target.mV[VZ] += clamp_rescale(dot, 0.f, -1.f, 0.f, 5.f);
00216 target.normVec();
00217 }
00218
00219 target = target * target_dist;
00220 if (!target.isFinite())
00221 {
00222 llerrs << "Non finite target in editing motion with target distance of " << target_dist <<
00223 " and focus point " << focus_pt << llendl;
00224 }
00225
00226 mTarget.setPosition( target + mParentJoint.getPosition());
00227
00228
00229
00230
00231 if (!mTarget.getPosition().isExactlyZero())
00232 {
00233 LLQuaternion shoulderRot = mShoulderJoint.getRotation();
00234 LLQuaternion elbowRot = mElbowJoint.getRotation();
00235 mIKSolver.solve();
00236
00237
00238 F32 slerp_amt = LLCriticalDamp::getInterpolant(TARGET_LAG_HALF_LIFE);
00239 shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot);
00240 elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot);
00241
00242
00243 llassert(shoulderRot.isFinite());
00244 llassert(elbowRot.isFinite());
00245 mShoulderState->setRotation(shoulderRot);
00246 mElbowState->setRotation(elbowRot);
00247 mWristState->setRotation(LLQuaternion::DEFAULT);
00248 }
00249
00250 mCharacter->setAnimationData("Hand Pose", &sHandPose);
00251 mCharacter->setAnimationData("Hand Pose Priority", &sHandPosePriority);
00252 return result;
00253 }
00254
00255
00256
00257
00258 void LLEditingMotion::onDeactivate()
00259 {
00260 }
00261
00262
00263