00001
00032
00033
00034
00035 #include "linden_common.h"
00036
00037 #include "llmotioncontroller.h"
00038 #include "llkeyframemotion.h"
00039 #include "llmath.h"
00040 #include "lltimer.h"
00041 #include "llanimationstates.h"
00042 #include "llstl.h"
00043
00044 const S32 NUM_JOINT_SIGNATURE_STRIDES = LL_CHARACTER_MAX_JOINTS / 4;
00045 const U32 MAX_MOTION_INSTANCES = 32;
00046
00047
00048
00049
00050 LLMotionRegistry LLMotionController::sRegistry;
00051
00052
00053
00054
00055 LLMotionTableEntry::LLMotionTableEntry()
00056 {
00057 mConstructor = NULL;
00058 mID.setNull();
00059 }
00060
00061 LLMotionTableEntry::LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id)
00062 : mConstructor(constructor), mID(id)
00063 {
00064
00065 }
00066
00067
00068
00069
00070 LLMotion* LLMotionTableEntry::create(const LLUUID &id)
00071 {
00072 LLMotion* motionp = mConstructor(id);
00073
00074 return motionp;
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, LLMotionTableEntry())
00089 {
00090
00091 }
00092
00093
00094
00095
00096
00097
00098 LLMotionRegistry::~LLMotionRegistry()
00099 {
00100 mMotionTable.removeAll();
00101 }
00102
00103
00104
00105
00106
00107 BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor constructor )
00108 {
00109
00110 if (!mMotionTable.check(id))
00111 {
00112 mMotionTable.set(id, LLMotionTableEntry(constructor, id));
00113 return TRUE;
00114 }
00115
00116 return FALSE;
00117 }
00118
00119
00120
00121
00122 void LLMotionRegistry::markBad( const LLUUID& id )
00123 {
00124 mMotionTable.set(id, LLMotionTableEntry());
00125 }
00126
00127
00128
00129
00130 LLMotion *LLMotionRegistry::createMotion( const LLUUID &id )
00131 {
00132 LLMotionTableEntry motion_entry = mMotionTable.get(id);
00133 LLMotion* motion = NULL;
00134
00135 if ( motion_entry.getID().isNull() )
00136 {
00137
00138 motion = LLKeyframeMotion::create(id);
00139 }
00140 else
00141 {
00142 motion = motion_entry.create(id);
00143 }
00144
00145 return motion;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 LLMotionController::LLMotionController( )
00159 {
00160 mTime = 0.f;
00161 mTimeOffset = 0.f;
00162 mLastTime = 0.0f;
00163 mHasRunOnce = FALSE;
00164 mPaused = FALSE;
00165 mPauseTime = 0.f;
00166 mTimeStep = 0.f;
00167 mTimeStepCount = 0;
00168 mLastInterp = 0.f;
00169 mTimeFactor = 1.f;
00170 }
00171
00172
00173
00174
00175
00176
00177 LLMotionController::~LLMotionController()
00178 {
00179 deleteAllMotions();
00180 }
00181
00182
00183
00184
00185 void LLMotionController::deleteAllMotions()
00186 {
00187 mLoadingMotions.clear();
00188 mLoadedMotions.clear();
00189 mActiveMotions.clear();
00190
00191 for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer());
00192 mAllMotions.clear();
00193 }
00194
00195
00196
00197
00198 void LLMotionController::addLoadedMotion(LLMotion* motionp)
00199 {
00200 std::set<LLUUID> motions_to_kill;
00201
00202
00203 if (mLoadedMotions.size() > MAX_MOTION_INSTANCES)
00204 {
00205
00206 mPoseBlender.clearBlenders();
00207
00208 for (motion_list_t::iterator loaded_motion_it = mLoadedMotions.begin();
00209 loaded_motion_it != mLoadedMotions.end();
00210 ++loaded_motion_it)
00211 {
00212 LLMotion* cur_motionp = *loaded_motion_it;
00213
00214
00215 if (!isMotionActive(cur_motionp))
00216 {
00217 motions_to_kill.insert(cur_motionp->getID());
00218 }
00219 }
00220 }
00221
00222
00223 for (std::set<LLUUID>::iterator motion_it = motions_to_kill.begin();
00224 motion_it != motions_to_kill.end();
00225 ++motion_it)
00226 {
00227
00228
00229 LLUUID motion_id = *motion_it;
00230 LLMotion* motionp = findMotion(motion_id);
00231 if (motionp && !isMotionActive(motionp))
00232 {
00233 removeMotion(motion_id);
00234 }
00235 }
00236
00237
00238 mLoadedMotions.push_back(motionp);
00239 }
00240
00241
00242
00243
00244 void LLMotionController::setTimeStep(F32 step)
00245 {
00246 mTimeStep = step;
00247
00248 if (step != 0.f)
00249 {
00250
00251 for (motion_list_t::iterator iter = mActiveMotions.begin();
00252 iter != mActiveMotions.end(); ++iter)
00253 {
00254 LLMotion* motionp = *iter;
00255 motionp->mActivationTimestamp = (F32)llfloor(motionp->mActivationTimestamp / step) * step;
00256 BOOL stopped = motionp->isStopped();
00257 motionp->setStopTime((F32)llfloor(motionp->getStopTime() / step) * step);
00258 motionp->setStopped(stopped);
00259 motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step;
00260 }
00261 }
00262 }
00263
00264
00265
00266
00267 void LLMotionController::setTimeFactor(F32 time_factor)
00268 {
00269 mTimeOffset += mTimer.getElapsedTimeAndResetF32() * mTimeFactor;
00270 mTimeFactor = time_factor;
00271 }
00272
00273
00274
00275
00276 void LLMotionController::setCharacter(LLCharacter *character)
00277 {
00278 mCharacter = character;
00279 }
00280
00281
00282
00283
00284
00285 BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constructor )
00286 {
00287 return sRegistry.addMotion(id, constructor);
00288 }
00289
00290
00291
00292
00293 void LLMotionController::removeMotion( const LLUUID& id)
00294 {
00295 LLMotion* motionp = findMotion(id);
00296
00297 removeMotionInstance(motionp);
00298
00299 mAllMotions.erase(id);
00300 }
00301
00302
00303
00304
00305 void LLMotionController::removeMotionInstance(LLMotion* motionp)
00306 {
00307 if (motionp)
00308 {
00309 stopMotionInstance(motionp, TRUE);
00310
00311 mLoadingMotions.erase(motionp);
00312 mLoadedMotions.remove(motionp);
00313 mActiveMotions.remove(motionp);
00314 delete motionp;
00315 }
00316 }
00317
00318
00319
00320
00321 LLMotion* LLMotionController::createMotion( const LLUUID &id )
00322 {
00323
00324 LLMotion *motion = findMotion(id);
00325
00326
00327 if (!motion)
00328 {
00329
00330 motion = sRegistry.createMotion(id);
00331 if (!motion)
00332 {
00333 return NULL;
00334 }
00335
00336
00337 const char* motion_name = gAnimLibrary.animStateToString(id);
00338 if (motion_name)
00339 {
00340 motion->setName(motion_name);
00341 }
00342
00343
00344 LLMotion::LLMotionInitStatus stat = motion->onInitialize(mCharacter);
00345 switch(stat)
00346 {
00347 case LLMotion::STATUS_FAILURE:
00348 llinfos << "Motion " << id << " init failed." << llendl;
00349 sRegistry.markBad(id);
00350 delete motion;
00351 return NULL;
00352 case LLMotion::STATUS_HOLD:
00353 mLoadingMotions.insert(motion);
00354 break;
00355 case LLMotion::STATUS_SUCCESS:
00356
00357 addLoadedMotion(motion);
00358 break;
00359 default:
00360 llerrs << "Invalid initialization status" << llendl;
00361 break;
00362 }
00363
00364 mAllMotions[id] = motion;
00365 }
00366 return motion;
00367 }
00368
00369
00370
00371
00372 BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset)
00373 {
00374
00375 LLMotion *motion = findMotion(id);
00376
00377
00378
00379 if (motion
00380 && motion->canDeprecate()
00381 && motion->getFadeWeight() > 0.01f
00382 && (motion->isBlending() || motion->getStopTime() != 0.f))
00383 {
00384 deprecateMotionInstance(motion);
00385
00386 motion = NULL;
00387 }
00388
00389
00390 if (!motion)
00391 {
00392 motion = createMotion(id);
00393 }
00394
00395 if (!motion)
00396 {
00397 return FALSE;
00398 }
00399
00400 else if (motion->canDeprecate() && isMotionActive(motion))
00401 {
00402 return TRUE;
00403 }
00404
00405
00406 return activateMotionInstance(motion, mTime - start_offset);
00407 }
00408
00409
00410
00411
00412
00413 BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate)
00414 {
00415
00416 LLMotion *motion = findMotion(id);
00417
00418 return stopMotionInstance(motion, stop_immediate);
00419 }
00420
00421 BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediate)
00422 {
00423 if (!motion)
00424 {
00425 return FALSE;
00426 }
00427
00428
00429 if (isMotionActive(motion) && !motion->isStopped())
00430 {
00431
00432
00433
00434 F32 stop_time = (mTimeStep != 0.f || mPaused) ? (mTime) : mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor);
00435 motion->setStopTime(stop_time);
00436
00437 if (stop_immediate)
00438 {
00439 deactivateMotionInstance(motion);
00440 }
00441 return TRUE;
00442 }
00443 else if (isMotionLoading(motion))
00444 {
00445 motion->setStopped(TRUE);
00446 return TRUE;
00447 }
00448
00449 return FALSE;
00450 }
00451
00452
00453
00454
00455
00456 void LLMotionController::updateRegularMotions()
00457 {
00458 updateMotionsByType(LLMotion::NORMAL_BLEND);
00459 }
00460
00461
00462
00463
00464 void LLMotionController::updateAdditiveMotions()
00465 {
00466 updateMotionsByType(LLMotion::ADDITIVE_BLEND);
00467 }
00468
00469
00470
00471
00472 void LLMotionController::resetJointSignatures()
00473 {
00474 memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS);
00475 memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS);
00476 }
00477
00478
00479
00480
00481 void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type)
00482 {
00483 BOOL update_result = TRUE;
00484 U8 last_joint_signature[LL_CHARACTER_MAX_JOINTS];
00485
00486 memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS);
00487
00488
00489 for (motion_list_t::iterator iter = mActiveMotions.begin();
00490 iter != mActiveMotions.end(); )
00491 {
00492 motion_list_t::iterator curiter = iter++;
00493 LLMotion* motionp = *curiter;
00494 if (motionp->getBlendType() != anim_type)
00495 {
00496 continue;
00497 }
00498
00499 BOOL update_motion = FALSE;
00500
00501 if (motionp->getPose()->getWeight() < 1.f)
00502 {
00503 update_motion = TRUE;
00504 }
00505 else
00506 {
00507
00508 for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++)
00509 {
00510 U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]);
00511 U32 test_signature = *(U32*)&(motionp->mJointSignature[0][i * 4]);
00512
00513 if ((*current_signature | test_signature) > (*current_signature))
00514 {
00515 *current_signature |= test_signature;
00516 update_motion = TRUE;
00517 }
00518
00519 *((U32*)&last_joint_signature[i * 4]) = *(U32*)&(mJointSignature[1][i * 4]);
00520 current_signature = (U32*)&(mJointSignature[1][i * 4]);
00521 test_signature = *(U32*)&(motionp->mJointSignature[1][i * 4]);
00522
00523 if ((*current_signature | test_signature) > (*current_signature))
00524 {
00525 *current_signature |= test_signature;
00526 update_motion = TRUE;
00527 }
00528 }
00529 }
00530
00531 if (!update_motion)
00532 {
00533 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
00534 {
00535 deactivateMotionInstance(motionp);
00536 }
00537 else if (motionp->isStopped() && mTime > motionp->getStopTime())
00538 {
00539
00540 if (mLastTime <= motionp->getStopTime())
00541 {
00542
00543 motionp->mResidualWeight = motionp->getPose()->getWeight();
00544 }
00545 }
00546 else if (mTime > motionp->mSendStopTimestamp)
00547 {
00548
00549
00550 if (mLastTime <= motionp->mSendStopTimestamp)
00551 {
00552 mCharacter->requestStopMotion( motionp );
00553 stopMotionInstance(motionp, FALSE);
00554 }
00555 }
00556 else if (mTime >= motionp->mActivationTimestamp)
00557 {
00558 if (mLastTime < motionp->mActivationTimestamp)
00559 {
00560 motionp->mResidualWeight = motionp->getPose()->getWeight();
00561 }
00562 }
00563 continue;
00564 }
00565
00566 LLPose *posep = motionp->getPose();
00567
00568
00569 if (mHasRunOnce && motionp->getMinPixelArea() > mCharacter->getPixelArea())
00570 {
00571 motionp->fadeOut();
00572
00573
00574 if (mTime > motionp->mSendStopTimestamp)
00575 {
00576
00577
00578 if (mLastTime <= motionp->mSendStopTimestamp)
00579 {
00580 mCharacter->requestStopMotion( motionp );
00581 stopMotionInstance(motionp, FALSE);
00582 }
00583 }
00584
00585 if (motionp->getFadeWeight() < 0.01f)
00586 {
00587 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
00588 {
00589 posep->setWeight(0.f);
00590 deactivateMotionInstance(motionp);
00591 }
00592 continue;
00593 }
00594 }
00595 else
00596 {
00597 motionp->fadeIn();
00598 }
00599
00600
00601
00602
00603 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
00604 {
00605
00606
00607 if (mLastTime <= motionp->getStopTime())
00608 {
00609
00610
00611 posep->setWeight(motionp->getFadeWeight());
00612 motionp->onUpdate(motionp->getStopTime() - motionp->mActivationTimestamp, last_joint_signature);
00613 }
00614 else
00615 {
00616 posep->setWeight(0.f);
00617 deactivateMotionInstance(motionp);
00618 continue;
00619 }
00620 }
00621
00622
00623
00624
00625 else if (motionp->isStopped() && mTime > motionp->getStopTime())
00626 {
00627
00628 if (mLastTime <= motionp->getStopTime())
00629 {
00630
00631 motionp->mResidualWeight = motionp->getPose()->getWeight();
00632 }
00633
00634 if (motionp->getEaseOutDuration() == 0.f)
00635 {
00636 posep->setWeight(0.f);
00637 }
00638 else
00639 {
00640 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mTime - motionp->getStopTime()) / motionp->getEaseOutDuration())));
00641 }
00642
00643
00644 update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature);
00645 }
00646
00647
00648
00649
00650 else if (mTime > motionp->mActivationTimestamp + motionp->getEaseInDuration())
00651 {
00652 posep->setWeight(motionp->getFadeWeight());
00653
00654
00655 if (mTime > motionp->mSendStopTimestamp)
00656 {
00657
00658
00659 if (mLastTime <= motionp->mSendStopTimestamp)
00660 {
00661 mCharacter->requestStopMotion( motionp );
00662 stopMotionInstance(motionp, FALSE);
00663 }
00664 }
00665
00666
00667 update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature);
00668 }
00669
00670
00671
00672
00673 else if (mTime >= motionp->mActivationTimestamp)
00674 {
00675 if (mLastTime < motionp->mActivationTimestamp)
00676 {
00677 motionp->mResidualWeight = motionp->getPose()->getWeight();
00678 }
00679 if (motionp->getEaseInDuration() == 0.f)
00680 {
00681 posep->setWeight(motionp->getFadeWeight());
00682 }
00683 else
00684 {
00685
00686 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration()));
00687 }
00688
00689 update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature);
00690 }
00691 else
00692 {
00693 posep->setWeight(0.f);
00694 update_result = motionp->onUpdate(0.f, last_joint_signature);
00695 }
00696
00697
00698 if (!update_result)
00699 {
00700 if (!motionp->isStopped() || motionp->getStopTime() > mTime)
00701 {
00702
00703
00704
00705 mCharacter->requestStopMotion( motionp );
00706 stopMotionInstance(motionp, FALSE);
00707 }
00708
00709 }
00710
00711
00712 mPoseBlender.addMotion(motionp);
00713 }
00714 }
00715
00716
00717
00718
00719
00720 void LLMotionController::updateMotion()
00721 {
00722 BOOL use_quantum = (mTimeStep != 0.f);
00723
00724
00725 if (!mPaused)
00726 {
00727 F32 update_time = mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor);
00728 if (use_quantum)
00729 {
00730 F32 time_interval = fmodf(update_time, mTimeStep);
00731
00732
00733 S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1;
00734 if (quantum_count == mTimeStepCount)
00735 {
00736
00737 if (!mPaused)
00738 {
00739 F32 interp = time_interval / mTimeStep;
00740 mPoseBlender.interpolate(interp - mLastInterp);
00741 mLastInterp = interp;
00742 }
00743
00744 return;
00745 }
00746
00747
00748 mPoseBlender.interpolate(1.f);
00749 mPoseBlender.clearBlenders();
00750
00751 mTimeStepCount = quantum_count;
00752 mLastTime = mTime;
00753 mTime = (F32)quantum_count * mTimeStep;
00754 mLastInterp = 0.f;
00755 }
00756 else
00757 {
00758 mLastTime = mTime;
00759 mTime = update_time;
00760 }
00761 }
00762
00763
00764 for (motion_set_t::iterator iter = mLoadingMotions.begin();
00765 iter != mLoadingMotions.end(); )
00766 {
00767 motion_set_t::iterator curiter = iter++;
00768 LLMotion* motionp = *curiter;
00769 if( !motionp)
00770 {
00771 continue;
00772 }
00773 LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter);
00774 if (status == LLMotion::STATUS_SUCCESS)
00775 {
00776 mLoadingMotions.erase(curiter);
00777
00778 addLoadedMotion(motionp);
00779
00780 if (!motionp->isStopped())
00781 {
00782 activateMotionInstance(motionp, mTime);
00783 }
00784 }
00785 else if (status == LLMotion::STATUS_FAILURE)
00786 {
00787 llinfos << "Motion " << motionp->getID() << " init failed." << llendl;
00788 sRegistry.markBad(motionp->getID());
00789 mLoadingMotions.erase(curiter);
00790
00791 mAllMotions.erase(motionp->getID());
00792 delete motionp;
00793 }
00794 }
00795
00796 resetJointSignatures();
00797
00798 if (!mPaused)
00799 {
00800
00801 updateAdditiveMotions();
00802 resetJointSignatures();
00803
00804
00805 updateRegularMotions();
00806
00807 if (use_quantum)
00808 {
00809 mPoseBlender.blendAndCache(TRUE);
00810 }
00811 else
00812 {
00813 mPoseBlender.blendAndApply();
00814 }
00815 }
00816
00817 mHasRunOnce = TRUE;
00818
00819 }
00820
00821
00822
00823
00824
00825 BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time)
00826 {
00827 if (mLoadingMotions.find(motion) != mLoadingMotions.end())
00828 {
00829
00830 motion->setStopped(FALSE);
00831
00832 return TRUE;
00833 }
00834
00835 motion->mResidualWeight = motion->getPose()->getWeight();
00836 motion->mActivationTimestamp = time;
00837
00838
00839 if (motion->getDuration() != 0.f && !motion->getLoop())
00840 {
00841 F32 ease_out_time;
00842 F32 motion_duration;
00843
00844
00845
00846 ease_out_time = motion->getEaseOutDuration();
00847
00848
00849
00850 motion_duration = llmax(motion->getDuration() - ease_out_time, 0.f);
00851 motion->mSendStopTimestamp = time + motion_duration;
00852 }
00853 else
00854 {
00855 motion->mSendStopTimestamp = F32_MAX;
00856 }
00857
00858 mActiveMotions.remove(motion);
00859 mActiveMotions.push_front(motion);
00860
00861 motion->activate();
00862 motion->onUpdate(0.f, mJointSignature[1]);
00863
00864 return TRUE;
00865 }
00866
00867
00868
00869
00870 BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion)
00871 {
00872 motion->deactivate();
00873
00874 motion_set_t::iterator found_it = mDeprecatedMotions.find(motion);
00875 if (found_it != mDeprecatedMotions.end())
00876 {
00877
00878 removeMotionInstance(motion);
00879 mDeprecatedMotions.erase(found_it);
00880 }
00881 else
00882 {
00883
00884 mActiveMotions.remove(motion);
00885 }
00886
00887 return TRUE;
00888 }
00889
00890 void LLMotionController::deprecateMotionInstance(LLMotion* motion)
00891 {
00892 mDeprecatedMotions.insert(motion);
00893
00894
00895 stopMotionInstance(motion, FALSE);
00896
00897 mAllMotions.erase(motion->getID());
00898 }
00899
00900
00901
00902
00903 bool LLMotionController::isMotionActive(LLMotion *motion)
00904 {
00905 return (motion && motion->isActive());
00906 }
00907
00908
00909
00910
00911 bool LLMotionController::isMotionLoading(LLMotion* motion)
00912 {
00913 return (mLoadingMotions.find(motion) != mLoadingMotions.end());
00914 }
00915
00916
00917
00918
00919
00920 LLMotion *LLMotionController::findMotion(const LLUUID& id)
00921 {
00922 return get_if_there<LLUUID, LLMotion*>(mAllMotions, id, NULL);
00923 }
00924
00925
00926
00927
00928 void LLMotionController::deactivateAllMotions()
00929 {
00930
00931 for (std::map<LLUUID, LLMotion*>::iterator iter = mAllMotions.begin();
00932 iter != mAllMotions.end(); iter++)
00933 {
00934 LLMotion* motionp = iter->second;
00935 if (motionp) motionp->deactivate();
00936 }
00937
00938
00939 deleteAllMotions();
00940 }
00941
00942
00943
00944
00945
00946 void LLMotionController::flushAllMotions()
00947 {
00948 std::vector<std::pair<LLUUID,F32> > active_motions;
00949 active_motions.reserve(mActiveMotions.size());
00950 for (motion_list_t::iterator iter = mActiveMotions.begin();
00951 iter != mActiveMotions.end(); )
00952 {
00953 motion_list_t::iterator curiter = iter++;
00954 LLMotion* motionp = *curiter;
00955 F32 dtime = mTime - motionp->mActivationTimestamp;
00956 active_motions.push_back(std::make_pair(motionp->getID(),dtime));
00957 motionp->deactivate();
00958 }
00959
00960
00961 deleteAllMotions();
00962
00963
00964
00965 mCharacter->removeAnimationData("Hand Pose");
00966
00967
00968 for (std::vector<std::pair<LLUUID,F32> >::iterator iter = active_motions.begin();
00969 iter != active_motions.end(); ++iter)
00970 {
00971 startMotion(iter->first, iter->second);
00972 }
00973 }
00974
00975
00976
00977
00978 void LLMotionController::pause()
00979 {
00980 if (!mPaused)
00981 {
00982
00983 mPauseTime = mTimer.getElapsedTimeF32();
00984 mPaused = TRUE;
00985 }
00986
00987 }
00988
00989
00990
00991
00992 void LLMotionController::unpause()
00993 {
00994 if (mPaused)
00995 {
00996
00997 mTimer.reset();
00998 mTimer.setAge(mPauseTime);
00999 mPaused = FALSE;
01000 }
01001 }
01002