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

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