diff options
Diffstat (limited to 'indra/llcharacter')
-rw-r--r-- | indra/llcharacter/llcharacter.cpp | 47 | ||||
-rw-r--r-- | indra/llcharacter/llcharacter.h | 13 | ||||
-rw-r--r-- | indra/llcharacter/llkeyframemotion.cpp | 10 | ||||
-rw-r--r-- | indra/llcharacter/llkeyframemotionparam.cpp | 53 | ||||
-rw-r--r-- | indra/llcharacter/llkeyframemotionparam.h | 15 | ||||
-rw-r--r-- | indra/llcharacter/llmotion.cpp | 17 | ||||
-rw-r--r-- | indra/llcharacter/llmotion.h | 25 | ||||
-rw-r--r-- | indra/llcharacter/llmotioncontroller.cpp | 442 | ||||
-rw-r--r-- | indra/llcharacter/llmotioncontroller.h | 58 |
9 files changed, 395 insertions, 285 deletions
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 033ac16274..1d5947c9ef 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -103,11 +103,11 @@ LLJoint *LLCharacter::getJoint( const std::string &name ) } //----------------------------------------------------------------------------- -// addMotion() +// registerMotion() //----------------------------------------------------------------------------- -BOOL LLCharacter::addMotion( const LLUUID& id, LLMotionConstructor create ) +BOOL LLCharacter::registerMotion( const LLUUID& id, LLMotionConstructor create ) { - return mMotionController.addMotion(id, create); + return mMotionController.registerMotion(id, create); } //----------------------------------------------------------------------------- @@ -119,7 +119,16 @@ void LLCharacter::removeMotion( const LLUUID& id ) } //----------------------------------------------------------------------------- -// getMotion() +// findMotion() +//----------------------------------------------------------------------------- +LLMotion* LLCharacter::findMotion( const LLUUID &id ) +{ + return mMotionController.findMotion( id ); +} + +//----------------------------------------------------------------------------- +// createMotion() +// NOTE: Always assign the result to a LLPointer! //----------------------------------------------------------------------------- LLMotion* LLCharacter::createMotion( const LLUUID &id ) { @@ -168,26 +177,24 @@ void LLCharacter::requestStopMotion( LLMotion* motion) //----------------------------------------------------------------------------- -// updateMotion() +// updateMotions() //----------------------------------------------------------------------------- -void LLCharacter::updateMotion(BOOL force_update) +void LLCharacter::updateMotions(e_update_t update_type) { - // unpause if we're forcing an update or - // number of outstanding pause requests has dropped - // to the initial one - if (mMotionController.isPaused() && - (force_update || mPauseRequest->getNumRefs() == 1)) + LLFastTimer t(LLFastTimer::FTM_UPDATE_ANIMATION); + if (update_type == HIDDEN_UPDATE) { - mMotionController.unpause(); + mMotionController.updateMotionsMinimal(); } - - mMotionController.updateMotion(); - - // pause once again, after forced update, if there are outstanding - // pause requests - if (force_update && mPauseRequest->getNumRefs() > 1) + else { - mMotionController.pause(); + // unpause if the number of outstanding pause requests has dropped to the initial one + if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1) + { + mMotionController.unpauseAllMotions(); + } + bool force_update = (update_type == FORCE_UPDATE); + mMotionController.updateMotions(force_update); } } @@ -499,7 +506,7 @@ void LLCharacter::updateVisualParams() LLAnimPauseRequest LLCharacter::requestPause() { - mMotionController.pause(); + mMotionController.pauseAllMotions(); return mPauseRequest; } diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 2c0451d46c..4fd135721b 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -137,13 +137,16 @@ public: //------------------------------------------------------------------------- // registers a motion with the character // returns true if successfull - BOOL addMotion( const LLUUID& id, LLMotionConstructor create ); + BOOL registerMotion( const LLUUID& id, LLMotionConstructor create ); void removeMotion( const LLUUID& id ); - // returns an instance of a registered motion + // returns an instance of a registered motion, creating one if necessary LLMotion* createMotion( const LLUUID &id ); + // returns an existing instance of a registered motion + LLMotion* findMotion( const LLUUID &id ); + // start a motion // returns true if successful, false if an error occurred virtual BOOL startMotion( const LLUUID& id, F32 start_offset = 0.f); @@ -161,12 +164,16 @@ public: virtual void requestStopMotion( LLMotion* motion ); // periodic update function, steps the motion controller - void updateMotion(BOOL force_update = FALSE); + enum e_update_t { NORMAL_UPDATE, HIDDEN_UPDATE, FORCE_UPDATE }; + void updateMotions(e_update_t update_type); LLAnimPauseRequest requestPause(); BOOL areAnimationsPaused() { return mMotionController.isPaused(); } void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); } void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); } + + LLMotionController& getMotionController() { return mMotionController; } + // Releases all motion instances which should result in // no cached references to character joint data. This is // useful if a character wants to rebuild it's skeleton. diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index d9e8407d44..710cd44a6f 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1986,9 +1986,8 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, LLCharacter* character = *char_iter; - // create an instance of this motion (it may or may not already exist) - LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->createMotion(asset_uuid); - + // look for an existing instance of this motion + LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->findMotion(asset_uuid); if (motionp) { if (0 == status) @@ -2017,7 +2016,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, motionp->mAssetStatus = ASSET_FETCH_FAILED; } - delete []buffer; + delete[] buffer; } else { @@ -2027,8 +2026,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, } else { - // motionp is NULL - llwarns << "Failed to createMotion() for asset UUID " << asset_uuid << llendl; + llwarns << "No existing motion for asset data. UUID: " << asset_uuid << llendl; } } diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp index 513b7688ce..ea88e18367 100644 --- a/indra/llcharacter/llkeyframemotionparam.cpp +++ b/indra/llcharacter/llkeyframemotionparam.cpp @@ -76,7 +76,7 @@ LLKeyframeMotionParam::~LLKeyframeMotionParam() for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - delete paramMotion.first; // note - deletes the structure; ParameterizedMotion pair remains intact + delete paramMotion.mMotion; } motionList.clear(); } @@ -102,32 +102,32 @@ LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *ch for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; + LLMotion* motion = paramMotion.mMotion; + motion->onInitialize(character); - paramMotion.first->onInitialize(character); - - if (paramMotion.first->getDuration() > mEaseInDuration) + if (motion->getDuration() > mEaseInDuration) { - mEaseInDuration = paramMotion.first->getEaseInDuration(); + mEaseInDuration = motion->getEaseInDuration(); } - if (paramMotion.first->getEaseOutDuration() > mEaseOutDuration) + if (motion->getEaseOutDuration() > mEaseOutDuration) { - mEaseOutDuration = paramMotion.first->getEaseOutDuration(); + mEaseOutDuration = motion->getEaseOutDuration(); } - if (paramMotion.first->getDuration() > mDuration) + if (motion->getDuration() > mDuration) { - mDuration = paramMotion.first->getDuration(); + mDuration = motion->getDuration(); } - if (paramMotion.first->getPriority() > mPriority) + if (motion->getPriority() > mPriority) { - mPriority = paramMotion.first->getPriority(); + mPriority = motion->getPriority(); } - LLPose *pose = paramMotion.first->getPose(); + LLPose *pose = motion->getPose(); - mPoseBlender.addMotion(paramMotion.first); + mPoseBlender.addMotion(motion); for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) { LLPose *blendedPose = mPoseBlender.getBlendedPose(); @@ -151,7 +151,7 @@ BOOL LLKeyframeMotionParam::onActivate() for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - paramMotion.first->activate(); + paramMotion.mMotion->activate(mActivationTimestamp); } } return TRUE; @@ -173,8 +173,8 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; -// llinfos << "Weight for pose " << paramMotion.first->getName() << " is " << paramMotion.first->getPose()->getWeight() << llendl; - paramMotion.first->getPose()->setWeight(0.f); +// llinfos << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << llendl; + paramMotion.mMotion->getPose()->setWeight(0.f); } } @@ -190,6 +190,7 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) continue; } + // DANGER! Do not modify mParameterizedMotions while using these pointers! const ParameterizedMotion* firstMotion = NULL; const ParameterizedMotion* secondMotion = NULL; @@ -197,9 +198,9 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - paramMotion.first->onUpdate(time, joint_mask); + paramMotion.mMotion->onUpdate(time, joint_mask); - F32 distToParam = paramMotion.second - *paramValue; + F32 distToParam = paramMotion.mParam - *paramValue; if ( distToParam <= 0.f) { @@ -227,12 +228,12 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) LLPose *secondPose; if (firstMotion) - firstPose = firstMotion->first->getPose(); + firstPose = firstMotion->mMotion->getPose(); else firstPose = NULL; if (secondMotion) - secondPose = secondMotion->first->getPose(); + secondPose = secondMotion->mMotion->getPose(); else secondPose = NULL; @@ -243,7 +244,7 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) { firstPose->setWeight(weightFactor); } - else if (firstMotion->second == secondMotion->second) + else if (firstMotion->mParam == secondMotion->mParam) { firstPose->setWeight(0.5f * weightFactor); secondPose->setWeight(0.5f * weightFactor); @@ -251,8 +252,8 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) else { F32 first_weight = 1.f - - ((llclamp(*paramValue - firstMotion->second, 0.f, (secondMotion->second - firstMotion->second))) / - (secondMotion->second - firstMotion->second)); + ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) / + (secondMotion->mParam - firstMotion->mParam)); first_weight = llclamp(first_weight, 0.f, 1.f); F32 second_weight = 1.f - first_weight; @@ -290,7 +291,7 @@ void LLKeyframeMotionParam::onDeactivate() for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - paramMotion.first->onDeactivate(); + paramMotion.mMotion->onDeactivate(); } } } @@ -328,9 +329,9 @@ void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name) for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; - if (paramMotion.first->getName() == name) + if (paramMotion.mMotion->getName() == name) { - mDefaultKeyframeMotion = paramMotion.first; + mDefaultKeyframeMotion = paramMotion.mMotion; } } } diff --git a/indra/llcharacter/llkeyframemotionparam.h b/indra/llcharacter/llkeyframemotionparam.h index 305207eb09..c8104d2b38 100644 --- a/indra/llcharacter/llkeyframemotionparam.h +++ b/indra/llcharacter/llkeyframemotionparam.h @@ -126,7 +126,12 @@ protected: //------------------------------------------------------------------------- // new functions defined by this subclass //------------------------------------------------------------------------- - typedef std::pair<LLMotion*, F32> ParameterizedMotion; + struct ParameterizedMotion + { + ParameterizedMotion(LLMotion* motion, F32 param) : mMotion(motion), mParam(param) {} + LLMotion* mMotion; + F32 mParam; + }; // add a motion and associated parameter triplet BOOL addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value); @@ -134,8 +139,6 @@ protected: // set default motion for LOD and retrieving blend constants void setDefaultKeyframeMotion(char *); - static BOOL sortFunc(ParameterizedMotion *new_motion, ParameterizedMotion *tested_motion); - BOOL loadMotions(); protected: @@ -147,10 +150,10 @@ protected: { bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const { - if (a.second != b.second) - return (a.second < b.second); + if (a.mParam != b.mParam) + return (a.mParam < b.mParam); else - return a.first < b.first; + return a.mMotion < b.mMotion; } }; diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp index 9123ebfcbd..369e516482 100644 --- a/indra/llcharacter/llmotion.cpp +++ b/indra/llcharacter/llmotion.cpp @@ -127,6 +127,13 @@ void LLMotion::setDeactivateCallback( void (*cb)(void *), void* userdata ) mDeactivateCallbackUserData = userdata; } +//virtual +void LLMotion::setStopTime(F32 time) +{ + mStopTimestamp = time; + mStopped = TRUE; +} + BOOL LLMotion::isBlending() { return mPose.getWeight() < 1.f; @@ -135,8 +142,9 @@ BOOL LLMotion::isBlending() //----------------------------------------------------------------------------- // activate() //----------------------------------------------------------------------------- -void LLMotion::activate() +void LLMotion::activate(F32 time) { + mActivationTimestamp = time; mStopped = FALSE; mActive = TRUE; onActivate(); @@ -150,7 +158,12 @@ void LLMotion::deactivate() mActive = FALSE; mPose.setWeight(0.f); - if (mDeactivateCallback) (*mDeactivateCallback)(mDeactivateCallbackUserData); + if (mDeactivateCallback) + { + (*mDeactivateCallback)(mDeactivateCallbackUserData); + mDeactivateCallback = NULL; // only call callback once + mDeactivateCallbackUserData = NULL; + } onDeactivate(); } diff --git a/indra/llcharacter/llmotion.h b/indra/llcharacter/llmotion.h index 7669920339..50090e65e4 100644 --- a/indra/llcharacter/llmotion.h +++ b/indra/llcharacter/llmotion.h @@ -48,6 +48,8 @@ class LLCharacter; //----------------------------------------------------------------------------- class LLMotion { + friend class LLMotionController; + public: enum LLMotionBlendType { @@ -73,10 +75,6 @@ public: // functions to support MotionController and MotionRegistry //------------------------------------------------------------------------- - // static constructor - // all subclasses must implement such a function and register it - static LLMotion *create(const LLUUID &id) { return NULL; } - // get the name of this instance const std::string &getName() const { return mName; } @@ -96,7 +94,7 @@ public: F32 getStopTime() const { return mStopTimestamp; } - virtual void setStopTime(F32 time) { mStopTimestamp = time; mStopped = TRUE; } + virtual void setStopTime(F32 time); BOOL isStopped() const { return mStopped; } @@ -104,12 +102,18 @@ public: BOOL isBlending(); - void activate(); - + // Activation functions. + // It is OK for other classes to activate a motion, + // but only the controller can deactivate it. + // Thus, if mActive == TRUE, the motion *may* be on the controllers active list, + // but if mActive == FALSE, the motion is gauranteed not to be on the active list. +protected: + // Used by LLMotionController only void deactivate(); - BOOL isActive() { return mActive; } - +public: + void activate(F32 time); + public: //------------------------------------------------------------------------- // animation callbacks to be implemented by subclasses @@ -170,14 +174,13 @@ protected: BOOL mStopped; // motion has been stopped; BOOL mActive; // motion is on active list (can be stopped or not stopped) -public: //------------------------------------------------------------------------- // these are set implicitly by the motion controller and // may be referenced (read only) in the above handlers. //------------------------------------------------------------------------- std::string mName; // instance name assigned by motion controller LLUUID mID; - + F32 mActivationTimestamp; // time when motion was activated F32 mStopTimestamp; // time when motion was told to stop F32 mSendStopTimestamp; // time when simulator should be told to stop this motion diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 5bcae5e635..3cb4da4e3a 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -34,6 +34,8 @@ //----------------------------------------------------------------------------- #include "linden_common.h" +#include "llmemtype.h" + #include "llmotioncontroller.h" #include "llkeyframemotion.h" #include "llmath.h" @@ -50,32 +52,6 @@ const U32 MAX_MOTION_INSTANCES = 32; LLMotionRegistry LLMotionController::sRegistry; //----------------------------------------------------------------------------- -// LLMotionTableEntry() -//----------------------------------------------------------------------------- -LLMotionTableEntry::LLMotionTableEntry() -{ - mConstructor = NULL; - mID.setNull(); -} - -LLMotionTableEntry::LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id) - : mConstructor(constructor), mID(id) -{ - -} - -//----------------------------------------------------------------------------- -// create() -//----------------------------------------------------------------------------- -LLMotion* LLMotionTableEntry::create(const LLUUID &id) -{ - LLMotion* motionp = mConstructor(id); - - return motionp; -} - - -//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // LLMotionRegistry class //----------------------------------------------------------------------------- @@ -85,7 +61,7 @@ LLMotion* LLMotionTableEntry::create(const LLUUID &id) // LLMotionRegistry() // Class Constructor //----------------------------------------------------------------------------- -LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, LLMotionTableEntry()) +LLMotionRegistry::LLMotionRegistry() { } @@ -97,19 +73,19 @@ LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, //----------------------------------------------------------------------------- LLMotionRegistry::~LLMotionRegistry() { - mMotionTable.removeAll(); + mMotionTable.clear(); } //----------------------------------------------------------------------------- // addMotion() //----------------------------------------------------------------------------- -BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor constructor ) +BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) { -// llinfos << "Registering motion: " << name << llendl; - if (!mMotionTable.check(id)) + // llinfos << "Registering motion: " << name << llendl; + if (!is_in_map(mMotionTable, id)) { - mMotionTable.set(id, LLMotionTableEntry(constructor, id)); + mMotionTable[id] = constructor; return TRUE; } @@ -121,7 +97,7 @@ BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor construc //----------------------------------------------------------------------------- void LLMotionRegistry::markBad( const LLUUID& id ) { - mMotionTable.set(id, LLMotionTableEntry()); + mMotionTable[id] = LLMotionConstructor(NULL); } //----------------------------------------------------------------------------- @@ -129,17 +105,17 @@ void LLMotionRegistry::markBad( const LLUUID& id ) //----------------------------------------------------------------------------- LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) { - LLMotionTableEntry motion_entry = mMotionTable.get(id); + LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL)); LLMotion* motion = NULL; - if ( motion_entry.getID().isNull() ) + if ( constructor == NULL ) { // *FIX: need to replace with a better default scheme. RN motion = LLKeyframeMotion::create(id); } else { - motion = motion_entry.create(id); + motion = constructor(id); } return motion; @@ -158,8 +134,8 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) LLMotionController::LLMotionController() : mTimeFactor(1.f), mCharacter(NULL), - mTime(0.f), - mTimeOffset(0.f), + mAnimTime(0.f), + mPrevTimerElapsed(0.f), mLastTime(0.0f), mHasRunOnce(FALSE), mPaused(FALSE), @@ -180,6 +156,15 @@ LLMotionController::~LLMotionController() deleteAllMotions(); } +void LLMotionController::incMotionCounts(S32& num_motions, S32& num_loading_motions, S32& num_loaded_motions, S32& num_active_motions, S32& num_deprecated_motions) +{ + num_motions += mAllMotions.size(); + num_loading_motions += mLoadingMotions.size(); + num_loaded_motions += mLoadedMotions.size(); + num_active_motions += mActiveMotions.size(); + num_deprecated_motions += mDeprecatedMotions.size(); +} + //----------------------------------------------------------------------------- // deleteAllMotions() //----------------------------------------------------------------------------- @@ -194,24 +179,38 @@ void LLMotionController::deleteAllMotions() } //----------------------------------------------------------------------------- -// addLoadedMotion() +// purgeExcessMotion() //----------------------------------------------------------------------------- -void LLMotionController::addLoadedMotion(LLMotion* motionp) +void LLMotionController::purgeExcessMotions() { - std::set<LLUUID> motions_to_kill; + if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) + { + // clean up deprecated motions + for (motion_set_t::iterator deprecated_motion_it = mDeprecatedMotions.begin(); + deprecated_motion_it != mDeprecatedMotions.end(); ) + { + motion_set_t::iterator cur_iter = deprecated_motion_it++; + LLMotion* cur_motionp = *cur_iter; + if (!isMotionActive(cur_motionp)) + { + // Motion is deprecated so we know it's not cannonical, + // we can safely remove the instance + removeMotionInstance(cur_motionp); // modifies mDeprecatedMotions + mDeprecatedMotions.erase(cur_iter); + } + } + } - // gather all inactive, loaded motions + std::set<LLUUID> motions_to_kill; if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) { // too many motions active this frame, kill all blenders mPoseBlender.clearBlenders(); - - for (motion_list_t::iterator loaded_motion_it = mLoadedMotions.begin(); - loaded_motion_it != mLoadedMotions.end(); - ++loaded_motion_it) + for (motion_set_t::iterator loaded_motion_it = mLoadedMotions.begin(); + loaded_motion_it != mLoadedMotions.end(); + ++loaded_motion_it) { LLMotion* cur_motionp = *loaded_motion_it; - // motion isn't playing, delete it if (!isMotionActive(cur_motionp)) { @@ -219,7 +218,7 @@ void LLMotionController::addLoadedMotion(LLMotion* motionp) } } } - + // clean up all inactive, loaded motions for (std::set<LLUUID>::iterator motion_it = motions_to_kill.begin(); motion_it != motions_to_kill.end(); @@ -235,8 +234,28 @@ void LLMotionController::addLoadedMotion(LLMotion* motionp) } } - // add new motion to loaded list - mLoadedMotions.push_back(motionp); + if (mLoadedMotions.size() > 2*MAX_MOTION_INSTANCES) + { + LL_WARNS_ONCE("Animation") << "> " << 2*MAX_MOTION_INSTANCES << " Loaded Motions" << llendl; + } +} + +//----------------------------------------------------------------------------- +// deactivateStoppedMotions() +//----------------------------------------------------------------------------- +void LLMotionController::deactivateStoppedMotions() +{ + // Since we're hidden, deactivate any stopped motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ) + { + motion_list_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + if (motionp->isStopped()) + { + deactivateMotionInstance(motionp); + } + } } //----------------------------------------------------------------------------- @@ -253,9 +272,10 @@ void LLMotionController::setTimeStep(F32 step) iter != mActiveMotions.end(); ++iter) { LLMotion* motionp = *iter; - motionp->mActivationTimestamp = (F32)llfloor(motionp->mActivationTimestamp / step) * step; + F32 activation_time = motionp->mActivationTimestamp; + motionp->mActivationTimestamp = (F32)(llfloor(activation_time / step)) * step; BOOL stopped = motionp->isStopped(); - motionp->setStopTime((F32)llfloor(motionp->getStopTime() / step) * step); + motionp->setStopTime((F32)(llfloor(motionp->getStopTime() / step)) * step); motionp->setStopped(stopped); motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step; } @@ -267,7 +287,6 @@ void LLMotionController::setTimeStep(F32 step) //----------------------------------------------------------------------------- void LLMotionController::setTimeFactor(F32 time_factor) { - mTimeOffset += mTimer.getElapsedTimeAndResetF32() * mTimeFactor; mTimeFactor = time_factor; } @@ -281,11 +300,11 @@ void LLMotionController::setCharacter(LLCharacter *character) //----------------------------------------------------------------------------- -// addMotion() +// registerMotion() //----------------------------------------------------------------------------- -BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constructor ) +BOOL LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) { - return sRegistry.addMotion(id, constructor); + return sRegistry.registerMotion(id, constructor); } //----------------------------------------------------------------------------- @@ -294,10 +313,8 @@ BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constr void LLMotionController::removeMotion( const LLUUID& id) { LLMotion* motionp = findMotion(id); - - removeMotionInstance(motionp); - mAllMotions.erase(id); + removeMotionInstance(motionp); } // removes instance of a motion from all runtime structures, but does @@ -307,10 +324,11 @@ void LLMotionController::removeMotionInstance(LLMotion* motionp) { if (motionp) { - stopMotionInstance(motionp, TRUE); - + llassert(findMotion(motionp->getID()) != motionp); + if (motionp->isActive()) + motionp->deactivate(); mLoadingMotions.erase(motionp); - mLoadedMotions.remove(motionp); + mLoadedMotions.erase(motionp); mActiveMotions.remove(motionp); delete motionp; } @@ -321,6 +339,7 @@ void LLMotionController::removeMotionInstance(LLMotion* motionp) //----------------------------------------------------------------------------- LLMotion* LLMotionController::createMotion( const LLUUID &id ) { + LLMemType mt(LLMemType::MTYPE_ANIMATION); // do we have an instance of this motion for this character? LLMotion *motion = findMotion(id); @@ -354,8 +373,8 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id ) mLoadingMotions.insert(motion); break; case LLMotion::STATUS_SUCCESS: - // add motion to our list - addLoadedMotion(motion); + // add motion to our list + mLoadedMotions.insert(motion); break; default: llerrs << "Invalid initialization status" << llendl; @@ -378,6 +397,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) // motion that is stopping will be allowed to stop but // replaced by a new instance of that motion if (motion + && !mPaused && motion->canDeprecate() && motion->getFadeWeight() > 0.01f // not LOD-ed out && (motion->isBlending() || motion->getStopTime() != 0.f)) @@ -404,7 +424,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) } // llinfos << "Starting motion " << name << llendl; - return activateMotionInstance(motion, mTime - start_offset); + return activateMotionInstance(motion, mAnimTime - start_offset); } @@ -415,7 +435,6 @@ BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate { // if already inactive, return false LLMotion *motion = findMotion(id); - return stopMotionInstance(motion, stop_immediate); } @@ -429,12 +448,7 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat // If on active list, stop it if (isMotionActive(motion) && !motion->isStopped()) { - // when using timesteps, set stop time to last frame's time, otherwise grab current timer value - // *FIX: should investigate this inconsistency...hints of obscure bugs - - F32 stop_time = (mTimeStep != 0.f || mPaused) ? (mTime) : mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor); - motion->setStopTime(stop_time); - + motion->setStopTime(mAnimTime); if (stop_immediate) { deactivateMotionInstance(motion); @@ -450,7 +464,6 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat return FALSE; } - //----------------------------------------------------------------------------- // updateRegularMotions() //----------------------------------------------------------------------------- @@ -477,6 +490,59 @@ void LLMotionController::resetJointSignatures() } //----------------------------------------------------------------------------- +// updateIdleMotion() +// minimal updates for active motions +//----------------------------------------------------------------------------- +void LLMotionController::updateIdleMotion(LLMotion* motionp) +{ + if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) + { + deactivateMotionInstance(motionp); + } + else if (motionp->isStopped() && mAnimTime > motionp->getStopTime()) + { + // is this the first iteration in the ease out phase? + if (mLastTime <= motionp->getStopTime()) + { + // store residual weight for this motion + motionp->mResidualWeight = motionp->getPose()->getWeight(); + } + } + else if (mAnimTime > motionp->mSendStopTimestamp) + { + // notify character of timed stop event on first iteration past sendstoptimestamp + // this will only be called when an animation stops itself (runs out of time) + if (mLastTime <= motionp->mSendStopTimestamp) + { + mCharacter->requestStopMotion( motionp ); + stopMotionInstance(motionp, FALSE); + } + } + else if (mAnimTime >= motionp->mActivationTimestamp) + { + if (mLastTime < motionp->mActivationTimestamp) + { + motionp->mResidualWeight = motionp->getPose()->getWeight(); + } + } +} + +//----------------------------------------------------------------------------- +// updateIdleActiveMotions() +// Call this instead of updateMotionsByType for hidden avatars +//----------------------------------------------------------------------------- +void LLMotionController::updateIdleActiveMotions() +{ + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ) + { + motion_list_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + updateIdleMotion(motionp); + } +} + +//----------------------------------------------------------------------------- // updateMotionsByType() //----------------------------------------------------------------------------- void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) @@ -531,36 +597,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty if (!update_motion) { - if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) - { - deactivateMotionInstance(motionp); - } - else if (motionp->isStopped() && mTime > motionp->getStopTime()) - { - // is this the first iteration in the ease out phase? - if (mLastTime <= motionp->getStopTime()) - { - // store residual weight for this motion - motionp->mResidualWeight = motionp->getPose()->getWeight(); - } - } - else if (mTime > motionp->mSendStopTimestamp) - { - // notify character of timed stop event on first iteration past sendstoptimestamp - // this will only be called when an animation stops itself (runs out of time) - if (mLastTime <= motionp->mSendStopTimestamp) - { - mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, FALSE); - } - } - else if (mTime >= motionp->mActivationTimestamp) - { - if (mLastTime < motionp->mActivationTimestamp) - { - motionp->mResidualWeight = motionp->getPose()->getWeight(); - } - } + updateIdleMotion(motionp); continue; } @@ -572,7 +609,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty motionp->fadeOut(); //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic) - if (mTime > motionp->mSendStopTimestamp) + if (mAnimTime > motionp->mSendStopTimestamp) { // notify character of timed stop event on first iteration past sendstoptimestamp // this will only be called when an animation stops itself (runs out of time) @@ -585,7 +622,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty if (motionp->getFadeWeight() < 0.01f) { - if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) + if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) { posep->setWeight(0.f); deactivateMotionInstance(motionp); @@ -601,7 +638,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty //********************** // MOTION INACTIVE //********************** - if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) + if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) { // this motion has gone on too long, deactivate it // did we have a chance to stop it? @@ -623,7 +660,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty //********************** // MOTION EASE OUT //********************** - else if (motionp->isStopped() && mTime > motionp->getStopTime()) + else if (motionp->isStopped() && mAnimTime > motionp->getStopTime()) { // is this the first iteration in the ease out phase? if (mLastTime <= motionp->getStopTime()) @@ -638,22 +675,22 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } else { - posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mTime - motionp->getStopTime()) / motionp->getEaseOutDuration()))); + posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mAnimTime - motionp->getStopTime()) / motionp->getEaseOutDuration()))); } // perform motion update - update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature); + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); } //********************** // MOTION ACTIVE //********************** - else if (mTime > motionp->mActivationTimestamp + motionp->getEaseInDuration()) + else if (mAnimTime > motionp->mActivationTimestamp + motionp->getEaseInDuration()) { posep->setWeight(motionp->getFadeWeight()); //should we notify the simulator that this motion should be stopped? - if (mTime > motionp->mSendStopTimestamp) + if (mAnimTime > motionp->mSendStopTimestamp) { // notify character of timed stop event on first iteration past sendstoptimestamp // this will only be called when an animation stops itself (runs out of time) @@ -665,13 +702,13 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } // perform motion update - update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature); + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); } //********************** // MOTION EASE IN //********************** - else if (mTime >= motionp->mActivationTimestamp) + else if (mAnimTime >= motionp->mActivationTimestamp) { if (mLastTime < motionp->mActivationTimestamp) { @@ -684,10 +721,10 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty else { // perform motion update - posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration())); + posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mAnimTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration())); } // perform motion update - update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature); + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); } else { @@ -698,7 +735,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty // allow motions to deactivate themselves if (!update_result) { - if (!motionp->isStopped() || motionp->getStopTime() > mTime) + if (!motionp->isStopped() || motionp->getStopTime() > mAnimTime) { // animation has stopped itself due to internal logic // propagate this to the network @@ -714,18 +751,68 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } } +//----------------------------------------------------------------------------- +// updateLoadingMotions() +//----------------------------------------------------------------------------- +void LLMotionController::updateLoadingMotions() +{ + // query pending motions for completion + for (motion_set_t::iterator iter = mLoadingMotions.begin(); + iter != mLoadingMotions.end(); ) + { + motion_set_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + if( !motionp) + { + continue; // maybe shouldn't happen but i've seen it -MG + } + LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter); + if (status == LLMotion::STATUS_SUCCESS) + { + mLoadingMotions.erase(curiter); + // add motion to our loaded motion list + mLoadedMotions.insert(motionp); + // this motion should be playing + if (!motionp->isStopped()) + { + activateMotionInstance(motionp, mAnimTime); + } + } + else if (status == LLMotion::STATUS_FAILURE) + { + llinfos << "Motion " << motionp->getID() << " init failed." << llendl; + sRegistry.markBad(motionp->getID()); + mLoadingMotions.erase(curiter); + mAllMotions.erase(motionp->getID()); + delete motionp; + } + } +} + +//----------------------------------------------------------------------------- +// call updateMotion() or updateMotionsMinimal() every frame +//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // updateMotion() //----------------------------------------------------------------------------- -void LLMotionController::updateMotion() +void LLMotionController::updateMotions(bool force_update) { BOOL use_quantum = (mTimeStep != 0.f); + // Always update mPrevTimerElapsed + F32 cur_time = mTimer.getElapsedTimeF32(); + F32 delta_time = cur_time - mPrevTimerElapsed; + mPrevTimerElapsed = cur_time; + mLastTime = mAnimTime; + + // Always cap the number of loaded motions + purgeExcessMotions(); + // Update timing info for this time step. if (!mPaused) { - F32 update_time = mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor); + F32 update_time = mAnimTime + delta_time * mTimeFactor; if (use_quantum) { F32 time_interval = fmodf(update_time, mTimeStep); @@ -741,7 +828,8 @@ void LLMotionController::updateMotion() mPoseBlender.interpolate(interp - mLastInterp); mLastInterp = interp; } - + + updateLoadingMotions(); return; } @@ -750,53 +838,24 @@ void LLMotionController::updateMotion() clearBlenders(); mTimeStepCount = quantum_count; - mLastTime = mTime; - mTime = (F32)quantum_count * mTimeStep; + mAnimTime = (F32)quantum_count * mTimeStep; mLastInterp = 0.f; } else { - mLastTime = mTime; - mTime = update_time; + mAnimTime = update_time; } } - // query pending motions for completion - for (motion_set_t::iterator iter = mLoadingMotions.begin(); - iter != mLoadingMotions.end(); ) - { - motion_set_t::iterator curiter = iter++; - LLMotion* motionp = *curiter; - if( !motionp) - { - continue; // maybe shouldn't happen but i've seen it -MG - } - LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter); - if (status == LLMotion::STATUS_SUCCESS) - { - mLoadingMotions.erase(curiter); - // add motion to our loaded motion list - addLoadedMotion(motionp); - // this motion should be playing - if (!motionp->isStopped()) - { - activateMotionInstance(motionp, mTime); - } - } - else if (status == LLMotion::STATUS_FAILURE) - { - llinfos << "Motion " << motionp->getID() << " init failed." << llendl; - sRegistry.markBad(motionp->getID()); - mLoadingMotions.erase(curiter); - - mAllMotions.erase(motionp->getID()); - delete motionp; - } - } + updateLoadingMotions(); resetJointSignatures(); - if (!mPaused) + if (mPaused && !force_update) + { + updateIdleActiveMotions(); + } + else { // update additive motions updateAdditiveMotions(); @@ -819,6 +878,23 @@ void LLMotionController::updateMotion() // llinfos << "Motion controller time " << motionTimer.getElapsedTimeF32() << llendl; } +//----------------------------------------------------------------------------- +// updateMotionsMinimal() +// minimal update (e.g. while hidden) +//----------------------------------------------------------------------------- +void LLMotionController::updateMotionsMinimal() +{ + // Always update mPrevTimerElapsed + mPrevTimerElapsed = mTimer.getElapsedTimeF32(); + + purgeExcessMotions(); + updateLoadingMotions(); + resetJointSignatures(); + + deactivateStoppedMotions(); + + mHasRunOnce = TRUE; +} //----------------------------------------------------------------------------- // activateMotionInstance() @@ -841,7 +917,6 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) } motion->mResidualWeight = motion->getPose()->getWeight(); - motion->mActivationTimestamp = time; // set stop time based on given duration and ease out time if (motion->getDuration() != 0.f && !motion->getLoop()) @@ -862,13 +937,26 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) { motion->mSendStopTimestamp = F32_MAX; } - - mActiveMotions.remove(motion); // in case it is already in the active list + + if (motion->isActive()) + { + mActiveMotions.remove(motion); + } mActiveMotions.push_front(motion); - motion->activate(); + motion->activate(time); motion->onUpdate(0.f, mJointSignature[1]); + if (mAnimTime >= motion->mSendStopTimestamp) + { + motion->setStopTime(motion->mSendStopTimestamp); + if (motion->mResidualWeight == 0.0f) + { + // bit of a hack; if newly activating a motion while easing out, weight should = 1 + motion->mResidualWeight = 1.f; + } + } + return TRUE; } @@ -925,9 +1013,17 @@ bool LLMotionController::isMotionLoading(LLMotion* motion) //----------------------------------------------------------------------------- // findMotion() //----------------------------------------------------------------------------- -LLMotion *LLMotionController::findMotion(const LLUUID& id) +LLMotion* LLMotionController::findMotion(const LLUUID& id) { - return get_if_there<LLUUID, LLMotion*>(mAllMotions, id, NULL); + motion_map_t::iterator iter = mAllMotions.find(id); + if(iter == mAllMotions.end()) + { + return NULL; + } + else + { + return iter->second; + } } //----------------------------------------------------------------------------- @@ -935,16 +1031,12 @@ LLMotion *LLMotionController::findMotion(const LLUUID& id) //----------------------------------------------------------------------------- void LLMotionController::deactivateAllMotions() { - //They must all die, precious. - for (std::map<LLUUID, LLMotion*>::iterator iter = mAllMotions.begin(); + for (motion_map_t::iterator iter = mAllMotions.begin(); iter != mAllMotions.end(); iter++) { LLMotion* motionp = iter->second; - if (motionp) motionp->deactivate(); + deactivateMotionInstance(motionp); } - - // delete all motion instances - deleteAllMotions(); } @@ -960,11 +1052,12 @@ void LLMotionController::flushAllMotions() { motion_list_t::iterator curiter = iter++; LLMotion* motionp = *curiter; - F32 dtime = mTime - motionp->mActivationTimestamp; + F32 dtime = mAnimTime - motionp->mActivationTimestamp; active_motions.push_back(std::make_pair(motionp->getID(),dtime)); - motionp->deactivate(); + motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it } - + mActiveMotions.clear(); + // delete all motion instances deleteAllMotions(); @@ -983,12 +1076,11 @@ void LLMotionController::flushAllMotions() //----------------------------------------------------------------------------- // pause() //----------------------------------------------------------------------------- -void LLMotionController::pause() +void LLMotionController::pauseAllMotions() { if (!mPaused) { //llinfos << "Pausing animations..." << llendl; - mPauseTime = mTimer.getElapsedTimeF32(); mPaused = TRUE; } @@ -997,13 +1089,11 @@ void LLMotionController::pause() //----------------------------------------------------------------------------- // unpause() //----------------------------------------------------------------------------- -void LLMotionController::unpause() +void LLMotionController::unpauseAllMotions() { if (mPaused) { //llinfos << "Unpausing animations..." << llendl; - mTimer.reset(); - mTimer.setAge(mPauseTime); mPaused = FALSE; } } diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index c6749c5c36..4da6d8ac57 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -57,30 +57,6 @@ class LLCharacter; //----------------------------------------------------------------------------- typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id); -class LLMotionTableEntry -{ -public: - LLMotionTableEntry(); - LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id); - ~LLMotionTableEntry(){}; - - LLMotion* create(const LLUUID& id); - static BOOL uuidEq(const LLUUID &uuid, const LLMotionTableEntry &id_pair) - { - if (uuid == id_pair.mID) - { - return TRUE; - } - return FALSE; - } - - const LLUUID& getID() { return mID; } - -protected: - LLMotionConstructor mConstructor; - LLUUID mID; -}; - class LLMotionRegistry { public: @@ -92,7 +68,7 @@ public: // adds motion classes to the registry // returns true if successfull - BOOL addMotion( const LLUUID& id, LLMotionConstructor create); + BOOL registerMotion( const LLUUID& id, LLMotionConstructor create); // creates a new instance of a named motion // returns NULL motion is not registered @@ -103,7 +79,8 @@ public: protected: - LLUUIDHashMap<LLMotionTableEntry, 32> mMotionTable; + typedef std::map<LLUUID, LLMotionConstructor> motion_map_t; + motion_map_t mMotionTable; }; //----------------------------------------------------------------------------- @@ -130,7 +107,7 @@ public: // registers a motion with the controller // (actually just forwards call to motion registry) // returns true if successfull - BOOL addMotion( const LLUUID& id, LLMotionConstructor create ); + BOOL registerMotion( const LLUUID& id, LLMotionConstructor create ); // creates a motion from the registry LLMotion *createMotion( const LLUUID &id ); @@ -151,11 +128,17 @@ public: // returns true if successful BOOL stopMotionLocally( const LLUUID &id, BOOL stop_immediate ); + // Move motions from loading to loaded + void updateLoadingMotions(); + // update motions // invokes the update handlers for each active motion // activates sequenced motions // deactivates terminated motions` - void updateMotion(); + void updateMotions(bool force_update = false); + + // minimal update (e.g. while hidden) + void updateMotionsMinimal(); void clearBlenders() { mPoseBlender.clearBlenders(); } @@ -167,8 +150,8 @@ public: void deactivateAllMotions(); // pause and continue all motions - void pause(); - void unpause(); + void pauseAllMotions(); + void unpauseAllMotions(); BOOL isPaused() { return mPaused; } void setTimeStep(F32 step); @@ -178,6 +161,8 @@ public: motion_list_t& getActiveMotions() { return mActiveMotions; } + void incMotionCounts(S32& num_motions, S32& num_loading_motions, S32& num_loaded_motions, S32& num_active_motions, S32& num_deprecated_motions); + //protected: bool isMotionActive( LLMotion *motion ); bool isMotionLoading( LLMotion *motion ); @@ -187,7 +172,6 @@ protected: // internal operations act on motion instances directly // as there can be duplicate motions per id during blending overlap void deleteAllMotions(); - void addLoadedMotion(LLMotion *motion); BOOL activateMotionInstance(LLMotion *motion, F32 time); BOOL deactivateMotionInstance(LLMotion *motion); void deprecateMotionInstance(LLMotion* motion); @@ -197,6 +181,10 @@ protected: void updateAdditiveMotions(); void resetJointSignatures(); void updateMotionsByType(LLMotion::LLMotionBlendType motion_type); + void updateIdleMotion(LLMotion* motionp); + void updateIdleActiveMotions(); + void purgeExcessMotions(); + void deactivateStoppedMotions(); protected: F32 mTimeFactor; @@ -210,20 +198,20 @@ protected: // Animations are instantiated and immediately put in the mAllMotions map for their entire lifetime. // If the animations depend on any asset data, the appropriate data is fetched from the data server, // and the animation is put on the mLoadingMotions list. -// Once an animations is loaded, it will be initialized and put on the mLoadedMotions deque. +// Once an animations is loaded, it will be initialized and put on the mLoadedMotions list. // Any animation that is currently playing also sits in the mActiveMotions list. typedef std::map<LLUUID, LLMotion*> motion_map_t; motion_map_t mAllMotions; motion_set_t mLoadingMotions; - motion_list_t mLoadedMotions; + motion_set_t mLoadedMotions; motion_list_t mActiveMotions; motion_set_t mDeprecatedMotions; LLFrameTimer mTimer; - F32 mTime; - F32 mTimeOffset; + F32 mPrevTimerElapsed; + F32 mAnimTime; F32 mLastTime; BOOL mHasRunOnce; BOOL mPaused; |