llkeyframemotion.cpp

Go to the documentation of this file.
00001 
00032 //-----------------------------------------------------------------------------
00033 // Header Files
00034 //-----------------------------------------------------------------------------
00035 #include "linden_common.h"
00036 
00037 #include "llmath.h"
00038 #include "llanimationstates.h"
00039 #include "llassetstorage.h"
00040 #include "lldatapacker.h"
00041 #include "llcharacter.h"
00042 #include "llcriticaldamp.h"
00043 #include "lldir.h"
00044 #include "llendianswizzle.h"
00045 #include "llkeyframemotion.h"
00046 #include "llquantize.h"
00047 #include "llvfile.h"
00048 #include "m3math.h"
00049 #include "message.h"
00050 
00051 //-----------------------------------------------------------------------------
00052 // Static Definitions
00053 //-----------------------------------------------------------------------------
00054 LLVFS*                          LLKeyframeMotion::sVFS = NULL;
00055 LLKeyframeDataCache::keyframe_data_map_t        LLKeyframeDataCache::sKeyframeDataMap;
00056 
00057 //-----------------------------------------------------------------------------
00058 // Globals
00059 //-----------------------------------------------------------------------------
00060 static F32 JOINT_LENGTH_K = 0.7f;
00061 static S32 MAX_ITERATIONS = 20;
00062 static S32 MIN_ITERATIONS = 1;
00063 static S32 MIN_ITERATION_COUNT = 2;
00064 static F32 MAX_PIXEL_AREA_CONSTRAINTS = 80000.f;
00065 static F32 MIN_PIXEL_AREA_CONSTRAINTS = 1000.f;
00066 static F32 MIN_ACCELERATION_SQUARED = 0.0005f * 0.0005f;
00067 
00068 static F32 MAX_CONSTRAINTS = 10;
00069 
00070 //-----------------------------------------------------------------------------
00071 // JointMotionList
00072 //-----------------------------------------------------------------------------
00073 LLKeyframeMotion::JointMotionList::JointMotionList()
00074         : mNumJointMotions(0),
00075           mJointMotionArray(NULL)
00076 {
00077 }
00078 
00079 LLKeyframeMotion::JointMotionList::~JointMotionList()
00080 {
00081         for_each(mConstraints.begin(), mConstraints.end(), DeletePointer());
00082         delete [] mJointMotionArray;
00083 }
00084 
00085 U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo()
00086 {
00087         S32     total_size = sizeof(JointMotionList);
00088 
00089         for (U32 i = 0; i < mNumJointMotions; i++)
00090         {
00091                 LLKeyframeMotion::JointMotion* joint_motion_p = &mJointMotionArray[i];
00092 
00093                 llinfos << "\tJoint " << joint_motion_p->mJointName << llendl;
00094                 if (joint_motion_p->mUsage & LLJointState::SCALE)
00095                 {
00096                         llinfos << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at " 
00097                         << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << llendl;
00098 
00099                         total_size += joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey);
00100                 }
00101                 if (joint_motion_p->mUsage & LLJointState::ROT)
00102                 {
00103                         llinfos << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at " 
00104                         << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << llendl;
00105 
00106                         total_size += joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey);
00107                 }
00108                 if (joint_motion_p->mUsage & LLJointState::POS)
00109                 {
00110                         llinfos << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at " 
00111                         << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << llendl;
00112 
00113                         total_size += joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey);
00114                 }
00115         }
00116         llinfos << "Size: " << total_size << " bytes" << llendl;
00117 
00118         return total_size;
00119 }
00120 
00121 //-----------------------------------------------------------------------------
00122 //-----------------------------------------------------------------------------
00123 // ****Curve classes
00124 //-----------------------------------------------------------------------------
00125 //-----------------------------------------------------------------------------
00126 
00127 //-----------------------------------------------------------------------------
00128 // ScaleCurve::ScaleCurve()
00129 //-----------------------------------------------------------------------------
00130 LLKeyframeMotion::ScaleCurve::ScaleCurve()
00131 {
00132         mInterpolationType = LLKeyframeMotion::IT_LINEAR;
00133         mNumKeys = 0;
00134 }
00135 
00136 //-----------------------------------------------------------------------------
00137 // ScaleCurve::~ScaleCurve()
00138 //-----------------------------------------------------------------------------
00139 LLKeyframeMotion::ScaleCurve::~ScaleCurve() 
00140 {
00141         mKeys.deleteAllData();
00142         mNumKeys = 0;
00143 }
00144 
00145 //-----------------------------------------------------------------------------
00146 // getValue()
00147 //-----------------------------------------------------------------------------
00148 LLVector3 LLKeyframeMotion::ScaleCurve::getValue(F32 time, F32 duration)
00149 {
00150         LLVector3 value;
00151         F32 index_before, index_after;
00152         ScaleKey* scale_before;
00153         ScaleKey* scale_after;
00154 
00155         mKeys.getInterval(time, index_before, index_after, scale_before, scale_after);
00156         if (scale_before)
00157         {
00158                 if (!scale_after)
00159                 {
00160                         scale_after = &mLoopInKey;
00161                         index_after = duration;
00162                 }
00163 
00164                 if (index_after == index_before)
00165                 {
00166                         value = scale_after->mScale;
00167                 }
00168                 else
00169                 {
00170                         F32 u = (time - index_before) / (index_after - index_before);
00171                         value = interp(u, *scale_before, *scale_after);
00172                 }
00173         }
00174         else
00175         {
00176                 // before first key
00177                 if (scale_after)
00178                 {
00179                         value = scale_after->mScale;
00180                 }
00181                 // no keys?
00182                 else
00183                 {
00184                         value.clearVec();
00185                 }
00186         }
00187 
00188         return value;
00189 }
00190 
00191 //-----------------------------------------------------------------------------
00192 // interp()
00193 //-----------------------------------------------------------------------------
00194 LLVector3 LLKeyframeMotion::ScaleCurve::interp(F32 u, ScaleKey& before, ScaleKey& after)
00195 {
00196         switch (mInterpolationType)
00197         {
00198         case IT_STEP:
00199                 return before.mScale;
00200 
00201         default:
00202         case IT_LINEAR:
00203         case IT_SPLINE:
00204                 return lerp(before.mScale, after.mScale, u);
00205         }
00206 }
00207 
00208 //-----------------------------------------------------------------------------
00209 // RotationCurve::RotationCurve()
00210 //-----------------------------------------------------------------------------
00211 LLKeyframeMotion::RotationCurve::RotationCurve()
00212 {
00213         mInterpolationType = LLKeyframeMotion::IT_LINEAR;
00214         mNumKeys = 0;
00215 }
00216 
00217 //-----------------------------------------------------------------------------
00218 // RotationCurve::~RotationCurve()
00219 //-----------------------------------------------------------------------------
00220 LLKeyframeMotion::RotationCurve::~RotationCurve()
00221 {
00222         mKeys.deleteAllData();
00223         mNumKeys = 0;
00224 }
00225 
00226 //-----------------------------------------------------------------------------
00227 // RotationCurve::getValue()
00228 //-----------------------------------------------------------------------------
00229 LLQuaternion LLKeyframeMotion::RotationCurve::getValue(F32 time, F32 duration)
00230 {
00231         LLQuaternion value;
00232         F32 index_before, index_after;
00233         RotationKey* rot_before;
00234         RotationKey* rot_after;
00235 
00236         mKeys.getInterval(time, index_before, index_after, rot_before, rot_after);
00237 
00238         if (rot_before)
00239         {
00240                 if (!rot_after)
00241                 {
00242                         rot_after = &mLoopInKey;
00243                         index_after = duration;
00244                 }
00245 
00246                 if (index_after == index_before)
00247                 {
00248                         value = rot_after->mRotation;
00249                 }
00250                 else
00251                 {
00252                         F32 u = (time - index_before) / (index_after - index_before);
00253                         value = interp(u, *rot_before, *rot_after);
00254                 }
00255         }
00256         else
00257         {
00258                 // before first key
00259                 if (rot_after)
00260                 {
00261                         value = rot_after->mRotation;
00262                 }
00263                 // no keys?
00264                 else
00265                 {
00266                         value = LLQuaternion::DEFAULT;
00267                 }
00268         }
00269 
00270         return value;
00271 }
00272 
00273 //-----------------------------------------------------------------------------
00274 // interp()
00275 //-----------------------------------------------------------------------------
00276 LLQuaternion LLKeyframeMotion::RotationCurve::interp(F32 u, RotationKey& before, RotationKey& after)
00277 {
00278         switch (mInterpolationType)
00279         {
00280         case IT_STEP:
00281                 return before.mRotation;
00282 
00283         default:
00284         case IT_LINEAR:
00285         case IT_SPLINE:
00286                 return nlerp(u, before.mRotation, after.mRotation);
00287         }
00288 }
00289 
00290 
00291 //-----------------------------------------------------------------------------
00292 // PositionCurve::PositionCurve()
00293 //-----------------------------------------------------------------------------
00294 LLKeyframeMotion::PositionCurve::PositionCurve()
00295 {
00296         mInterpolationType = LLKeyframeMotion::IT_LINEAR;
00297         mNumKeys = 0;
00298 }
00299 
00300 //-----------------------------------------------------------------------------
00301 // PositionCurve::~PositionCurve()
00302 //-----------------------------------------------------------------------------
00303 LLKeyframeMotion::PositionCurve::~PositionCurve()
00304 {
00305         mKeys.deleteAllData();
00306         mNumKeys = 0;
00307 }
00308 
00309 //-----------------------------------------------------------------------------
00310 // PositionCurve::getValue()
00311 //-----------------------------------------------------------------------------
00312 LLVector3 LLKeyframeMotion::PositionCurve::getValue(F32 time, F32 duration)
00313 {
00314         LLVector3 value;
00315         F32 index_before, index_after;
00316         PositionKey* pos_before;
00317         PositionKey* pos_after;
00318 
00319         mKeys.getInterval(time, index_before, index_after, pos_before, pos_after);
00320 
00321         if (pos_before)
00322         {
00323                 if (!pos_after)
00324                 {
00325                         pos_after = &mLoopInKey;
00326                         index_after = duration;
00327                 }
00328 
00329                 if (index_after == index_before)
00330                 {
00331                         value = pos_after->mPosition;
00332                 }
00333                 else
00334                 {
00335                         F32 u = (time - index_before) / (index_after - index_before);
00336                         value = interp(u, *pos_before, *pos_after);
00337                 }
00338         }
00339         else
00340         {
00341                 // before first key
00342                 if (pos_after)
00343                 {
00344                         value = pos_after->mPosition;
00345                 }
00346                 // no keys?
00347                 else
00348                 {
00349                         value.clearVec();
00350                 }
00351         }
00352 
00353         llassert(value.isFinite());
00354 
00355         return value;
00356 }
00357 
00358 //-----------------------------------------------------------------------------
00359 // interp()
00360 //-----------------------------------------------------------------------------
00361 LLVector3 LLKeyframeMotion::PositionCurve::interp(F32 u, PositionKey& before, PositionKey& after)
00362 {
00363         switch (mInterpolationType)
00364         {
00365         case IT_STEP:
00366                 return before.mPosition;
00367         default:
00368         case IT_LINEAR:
00369         case IT_SPLINE:
00370                 return lerp(before.mPosition, after.mPosition, u);
00371         }
00372 }
00373 
00374 
00375 //-----------------------------------------------------------------------------
00376 //-----------------------------------------------------------------------------
00377 // JointMotion class
00378 //-----------------------------------------------------------------------------
00379 //-----------------------------------------------------------------------------
00380 
00381 //-----------------------------------------------------------------------------
00382 // JointMotion::update()
00383 //-----------------------------------------------------------------------------
00384 void LLKeyframeMotion::JointMotion::update(LLJointState* joint_state, F32 time, F32 duration)
00385 {
00386         // this value being 0 is the cause of https://jira.lindenlab.com/browse/SL-22678 but I haven't 
00387         // managed to get a stack to see how it got here. Testing for 0 here will stop the crash.
00388         if ( joint_state == 0 )
00389         {
00390                 return;
00391         };
00392 
00393         U32 usage = joint_state->getUsage();
00394 
00395         //-------------------------------------------------------------------------
00396         // update scale component of joint state
00397         //-------------------------------------------------------------------------
00398         if ((usage & LLJointState::SCALE) && mScaleCurve.mNumKeys)
00399         {
00400                 joint_state->setScale( mScaleCurve.getValue( time, duration ) );
00401         }
00402 
00403         //-------------------------------------------------------------------------
00404         // update rotation component of joint state
00405         //-------------------------------------------------------------------------
00406         if ((usage & LLJointState::ROT) && mRotationCurve.mNumKeys)
00407         {
00408                 joint_state->setRotation( mRotationCurve.getValue( time, duration ) );
00409         }
00410 
00411         //-------------------------------------------------------------------------
00412         // update position component of joint state
00413         //-------------------------------------------------------------------------
00414         if ((usage & LLJointState::POS) && mPositionCurve.mNumKeys)
00415         {
00416                 joint_state->setPosition( mPositionCurve.getValue( time, duration ) );
00417         }
00418 }
00419 
00420 
00421 //-----------------------------------------------------------------------------
00422 //-----------------------------------------------------------------------------
00423 // LLKeyframeMotion class
00424 //-----------------------------------------------------------------------------
00425 //-----------------------------------------------------------------------------
00426 
00427 //-----------------------------------------------------------------------------
00428 // LLKeyframeMotion()
00429 // Class Constructor
00430 //-----------------------------------------------------------------------------
00431 LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id) 
00432         : LLMotion(id),
00433                 mJointMotionList(NULL),
00434                 mJointStates(NULL),
00435                 mPelvisp(NULL),
00436                 mLastSkeletonSerialNum(0),
00437                 mLastUpdateTime(0.f),
00438                 mLastLoopedTime(0.f),
00439                 mAssetStatus(ASSET_UNDEFINED)
00440 {
00441 
00442 }
00443 
00444 
00445 //-----------------------------------------------------------------------------
00446 // ~LLKeyframeMotion()
00447 // Class Destructor
00448 //-----------------------------------------------------------------------------
00449 LLKeyframeMotion::~LLKeyframeMotion()
00450 {
00451         if (mJointStates)
00452         {
00453                 delete [] mJointStates;
00454         }
00455         for_each(mConstraints.begin(), mConstraints.end(), DeletePointer());
00456 }
00457 
00458 //-----------------------------------------------------------------------------
00459 // create()
00460 //-----------------------------------------------------------------------------
00461 LLMotion *LLKeyframeMotion::create(const LLUUID &id)
00462 {
00463         return new LLKeyframeMotion(id);
00464 }
00465 
00466 //-----------------------------------------------------------------------------
00467 // LLKeyframeMotion::onInitialize(LLCharacter *character)
00468 //-----------------------------------------------------------------------------
00469 LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *character)
00470 {
00471         mCharacter = character;
00472         
00473         LLUUID* character_id;
00474 
00475         // asset already loaded?
00476         switch(mAssetStatus)
00477         {
00478         case ASSET_NEEDS_FETCH:
00479                 // request asset
00480                 mAssetStatus = ASSET_FETCHED;
00481 
00482                 character_id = new LLUUID(mCharacter->getID());
00483                 gAssetStorage->getAssetData(mID,
00484                                                 LLAssetType::AT_ANIMATION,
00485                                                 onLoadComplete,
00486                                                 (void *)character_id,
00487                                                 FALSE);
00488 
00489                 return STATUS_HOLD;
00490         case ASSET_FETCHED:
00491                 return STATUS_HOLD;
00492         case ASSET_FETCH_FAILED:
00493                 return STATUS_FAILURE;
00494         case ASSET_LOADED:
00495                 return STATUS_SUCCESS;
00496         default:
00497                 // we don't know what state the asset is in yet, so keep going
00498                 // check keyframe cache first then static vfs then asset request
00499                 break;
00500         }
00501 
00502         LLKeyframeMotion::JointMotionList* joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID());
00503 
00504         if(joint_motion_list)
00505         {
00506                 // motion already existed in cache, so grab it
00507                 mJointMotionList = joint_motion_list;
00508 
00509                 // don't forget to allocate joint states
00510                 mJointStates = new LLJointState[mJointMotionList->mNumJointMotions];
00511 
00512                 // set up joint states to point to character joints
00513                 for(U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
00514                 {
00515                         if (LLJoint *jointp = mCharacter->getJoint(mJointMotionList->mJointMotionArray[i].mJointName))
00516                         {
00517                                 mJointStates[i].setJoint(jointp);
00518                                 mJointStates[i].setUsage(mJointMotionList->mJointMotionArray[i].mUsage);
00519                                 mJointStates[i].setPriority(joint_motion_list->mJointMotionArray[i].mPriority);
00520                         }
00521                 }
00522                 mAssetStatus = ASSET_LOADED;
00523                 setupPose();
00524                 return STATUS_SUCCESS;
00525         }
00526 
00527         //-------------------------------------------------------------------------
00528         // Load named file by concatenating the character prefix with the motion name.
00529         // Load data into a buffer to be parsed.
00530         //-------------------------------------------------------------------------
00531         U8 *anim_data;
00532         S32 anim_file_size;
00533 
00534         if (!sVFS)
00535         {
00536                 llerrs << "Must call LLKeyframeMotion::setVFS() first before loading a keyframe file!" << llendl;
00537         }
00538 
00539         BOOL success = FALSE;
00540         LLVFile* anim_file = new LLVFile(sVFS, mID, LLAssetType::AT_ANIMATION);
00541         if (!anim_file || !anim_file->getSize())
00542         {
00543                 delete anim_file;
00544                 anim_file = NULL;
00545                 
00546                 // request asset over network on next call to load
00547                 mAssetStatus = ASSET_NEEDS_FETCH;
00548 
00549                 return STATUS_HOLD;
00550         }
00551         else
00552         {
00553                 anim_file_size = anim_file->getSize();
00554                 anim_data = new U8[anim_file_size];
00555                 success = anim_file->read(anim_data, anim_file_size);   /*Flawfinder: ignore*/
00556                 delete anim_file;
00557                 anim_file = NULL;
00558         }
00559 
00560         if (!success)
00561         {
00562                 llwarns << "Can't open animation file " << mID << llendl;
00563                 mAssetStatus = ASSET_FETCH_FAILED;
00564                 return STATUS_FAILURE;
00565         }
00566 
00567         lldebugs << "Loading keyframe data for: " << getName() << ":" << getID() << " (" << anim_file_size << " bytes)" << llendl;
00568 
00569         LLDataPackerBinaryBuffer dp(anim_data, anim_file_size);
00570 
00571         if (!deserialize(dp))
00572         {
00573                 llwarns << "Failed to decode asset for animation " << getName() << ":" << getID() << llendl;
00574                 mAssetStatus = ASSET_FETCH_FAILED;
00575                 return STATUS_FAILURE;
00576         }
00577 
00578         delete []anim_data;
00579 
00580         mAssetStatus = ASSET_LOADED;
00581         return STATUS_SUCCESS;
00582 }
00583 
00584 //-----------------------------------------------------------------------------
00585 // setupPose()
00586 //-----------------------------------------------------------------------------
00587 BOOL LLKeyframeMotion::setupPose()
00588 {
00589         // add all valid joint states to the pose
00590         for (U32 jm=0; jm<mJointMotionList->mNumJointMotions; jm++)
00591         {
00592                 if ( mJointStates[jm].getJoint() )
00593                 {
00594                         addJointState( &mJointStates[jm] );
00595                 }
00596         }
00597 
00598         // initialize joint constraints
00599         for (JointMotionList::constraint_list_t::iterator iter = mJointMotionList->mConstraints.begin();
00600                  iter != mJointMotionList->mConstraints.end(); ++iter)
00601         {
00602                 JointConstraintSharedData* shared_constraintp = *iter;
00603                 JointConstraint* constraintp = new JointConstraint(shared_constraintp);
00604                 initializeConstraint(constraintp);
00605                 mConstraints.push_front(constraintp);
00606         }
00607 
00608         if (mJointMotionList->mConstraints.size())
00609         {
00610                 mPelvisp = mCharacter->getJoint("mPelvis");
00611                 if (!mPelvisp)
00612                 {
00613                         return FALSE;
00614                 }
00615         }
00616 
00617         // setup loop keys
00618         setLoopIn(mJointMotionList->mLoopInPoint);
00619         setLoopOut(mJointMotionList->mLoopOutPoint);
00620 
00621         return TRUE;
00622 }
00623 
00624 //-----------------------------------------------------------------------------
00625 // LLKeyframeMotion::onActivate()
00626 //-----------------------------------------------------------------------------
00627 BOOL LLKeyframeMotion::onActivate()
00628 {
00629         // If the keyframe anim has an associated emote, trigger it. 
00630         if( mEmoteName.length() > 0 )
00631         {
00632                 mCharacter->startMotion( gAnimLibrary.stringToAnimState(mEmoteName.c_str()) );
00633         }
00634 
00635         mLastLoopedTime = 0.f;
00636 
00637         return TRUE;
00638 }
00639 
00640 //-----------------------------------------------------------------------------
00641 // LLKeyframeMotion::onUpdate()
00642 //-----------------------------------------------------------------------------
00643 BOOL LLKeyframeMotion::onUpdate(F32 time, U8* joint_mask)
00644 {
00645         llassert(time >= 0.f);
00646 
00647         if (mJointMotionList->mLoop)
00648         {
00649                 if (mJointMotionList->mDuration == 0.0f)
00650                 {
00651                         time = 0.f;
00652                         mLastLoopedTime = 0.0f;
00653                 }
00654                 else if (mStopped)
00655                 {
00656                         mLastLoopedTime = llmin(mJointMotionList->mDuration, mLastLoopedTime + time - mLastUpdateTime);
00657                 }
00658                 else if (time > mJointMotionList->mLoopOutPoint)
00659                 {
00660                         if ((mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint) == 0.f)
00661                         {
00662                                 mLastLoopedTime = mJointMotionList->mLoopOutPoint;
00663                         }
00664                         else
00665                         {
00666                                 mLastLoopedTime = mJointMotionList->mLoopInPoint + 
00667                                         fmod(time - mJointMotionList->mLoopOutPoint, 
00668                                         mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint);
00669                         }
00670                 }
00671                 else
00672                 {
00673                         mLastLoopedTime = time;
00674                 }
00675         }
00676         else
00677         {
00678                 mLastLoopedTime = time;
00679         }
00680 
00681         applyKeyframes(mLastLoopedTime);
00682 
00683         applyConstraints(mLastLoopedTime, joint_mask);
00684 
00685         mLastUpdateTime = time;
00686 
00687         return mLastLoopedTime <= mJointMotionList->mDuration;
00688 }
00689 
00690 //-----------------------------------------------------------------------------
00691 // applyKeyframes()
00692 //-----------------------------------------------------------------------------
00693 void LLKeyframeMotion::applyKeyframes(F32 time)
00694 {
00695         U32 i;
00696         for (i=0; i<mJointMotionList->mNumJointMotions; i++)
00697         {
00698                 mJointMotionList->mJointMotionArray[i].update(
00699                         &mJointStates[i], 
00700                         time, 
00701                         mJointMotionList->mDuration );
00702         }
00703 
00704         LLJoint::JointPriority* pose_priority = (LLJoint::JointPriority* )mCharacter->getAnimationData("Hand Pose Priority");
00705         if (pose_priority)
00706         {
00707                 if (mJointMotionList->mMaxPriority >= *pose_priority)
00708                 {
00709                         mCharacter->setAnimationData("Hand Pose", &mJointMotionList->mHandPose);
00710                         mCharacter->setAnimationData("Hand Pose Priority", &mJointMotionList->mMaxPriority);
00711                 }
00712         }
00713         else
00714         {
00715                 mCharacter->setAnimationData("Hand Pose", &mJointMotionList->mHandPose);
00716                 mCharacter->setAnimationData("Hand Pose Priority", &mJointMotionList->mMaxPriority);
00717         }
00718 }
00719 
00720 //-----------------------------------------------------------------------------
00721 // applyConstraints()
00722 //-----------------------------------------------------------------------------
00723 void LLKeyframeMotion::applyConstraints(F32 time, U8* joint_mask)
00724 {
00725         //TODO: investigate replacing spring simulation with critically damped motion
00726 
00727         // re-init constraints if skeleton has changed
00728         if (mCharacter->getSkeletonSerialNum() != mLastSkeletonSerialNum)
00729         {
00730                 mLastSkeletonSerialNum = mCharacter->getSkeletonSerialNum();
00731                 for (constraint_list_t::iterator iter = mConstraints.begin();
00732                          iter != mConstraints.end(); ++iter)
00733                 {
00734                         JointConstraint* constraintp = *iter;
00735                         initializeConstraint(constraintp);
00736                 }
00737         }
00738 
00739         // apply constraints
00740         for (constraint_list_t::iterator iter = mConstraints.begin();
00741                  iter != mConstraints.end(); ++iter)
00742         {
00743                 JointConstraint* constraintp = *iter;
00744                 applyConstraint(constraintp, time, joint_mask);
00745         }
00746 }
00747 
00748 //-----------------------------------------------------------------------------
00749 // LLKeyframeMotion::onDeactivate()
00750 //-----------------------------------------------------------------------------
00751 void LLKeyframeMotion::onDeactivate()
00752 {
00753         for (constraint_list_t::iterator iter = mConstraints.begin();
00754                  iter != mConstraints.end(); ++iter)
00755         {
00756                 JointConstraint* constraintp = *iter;
00757                 deactivateConstraint(constraintp);
00758         }
00759 }
00760 
00761 //-----------------------------------------------------------------------------
00762 // setStopTime()
00763 //-----------------------------------------------------------------------------
00764 // time is in seconds since character creation
00765 void LLKeyframeMotion::setStopTime(F32 time)
00766 {
00767         LLMotion::setStopTime(time);
00768 
00769         if (mJointMotionList->mLoop && mJointMotionList->mLoopOutPoint != mJointMotionList->mDuration)
00770         {
00771                 F32 start_loop_time = mActivationTimestamp + mJointMotionList->mLoopInPoint;
00772                 F32 loop_fraction_time;
00773                 if (mJointMotionList->mLoopOutPoint == mJointMotionList->mLoopInPoint)
00774                 {
00775                         loop_fraction_time = 0.f;
00776                 }
00777                 else
00778                 {
00779                         loop_fraction_time = fmod(time - start_loop_time, 
00780                                 mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint);
00781                 }
00782                 mStopTimestamp = llmax(time, 
00783                         (time - loop_fraction_time) + (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint) - getEaseOutDuration());
00784         }
00785 }
00786 
00787 //-----------------------------------------------------------------------------
00788 // initializeConstraint()
00789 //-----------------------------------------------------------------------------
00790 void LLKeyframeMotion::initializeConstraint(JointConstraint* constraint)
00791 {
00792         JointConstraintSharedData *shared_data = constraint->mSharedData;
00793 
00794         S32 joint_num;
00795         LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);
00796         LLJoint* cur_joint = mJointStates[shared_data->mJointStateIndices[0]].getJoint();
00797 
00798         F32 source_pos_offset = dist_vec(source_pos, cur_joint->getWorldPosition());
00799 
00800         constraint->mTotalLength = constraint->mJointLengths[0] = dist_vec(cur_joint->getParent()->getWorldPosition(), source_pos);
00801         
00802         // grab joint lengths
00803         for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
00804         {
00805                 cur_joint = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint();
00806                 if (!cur_joint)
00807                 {
00808                         return;
00809                 }
00810                 constraint->mJointLengths[joint_num] = dist_vec(cur_joint->getWorldPosition(), cur_joint->getParent()->getWorldPosition());
00811                 constraint->mTotalLength += constraint->mJointLengths[joint_num];
00812         }
00813 
00814         // store fraction of total chain length so we know how to shear the entire chain towards the goal position
00815         for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
00816         {
00817                 constraint->mJointLengthFractions[joint_num] = constraint->mJointLengths[joint_num] / constraint->mTotalLength;
00818         }
00819 
00820         // add last step in chain, from final joint to constraint position
00821         constraint->mTotalLength += source_pos_offset;
00822 
00823         constraint->mSourceVolume = mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume);
00824         constraint->mTargetVolume = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume);
00825 }
00826 
00827 //-----------------------------------------------------------------------------
00828 // activateConstraint()
00829 //-----------------------------------------------------------------------------
00830 void LLKeyframeMotion::activateConstraint(JointConstraint* constraint)
00831 {
00832         JointConstraintSharedData *shared_data = constraint->mSharedData;
00833         constraint->mActive = TRUE;
00834         S32 joint_num;
00835 
00836         // grab ground position if we need to
00837         if (shared_data->mConstraintTargetType == TYPE_GROUND)
00838         {
00839                 LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);
00840                 LLVector3 ground_pos_agent;
00841                 mCharacter->getGround(source_pos, ground_pos_agent, constraint->mGroundNorm);
00842                 constraint->mGroundPos = mCharacter->getPosGlobalFromAgent(ground_pos_agent + shared_data->mTargetConstraintOffset);
00843         }
00844 
00845         for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
00846         {
00847                 LLJoint* cur_joint = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint();
00848                 constraint->mPositions[joint_num] = (cur_joint->getWorldPosition() - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation();
00849         }
00850 
00851         constraint->mWeight = 1.f;
00852 }
00853 
00854 //-----------------------------------------------------------------------------
00855 // deactivateConstraint()
00856 //-----------------------------------------------------------------------------
00857 void LLKeyframeMotion::deactivateConstraint(JointConstraint *constraintp)
00858 {
00859         if (constraintp->mSourceVolume)
00860         {
00861                 constraintp->mSourceVolume->mUpdateXform = FALSE;
00862         }
00863 
00864         if (!constraintp->mSharedData->mConstraintTargetType == TYPE_GROUND)
00865         {
00866                 if (constraintp->mTargetVolume)
00867                 {
00868                         constraintp->mTargetVolume->mUpdateXform = FALSE;
00869                 }
00870         }
00871         constraintp->mActive = FALSE;
00872 }
00873 
00874 //-----------------------------------------------------------------------------
00875 // applyConstraint()
00876 //-----------------------------------------------------------------------------
00877 void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8* joint_mask)
00878 {
00879         JointConstraintSharedData *shared_data = constraint->mSharedData;
00880         if (!shared_data) return;
00881 
00882         LLVector3               positions[MAX_CHAIN_LENGTH];
00883         const F32*              joint_lengths = constraint->mJointLengths;
00884         LLVector3               velocities[MAX_CHAIN_LENGTH - 1];
00885         LLQuaternion    old_rots[MAX_CHAIN_LENGTH];
00886         S32                             joint_num;
00887         LLJoint*                cur_joint;
00888 
00889         if (time < shared_data->mEaseInStartTime)
00890         {
00891                 return;
00892         }
00893 
00894         if (time > shared_data->mEaseOutStopTime)
00895         {
00896                 if (constraint->mActive)
00897                 {
00898                         deactivateConstraint(constraint);
00899                 }
00900                 return;
00901         }
00902 
00903         if (!constraint->mActive || time < shared_data->mEaseInStopTime)
00904         {
00905                 activateConstraint(constraint);
00906         }
00907 
00908         LLJoint* root_joint = mJointStates[shared_data->mJointStateIndices[shared_data->mChainLength]].getJoint();
00909         LLVector3 root_pos = root_joint->getWorldPosition();
00910 //      LLQuaternion root_rot = 
00911         root_joint->getParent()->getWorldRotation();
00912 //      LLQuaternion inv_root_rot = ~root_rot;
00913 
00914 //      LLVector3 current_source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);
00915 
00916         //apply underlying keyframe animation to get nominal "kinematic" joint positions
00917         for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++)
00918         {
00919                 cur_joint = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint();
00920                 if (joint_mask[cur_joint->getJointNum()] >= (0xff >> (7 - getPriority())))
00921                 {
00922                         // skip constraint
00923                         return;
00924                 }
00925                 old_rots[joint_num] = cur_joint->getRotation();
00926                 cur_joint->setRotation(mJointStates[shared_data->mJointStateIndices[joint_num]].getRotation());
00927         }
00928 
00929 
00930         LLVector3 keyframe_source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);
00931         LLVector3 target_pos;
00932 
00933         switch(shared_data->mConstraintTargetType)
00934         {
00935         case TYPE_GROUND:
00936                 target_pos = mCharacter->getPosAgentFromGlobal(constraint->mGroundPos);
00937 //              llinfos << "Target Pos " << constraint->mGroundPos << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
00938                 break;
00939         case TYPE_BODY:
00940                 target_pos = mCharacter->getVolumePos(shared_data->mTargetConstraintVolume, shared_data->mTargetConstraintOffset);
00941                 break;
00942         default:
00943                 break;
00944         }
00945         
00946         LLVector3 norm;
00947         LLJoint *source_jointp = NULL;
00948         LLJoint *target_jointp = NULL;
00949 
00950         if (shared_data->mConstraintType == TYPE_PLANE)
00951         {
00952                 switch(shared_data->mConstraintTargetType)
00953                 {
00954                 case TYPE_GROUND:
00955                         norm = constraint->mGroundNorm;
00956                         break;
00957                 case TYPE_BODY:
00958                         target_jointp = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume);
00959                         if (target_jointp)
00960                         {
00961                                 // *FIX: do proper normal calculation for stretched
00962                                 // spheres (inverse transpose)
00963                                 norm = target_pos - target_jointp->getWorldPosition();
00964                         }
00965 
00966                         if (norm.isExactlyZero())
00967                         {
00968                                 source_jointp = mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume);
00969                                 norm = -1.f * shared_data->mSourceConstraintOffset;
00970                                 if (source_jointp)      
00971                                 {
00972                                         norm = norm * source_jointp->getWorldRotation();
00973                                 }
00974                         }
00975                         norm.normVec();
00976                         break;
00977                 default:
00978                         norm.clearVec();
00979                         break;
00980                 }
00981                 
00982                 target_pos = keyframe_source_pos + (norm * ((target_pos - keyframe_source_pos) * norm));
00983         }
00984 
00985         if (constraint->mSharedData->mChainLength != 0 &&
00986                 dist_vec_squared(root_pos, target_pos) * 0.95f > constraint->mTotalLength * constraint->mTotalLength)
00987         {
00988                 constraint->mWeight = lerp(constraint->mWeight, 0.f, LLCriticalDamp::getInterpolant(0.1f));
00989         }
00990         else
00991         {
00992                 constraint->mWeight = lerp(constraint->mWeight, 1.f, LLCriticalDamp::getInterpolant(0.3f));
00993         }
00994 
00995         F32 weight = constraint->mWeight * ((shared_data->mEaseOutStopTime == 0.f) ? 1.f : 
00996                 llmin(clamp_rescale(time, shared_data->mEaseInStartTime, shared_data->mEaseInStopTime, 0.f, 1.f), 
00997                 clamp_rescale(time, shared_data->mEaseOutStartTime, shared_data->mEaseOutStopTime, 1.f, 0.f)));
00998 
00999         LLVector3 source_to_target = target_pos - keyframe_source_pos;
01000         
01001         S32 max_iteration_count = llround(clamp_rescale(
01002                                                                                   mCharacter->getPixelArea(),
01003                                                                                   MAX_PIXEL_AREA_CONSTRAINTS,
01004                                                                                   MIN_PIXEL_AREA_CONSTRAINTS,
01005                                                                                   (F32)MAX_ITERATIONS,
01006                                                                                   (F32)MIN_ITERATIONS));
01007 
01008         if (shared_data->mChainLength)
01009         {
01010                 LLQuaternion end_rot = mJointStates[shared_data->mJointStateIndices[0]].getJoint()->getWorldRotation();
01011 
01012                 // slam start and end of chain to the proper positions (rest of chain stays put)
01013                 positions[0] = lerp(keyframe_source_pos, target_pos, weight);
01014                 positions[shared_data->mChainLength] = root_pos;
01015 
01016                 // grab keyframe-specified positions of joints  
01017                 for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
01018                 {
01019                         LLVector3 kinematic_position = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint()->getWorldPosition() + 
01020                                 (source_to_target * constraint->mJointLengthFractions[joint_num]);
01021 
01022                         // convert intermediate joint positions to world coordinates
01023                         positions[joint_num] = ( constraint->mPositions[joint_num] * mPelvisp->getWorldRotation()) + mPelvisp->getWorldPosition();
01024                         F32 time_constant = 1.f / clamp_rescale(constraint->mFixupDistanceRMS, 0.f, 0.5f, 0.2f, 8.f);
01025 //                      llinfos << "Interpolant " << LLCriticalDamp::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
01026                         positions[joint_num] = lerp(positions[joint_num], kinematic_position, 
01027                                 LLCriticalDamp::getInterpolant(time_constant, FALSE));
01028                 }
01029 
01030                 S32 iteration_count;
01031                 for (iteration_count = 0; iteration_count < max_iteration_count; iteration_count++)
01032                 {
01033                         S32 num_joints_finished = 0;
01034                         for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
01035                         {
01036                                 // constraint to child
01037                                 LLVector3 acceleration = (positions[joint_num - 1] - positions[joint_num]) * 
01038                                         (dist_vec(positions[joint_num], positions[joint_num - 1]) - joint_lengths[joint_num - 1]) * JOINT_LENGTH_K;
01039                                 // constraint to parent
01040                                 acceleration  += (positions[joint_num + 1] - positions[joint_num]) * 
01041                                         (dist_vec(positions[joint_num + 1], positions[joint_num]) - joint_lengths[joint_num]) * JOINT_LENGTH_K;
01042 
01043                                 if (acceleration.magVecSquared() < MIN_ACCELERATION_SQUARED)
01044                                 {
01045                                         num_joints_finished++;
01046                                 }
01047 
01048                                 velocities[joint_num - 1] = velocities[joint_num - 1] * 0.7f;
01049                                 positions[joint_num] += velocities[joint_num - 1] + (acceleration * 0.5f);
01050                                 velocities[joint_num - 1] += acceleration;
01051                         }
01052 
01053                         if ((iteration_count >= MIN_ITERATION_COUNT) && 
01054                                 (num_joints_finished == shared_data->mChainLength - 1))
01055                         {
01056 //                              llinfos << iteration_count << " iterations on " << 
01057 //                                      mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
01058                                 break;
01059                         }
01060                 }
01061 
01062                 for (joint_num = shared_data->mChainLength; joint_num > 0; joint_num--)
01063                 {
01064                         LLQuaternion parent_rot = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint()->getParent()->getWorldRotation();
01065                         cur_joint = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint();
01066                         LLJoint* child_joint = mJointStates[shared_data->mJointStateIndices[joint_num - 1]].getJoint();
01067 
01068                         LLQuaternion cur_rot = cur_joint->getWorldRotation();
01069                         LLQuaternion fixup_rot;
01070                         
01071                         LLVector3 target_at = positions[joint_num - 1] - positions[joint_num];
01072                         LLVector3 current_at;
01073 
01074                         // at bottom of chain, use point on collision volume, not joint position
01075                         if (joint_num == 1)
01076                         {
01077                                 current_at = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset) -
01078                                         cur_joint->getWorldPosition();
01079                         }
01080                         else
01081                         {
01082                                 current_at = child_joint->getPosition() * cur_rot;
01083                         }
01084                         fixup_rot.shortestArc(current_at, target_at);
01085 
01086                         LLQuaternion target_rot = cur_rot * fixup_rot;
01087                         target_rot = target_rot * ~parent_rot;
01088 
01089                         if (weight != 1.f)
01090                         {
01091                                 LLQuaternion cur_rot = mJointStates[shared_data->mJointStateIndices[joint_num]].getRotation();
01092                                 target_rot = nlerp(weight, cur_rot, target_rot);
01093                         }
01094 
01095                         mJointStates[shared_data->mJointStateIndices[joint_num]].setRotation(target_rot);
01096                         cur_joint->setRotation(target_rot);
01097                 }
01098 
01099                 LLJoint* end_joint = mJointStates[shared_data->mJointStateIndices[0]].getJoint();
01100                 LLQuaternion end_local_rot = end_rot * ~end_joint->getParent()->getWorldRotation();
01101 
01102                 if (weight == 1.f)
01103                 {
01104                         mJointStates[shared_data->mJointStateIndices[0]].setRotation(end_local_rot);
01105                 }
01106                 else
01107                 {
01108                         LLQuaternion cur_rot = mJointStates[shared_data->mJointStateIndices[0]].getRotation();
01109                         mJointStates[shared_data->mJointStateIndices[0]].setRotation(nlerp(weight, cur_rot, end_local_rot));
01110                 }
01111 
01112                 // save simulated positions in pelvis-space and calculate total fixup distance
01113                 constraint->mFixupDistanceRMS = 0.f;
01114                 F32 delta_time = llmax(0.02f, llabs(time - mLastUpdateTime));
01115                 for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
01116                 {
01117                         LLVector3 new_pos = (positions[joint_num] - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation();
01118                         constraint->mFixupDistanceRMS += dist_vec_squared(new_pos, constraint->mPositions[joint_num]) / delta_time;
01119                         constraint->mPositions[joint_num] = new_pos;
01120                 }
01121                 constraint->mFixupDistanceRMS *= 1.f / (constraint->mTotalLength * (F32)(shared_data->mChainLength - 1));
01122                 constraint->mFixupDistanceRMS = fsqrtf(constraint->mFixupDistanceRMS);
01123 
01124                 //reset old joint rots
01125                 for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++)
01126                 {
01127                         mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint()->setRotation(old_rots[joint_num]);
01128                 }
01129         }
01130         // simple positional constraint (pelvis only)
01131         else if (mJointStates[shared_data->mJointStateIndices[0]].getUsage() & LLJointState::POS)
01132         {
01133                 LLVector3 delta = source_to_target * weight;
01134                 LLJointState* current_joint_statep = &mJointStates[shared_data->mJointStateIndices[0]];
01135                 LLQuaternion parent_rot = current_joint_statep->getJoint()->getParent()->getWorldRotation();
01136                 delta = delta * ~parent_rot;
01137                 current_joint_statep->setPosition(current_joint_statep->getJoint()->getPosition() + delta);
01138         }
01139 }
01140 
01141 //-----------------------------------------------------------------------------
01142 // deserialize()
01143 //-----------------------------------------------------------------------------
01144 BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
01145 {
01146         BOOL old_version = FALSE;
01147         mJointMotionList = new LLKeyframeMotion::JointMotionList;
01148         mJointMotionList->mNumJointMotions = 0;
01149 
01150         //-------------------------------------------------------------------------
01151         // get base priority
01152         //-------------------------------------------------------------------------
01153         S32 temp_priority;
01154         U16 version;
01155         U16 sub_version;
01156 
01157         if (!dp.unpackU16(version, "version"))
01158         {
01159                 llwarns << "can't read version number" << llendl;
01160                 return FALSE;
01161         }
01162 
01163         if (!dp.unpackU16(sub_version, "sub_version"))
01164         {
01165                 llwarns << "can't read sub version number" << llendl;
01166                 return FALSE;
01167         }
01168 
01169         if (version == 0 && sub_version == 1)
01170         {
01171                 old_version = TRUE;
01172         }
01173         else if (version != KEYFRAME_MOTION_VERSION || sub_version != KEYFRAME_MOTION_SUBVERSION)
01174         {
01175 #if LL_RELEASE
01176                 llwarns << "Bad animation version " << version << "." << sub_version << llendl;
01177                 return FALSE;
01178 #else
01179                 llerrs << "Bad animation version " << version << "." << sub_version << llendl;
01180 #endif
01181         }
01182 
01183         if (!dp.unpackS32(temp_priority, "base_priority"))
01184         {
01185                 llwarns << "can't read priority" << llendl;
01186                 return FALSE;
01187         }
01188         mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority;
01189 
01190         if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY)
01191         {
01192                 mJointMotionList->mBasePriority = (LLJoint::JointPriority)((int)LLJoint::ADDITIVE_PRIORITY-1);
01193                 mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority;
01194         }
01195 
01196         //-------------------------------------------------------------------------
01197         // get duration
01198         //-------------------------------------------------------------------------
01199         if (!dp.unpackF32(mJointMotionList->mDuration, "duration"))
01200         {
01201                 llwarns << "can't read duration" << llendl;
01202                 return FALSE;
01203         }
01204 
01205         //-------------------------------------------------------------------------
01206         // get emote (optional)
01207         //-------------------------------------------------------------------------
01208         if (!dp.unpackString(mEmoteName, "emote_name"))
01209         {
01210                 llwarns << "can't read optional_emote_animation" << llendl;
01211                 return FALSE;
01212         }
01213 
01214         //-------------------------------------------------------------------------
01215         // get loop
01216         //-------------------------------------------------------------------------
01217         if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point"))
01218         {
01219                 llwarns << "can't read loop point" << llendl;
01220                 return FALSE;
01221         }
01222 
01223         if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point"))
01224         {
01225                 llwarns << "can't read loop point" << llendl;
01226                 return FALSE;
01227         }
01228 
01229         if (!dp.unpackS32(mJointMotionList->mLoop, "loop"))
01230         {
01231                 llwarns << "can't read loop" << llendl;
01232                 return FALSE;
01233         }
01234 
01235         //-------------------------------------------------------------------------
01236         // get easeIn and easeOut
01237         //-------------------------------------------------------------------------
01238         if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration"))
01239         {
01240                 llwarns << "can't read easeIn" << llendl;
01241                 return FALSE;
01242         }
01243 
01244         if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration"))
01245         {
01246                 llwarns << "can't read easeOut" << llendl;
01247                 return FALSE;
01248         }
01249 
01250         //-------------------------------------------------------------------------
01251         // get hand pose
01252         //-------------------------------------------------------------------------
01253         U32 word;
01254         if (!dp.unpackU32(word, "hand_pose"))
01255         {
01256                 llwarns << "can't read hand pose" << llendl;
01257                 return FALSE;
01258         }
01259         mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word;
01260 
01261         //-------------------------------------------------------------------------
01262         // get number of joint motions
01263         //-------------------------------------------------------------------------
01264         if (!dp.unpackU32(mJointMotionList->mNumJointMotions, "num_joints"))
01265         {
01266                 llwarns << "can't read number of joints" << llendl;
01267                 return FALSE;
01268         }
01269 
01270         if (mJointMotionList->mNumJointMotions == 0)
01271         {
01272                 llwarns << "no joints in animation" << llendl;
01273                 return FALSE;
01274         }
01275         else if (mJointMotionList->mNumJointMotions > LL_CHARACTER_MAX_JOINTS)
01276         {
01277                 llwarns << "too many joints in animation" << llendl;
01278                 return FALSE;
01279         }
01280 
01281         mJointMotionList->mJointMotionArray = new JointMotion[mJointMotionList->mNumJointMotions];
01282         mJointStates = new LLJointState[mJointMotionList->mNumJointMotions];
01283 
01284         if (!mJointMotionList->mJointMotionArray)
01285         {
01286                 mJointMotionList->mDuration = 0.0f;
01287                 mJointMotionList->mEaseInDuration = 0.0f;
01288                 mJointMotionList->mEaseOutDuration = 0.0f;
01289                 return FALSE;
01290         }
01291 
01292         //-------------------------------------------------------------------------
01293         // initialize joint motions
01294         //-------------------------------------------------------------------------
01295         S32 k;
01296         for(U32 i=0; i<mJointMotionList->mNumJointMotions; ++i)
01297         {
01298                 std::string joint_name;
01299                 if (!dp.unpackString(joint_name, "joint_name"))
01300                 {
01301                         llwarns << "can't read joint name" << llendl;
01302                         return FALSE;
01303                 }
01304         
01305                 //---------------------------------------------------------------------
01306                 // find the corresponding joint
01307                 //---------------------------------------------------------------------
01308                 LLJoint *joint = mCharacter->getJoint( joint_name );
01309                 if (joint)
01310                 {
01311 //                      llinfos << "  joint: " << joint_name << llendl;
01312                 }
01313                 else
01314                 {
01315                         llwarns << "joint not found: " << joint_name << llendl;
01316                         //return FALSE;
01317                 }
01318 
01319                 mJointMotionList->mJointMotionArray[i].mJointName = joint_name;
01320                 mJointStates[i].setJoint( joint );
01321                 mJointStates[i].setUsage( 0 );
01322 
01323                 //---------------------------------------------------------------------
01324                 // get joint priority
01325                 //---------------------------------------------------------------------
01326                 S32 joint_priority;
01327                 if (!dp.unpackS32(joint_priority, "joint_priority"))
01328                 {
01329                         llwarns << "can't read joint priority." << llendl;
01330                         return FALSE;
01331                 }
01332                 
01333                 mJointMotionList->mJointMotionArray[i].mPriority = (LLJoint::JointPriority)joint_priority;
01334                 if (joint_priority != LLJoint::USE_MOTION_PRIORITY &&
01335                         joint_priority > mJointMotionList->mMaxPriority)
01336                 {
01337                         mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority;
01338                 }
01339 
01340                 mJointStates[i].setPriority((LLJoint::JointPriority)joint_priority);
01341 
01342                 //---------------------------------------------------------------------
01343                 // scan rotation curve header
01344                 //---------------------------------------------------------------------
01345                 if (!dp.unpackS32(mJointMotionList->mJointMotionArray[i].mRotationCurve.mNumKeys, "num_rot_keys"))
01346                 {
01347                         llwarns << "can't read number of rotation keys" << llendl;
01348                         return FALSE;
01349                 }
01350 
01351                 mJointMotionList->mJointMotionArray[i].mRotationCurve.mInterpolationType = IT_LINEAR;
01352                 if (mJointMotionList->mJointMotionArray[i].mRotationCurve.mNumKeys != 0)
01353                 {
01354                         mJointStates[i].setUsage(mJointStates[i].getUsage() | LLJointState::ROT );
01355                 }
01356 
01357                 //---------------------------------------------------------------------
01358                 // scan rotation curve keys
01359                 //---------------------------------------------------------------------
01360                 RotationCurve *rCurve = &mJointMotionList->mJointMotionArray[i].mRotationCurve;
01361 
01362                 for (k = 0; k < mJointMotionList->mJointMotionArray[i].mRotationCurve.mNumKeys; k++)
01363                 {
01364                         F32 time;
01365                         U16 time_short;
01366 
01367                         if (old_version)
01368                         {
01369                                 if (!dp.unpackF32(time, "time"))
01370                                 {
01371                                         llwarns << "can't read rotation key (" << k << ")" << llendl;
01372                                         return FALSE;
01373                                 }
01374 
01375                         }
01376                         else
01377                         {
01378                                 if (!dp.unpackU16(time_short, "time"))
01379                                 {
01380                                         llwarns << "can't read rotation key (" << k << ")" << llendl;
01381                                         return FALSE;
01382                                 }
01383 
01384                                 time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration);
01385                         }
01386                         
01387                         RotationKey *rot_key = new RotationKey;
01388                         rot_key->mTime = time;
01389                         LLVector3 rot_angles;
01390                         U16 x, y, z;
01391 
01392                         BOOL success = TRUE;
01393 
01394                         if (old_version)
01395                         {
01396                                 success = dp.unpackVector3(rot_angles, "rot_angles");
01397 
01398                                 LLQuaternion::Order ro = StringToOrder("ZYX");
01399                                 rot_key->mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro);
01400                         }
01401                         else
01402                         {
01403                                 success &= dp.unpackU16(x, "rot_angle_x");
01404                                 success &= dp.unpackU16(y, "rot_angle_y");
01405                                 success &= dp.unpackU16(z, "rot_angle_z");
01406 
01407                                 LLVector3 rot_vec;
01408                                 rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f);
01409                                 rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f);
01410                                 rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f);
01411                                 rot_key->mRotation.unpackFromVector3(rot_vec);
01412                         }
01413 
01414                         if (!success)
01415                         {
01416                                 llwarns << "can't read rotation key (" << k << ")" << llendl;
01417                                 delete rot_key;
01418                                 return FALSE;
01419                         }
01420 
01421                         rCurve->mKeys[time] = rot_key;
01422                 }
01423 
01424                 //---------------------------------------------------------------------
01425                 // scan position curve header
01426                 //---------------------------------------------------------------------
01427                 if (!dp.unpackS32(mJointMotionList->mJointMotionArray[i].mPositionCurve.mNumKeys, "num_pos_keys"))
01428                 {
01429                         llwarns << "can't read number of position keys" << llendl;
01430                         return FALSE;
01431                 }
01432 
01433                 mJointMotionList->mJointMotionArray[i].mPositionCurve.mInterpolationType = IT_LINEAR;
01434                 if (mJointMotionList->mJointMotionArray[i].mPositionCurve.mNumKeys != 0)
01435                 {
01436                         mJointStates[i].setUsage(mJointStates[i].getUsage() | LLJointState::POS );
01437                 }
01438 
01439                 //---------------------------------------------------------------------
01440                 // scan position curve keys
01441                 //---------------------------------------------------------------------
01442                 PositionCurve *pCurve = &mJointMotionList->mJointMotionArray[i].mPositionCurve;
01443                 BOOL is_pelvis = mJointMotionList->mJointMotionArray[i].mJointName == "mPelvis";
01444                 for (k = 0; k < mJointMotionList->mJointMotionArray[i].mPositionCurve.mNumKeys; k++)
01445                 {
01446                         U16 time_short;
01447                         PositionKey* pos_key = new PositionKey;
01448 
01449                         if (old_version)
01450                         {
01451                                 if (!dp.unpackF32(pos_key->mTime, "time"))
01452                                 {
01453                                         llwarns << "can't read position key (" << k << ")" << llendl;
01454                                         delete pos_key;
01455                                         return FALSE;
01456                                 }
01457                         }
01458                         else
01459                         {
01460                                 if (!dp.unpackU16(time_short, "time"))
01461                                 {
01462                                         llwarns << "can't read position key (" << k << ")" << llendl;
01463                                         delete pos_key;
01464                                         return FALSE;
01465                                 }
01466 
01467                                 pos_key->mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration);
01468                         }
01469 
01470                         BOOL success = TRUE;
01471 
01472                         if (old_version)
01473                         {
01474                                 success = dp.unpackVector3(pos_key->mPosition, "pos");
01475                         }
01476                         else
01477                         {
01478                                 U16 x, y, z;
01479 
01480                                 success &= dp.unpackU16(x, "pos_x");
01481                                 success &= dp.unpackU16(y, "pos_y");
01482                                 success &= dp.unpackU16(z, "pos_z");
01483 
01484                                 pos_key->mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
01485                                 pos_key->mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
01486                                 pos_key->mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
01487                         }
01488 
01489                         if (!success)
01490                         {
01491                                 llwarns << "can't read position key (" << k << ")" << llendl;
01492                                 delete pos_key;
01493                                 return FALSE;
01494                         }
01495                         
01496                         pCurve->mKeys[pos_key->mTime] = pos_key;
01497 
01498                         if (is_pelvis)
01499                         {
01500                                 mJointMotionList->mPelvisBBox.addPoint(pos_key->mPosition);
01501                         }
01502                 }
01503 
01504                 mJointMotionList->mJointMotionArray[i].mUsage = mJointStates[i].getUsage();
01505         }
01506 
01507         //-------------------------------------------------------------------------
01508         // get number of constraints
01509         //-------------------------------------------------------------------------
01510         S32 num_constraints = 0;
01511         if (!dp.unpackS32(num_constraints, "num_constraints"))
01512         {
01513                 llwarns << "can't read number of constraints" << llendl;
01514                 return FALSE;
01515         }
01516 
01517         if (num_constraints > MAX_CONSTRAINTS)
01518         {
01519                 llwarns << "Too many constraints...ignoring" << llendl;
01520         }
01521         else
01522         {
01523                 //-------------------------------------------------------------------------
01524                 // get constraints
01525                 //-------------------------------------------------------------------------
01526                 std::string str;
01527                 for(S32 i = 0; i < num_constraints; ++i)
01528                 {
01529                         // read in constraint data
01530                         JointConstraintSharedData* constraintp = new JointConstraintSharedData;
01531                         U8 byte = 0;
01532 
01533                         if (!dp.unpackU8(byte, "chain_length"))
01534                         {
01535                                 llwarns << "can't read constraint chain length" << llendl;
01536                                 delete constraintp;
01537                                 return FALSE;
01538                         }
01539                         constraintp->mChainLength = (S32) byte;
01540 
01541                         if (!dp.unpackU8(byte, "constraint_type"))
01542                         {
01543                                 llwarns << "can't read constraint type" << llendl;
01544                                 delete constraintp;
01545                                 return FALSE;
01546                         }
01547                         constraintp->mConstraintType = (EConstraintType)byte;
01548 
01549                         const S32 BIN_DATA_LENGTH = 16;
01550                         U8 bin_data[BIN_DATA_LENGTH];
01551                         if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "source_volume"))
01552                         {
01553                                 llwarns << "can't read source volume name" << llendl;
01554                                 delete constraintp;
01555                                 return FALSE;
01556                         }
01557 
01558                         bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination
01559                         str = (char*)bin_data;
01560                         constraintp->mSourceConstraintVolume = mCharacter->getCollisionVolumeID(str);
01561 
01562                         if (!dp.unpackVector3(constraintp->mSourceConstraintOffset, "source_offset"))
01563                         {
01564                                 llwarns << "can't read constraint source offset" << llendl;
01565                                 delete constraintp;
01566                                 return FALSE;
01567                         }
01568 
01569                         if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "target_volume"))
01570                         {
01571                                 llwarns << "can't read target volume name" << llendl;
01572                                 delete constraintp;
01573                                 return FALSE;
01574                         }
01575 
01576                         bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination
01577                         str = (char*)bin_data;
01578                         if (str == "GROUND")
01579                         {
01580                                 // constrain to ground
01581                                 constraintp->mConstraintTargetType = TYPE_GROUND;
01582                         }
01583                         else
01584                         {
01585                                 constraintp->mConstraintTargetType = TYPE_BODY;
01586                                 constraintp->mTargetConstraintVolume = mCharacter->getCollisionVolumeID(str);
01587                         }
01588 
01589                         if (!dp.unpackVector3(constraintp->mTargetConstraintOffset, "target_offset"))
01590                         {
01591                                 llwarns << "can't read constraint target offset" << llendl;
01592                                 delete constraintp;
01593                                 return FALSE;
01594                         }
01595 
01596                         if (!dp.unpackVector3(constraintp->mTargetConstraintDir, "target_dir"))
01597                         {
01598                                 llwarns << "can't read constraint target direction" << llendl;
01599                                 delete constraintp;
01600                                 return FALSE;
01601                         }
01602 
01603                         if (!constraintp->mTargetConstraintDir.isExactlyZero())
01604                         {
01605                                 constraintp->mUseTargetOffset = TRUE;
01606         //                      constraintp->mTargetConstraintDir *= constraintp->mSourceConstraintOffset.magVec();
01607                         }
01608 
01609                         if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start"))
01610                         {
01611                                 llwarns << "can't read constraint ease in start time" << llendl;
01612                                 delete constraintp;
01613                                 return FALSE;
01614                         }
01615 
01616                         if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop"))
01617                         {
01618                                 llwarns << "can't read constraint ease in stop time" << llendl;
01619                                 delete constraintp;
01620                                 return FALSE;
01621                         }
01622 
01623                         if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start"))
01624                         {
01625                                 llwarns << "can't read constraint ease out start time" << llendl;
01626                                 delete constraintp;
01627                                 return FALSE;
01628                         }
01629 
01630                         if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop"))
01631                         {
01632                                 llwarns << "can't read constraint ease out stop time" << llendl;
01633                                 delete constraintp;
01634                                 return FALSE;
01635                         }
01636 
01637                         mJointMotionList->mConstraints.push_front(constraintp);
01638 
01639                         constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1];
01640                         
01641                         LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume);
01642                         // get joint to which this collision volume is attached
01643                         if (!joint)
01644                         {
01645                                 return FALSE;
01646                         }
01647                         for (S32 i = 0; i < constraintp->mChainLength + 1; i++)
01648                         {
01649                                 LLJoint* parent = joint->getParent();
01650                                 if (!parent)
01651                                 {
01652                                         llwarns << "Joint with no parent: " << joint->getName()
01653                                                         << " Emote: " << mEmoteName << llendl;
01654                                         return FALSE;
01655                                 }
01656                                 joint = parent;
01657                                 constraintp->mJointStateIndices[i] = -1;
01658                                 for (U32 j = 0; j < mJointMotionList->mNumJointMotions; j++)
01659                                 {
01660                                         if(mJointStates[j].getJoint() == joint)
01661                                         {
01662                                                 constraintp->mJointStateIndices[i] = (S32)j;
01663                                                 break;
01664                                         }
01665                                 }
01666                         }
01667 
01668                 }
01669         }
01670 
01671         // *FIX: support cleanup of old keyframe data
01672         LLKeyframeDataCache::addKeyframeData(getID(),  mJointMotionList);
01673         mAssetStatus = ASSET_LOADED;
01674 
01675         setupPose();
01676 
01677         return TRUE;
01678 }
01679 
01680 //-----------------------------------------------------------------------------
01681 // serialize()
01682 //-----------------------------------------------------------------------------
01683 BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
01684 {
01685         BOOL success = TRUE;
01686 
01687         success &= dp.packU16(KEYFRAME_MOTION_VERSION, "version");
01688         success &= dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version");
01689         success &= dp.packS32(mJointMotionList->mBasePriority, "base_priority");
01690         success &= dp.packF32(mJointMotionList->mDuration, "duration");
01691         success &= dp.packString(mEmoteName.c_str(), "emote_name");
01692         success &= dp.packF32(mJointMotionList->mLoopInPoint, "loop_in_point");
01693         success &= dp.packF32(mJointMotionList->mLoopOutPoint, "loop_out_point");
01694         success &= dp.packS32(mJointMotionList->mLoop, "loop");
01695         success &= dp.packF32(mJointMotionList->mEaseInDuration, "ease_in_duration");
01696         success &= dp.packF32(mJointMotionList->mEaseOutDuration, "ease_out_duration");
01697         success &= dp.packU32(mJointMotionList->mHandPose, "hand_pose");
01698         success &= dp.packU32(mJointMotionList->mNumJointMotions, "num_joints");
01699 
01700         for (U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
01701         {
01702                 JointMotion* joint_motionp = &mJointMotionList->mJointMotionArray[i];
01703                 success &= dp.packString(joint_motionp->mJointName.c_str(), "joint_name");
01704                 success &= dp.packS32(joint_motionp->mPriority, "joint_priority");
01705                 success &= dp.packS32(joint_motionp->mRotationCurve.mNumKeys, "num_rot_keys");
01706 
01707                 for (RotationKey* rot_keyp = joint_motionp->mRotationCurve.mKeys.getFirstData();
01708                         rot_keyp;
01709                         rot_keyp = joint_motionp->mRotationCurve.mKeys.getNextData())
01710                 {
01711                         U16 time_short = F32_to_U16(rot_keyp->mTime, 0.f, mJointMotionList->mDuration);
01712                         success &= dp.packU16(time_short, "time");
01713 
01714                         LLVector3 rot_angles = rot_keyp->mRotation.packToVector3();
01715                         
01716                         U16 x, y, z;
01717                         rot_angles.quantize16(-1.f, 1.f, -1.f, 1.f);
01718                         x = F32_to_U16(rot_angles.mV[VX], -1.f, 1.f);
01719                         y = F32_to_U16(rot_angles.mV[VY], -1.f, 1.f);
01720                         z = F32_to_U16(rot_angles.mV[VZ], -1.f, 1.f);
01721                         success &= dp.packU16(x, "rot_angle_x");
01722                         success &= dp.packU16(y, "rot_angle_y");
01723                         success &= dp.packU16(z, "rot_angle_z");
01724                 }
01725 
01726                 success &= dp.packS32(joint_motionp->mPositionCurve.mNumKeys, "num_pos_keys");
01727                 for (PositionKey* pos_keyp = joint_motionp->mPositionCurve.mKeys.getFirstData();
01728                         pos_keyp;
01729                         pos_keyp = joint_motionp->mPositionCurve.mKeys.getNextData())
01730                 {
01731                         U16 time_short = F32_to_U16(pos_keyp->mTime, 0.f, mJointMotionList->mDuration);
01732                         success &= dp.packU16(time_short, "time");
01733 
01734                         U16 x, y, z;
01735                         pos_keyp->mPosition.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
01736                         x = F32_to_U16(pos_keyp->mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
01737                         y = F32_to_U16(pos_keyp->mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
01738                         z = F32_to_U16(pos_keyp->mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
01739                         success &= dp.packU16(x, "pos_x");
01740                         success &= dp.packU16(y, "pos_y");
01741                         success &= dp.packU16(z, "pos_z");
01742                 }
01743         }       
01744 
01745         success &= dp.packS32(mJointMotionList->mConstraints.size(), "num_constraints");
01746         for (JointMotionList::constraint_list_t::const_iterator iter = mJointMotionList->mConstraints.begin();
01747                  iter != mJointMotionList->mConstraints.end(); ++iter)
01748         {
01749                 JointConstraintSharedData* shared_constraintp = *iter;
01750                 success &= dp.packU8(shared_constraintp->mChainLength, "chain_length");
01751                 success &= dp.packU8(shared_constraintp->mConstraintType, "constraint_type");
01752                 char volume_name[16];   /* Flawfinder: ignore */
01753                 snprintf(volume_name, sizeof(volume_name), "%s",        /* Flawfinder: ignore */
01754                                  mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str()); 
01755                 success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "source_volume");
01756                 success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset");
01757                 if (shared_constraintp->mConstraintTargetType == TYPE_GROUND)
01758                 {
01759                         snprintf(volume_name,sizeof(volume_name), "%s", "GROUND");      /* Flawfinder: ignore */
01760                 }
01761                 else
01762                 {
01763                         snprintf(volume_name, sizeof(volume_name),"%s", /* Flawfinder: ignore */
01764                                          mCharacter->findCollisionVolume(shared_constraintp->mTargetConstraintVolume)->getName().c_str());      
01765                 }
01766                 success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "target_volume");
01767                 success &= dp.packVector3(shared_constraintp->mTargetConstraintOffset, "target_offset");
01768                 success &= dp.packVector3(shared_constraintp->mTargetConstraintDir, "target_dir");
01769                 success &= dp.packF32(shared_constraintp->mEaseInStartTime, "ease_in_start");
01770                 success &= dp.packF32(shared_constraintp->mEaseInStopTime, "ease_in_stop");
01771                 success &= dp.packF32(shared_constraintp->mEaseOutStartTime, "ease_out_start");
01772                 success &= dp.packF32(shared_constraintp->mEaseOutStopTime, "ease_out_stop");
01773         }
01774 
01775         return success;
01776 }
01777 
01778 //-----------------------------------------------------------------------------
01779 // getFileSize()
01780 //-----------------------------------------------------------------------------
01781 U32     LLKeyframeMotion::getFileSize()
01782 {
01783         // serialize into a dummy buffer to calculate required size
01784         LLDataPackerBinaryBuffer dp;
01785         serialize(dp);
01786 
01787         return dp.getCurrentSize();
01788 }
01789 
01790 //-----------------------------------------------------------------------------
01791 // getPelvisBBox()
01792 //-----------------------------------------------------------------------------
01793 const LLBBoxLocal &LLKeyframeMotion::getPelvisBBox()
01794 {
01795         return mJointMotionList->mPelvisBBox;
01796 }
01797 
01798 //-----------------------------------------------------------------------------
01799 // setPriority()
01800 //-----------------------------------------------------------------------------
01801 void LLKeyframeMotion::setPriority(S32 priority)
01802 {
01803         if (mJointMotionList) 
01804         {
01805                 S32 priority_delta = priority - mJointMotionList->mBasePriority;
01806                 mJointMotionList->mBasePriority = (LLJoint::JointPriority)priority;
01807                 mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority;
01808 
01809                 for (U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
01810                 {
01811                         mJointMotionList->mJointMotionArray[i].mPriority = (LLJoint::JointPriority)llclamp(
01812                                 (S32)mJointMotionList->mJointMotionArray[i].mPriority + priority_delta,
01813                                 (S32)LLJoint::LOW_PRIORITY, 
01814                                 (S32)LLJoint::HIGHEST_PRIORITY);
01815                         mJointStates[i].setPriority(mJointMotionList->mJointMotionArray[i].mPriority);
01816                 }
01817         }
01818 }
01819 
01820 //-----------------------------------------------------------------------------
01821 // setEmote()
01822 //-----------------------------------------------------------------------------
01823 void LLKeyframeMotion::setEmote(const LLUUID& emote_id)
01824 {
01825         const char* emote_name = gAnimLibrary.animStateToString(emote_id);
01826         if (emote_name)
01827         {
01828                 mEmoteName = emote_name;
01829         }
01830         else
01831         {
01832                 mEmoteName = "";
01833         }
01834 }
01835 
01836 //-----------------------------------------------------------------------------
01837 // setEaseIn()
01838 //-----------------------------------------------------------------------------
01839 void LLKeyframeMotion::setEaseIn(F32 ease_in)
01840 {
01841         if (mJointMotionList)
01842         {
01843                 mJointMotionList->mEaseInDuration = llmax(ease_in, 0.f);
01844         }
01845 }
01846 
01847 //-----------------------------------------------------------------------------
01848 // setEaseOut()
01849 //-----------------------------------------------------------------------------
01850 void LLKeyframeMotion::setEaseOut(F32 ease_in)
01851 {
01852         if (mJointMotionList)
01853         {
01854                 mJointMotionList->mEaseOutDuration = llmax(ease_in, 0.f);
01855         }
01856 }
01857 
01858 
01859 //-----------------------------------------------------------------------------
01860 // flushKeyframeCache()
01861 //-----------------------------------------------------------------------------
01862 void LLKeyframeMotion::flushKeyframeCache()
01863 {
01864         // TODO: Make this safe to do
01865 //      LLKeyframeDataCache::clear();
01866 }
01867 
01868 //-----------------------------------------------------------------------------
01869 // setLoop()
01870 //-----------------------------------------------------------------------------
01871 void LLKeyframeMotion::setLoop(BOOL loop)
01872 {
01873         if (mJointMotionList) 
01874         {
01875                 mJointMotionList->mLoop = loop; 
01876                 mSendStopTimestamp = F32_MAX;
01877         }
01878 }
01879 
01880 
01881 //-----------------------------------------------------------------------------
01882 // setLoopIn()
01883 //-----------------------------------------------------------------------------
01884 void LLKeyframeMotion::setLoopIn(F32 in_point)
01885 {
01886         if (mJointMotionList)
01887         {
01888                 mJointMotionList->mLoopInPoint = in_point; 
01889                 
01890                 // set up loop keys
01891                 for (U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
01892                 {
01893                         PositionCurve* pos_curve = &mJointMotionList->mJointMotionArray[i].mPositionCurve;
01894                         RotationCurve* rot_curve = &mJointMotionList->mJointMotionArray[i].mRotationCurve;
01895                         ScaleCurve* scale_curve = &mJointMotionList->mJointMotionArray[i].mScaleCurve;
01896                         
01897                         pos_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint;
01898                         rot_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint;
01899                         scale_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint;
01900 
01901                         pos_curve->mLoopInKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
01902                         rot_curve->mLoopInKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
01903                         scale_curve->mLoopInKey.mScale = scale_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
01904                 }
01905         }
01906 }
01907 
01908 //-----------------------------------------------------------------------------
01909 // setLoopOut()
01910 //-----------------------------------------------------------------------------
01911 void LLKeyframeMotion::setLoopOut(F32 out_point)
01912 {
01913         if (mJointMotionList)
01914         {
01915                 mJointMotionList->mLoopOutPoint = out_point; 
01916                 
01917                 // set up loop keys
01918                 for (U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
01919                 {
01920                         PositionCurve* pos_curve = &mJointMotionList->mJointMotionArray[i].mPositionCurve;
01921                         RotationCurve* rot_curve = &mJointMotionList->mJointMotionArray[i].mRotationCurve;
01922                         ScaleCurve* scale_curve = &mJointMotionList->mJointMotionArray[i].mScaleCurve;
01923                         
01924                         pos_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint;
01925                         rot_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint;
01926                         scale_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint;
01927 
01928                         pos_curve->mLoopOutKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
01929                         rot_curve->mLoopOutKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
01930                         scale_curve->mLoopOutKey.mScale = scale_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
01931                 }
01932         }
01933 }
01934 
01935 //-----------------------------------------------------------------------------
01936 // onLoadComplete()
01937 //-----------------------------------------------------------------------------
01938 void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
01939                                                                            const LLUUID& asset_uuid,
01940                                                                            LLAssetType::EType type,
01941                                                                            void* user_data, S32 status, LLExtStat ext_status)
01942 {
01943         LLUUID* id = (LLUUID*)user_data;
01944                 
01945         std::vector<LLCharacter* >::iterator char_iter = LLCharacter::sInstances.begin();
01946 
01947         while(char_iter != LLCharacter::sInstances.end() &&
01948                         (*char_iter)->getID() != *id)
01949         {
01950                 ++char_iter;
01951         }
01952         
01953         delete id;
01954 
01955         if (char_iter == LLCharacter::sInstances.end())
01956         {
01957                 return;
01958         }
01959 
01960         LLCharacter* character = *char_iter;
01961 
01962         // create an instance of this motion (it may or may not already exist)
01963         LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->createMotion(asset_uuid);
01964 
01965         if (motionp)
01966         {
01967                 if (0 == status)
01968                 {
01969                         if (motionp->mAssetStatus == ASSET_LOADED)
01970                         {
01971                                 // asset already loaded
01972                                 return;
01973                         }
01974                         LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
01975                         S32 size = file.getSize();
01976                         
01977                         U8* buffer = new U8[size];
01978                         file.read((U8*)buffer, size);   /*Flawfinder: ignore*/
01979                         
01980                         lldebugs << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << llendl;
01981                         
01982                         LLDataPackerBinaryBuffer dp(buffer, size);
01983                         if (motionp->deserialize(dp))
01984                         {
01985                                 motionp->mAssetStatus = ASSET_LOADED;
01986                         }
01987                         else
01988                         {
01989                                 llwarns << "Failed to decode asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl;
01990                                 motionp->mAssetStatus = ASSET_FETCH_FAILED;
01991                         }
01992                         
01993                         delete []buffer;
01994                 }
01995                 else
01996                 {
01997                         llwarns << "Failed to load asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl;
01998                         motionp->mAssetStatus = ASSET_FETCH_FAILED;
01999                 }
02000         }
02001         else
02002         {
02003                 // motionp is NULL
02004                 llwarns << "Failed to createMotion() for asset UUID " << asset_uuid << llendl;
02005         }
02006 }
02007 
02008 
02009 //-----------------------------------------------------------------------------
02010 // writeCAL3D()
02011 //-----------------------------------------------------------------------------
02012 void LLKeyframeMotion::writeCAL3D(apr_file_t* fp)
02013 {
02014 //      <ANIMATION VERSION="1000" DURATION="1.03333" NUMTRACKS="58">
02015 //              <TRACK BONEID="0" NUMKEYFRAMES="31">
02016 //                      <KEYFRAME TIME="0">
02017 //                              <TRANSLATION>0 0 48.8332</TRANSLATION>
02018 //                              <ROTATION>0.0512905 0.05657 0.66973 0.738668</ROTATION>
02019 //                      </KEYFRAME>
02020 //                      </TRACK>
02021 //      </ANIMATION>
02022 
02023         apr_file_printf(fp, "<ANIMATION VERSION=\"1000\" DURATION=\"%.5f\" NUMTRACKS=\"%d\">\n",  getDuration(), mJointMotionList->mNumJointMotions);
02024         for (U32 joint_index = 0; joint_index < mJointMotionList->mNumJointMotions; joint_index++)
02025         {
02026                 JointMotion* joint_motionp = &mJointMotionList->mJointMotionArray[joint_index];
02027                 LLJoint* animated_joint = mCharacter->getJoint(joint_motionp->mJointName);
02028                 S32 joint_num = animated_joint->mJointNum + 1;
02029 
02030                 apr_file_printf(fp, "   <TRACK BONEID=\"%d\" NUMKEYFRAMES=\"%d\">\n",  joint_num, joint_motionp->mRotationCurve.mNumKeys );
02031                 PositionKey* pos_keyp = joint_motionp->mPositionCurve.mKeys.getFirstData();
02032                 for (RotationKey* rot_keyp = joint_motionp->mRotationCurve.mKeys.getFirstData();
02033                         rot_keyp;
02034                         rot_keyp = joint_motionp->mRotationCurve.mKeys.getNextData())
02035                 {
02036                         apr_file_printf(fp, "           <KEYFRAME TIME=\"%0.3f\">\n", rot_keyp->mTime);
02037                         LLVector3 nominal_pos = animated_joint->getPosition();
02038                         if (animated_joint->getParent())
02039                         {
02040                                 nominal_pos.scaleVec(animated_joint->getParent()->getScale());
02041                         }
02042                         nominal_pos = nominal_pos * 100.f;
02043 
02044                         if (joint_motionp->mUsage & LLJointState::POS && pos_keyp)
02045                         {
02046                                 LLVector3 pos_val = pos_keyp->mPosition;
02047                                 pos_val = pos_val * 100.f;
02048                                 pos_val += nominal_pos;
02049                                 apr_file_printf(fp, "                   <TRANSLATION>%0.4f %0.4f %0.4f</TRANSLATION>\n", pos_val.mV[VX], pos_val.mV[VY], pos_val.mV[VZ]);
02050                                 pos_keyp = joint_motionp->mPositionCurve.mKeys.getNextData();
02051                         }
02052                         else
02053                         {
02054                                 apr_file_printf(fp, "                   <TRANSLATION>%0.4f %0.4f %0.4f</TRANSLATION>\n", nominal_pos.mV[VX], nominal_pos.mV[VY], nominal_pos.mV[VZ]);
02055                         }
02056 
02057                         LLQuaternion rot_val = ~rot_keyp->mRotation;
02058                         apr_file_printf(fp, "                   <ROTATION>%0.4f %0.4f %0.4f %0.4f</ROTATION>\n", rot_val.mQ[VX], rot_val.mQ[VY], rot_val.mQ[VZ], rot_val.mQ[VW]);
02059                         apr_file_printf(fp, "           </KEYFRAME>\n");
02060                 }
02061                 apr_file_printf(fp, "   </TRACK>\n");
02062         }
02063         apr_file_printf(fp, "</ANIMATION>\n");
02064 }
02065 
02066 //--------------------------------------------------------------------
02067 // LLKeyframeDataCache::dumpDiagInfo()
02068 //--------------------------------------------------------------------
02069 void LLKeyframeDataCache::dumpDiagInfo()
02070 {
02071         // keep track of totals
02072         U32 total_size = 0;
02073 
02074         char buf[1024];         /* Flawfinder: ignore */
02075 
02076         llinfos << "-----------------------------------------------------" << llendl;
02077         llinfos << "       Global Motion Table (DEBUG only)" << llendl;
02078         llinfos << "-----------------------------------------------------" << llendl;
02079 
02080         // print each loaded mesh, and it's memory usage
02081         for (keyframe_data_map_t::iterator map_it = sKeyframeDataMap.begin();
02082                  map_it != sKeyframeDataMap.end(); ++map_it)
02083         {
02084                 U32 joint_motion_kb;
02085 
02086                 LLKeyframeMotion::JointMotionList *motion_list_p = map_it->second;
02087 
02088                 llinfos << "Motion: " << map_it->first << llendl;
02089 
02090                 joint_motion_kb = motion_list_p->dumpDiagInfo();
02091 
02092                 total_size += joint_motion_kb;
02093         }
02094 
02095         llinfos << "-----------------------------------------------------" << llendl;
02096         llinfos << "Motions\tTotal Size" << llendl;
02097         snprintf(buf, sizeof(buf), "%d\t\t%d bytes", (S32)sKeyframeDataMap.size(), total_size );                /* Flawfinder: ignore */
02098         llinfos << buf << llendl;
02099         llinfos << "-----------------------------------------------------" << llendl;
02100 }
02101 
02102 
02103 //--------------------------------------------------------------------
02104 // LLKeyframeDataCache::addKeyframeData()
02105 //--------------------------------------------------------------------
02106 void LLKeyframeDataCache::addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList* joint_motion_listp)
02107 {
02108         sKeyframeDataMap[id] = joint_motion_listp;
02109 }
02110 
02111 //--------------------------------------------------------------------
02112 // LLKeyframeDataCache::removeKeyframeData()
02113 //--------------------------------------------------------------------
02114 void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id)
02115 {
02116         keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id);
02117         if (found_data != sKeyframeDataMap.end())
02118         {
02119                 delete found_data->second;
02120                 sKeyframeDataMap.erase(found_data);
02121         }
02122 }
02123 
02124 //--------------------------------------------------------------------
02125 // LLKeyframeDataCache::getKeyframeData()
02126 //--------------------------------------------------------------------
02127 LLKeyframeMotion::JointMotionList* LLKeyframeDataCache::getKeyframeData(const LLUUID& id)
02128 {
02129         keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id);
02130         if (found_data == sKeyframeDataMap.end())
02131         {
02132                 return NULL;
02133         }
02134         return found_data->second;
02135 }
02136 
02137 //--------------------------------------------------------------------
02138 // ~LLKeyframeDataCache::LLKeyframeDataCache()
02139 //--------------------------------------------------------------------
02140 LLKeyframeDataCache::~LLKeyframeDataCache()
02141 {
02142         clear();
02143 }
02144 
02145 //-----------------------------------------------------------------------------
02146 // clear()
02147 //-----------------------------------------------------------------------------
02148 void LLKeyframeDataCache::clear()
02149 {
02150         for_each(sKeyframeDataMap.begin(), sKeyframeDataMap.end(), DeletePairedPointer());
02151         sKeyframeDataMap.clear();
02152 }
02153 
02154 //-----------------------------------------------------------------------------
02155 // JointConstraint()
02156 //-----------------------------------------------------------------------------
02157 LLKeyframeMotion::JointConstraint::JointConstraint(JointConstraintSharedData* shared_data) : mSharedData(shared_data) 
02158 {
02159         mTotalLength = 0.f;
02160         mActive = FALSE;
02161         mSourceVolume = NULL;
02162         mTargetVolume = NULL;
02163         mFixupDistanceRMS = 0.f;
02164 }
02165 
02166 //-----------------------------------------------------------------------------
02167 // ~JointConstraint()
02168 //-----------------------------------------------------------------------------
02169 LLKeyframeMotion::JointConstraint::~JointConstraint()
02170 {
02171 }
02172 
02173 // End

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