From 70f8dc7a4f4be217fea5439e474fc75e567c23c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20N=C3=A6sbye=20Christensen?= Date: Sat, 10 Feb 2024 22:37:52 +0100 Subject: miscellaneous: BOOL (int) to real bool --- indra/llcharacter/llmotioncontroller.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'indra/llcharacter/llmotioncontroller.cpp') diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 96e0d5e8d7..750547da93 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -82,10 +82,10 @@ BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor con if (!is_in_map(mMotionTable, id)) { mMotionTable[id] = constructor; - return TRUE; + return true; } - return FALSE; + return false; } //----------------------------------------------------------------------------- @@ -415,12 +415,12 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) if (!motion) { - return FALSE; + return false; } //if the motion is already active and allows deprecation, then let it keep playing else if (motion->canDeprecate() && isMotionActive(motion)) { - return TRUE; + return true; } // LL_INFOS() << "Starting motion " << name << LL_ENDL; @@ -443,7 +443,7 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat { if (!motion) { - return FALSE; + return false; } @@ -455,15 +455,15 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat { deactivateMotionInstance(motion); } - return TRUE; + return true; } else if (isMotionLoading(motion)) { motion->setStopped(TRUE); - return TRUE; + return true; } - return FALSE; + return false; } //----------------------------------------------------------------------------- @@ -926,7 +926,7 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) // hopefully this fixes it. if (motion == NULL || motion->getPose() == NULL) { - return FALSE; + return false; } if (mLoadingMotions.find(motion) != mLoadingMotions.end()) @@ -934,7 +934,7 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) // we want to start this motion, but we can't yet, so flag it as started motion->setStopped(FALSE); // report pending animations as activated - return TRUE; + return true; } motion->mResidualWeight = motion->getPose()->getWeight(); @@ -978,7 +978,7 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) } } - return TRUE; + return true; } //----------------------------------------------------------------------------- @@ -1001,7 +1001,7 @@ BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion) mActiveMotions.remove(motion); } - return TRUE; + return true; } void LLMotionController::deprecateMotionInstance(LLMotion* motion) -- cgit v1.2.3 From 9e854b697a06abed2a0917fb6120445f176764f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20N=C3=A6sbye=20Christensen?= Date: Fri, 16 Feb 2024 19:29:51 +0100 Subject: misc: BOOL to bool --- indra/llcharacter/llmotioncontroller.cpp | 60 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'indra/llcharacter/llmotioncontroller.cpp') diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 750547da93..115606d863 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -76,7 +76,7 @@ LLMotionRegistry::~LLMotionRegistry() //----------------------------------------------------------------------------- // addMotion() //----------------------------------------------------------------------------- -BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) +bool LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) { // LL_INFOS() << "Registering motion: " << name << LL_ENDL; if (!is_in_map(mMotionTable, id)) @@ -133,13 +133,13 @@ LLMotionController::LLMotionController() mAnimTime(0.f), mPrevTimerElapsed(0.f), mLastTime(0.0f), - mHasRunOnce(FALSE), - mPaused(FALSE), + mHasRunOnce(false), + mPaused(false), mPausedFrame(0), mTimeStep(0.f), mTimeStepCount(0), mLastInterp(0.f), - mIsSelf(FALSE), + mIsSelf(false), mLastCountAfterPurge(0) { } @@ -275,7 +275,7 @@ void LLMotionController::setTimeStep(F32 step) LLMotion* motionp = *iter; F32 activation_time = motionp->mActivationTimestamp; motionp->mActivationTimestamp = (F32)(llfloor(activation_time / step)) * step; - BOOL stopped = motionp->isStopped(); + bool stopped = motionp->isStopped(); motionp->setStopTime((F32)(llfloor(motionp->getStopTime() / step)) * step); motionp->setStopped(stopped); motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step; @@ -303,7 +303,7 @@ void LLMotionController::setCharacter(LLCharacter *character) //----------------------------------------------------------------------------- // registerMotion() //----------------------------------------------------------------------------- -BOOL LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) +bool LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) { return sRegistry.registerMotion(id, constructor); } @@ -389,7 +389,7 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id ) //----------------------------------------------------------------------------- // startMotion() //----------------------------------------------------------------------------- -BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) +bool LLMotionController::startMotion(const LLUUID &id, F32 start_offset) { // do we have an instance of this motion for this character? LLMotion *motion = findMotion(id); @@ -431,7 +431,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) //----------------------------------------------------------------------------- // stopMotionLocally() //----------------------------------------------------------------------------- -BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate) +bool LLMotionController::stopMotionLocally(const LLUUID &id, bool stop_immediate) { // if already inactive, return false LLMotion *motion = findMotion(id); @@ -439,7 +439,7 @@ BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate return stopMotionInstance(motion, stop_immediate||mPaused); } -BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediate) +bool LLMotionController::stopMotionInstance(LLMotion* motion, bool stop_immediate) { if (!motion) { @@ -459,7 +459,7 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat } else if (isMotionLoading(motion)) { - motion->setStopped(TRUE); + motion->setStopped(true); return true; } @@ -518,7 +518,7 @@ void LLMotionController::updateIdleMotion(LLMotion* motionp) if (mLastTime <= motionp->mSendStopTimestamp) { mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, FALSE); + stopMotionInstance(motionp, false); } } else if (mAnimTime >= motionp->mActivationTimestamp) @@ -552,7 +552,7 @@ void LLMotionController::updateIdleActiveMotions() void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - BOOL update_result = TRUE; + bool update_result = true; U8 last_joint_signature[LL_CHARACTER_MAX_ANIMATED_JOINTS]; memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); @@ -568,11 +568,11 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty continue; } - BOOL update_motion = FALSE; + bool update_motion = false; if (motionp->getPose()->getWeight() < 1.f) { - update_motion = TRUE; + update_motion = true; } else { @@ -584,7 +584,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty if ((*current_signature | test_signature) > (*current_signature)) { *current_signature |= test_signature; - update_motion = TRUE; + update_motion = true; } *((U32*)&last_joint_signature[i * 4]) = *(U32*)&(mJointSignature[1][i * 4]); @@ -594,7 +594,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty if ((*current_signature | test_signature) > (*current_signature)) { *current_signature |= test_signature; - update_motion = TRUE; + update_motion = true; } } } @@ -620,7 +620,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty if (mLastTime <= motionp->mSendStopTimestamp) { mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, FALSE); + stopMotionInstance(motionp, false); } } @@ -701,7 +701,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty if (mLastTime <= motionp->mSendStopTimestamp) { mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, FALSE); + stopMotionInstance(motionp, false); } } @@ -747,12 +747,12 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty // propagate this to the network // as not all viewers are guaranteed to have access to the same logic mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, FALSE); + stopMotionInstance(motionp, false); } } - // even if onupdate returns FALSE, add this motion in to the blend one last time + // even if onupdate returns false, add this motion in to the blend one last time mPoseBlender.addMotion(motionp); } } @@ -815,7 +815,7 @@ void LLMotionController::updateMotions(bool force_update) // The use_quantum optimization or possibly the associated code in setTimeStamp() // does not work as implemented. // Currently setting mTimeStep to nonzero is disabled elsewhere. - BOOL use_quantum = (mTimeStep != 0.f); + bool use_quantum = (mTimeStep != 0.f); // Always update mPrevTimerElapsed F32 cur_time = mTimer.getElapsedTimeF32(); @@ -885,7 +885,7 @@ void LLMotionController::updateMotions(bool force_update) if (use_quantum) { - mPoseBlender.blendAndCache(TRUE); + mPoseBlender.blendAndCache(true); } else { @@ -893,7 +893,7 @@ void LLMotionController::updateMotions(bool force_update) } } - mHasRunOnce = TRUE; + mHasRunOnce = true; // LL_INFOS() << "Motion controller time " << motionTimer.getElapsedTimeF32() << LL_ENDL; } @@ -913,13 +913,13 @@ void LLMotionController::updateMotionsMinimal() deactivateStoppedMotions(); - mHasRunOnce = TRUE; + mHasRunOnce = true; } //----------------------------------------------------------------------------- // activateMotionInstance() //----------------------------------------------------------------------------- -BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) +bool LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; // It's not clear why the getWeight() line seems to be crashing this, but @@ -932,7 +932,7 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) if (mLoadingMotions.find(motion) != mLoadingMotions.end()) { // we want to start this motion, but we can't yet, so flag it as started - motion->setStopped(FALSE); + motion->setStopped(false); // report pending animations as activated return true; } @@ -984,7 +984,7 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) //----------------------------------------------------------------------------- // deactivateMotionInstance() //----------------------------------------------------------------------------- -BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion) +bool LLMotionController::deactivateMotionInstance(LLMotion *motion) { motion->deactivate(); @@ -1009,7 +1009,7 @@ void LLMotionController::deprecateMotionInstance(LLMotion* motion) mDeprecatedMotions.insert(motion); //fade out deprecated motion - stopMotionInstance(motion, FALSE); + stopMotionInstance(motion, false); //no longer canonical mAllMotions.erase(motion->getID()); } @@ -1124,7 +1124,7 @@ void LLMotionController::pauseAllMotions() if (!mPaused) { //LL_INFOS() << "Pausing animations..." << LL_ENDL; - mPaused = TRUE; + mPaused = true; mPausedFrame = LLFrameTimer::getFrameCount(); } @@ -1138,7 +1138,7 @@ void LLMotionController::unpauseAllMotions() if (mPaused) { //LL_INFOS() << "Unpausing animations..." << LL_ENDL; - mPaused = FALSE; + mPaused = false; } } // End -- cgit v1.2.3 From e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 21:25:21 +0200 Subject: Fix line endlings --- indra/llcharacter/llmotioncontroller.cpp | 2288 +++++++++++++++--------------- 1 file changed, 1144 insertions(+), 1144 deletions(-) (limited to 'indra/llcharacter/llmotioncontroller.cpp') diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index e4dc066d58..5f99633a58 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -1,1144 +1,1144 @@ -/** - * @file llmotioncontroller.cpp - * @brief Implementation of LLMotionController class. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -//----------------------------------------------------------------------------- -// Header Files -//----------------------------------------------------------------------------- -#include "linden_common.h" - -#include "llmotioncontroller.h" -#include "llfasttimer.h" -#include "llkeyframemotion.h" -#include "llmath.h" -#include "lltimer.h" -#include "llanimationstates.h" -#include "llstl.h" - -// This is why LL_CHARACTER_MAX_ANIMATED_JOINTS needs to be a multiple of 4. -const S32 NUM_JOINT_SIGNATURE_STRIDES = LL_CHARACTER_MAX_ANIMATED_JOINTS / 4; -const U32 MAX_MOTION_INSTANCES = 32; - -//----------------------------------------------------------------------------- -// Constants and statics -//----------------------------------------------------------------------------- -F32 LLMotionController::sCurrentTimeFactor = 1.f; -LLMotionRegistry LLMotionController::sRegistry; - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLMotionRegistry class -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// LLMotionRegistry() -// Class Constructor -//----------------------------------------------------------------------------- -LLMotionRegistry::LLMotionRegistry() -{ - -} - - -//----------------------------------------------------------------------------- -// ~LLMotionRegistry() -// Class Destructor -//----------------------------------------------------------------------------- -LLMotionRegistry::~LLMotionRegistry() -{ - mMotionTable.clear(); -} - - -//----------------------------------------------------------------------------- -// addMotion() -//----------------------------------------------------------------------------- -bool LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) -{ - // LL_INFOS() << "Registering motion: " << name << LL_ENDL; - if (!is_in_map(mMotionTable, id)) - { - mMotionTable[id] = constructor; - return true; - } - - return false; -} - -//----------------------------------------------------------------------------- -// markBad() -//----------------------------------------------------------------------------- -void LLMotionRegistry::markBad( const LLUUID& id ) -{ - mMotionTable[id] = LLMotionConstructor(NULL); -} - -//----------------------------------------------------------------------------- -// createMotion() -//----------------------------------------------------------------------------- -LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) -{ - LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL)); - LLMotion* motion = NULL; - - if ( constructor == NULL ) - { - // *FIX: need to replace with a better default scheme. RN - motion = LLKeyframeMotion::create(id); - } - else - { - motion = constructor(id); - } - - return motion; -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLMotionController class -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// LLMotionController() -// Class Constructor -//----------------------------------------------------------------------------- -LLMotionController::LLMotionController() - : mTimeFactor(sCurrentTimeFactor), - mCharacter(NULL), - mAnimTime(0.f), - mPrevTimerElapsed(0.f), - mLastTime(0.0f), - mHasRunOnce(false), - mPaused(false), - mPausedFrame(0), - mTimeStep(0.f), - mTimeStepCount(0), - mLastInterp(0.f), - mIsSelf(false), - mLastCountAfterPurge(0) -{ -} - - -//----------------------------------------------------------------------------- -// ~LLMotionController() -// Class Destructor -//----------------------------------------------------------------------------- -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() -//----------------------------------------------------------------------------- -void LLMotionController::deleteAllMotions() -{ - mLoadingMotions.clear(); - mLoadedMotions.clear(); - mActiveMotions.clear(); - - for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer()); - mAllMotions.clear(); - - // stinson 05/12/20014 : Ownership of the LLMotion pointers is transferred from - // mAllMotions to mDeprecatedMotions in method - // LLMotionController::deprecateMotionInstance(). Thus, we should also clean - // up the mDeprecatedMotions list as well. - for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer()); - mDeprecatedMotions.clear(); -} - -//----------------------------------------------------------------------------- -// purgeExcessMotion() -//----------------------------------------------------------------------------- -void LLMotionController::purgeExcessMotions() -{ - 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); - } - } - } - - std::set motions_to_kill; - if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) - { - // too many motions active this frame, kill all blenders - mPoseBlender.clearBlenders(); - for (LLMotion* cur_motionp : mLoadedMotions) - { - // motion isn't playing, delete it - if (!isMotionActive(cur_motionp)) - { - motions_to_kill.insert(cur_motionp->getID()); - } - } - } - - // clean up all inactive, loaded motions - for (LLUUID motion_id : motions_to_kill) - { - // look up the motion again by ID to get canonical instance - // and kill it only if that one is inactive - LLMotion* motionp = findMotion(motion_id); - if (motionp && !isMotionActive(motionp)) - { - removeMotion(motion_id); - } - } - - U32 loaded_count = mLoadedMotions.size(); - if (loaded_count > (2 * MAX_MOTION_INSTANCES) && loaded_count > mLastCountAfterPurge) - { - LL_WARNS_ONCE("Animation") << loaded_count << " Loaded Motions. Amount of motions is over limit." << LL_ENDL; - } - mLastCountAfterPurge = loaded_count; -} - -//----------------------------------------------------------------------------- -// 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); - } - } -} - -//----------------------------------------------------------------------------- -// setTimeStep() -//----------------------------------------------------------------------------- -void LLMotionController::setTimeStep(F32 step) -{ - mTimeStep = step; - - if (step != 0.f) - { - // make sure timestamps conform to new quantum - for (motion_list_t::iterator iter = mActiveMotions.begin(); - iter != mActiveMotions.end(); ++iter) - { - LLMotion* motionp = *iter; - 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->setStopped(stopped); - motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step; - } - } -} - -//----------------------------------------------------------------------------- -// setTimeFactor() -//----------------------------------------------------------------------------- -void LLMotionController::setTimeFactor(F32 time_factor) -{ - mTimeFactor = time_factor; -} - -//----------------------------------------------------------------------------- -// setCharacter() -//----------------------------------------------------------------------------- -void LLMotionController::setCharacter(LLCharacter *character) -{ - mCharacter = character; -} - - -//----------------------------------------------------------------------------- -// registerMotion() -//----------------------------------------------------------------------------- -bool LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) -{ - return sRegistry.registerMotion(id, constructor); -} - -//----------------------------------------------------------------------------- -// removeMotion() -//----------------------------------------------------------------------------- -void LLMotionController::removeMotion( const LLUUID& id) -{ - LLMotion* motionp = findMotion(id); - mAllMotions.erase(id); - removeMotionInstance(motionp); -} - -// removes instance of a motion from all runtime structures, but does -// not erase entry by ID, as this could be a duplicate instance -// use removeMotion(id) to remove all references to a given motion by id. -void LLMotionController::removeMotionInstance(LLMotion* motionp) -{ - if (motionp) - { - llassert(findMotion(motionp->getID()) != motionp); - if (motionp->isActive()) - motionp->deactivate(); - mLoadingMotions.erase(motionp); - mLoadedMotions.erase(motionp); - mActiveMotions.remove(motionp); - delete motionp; - } -} - -//----------------------------------------------------------------------------- -// createMotion() -//----------------------------------------------------------------------------- -LLMotion* LLMotionController::createMotion( const LLUUID &id ) -{ - // do we have an instance of this motion for this character? - LLMotion *motion = findMotion(id); - - // if not, we need to create one - if (!motion) - { - // look up constructor and create it - motion = sRegistry.createMotion(id); - if (!motion) - { - return NULL; - } - - // look up name for default motions - const char* motion_name = gAnimLibrary.animStateToString(id); - if (motion_name) - { - motion->setName(motion_name); - } - - // initialize the new instance - LLMotion::LLMotionInitStatus stat = motion->onInitialize(mCharacter); - switch(stat) - { - case LLMotion::STATUS_FAILURE: - LL_INFOS() << "Motion " << id << " init failed." << LL_ENDL; - sRegistry.markBad(id); - delete motion; - return NULL; - case LLMotion::STATUS_HOLD: - mLoadingMotions.insert(motion); - break; - case LLMotion::STATUS_SUCCESS: - // add motion to our list - mLoadedMotions.insert(motion); - break; - default: - LL_ERRS() << "Invalid initialization status" << LL_ENDL; - break; - } - - mAllMotions[id] = motion; - } - return motion; -} - -//----------------------------------------------------------------------------- -// startMotion() -//----------------------------------------------------------------------------- -bool LLMotionController::startMotion(const LLUUID &id, F32 start_offset) -{ - // do we have an instance of this motion for this character? - LLMotion *motion = findMotion(id); - - // 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)) - { - deprecateMotionInstance(motion); - // force creation of new instance - motion = NULL; - } - - // create new motion instance - if (!motion) - { - motion = createMotion(id); - } - - if (!motion) - { - return false; - } - //if the motion is already active and allows deprecation, then let it keep playing - else if (motion->canDeprecate() && isMotionActive(motion)) - { - return true; - } - -// LL_INFOS() << "Starting motion " << name << LL_ENDL; - return activateMotionInstance(motion, mAnimTime - start_offset); -} - - -//----------------------------------------------------------------------------- -// stopMotionLocally() -//----------------------------------------------------------------------------- -bool LLMotionController::stopMotionLocally(const LLUUID &id, bool stop_immediate) -{ - // if already inactive, return false - LLMotion *motion = findMotion(id); - // SL-1290: always stop immediate if paused - return stopMotionInstance(motion, stop_immediate||mPaused); -} - -bool LLMotionController::stopMotionInstance(LLMotion* motion, bool stop_immediate) -{ - if (!motion) - { - return false; - } - - - // If on active list, stop it - if (isMotionActive(motion) && !motion->isStopped()) - { - motion->setStopTime(mAnimTime); - if (stop_immediate) - { - deactivateMotionInstance(motion); - } - return true; - } - else if (isMotionLoading(motion)) - { - motion->setStopped(true); - return true; - } - - return false; -} - -//----------------------------------------------------------------------------- -// updateRegularMotions() -//----------------------------------------------------------------------------- -void LLMotionController::updateRegularMotions() -{ - updateMotionsByType(LLMotion::NORMAL_BLEND); -} - -//----------------------------------------------------------------------------- -// updateAdditiveMotions() -//----------------------------------------------------------------------------- -void LLMotionController::updateAdditiveMotions() -{ - updateMotionsByType(LLMotion::ADDITIVE_BLEND); -} - -//----------------------------------------------------------------------------- -// resetJointSignatures() -//----------------------------------------------------------------------------- -void LLMotionController::resetJointSignatures() -{ - memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); - memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); -} - -//----------------------------------------------------------------------------- -// updateIdleMotion() -// minimal updates for active motions -//----------------------------------------------------------------------------- -void LLMotionController::updateIdleMotion(LLMotion* motionp) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - 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() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - 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) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - bool update_result = true; - U8 last_joint_signature[LL_CHARACTER_MAX_ANIMATED_JOINTS]; - - memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); - - // iterate through active motions in chronological order - for (motion_list_t::iterator iter = mActiveMotions.begin(); - iter != mActiveMotions.end(); ) - { - motion_list_t::iterator curiter = iter++; - LLMotion* motionp = *curiter; - if (motionp->getBlendType() != anim_type) - { - continue; - } - - bool update_motion = false; - - if (motionp->getPose()->getWeight() < 1.f) - { - update_motion = true; - } - else - { - for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++) - { - U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]); - U32 test_signature = *(U32*)&(motionp->mJointSignature[0][i * 4]); - - if ((*current_signature | test_signature) > (*current_signature)) - { - *current_signature |= test_signature; - update_motion = true; - } - - *((U32*)&last_joint_signature[i * 4]) = *(U32*)&(mJointSignature[1][i * 4]); - current_signature = (U32*)&(mJointSignature[1][i * 4]); - test_signature = *(U32*)&(motionp->mJointSignature[1][i * 4]); - - if ((*current_signature | test_signature) > (*current_signature)) - { - *current_signature |= test_signature; - update_motion = true; - } - } - } - - if (!update_motion) - { - updateIdleMotion(motionp); - continue; - } - - LLPose *posep = motionp->getPose(); - - // only filter by LOD after running every animation at least once (to prime the avatar state) - if (mHasRunOnce && motionp->getMinPixelArea() > mCharacter->getPixelArea()) - { - motionp->fadeOut(); - - //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic) - 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); - } - } - - if (motionp->getFadeWeight() < 0.01f) - { - if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) - { - posep->setWeight(0.f); - deactivateMotionInstance(motionp); - } - continue; - } - } - else - { - motionp->fadeIn(); - } - - //********************** - // MOTION INACTIVE - //********************** - 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? - if (mLastTime <= motionp->getStopTime()) - { - // if not, let's stop it this time through and deactivate it the next - - posep->setWeight(motionp->getFadeWeight()); - motionp->onUpdate(motionp->getStopTime() - motionp->mActivationTimestamp, last_joint_signature); - } - else - { - posep->setWeight(0.f); - deactivateMotionInstance(motionp); - continue; - } - } - - //********************** - // MOTION EASE OUT - //********************** - 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(); - } - - if (motionp->getEaseOutDuration() == 0.f) - { - posep->setWeight(0.f); - } - else - { - posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mAnimTime - motionp->getStopTime()) / motionp->getEaseOutDuration()))); - } - - // perform motion update - update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); - } - - //********************** - // MOTION ACTIVE - //********************** - else if (mAnimTime > motionp->mActivationTimestamp + motionp->getEaseInDuration()) - { - posep->setWeight(motionp->getFadeWeight()); - - //should we notify the simulator that this motion should be stopped? - 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); - } - } - - // perform motion update - { - update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); - } - } - - //********************** - // MOTION EASE IN - //********************** - else if (mAnimTime >= motionp->mActivationTimestamp) - { - if (mLastTime < motionp->mActivationTimestamp) - { - motionp->mResidualWeight = motionp->getPose()->getWeight(); - } - if (motionp->getEaseInDuration() == 0.f) - { - posep->setWeight(motionp->getFadeWeight()); - } - else - { - // perform motion update - posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mAnimTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration())); - } - // perform motion update - update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); - } - else - { - posep->setWeight(0.f); - update_result = motionp->onUpdate(0.f, last_joint_signature); - } - - // allow motions to deactivate themselves - if (!update_result) - { - if (!motionp->isStopped() || motionp->getStopTime() > mAnimTime) - { - // animation has stopped itself due to internal logic - // propagate this to the network - // as not all viewers are guaranteed to have access to the same logic - mCharacter->requestStopMotion( motionp ); - stopMotionInstance(motionp, false); - } - - } - - // even if onupdate returns false, add this motion in to the blend one last time - mPoseBlender.addMotion(motionp); - } -} - -//----------------------------------------------------------------------------- -// updateLoadingMotions() -//----------------------------------------------------------------------------- -void LLMotionController::updateLoadingMotions() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // 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) - { - LL_INFOS() << "Motion " << motionp->getID() << " init failed." << LL_ENDL; - sRegistry.markBad(motionp->getID()); - mLoadingMotions.erase(curiter); - motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp); - if (found_it != mDeprecatedMotions.end()) - { - mDeprecatedMotions.erase(found_it); - } - mAllMotions.erase(motionp->getID()); - delete motionp; - } - } -} - -//----------------------------------------------------------------------------- -// call updateMotion() or updateMotionsMinimal() every frame -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// updateMotion() -//----------------------------------------------------------------------------- -void LLMotionController::updateMotions(bool force_update) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // SL-763: "Distant animated objects run at super fast speed" - // The use_quantum optimization or possibly the associated code in setTimeStamp() - // does not work as implemented. - // Currently setting mTimeStep to nonzero is disabled elsewhere. - 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 = mAnimTime + delta_time * mTimeFactor; - if (use_quantum) - { - F32 time_interval = fmodf(update_time, mTimeStep); - - // always animate *ahead* of actual time - S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1; - if (quantum_count == mTimeStepCount) - { - // we're still in same time quantum as before, so just interpolate and exit - if (!mPaused) - { - F32 interp = time_interval / mTimeStep; - mPoseBlender.interpolate(interp - mLastInterp); - mLastInterp = interp; - } - - updateLoadingMotions(); - - return; - } - - // is calculating a new keyframe pose, make sure the last one gets applied - mPoseBlender.interpolate(1.f); - clearBlenders(); - - mTimeStepCount = quantum_count; - mAnimTime = (F32)quantum_count * mTimeStep; - mLastInterp = 0.f; - } - else - { - mAnimTime = update_time; - } - } - - updateLoadingMotions(); - - resetJointSignatures(); - - if (mPaused && !force_update) - { - updateIdleActiveMotions(); - } - else - { - // update additive motions - updateAdditiveMotions(); - - resetJointSignatures(); - - // update all regular motions - updateRegularMotions(); - - if (use_quantum) - { - mPoseBlender.blendAndCache(true); - } - else - { - mPoseBlender.blendAndApply(); - } - } - - mHasRunOnce = true; -// LL_INFOS() << "Motion controller time " << motionTimer.getElapsedTimeF32() << LL_ENDL; -} - -//----------------------------------------------------------------------------- -// updateMotionsMinimal() -// minimal update (e.g. while hidden) -//----------------------------------------------------------------------------- -void LLMotionController::updateMotionsMinimal() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // Always update mPrevTimerElapsed - mPrevTimerElapsed = mTimer.getElapsedTimeF32(); - - purgeExcessMotions(); - updateLoadingMotions(); - resetJointSignatures(); - - deactivateStoppedMotions(); - - mHasRunOnce = true; -} - -//----------------------------------------------------------------------------- -// activateMotionInstance() -//----------------------------------------------------------------------------- -bool LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - // It's not clear why the getWeight() line seems to be crashing this, but - // hopefully this fixes it. - if (motion == NULL || motion->getPose() == NULL) - { - return false; - } - - if (mLoadingMotions.find(motion) != mLoadingMotions.end()) - { - // we want to start this motion, but we can't yet, so flag it as started - motion->setStopped(false); - // report pending animations as activated - return true; - } - - motion->mResidualWeight = motion->getPose()->getWeight(); - - // set stop time based on given duration and ease out time - if (motion->getDuration() != 0.f && !motion->getLoop()) - { - F32 ease_out_time; - F32 motion_duration; - - // should we stop at the end of motion duration, or a bit earlier - // to allow it to ease out while moving? - ease_out_time = motion->getEaseOutDuration(); - - // is the clock running when the motion is easing in? - // if not (POSTURE_EASE) then we need to wait that much longer before triggering the stop - motion_duration = llmax(motion->getDuration() - ease_out_time, 0.f); - motion->mSendStopTimestamp = time + motion_duration; - } - else - { - motion->mSendStopTimestamp = F32_MAX; - } - - if (motion->isActive()) - { - mActiveMotions.remove(motion); - } - mActiveMotions.push_front(motion); - - 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; -} - -//----------------------------------------------------------------------------- -// deactivateMotionInstance() -//----------------------------------------------------------------------------- -bool LLMotionController::deactivateMotionInstance(LLMotion *motion) -{ - motion->deactivate(); - - motion_set_t::iterator found_it = mDeprecatedMotions.find(motion); - if (found_it != mDeprecatedMotions.end()) - { - // deprecated motions need to be completely excised - removeMotionInstance(motion); - mDeprecatedMotions.erase(found_it); - } - else - { - // for motions that we are keeping, simply remove from active queue - mActiveMotions.remove(motion); - } - - return true; -} - -void LLMotionController::deprecateMotionInstance(LLMotion* motion) -{ - mDeprecatedMotions.insert(motion); - - //fade out deprecated motion - stopMotionInstance(motion, false); - //no longer canonical - mAllMotions.erase(motion->getID()); -} - -//----------------------------------------------------------------------------- -// isMotionActive() -//----------------------------------------------------------------------------- -bool LLMotionController::isMotionActive(LLMotion *motion) -{ - return (motion && motion->isActive()); -} - -//----------------------------------------------------------------------------- -// isMotionLoading() -//----------------------------------------------------------------------------- -bool LLMotionController::isMotionLoading(LLMotion* motion) -{ - return (mLoadingMotions.find(motion) != mLoadingMotions.end()); -} - - -//----------------------------------------------------------------------------- -// findMotion() -//----------------------------------------------------------------------------- -LLMotion* LLMotionController::findMotion(const LLUUID& id) const -{ - motion_map_t::const_iterator iter = mAllMotions.find(id); - if(iter == mAllMotions.end()) - { - return NULL; - } - else - { - return iter->second; - } -} - -//----------------------------------------------------------------------------- -// dumpMotions() -//----------------------------------------------------------------------------- -void LLMotionController::dumpMotions() -{ - LL_INFOS() << "=====================================" << LL_ENDL; - for (motion_map_t::value_type& motion_pair : mAllMotions) - { - LLUUID id = motion_pair.first; - std::string state_string; - LLMotion *motion = motion_pair.second; - if (mLoadingMotions.find(motion) != mLoadingMotions.end()) - state_string += std::string("l"); - if (mLoadedMotions.find(motion) != mLoadedMotions.end()) - state_string += std::string("L"); - if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end()) - state_string += std::string("A"); - if (mDeprecatedMotions.find(motion) != mDeprecatedMotions.end()) - state_string += std::string("D"); - LL_INFOS() << gAnimLibrary.animationName(id) << " " << state_string << LL_ENDL; - - } -} - -//----------------------------------------------------------------------------- -// deactivateAllMotions() -//----------------------------------------------------------------------------- -void LLMotionController::deactivateAllMotions() -{ - for (motion_map_t::value_type& motion_pair : mAllMotions) - { - LLMotion* motionp = motion_pair.second; - deactivateMotionInstance(motionp); - } -} - - -//----------------------------------------------------------------------------- -// flushAllMotions() -//----------------------------------------------------------------------------- -void LLMotionController::flushAllMotions() -{ - std::vector > active_motions; - active_motions.reserve(mActiveMotions.size()); - for (motion_list_t::iterator iter = mActiveMotions.begin(); - iter != mActiveMotions.end(); ) - { - motion_list_t::iterator curiter = iter++; - LLMotion* motionp = *curiter; - F32 dtime = mAnimTime - motionp->mActivationTimestamp; - active_motions.push_back(std::make_pair(motionp->getID(),dtime)); - motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it - } - mActiveMotions.clear(); - - // delete all motion instances - deleteAllMotions(); - - // kill current hand pose that was previously called out by - // keyframe motion - mCharacter->removeAnimationData("Hand Pose"); - - // restart motions - for (std::vector >::value_type& motion_pair : active_motions) - { - startMotion(motion_pair.first, motion_pair.second); - } -} - -//----------------------------------------------------------------------------- -// pause() -//----------------------------------------------------------------------------- -void LLMotionController::pauseAllMotions() -{ - if (!mPaused) - { - //LL_INFOS() << "Pausing animations..." << LL_ENDL; - mPaused = true; - mPausedFrame = LLFrameTimer::getFrameCount(); - } - -} - -//----------------------------------------------------------------------------- -// unpause() -//----------------------------------------------------------------------------- -void LLMotionController::unpauseAllMotions() -{ - if (mPaused) - { - //LL_INFOS() << "Unpausing animations..." << LL_ENDL; - mPaused = false; - } -} -// End +/** + * @file llmotioncontroller.cpp + * @brief Implementation of LLMotionController class. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "linden_common.h" + +#include "llmotioncontroller.h" +#include "llfasttimer.h" +#include "llkeyframemotion.h" +#include "llmath.h" +#include "lltimer.h" +#include "llanimationstates.h" +#include "llstl.h" + +// This is why LL_CHARACTER_MAX_ANIMATED_JOINTS needs to be a multiple of 4. +const S32 NUM_JOINT_SIGNATURE_STRIDES = LL_CHARACTER_MAX_ANIMATED_JOINTS / 4; +const U32 MAX_MOTION_INSTANCES = 32; + +//----------------------------------------------------------------------------- +// Constants and statics +//----------------------------------------------------------------------------- +F32 LLMotionController::sCurrentTimeFactor = 1.f; +LLMotionRegistry LLMotionController::sRegistry; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// LLMotionRegistry class +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// LLMotionRegistry() +// Class Constructor +//----------------------------------------------------------------------------- +LLMotionRegistry::LLMotionRegistry() +{ + +} + + +//----------------------------------------------------------------------------- +// ~LLMotionRegistry() +// Class Destructor +//----------------------------------------------------------------------------- +LLMotionRegistry::~LLMotionRegistry() +{ + mMotionTable.clear(); +} + + +//----------------------------------------------------------------------------- +// addMotion() +//----------------------------------------------------------------------------- +bool LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) +{ + // LL_INFOS() << "Registering motion: " << name << LL_ENDL; + if (!is_in_map(mMotionTable, id)) + { + mMotionTable[id] = constructor; + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// markBad() +//----------------------------------------------------------------------------- +void LLMotionRegistry::markBad( const LLUUID& id ) +{ + mMotionTable[id] = LLMotionConstructor(NULL); +} + +//----------------------------------------------------------------------------- +// createMotion() +//----------------------------------------------------------------------------- +LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) +{ + LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL)); + LLMotion* motion = NULL; + + if ( constructor == NULL ) + { + // *FIX: need to replace with a better default scheme. RN + motion = LLKeyframeMotion::create(id); + } + else + { + motion = constructor(id); + } + + return motion; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// LLMotionController class +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// LLMotionController() +// Class Constructor +//----------------------------------------------------------------------------- +LLMotionController::LLMotionController() + : mTimeFactor(sCurrentTimeFactor), + mCharacter(NULL), + mAnimTime(0.f), + mPrevTimerElapsed(0.f), + mLastTime(0.0f), + mHasRunOnce(false), + mPaused(false), + mPausedFrame(0), + mTimeStep(0.f), + mTimeStepCount(0), + mLastInterp(0.f), + mIsSelf(false), + mLastCountAfterPurge(0) +{ +} + + +//----------------------------------------------------------------------------- +// ~LLMotionController() +// Class Destructor +//----------------------------------------------------------------------------- +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() +//----------------------------------------------------------------------------- +void LLMotionController::deleteAllMotions() +{ + mLoadingMotions.clear(); + mLoadedMotions.clear(); + mActiveMotions.clear(); + + for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer()); + mAllMotions.clear(); + + // stinson 05/12/20014 : Ownership of the LLMotion pointers is transferred from + // mAllMotions to mDeprecatedMotions in method + // LLMotionController::deprecateMotionInstance(). Thus, we should also clean + // up the mDeprecatedMotions list as well. + for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer()); + mDeprecatedMotions.clear(); +} + +//----------------------------------------------------------------------------- +// purgeExcessMotion() +//----------------------------------------------------------------------------- +void LLMotionController::purgeExcessMotions() +{ + 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); + } + } + } + + std::set motions_to_kill; + if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) + { + // too many motions active this frame, kill all blenders + mPoseBlender.clearBlenders(); + for (LLMotion* cur_motionp : mLoadedMotions) + { + // motion isn't playing, delete it + if (!isMotionActive(cur_motionp)) + { + motions_to_kill.insert(cur_motionp->getID()); + } + } + } + + // clean up all inactive, loaded motions + for (LLUUID motion_id : motions_to_kill) + { + // look up the motion again by ID to get canonical instance + // and kill it only if that one is inactive + LLMotion* motionp = findMotion(motion_id); + if (motionp && !isMotionActive(motionp)) + { + removeMotion(motion_id); + } + } + + U32 loaded_count = mLoadedMotions.size(); + if (loaded_count > (2 * MAX_MOTION_INSTANCES) && loaded_count > mLastCountAfterPurge) + { + LL_WARNS_ONCE("Animation") << loaded_count << " Loaded Motions. Amount of motions is over limit." << LL_ENDL; + } + mLastCountAfterPurge = loaded_count; +} + +//----------------------------------------------------------------------------- +// 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); + } + } +} + +//----------------------------------------------------------------------------- +// setTimeStep() +//----------------------------------------------------------------------------- +void LLMotionController::setTimeStep(F32 step) +{ + mTimeStep = step; + + if (step != 0.f) + { + // make sure timestamps conform to new quantum + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + 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->setStopped(stopped); + motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step; + } + } +} + +//----------------------------------------------------------------------------- +// setTimeFactor() +//----------------------------------------------------------------------------- +void LLMotionController::setTimeFactor(F32 time_factor) +{ + mTimeFactor = time_factor; +} + +//----------------------------------------------------------------------------- +// setCharacter() +//----------------------------------------------------------------------------- +void LLMotionController::setCharacter(LLCharacter *character) +{ + mCharacter = character; +} + + +//----------------------------------------------------------------------------- +// registerMotion() +//----------------------------------------------------------------------------- +bool LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor constructor ) +{ + return sRegistry.registerMotion(id, constructor); +} + +//----------------------------------------------------------------------------- +// removeMotion() +//----------------------------------------------------------------------------- +void LLMotionController::removeMotion( const LLUUID& id) +{ + LLMotion* motionp = findMotion(id); + mAllMotions.erase(id); + removeMotionInstance(motionp); +} + +// removes instance of a motion from all runtime structures, but does +// not erase entry by ID, as this could be a duplicate instance +// use removeMotion(id) to remove all references to a given motion by id. +void LLMotionController::removeMotionInstance(LLMotion* motionp) +{ + if (motionp) + { + llassert(findMotion(motionp->getID()) != motionp); + if (motionp->isActive()) + motionp->deactivate(); + mLoadingMotions.erase(motionp); + mLoadedMotions.erase(motionp); + mActiveMotions.remove(motionp); + delete motionp; + } +} + +//----------------------------------------------------------------------------- +// createMotion() +//----------------------------------------------------------------------------- +LLMotion* LLMotionController::createMotion( const LLUUID &id ) +{ + // do we have an instance of this motion for this character? + LLMotion *motion = findMotion(id); + + // if not, we need to create one + if (!motion) + { + // look up constructor and create it + motion = sRegistry.createMotion(id); + if (!motion) + { + return NULL; + } + + // look up name for default motions + const char* motion_name = gAnimLibrary.animStateToString(id); + if (motion_name) + { + motion->setName(motion_name); + } + + // initialize the new instance + LLMotion::LLMotionInitStatus stat = motion->onInitialize(mCharacter); + switch(stat) + { + case LLMotion::STATUS_FAILURE: + LL_INFOS() << "Motion " << id << " init failed." << LL_ENDL; + sRegistry.markBad(id); + delete motion; + return NULL; + case LLMotion::STATUS_HOLD: + mLoadingMotions.insert(motion); + break; + case LLMotion::STATUS_SUCCESS: + // add motion to our list + mLoadedMotions.insert(motion); + break; + default: + LL_ERRS() << "Invalid initialization status" << LL_ENDL; + break; + } + + mAllMotions[id] = motion; + } + return motion; +} + +//----------------------------------------------------------------------------- +// startMotion() +//----------------------------------------------------------------------------- +bool LLMotionController::startMotion(const LLUUID &id, F32 start_offset) +{ + // do we have an instance of this motion for this character? + LLMotion *motion = findMotion(id); + + // 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)) + { + deprecateMotionInstance(motion); + // force creation of new instance + motion = NULL; + } + + // create new motion instance + if (!motion) + { + motion = createMotion(id); + } + + if (!motion) + { + return false; + } + //if the motion is already active and allows deprecation, then let it keep playing + else if (motion->canDeprecate() && isMotionActive(motion)) + { + return true; + } + +// LL_INFOS() << "Starting motion " << name << LL_ENDL; + return activateMotionInstance(motion, mAnimTime - start_offset); +} + + +//----------------------------------------------------------------------------- +// stopMotionLocally() +//----------------------------------------------------------------------------- +bool LLMotionController::stopMotionLocally(const LLUUID &id, bool stop_immediate) +{ + // if already inactive, return false + LLMotion *motion = findMotion(id); + // SL-1290: always stop immediate if paused + return stopMotionInstance(motion, stop_immediate||mPaused); +} + +bool LLMotionController::stopMotionInstance(LLMotion* motion, bool stop_immediate) +{ + if (!motion) + { + return false; + } + + + // If on active list, stop it + if (isMotionActive(motion) && !motion->isStopped()) + { + motion->setStopTime(mAnimTime); + if (stop_immediate) + { + deactivateMotionInstance(motion); + } + return true; + } + else if (isMotionLoading(motion)) + { + motion->setStopped(true); + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// updateRegularMotions() +//----------------------------------------------------------------------------- +void LLMotionController::updateRegularMotions() +{ + updateMotionsByType(LLMotion::NORMAL_BLEND); +} + +//----------------------------------------------------------------------------- +// updateAdditiveMotions() +//----------------------------------------------------------------------------- +void LLMotionController::updateAdditiveMotions() +{ + updateMotionsByType(LLMotion::ADDITIVE_BLEND); +} + +//----------------------------------------------------------------------------- +// resetJointSignatures() +//----------------------------------------------------------------------------- +void LLMotionController::resetJointSignatures() +{ + memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); + memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); +} + +//----------------------------------------------------------------------------- +// updateIdleMotion() +// minimal updates for active motions +//----------------------------------------------------------------------------- +void LLMotionController::updateIdleMotion(LLMotion* motionp) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + 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() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + 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) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + bool update_result = true; + U8 last_joint_signature[LL_CHARACTER_MAX_ANIMATED_JOINTS]; + + memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_ANIMATED_JOINTS); + + // iterate through active motions in chronological order + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ) + { + motion_list_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + if (motionp->getBlendType() != anim_type) + { + continue; + } + + bool update_motion = false; + + if (motionp->getPose()->getWeight() < 1.f) + { + update_motion = true; + } + else + { + for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++) + { + U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]); + U32 test_signature = *(U32*)&(motionp->mJointSignature[0][i * 4]); + + if ((*current_signature | test_signature) > (*current_signature)) + { + *current_signature |= test_signature; + update_motion = true; + } + + *((U32*)&last_joint_signature[i * 4]) = *(U32*)&(mJointSignature[1][i * 4]); + current_signature = (U32*)&(mJointSignature[1][i * 4]); + test_signature = *(U32*)&(motionp->mJointSignature[1][i * 4]); + + if ((*current_signature | test_signature) > (*current_signature)) + { + *current_signature |= test_signature; + update_motion = true; + } + } + } + + if (!update_motion) + { + updateIdleMotion(motionp); + continue; + } + + LLPose *posep = motionp->getPose(); + + // only filter by LOD after running every animation at least once (to prime the avatar state) + if (mHasRunOnce && motionp->getMinPixelArea() > mCharacter->getPixelArea()) + { + motionp->fadeOut(); + + //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic) + 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); + } + } + + if (motionp->getFadeWeight() < 0.01f) + { + if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) + { + posep->setWeight(0.f); + deactivateMotionInstance(motionp); + } + continue; + } + } + else + { + motionp->fadeIn(); + } + + //********************** + // MOTION INACTIVE + //********************** + 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? + if (mLastTime <= motionp->getStopTime()) + { + // if not, let's stop it this time through and deactivate it the next + + posep->setWeight(motionp->getFadeWeight()); + motionp->onUpdate(motionp->getStopTime() - motionp->mActivationTimestamp, last_joint_signature); + } + else + { + posep->setWeight(0.f); + deactivateMotionInstance(motionp); + continue; + } + } + + //********************** + // MOTION EASE OUT + //********************** + 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(); + } + + if (motionp->getEaseOutDuration() == 0.f) + { + posep->setWeight(0.f); + } + else + { + posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mAnimTime - motionp->getStopTime()) / motionp->getEaseOutDuration()))); + } + + // perform motion update + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); + } + + //********************** + // MOTION ACTIVE + //********************** + else if (mAnimTime > motionp->mActivationTimestamp + motionp->getEaseInDuration()) + { + posep->setWeight(motionp->getFadeWeight()); + + //should we notify the simulator that this motion should be stopped? + 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); + } + } + + // perform motion update + { + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); + } + } + + //********************** + // MOTION EASE IN + //********************** + else if (mAnimTime >= motionp->mActivationTimestamp) + { + if (mLastTime < motionp->mActivationTimestamp) + { + motionp->mResidualWeight = motionp->getPose()->getWeight(); + } + if (motionp->getEaseInDuration() == 0.f) + { + posep->setWeight(motionp->getFadeWeight()); + } + else + { + // perform motion update + posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mAnimTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration())); + } + // perform motion update + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); + } + else + { + posep->setWeight(0.f); + update_result = motionp->onUpdate(0.f, last_joint_signature); + } + + // allow motions to deactivate themselves + if (!update_result) + { + if (!motionp->isStopped() || motionp->getStopTime() > mAnimTime) + { + // animation has stopped itself due to internal logic + // propagate this to the network + // as not all viewers are guaranteed to have access to the same logic + mCharacter->requestStopMotion( motionp ); + stopMotionInstance(motionp, false); + } + + } + + // even if onupdate returns false, add this motion in to the blend one last time + mPoseBlender.addMotion(motionp); + } +} + +//----------------------------------------------------------------------------- +// updateLoadingMotions() +//----------------------------------------------------------------------------- +void LLMotionController::updateLoadingMotions() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + // 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) + { + LL_INFOS() << "Motion " << motionp->getID() << " init failed." << LL_ENDL; + sRegistry.markBad(motionp->getID()); + mLoadingMotions.erase(curiter); + motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp); + if (found_it != mDeprecatedMotions.end()) + { + mDeprecatedMotions.erase(found_it); + } + mAllMotions.erase(motionp->getID()); + delete motionp; + } + } +} + +//----------------------------------------------------------------------------- +// call updateMotion() or updateMotionsMinimal() every frame +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// updateMotion() +//----------------------------------------------------------------------------- +void LLMotionController::updateMotions(bool force_update) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + // SL-763: "Distant animated objects run at super fast speed" + // The use_quantum optimization or possibly the associated code in setTimeStamp() + // does not work as implemented. + // Currently setting mTimeStep to nonzero is disabled elsewhere. + 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 = mAnimTime + delta_time * mTimeFactor; + if (use_quantum) + { + F32 time_interval = fmodf(update_time, mTimeStep); + + // always animate *ahead* of actual time + S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1; + if (quantum_count == mTimeStepCount) + { + // we're still in same time quantum as before, so just interpolate and exit + if (!mPaused) + { + F32 interp = time_interval / mTimeStep; + mPoseBlender.interpolate(interp - mLastInterp); + mLastInterp = interp; + } + + updateLoadingMotions(); + + return; + } + + // is calculating a new keyframe pose, make sure the last one gets applied + mPoseBlender.interpolate(1.f); + clearBlenders(); + + mTimeStepCount = quantum_count; + mAnimTime = (F32)quantum_count * mTimeStep; + mLastInterp = 0.f; + } + else + { + mAnimTime = update_time; + } + } + + updateLoadingMotions(); + + resetJointSignatures(); + + if (mPaused && !force_update) + { + updateIdleActiveMotions(); + } + else + { + // update additive motions + updateAdditiveMotions(); + + resetJointSignatures(); + + // update all regular motions + updateRegularMotions(); + + if (use_quantum) + { + mPoseBlender.blendAndCache(true); + } + else + { + mPoseBlender.blendAndApply(); + } + } + + mHasRunOnce = true; +// LL_INFOS() << "Motion controller time " << motionTimer.getElapsedTimeF32() << LL_ENDL; +} + +//----------------------------------------------------------------------------- +// updateMotionsMinimal() +// minimal update (e.g. while hidden) +//----------------------------------------------------------------------------- +void LLMotionController::updateMotionsMinimal() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + // Always update mPrevTimerElapsed + mPrevTimerElapsed = mTimer.getElapsedTimeF32(); + + purgeExcessMotions(); + updateLoadingMotions(); + resetJointSignatures(); + + deactivateStoppedMotions(); + + mHasRunOnce = true; +} + +//----------------------------------------------------------------------------- +// activateMotionInstance() +//----------------------------------------------------------------------------- +bool LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + // It's not clear why the getWeight() line seems to be crashing this, but + // hopefully this fixes it. + if (motion == NULL || motion->getPose() == NULL) + { + return false; + } + + if (mLoadingMotions.find(motion) != mLoadingMotions.end()) + { + // we want to start this motion, but we can't yet, so flag it as started + motion->setStopped(false); + // report pending animations as activated + return true; + } + + motion->mResidualWeight = motion->getPose()->getWeight(); + + // set stop time based on given duration and ease out time + if (motion->getDuration() != 0.f && !motion->getLoop()) + { + F32 ease_out_time; + F32 motion_duration; + + // should we stop at the end of motion duration, or a bit earlier + // to allow it to ease out while moving? + ease_out_time = motion->getEaseOutDuration(); + + // is the clock running when the motion is easing in? + // if not (POSTURE_EASE) then we need to wait that much longer before triggering the stop + motion_duration = llmax(motion->getDuration() - ease_out_time, 0.f); + motion->mSendStopTimestamp = time + motion_duration; + } + else + { + motion->mSendStopTimestamp = F32_MAX; + } + + if (motion->isActive()) + { + mActiveMotions.remove(motion); + } + mActiveMotions.push_front(motion); + + 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; +} + +//----------------------------------------------------------------------------- +// deactivateMotionInstance() +//----------------------------------------------------------------------------- +bool LLMotionController::deactivateMotionInstance(LLMotion *motion) +{ + motion->deactivate(); + + motion_set_t::iterator found_it = mDeprecatedMotions.find(motion); + if (found_it != mDeprecatedMotions.end()) + { + // deprecated motions need to be completely excised + removeMotionInstance(motion); + mDeprecatedMotions.erase(found_it); + } + else + { + // for motions that we are keeping, simply remove from active queue + mActiveMotions.remove(motion); + } + + return true; +} + +void LLMotionController::deprecateMotionInstance(LLMotion* motion) +{ + mDeprecatedMotions.insert(motion); + + //fade out deprecated motion + stopMotionInstance(motion, false); + //no longer canonical + mAllMotions.erase(motion->getID()); +} + +//----------------------------------------------------------------------------- +// isMotionActive() +//----------------------------------------------------------------------------- +bool LLMotionController::isMotionActive(LLMotion *motion) +{ + return (motion && motion->isActive()); +} + +//----------------------------------------------------------------------------- +// isMotionLoading() +//----------------------------------------------------------------------------- +bool LLMotionController::isMotionLoading(LLMotion* motion) +{ + return (mLoadingMotions.find(motion) != mLoadingMotions.end()); +} + + +//----------------------------------------------------------------------------- +// findMotion() +//----------------------------------------------------------------------------- +LLMotion* LLMotionController::findMotion(const LLUUID& id) const +{ + motion_map_t::const_iterator iter = mAllMotions.find(id); + if(iter == mAllMotions.end()) + { + return NULL; + } + else + { + return iter->second; + } +} + +//----------------------------------------------------------------------------- +// dumpMotions() +//----------------------------------------------------------------------------- +void LLMotionController::dumpMotions() +{ + LL_INFOS() << "=====================================" << LL_ENDL; + for (motion_map_t::value_type& motion_pair : mAllMotions) + { + LLUUID id = motion_pair.first; + std::string state_string; + LLMotion *motion = motion_pair.second; + if (mLoadingMotions.find(motion) != mLoadingMotions.end()) + state_string += std::string("l"); + if (mLoadedMotions.find(motion) != mLoadedMotions.end()) + state_string += std::string("L"); + if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end()) + state_string += std::string("A"); + if (mDeprecatedMotions.find(motion) != mDeprecatedMotions.end()) + state_string += std::string("D"); + LL_INFOS() << gAnimLibrary.animationName(id) << " " << state_string << LL_ENDL; + + } +} + +//----------------------------------------------------------------------------- +// deactivateAllMotions() +//----------------------------------------------------------------------------- +void LLMotionController::deactivateAllMotions() +{ + for (motion_map_t::value_type& motion_pair : mAllMotions) + { + LLMotion* motionp = motion_pair.second; + deactivateMotionInstance(motionp); + } +} + + +//----------------------------------------------------------------------------- +// flushAllMotions() +//----------------------------------------------------------------------------- +void LLMotionController::flushAllMotions() +{ + std::vector > active_motions; + active_motions.reserve(mActiveMotions.size()); + for (motion_list_t::iterator iter = mActiveMotions.begin(); + iter != mActiveMotions.end(); ) + { + motion_list_t::iterator curiter = iter++; + LLMotion* motionp = *curiter; + F32 dtime = mAnimTime - motionp->mActivationTimestamp; + active_motions.push_back(std::make_pair(motionp->getID(),dtime)); + motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it + } + mActiveMotions.clear(); + + // delete all motion instances + deleteAllMotions(); + + // kill current hand pose that was previously called out by + // keyframe motion + mCharacter->removeAnimationData("Hand Pose"); + + // restart motions + for (std::vector >::value_type& motion_pair : active_motions) + { + startMotion(motion_pair.first, motion_pair.second); + } +} + +//----------------------------------------------------------------------------- +// pause() +//----------------------------------------------------------------------------- +void LLMotionController::pauseAllMotions() +{ + if (!mPaused) + { + //LL_INFOS() << "Pausing animations..." << LL_ENDL; + mPaused = true; + mPausedFrame = LLFrameTimer::getFrameCount(); + } + +} + +//----------------------------------------------------------------------------- +// unpause() +//----------------------------------------------------------------------------- +void LLMotionController::unpauseAllMotions() +{ + if (mPaused) + { + //LL_INFOS() << "Unpausing animations..." << LL_ENDL; + mPaused = false; + } +} +// End -- cgit v1.2.3 From b42f9d836b4c0f7fbd4bdae1734021e2a09fdbe8 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 1 Jun 2024 15:49:26 +0200 Subject: Re-enable a lot of compiler warnings for MSVC and address the C4267 "possible loss of precision" warnings --- indra/llcharacter/llmotioncontroller.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indra/llcharacter/llmotioncontroller.cpp') diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 5f99633a58..c204c96f6c 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -156,11 +156,11 @@ LLMotionController::~LLMotionController() 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(); + num_motions += static_cast(mAllMotions.size()); + num_loading_motions += static_cast(mLoadingMotions.size()); + num_loaded_motions += static_cast(mLoadedMotions.size()); + num_active_motions += static_cast(mActiveMotions.size()); + num_deprecated_motions += static_cast(mDeprecatedMotions.size()); } //----------------------------------------------------------------------------- @@ -222,7 +222,7 @@ void LLMotionController::purgeExcessMotions() } // clean up all inactive, loaded motions - for (LLUUID motion_id : motions_to_kill) + for (const LLUUID& motion_id : motions_to_kill) { // look up the motion again by ID to get canonical instance // and kill it only if that one is inactive @@ -233,7 +233,7 @@ void LLMotionController::purgeExcessMotions() } } - U32 loaded_count = mLoadedMotions.size(); + U32 loaded_count = static_cast(mLoadedMotions.size()); if (loaded_count > (2 * MAX_MOTION_INSTANCES) && loaded_count > mLastCountAfterPurge) { LL_WARNS_ONCE("Animation") << loaded_count << " Loaded Motions. Amount of motions is over limit." << LL_ENDL; -- cgit v1.2.3