summaryrefslogtreecommitdiff
path: root/indra/llcharacter
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcharacter')
-rw-r--r--indra/llcharacter/llcharacter.cpp47
-rw-r--r--indra/llcharacter/llcharacter.h13
-rw-r--r--indra/llcharacter/llkeyframemotion.cpp10
-rw-r--r--indra/llcharacter/llkeyframemotionparam.cpp53
-rw-r--r--indra/llcharacter/llkeyframemotionparam.h15
-rw-r--r--indra/llcharacter/llmotion.cpp17
-rw-r--r--indra/llcharacter/llmotion.h25
-rw-r--r--indra/llcharacter/llmotioncontroller.cpp442
-rw-r--r--indra/llcharacter/llmotioncontroller.h58
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;