summaryrefslogtreecommitdiff
path: root/indra/llcharacter/llmotioncontroller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcharacter/llmotioncontroller.cpp')
-rw-r--r--indra/llcharacter/llmotioncontroller.cpp442
1 files changed, 266 insertions, 176 deletions
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;
}
}