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         mParentState = new LLJointState;
00069         mShoulderState = new LLJointState;
00070         mElbowState = new LLJointState;
00071         mWristState = new LLJointState;
00072         mTorsoState = new LLJointState;
00073 }
00074 
00075 
00076 //-----------------------------------------------------------------------------
00077 // ~LLEditingMotion()
00078 // Class Destructor
00079 //-----------------------------------------------------------------------------
00080 LLEditingMotion::~LLEditingMotion()
00081 {
00082 }
00083 
00084 //-----------------------------------------------------------------------------
00085 // LLEditingMotion::onInitialize(LLCharacter *character)
00086 //-----------------------------------------------------------------------------
00087 LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *character)
00088 {
00089         // save character for future use
00090         mCharacter = character;
00091 
00092         // make sure character skeleton is copacetic
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         // get the shoulder, elbow, wrist joints from the character
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         // add joint states to the pose
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         // propagate joint positions to kinematic chain
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         // propagate current joint rotations to kinematic chain
00133         mParentJoint.setRotation(       mParentState->getJoint()->getWorldRotation() );
00134         mShoulderJoint.setRotation(     mShoulderState->getJoint()->getRotation() );
00135         mElbowJoint.setRotation(        mElbowState->getJoint()->getRotation() );
00136 
00137         // connect the ikSolver to the chain
00138         mIKSolver.setPoleVector( LLVector3( -1.0f, 1.0f, 0.0f ) );
00139         // specifying the elbow's axis will prevent bad IK for the more
00140         // singular configurations, but the axis is limb-specific -- Leviathan 
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 // LLEditingMotion::onActivate()
00149 //-----------------------------------------------------------------------------
00150 BOOL LLEditingMotion::onActivate()
00151 {
00152         // propagate joint positions to kinematic chain
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         // propagate current joint rotations to kinematic chain
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 // LLEditingMotion::onUpdate()
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         // propagate joint positions to kinematic chain
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         // propagate current joint rotations to kinematic chain
00197         mParentJoint.setRotation(       mParentState->getJoint()->getWorldRotation() );
00198         mShoulderJoint.setRotation(     mShoulderState->getJoint()->getRotation() );
00199         mElbowJoint.setRotation(        mElbowState->getJoint()->getRotation() );
00200 
00201         // update target position from character
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 //      llinfos << "Point At: " << mTarget.getPosition() << llendl;
00229 
00230         // update the ikSolver
00231         if (!mTarget.getPosition().isExactlyZero())
00232         {
00233                 LLQuaternion shoulderRot = mShoulderJoint.getRotation();
00234                 LLQuaternion elbowRot = mElbowJoint.getRotation();
00235                 mIKSolver.solve();
00236 
00237                 // use blending...
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                 // now put blended values back into joints
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 // LLEditingMotion::onDeactivate()
00257 //-----------------------------------------------------------------------------
00258 void LLEditingMotion::onDeactivate()
00259 {
00260 }
00261 
00262 
00263 // End

Generated on Fri May 16 08:31:57 2008 for SecondLife by  doxygen 1.5.5