lleditingmotion.cpp

Go to the documentation of this file.
00001 
00032 //-----------------------------------------------------------------------------
00033 // Header Files
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 // Constants
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;         // half-life of IK targeting
00047 const F32 TORSO_LAG_HALF_LIFE = 0.2f;
00048 const F32 MAX_TIME_DELTA = 2.f; //max two seconds a frame for calculating interpolation
00049 
00050 S32 LLEditingMotion::sHandPose = LLHandMotion::HAND_POSE_RELAXED_R;
00051 S32 LLEditingMotion::sHandPosePriority = 3;
00052 
00053 //-----------------------------------------------------------------------------
00054 // LLEditingMotion()
00055 // Class Constructor
00056 //-----------------------------------------------------------------------------
00057 LLEditingMotion::LLEditingMotion( const LLUUID &id) : LLMotion(id)
00058 {
00059         mCharacter = NULL;
00060 
00061         // create kinematic chain
00062         mParentJoint.addChild( &mShoulderJoint );
00063         mShoulderJoint.addChild( &mElbowJoint );
00064         mElbowJoint.addChild( &mWristJoint );
00065 
00066         mName = "editing";
00067 }
00068 
00069 
00070 //-----------------------------------------------------------------------------
00071 // ~LLEditingMotion()
00072 // Class Destructor
00073 //-----------------------------------------------------------------------------
00074 LLEditingMotion::~LLEditingMotion()
00075 {
00076 }
00077 
00078 //-----------------------------------------------------------------------------
00079 // LLEditingMotion::onInitialize(LLCharacter *character)
00080 //-----------------------------------------------------------------------------
00081 LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *character)
00082 {
00083         // save character for future use
00084         mCharacter = character;
00085 
00086         // make sure character skeleton is copacetic
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         // get the shoulder, elbow, wrist joints from the character
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         // add joint states to the pose
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         // propagate joint positions to kinematic chain
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         // propagate current joint rotations to kinematic chain
00127         mParentJoint.setRotation(       mParentState.getJoint()->getWorldRotation() );
00128         mShoulderJoint.setRotation(     mShoulderState.getJoint()->getRotation() );
00129         mElbowJoint.setRotation(        mElbowState.getJoint()->getRotation() );
00130 
00131         // connect the ikSolver to the chain
00132         mIKSolver.setPoleVector( LLVector3( -1.0f, 1.0f, 0.0f ) );
00133         // specifying the elbow's axis will prevent bad IK for the more
00134         // singular configurations, but the axis is limb-specific -- Leviathan 
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 // LLEditingMotion::onActivate()
00143 //-----------------------------------------------------------------------------
00144 BOOL LLEditingMotion::onActivate()
00145 {
00146         // propagate joint positions to kinematic chain
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         // propagate current joint rotations to kinematic chain
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 // LLEditingMotion::onUpdate()
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         // propagate joint positions to kinematic chain
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         // propagate current joint rotations to kinematic chain
00191         mParentJoint.setRotation(       mParentState.getJoint()->getWorldRotation() );
00192         mShoulderJoint.setRotation(     mShoulderState.getJoint()->getRotation() );
00193         mElbowJoint.setRotation(        mElbowState.getJoint()->getRotation() );
00194 
00195         // update target position from character
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 //      llinfos << "Point At: " << mTarget.getPosition() << llendl;
00223 
00224         // update the ikSolver
00225         if (!mTarget.getPosition().isExactlyZero())
00226         {
00227                 LLQuaternion shoulderRot = mShoulderJoint.getRotation();
00228                 LLQuaternion elbowRot = mElbowJoint.getRotation();
00229                 mIKSolver.solve();
00230 
00231                 // use blending...
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                 // now put blended values back into joints
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 // LLEditingMotion::onDeactivate()
00251 //-----------------------------------------------------------------------------
00252 void LLEditingMotion::onDeactivate()
00253 {
00254 }
00255 
00256 
00257 // End

Generated on Thu Jul 1 06:08:28 2010 for Second Life Viewer by  doxygen 1.4.7