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