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