aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcharacter
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:57 -0500
committerJacek Antonelli2008-08-15 23:45:57 -0500
commit7e3007b63521c4b0c5bbad1c3964a557fc526ce2 (patch)
treeab231ed574db618873d6ebb25293cf7c0cb6d26e /linden/indra/llcharacter
parentSecond Life viewer sources 1.20.10 (diff)
downloadmeta-impy-7e3007b63521c4b0c5bbad1c3964a557fc526ce2.zip
meta-impy-7e3007b63521c4b0c5bbad1c3964a557fc526ce2.tar.gz
meta-impy-7e3007b63521c4b0c5bbad1c3964a557fc526ce2.tar.bz2
meta-impy-7e3007b63521c4b0c5bbad1c3964a557fc526ce2.tar.xz
Second Life viewer sources 1.20.11
Diffstat (limited to 'linden/indra/llcharacter')
-rw-r--r--linden/indra/llcharacter/llcharacter.cpp47
-rw-r--r--linden/indra/llcharacter/llcharacter.h13
-rw-r--r--linden/indra/llcharacter/llkeyframemotion.cpp10
-rw-r--r--linden/indra/llcharacter/llkeyframemotionparam.cpp53
-rw-r--r--linden/indra/llcharacter/llkeyframemotionparam.h15
-rw-r--r--linden/indra/llcharacter/llmotion.cpp17
-rw-r--r--linden/indra/llcharacter/llmotion.h25
-rw-r--r--linden/indra/llcharacter/llmotioncontroller.cpp461
-rw-r--r--linden/indra/llcharacter/llmotioncontroller.h58
9 files changed, 405 insertions, 294 deletions
diff --git a/linden/indra/llcharacter/llcharacter.cpp b/linden/indra/llcharacter/llcharacter.cpp
index ad648f8..83487bc 100644
--- a/linden/indra/llcharacter/llcharacter.cpp
+++ b/linden/indra/llcharacter/llcharacter.cpp
@@ -103,11 +103,11 @@ LLJoint *LLCharacter::getJoint( const std::string &name )
103} 103}
104 104
105//----------------------------------------------------------------------------- 105//-----------------------------------------------------------------------------
106// addMotion() 106// registerMotion()
107//----------------------------------------------------------------------------- 107//-----------------------------------------------------------------------------
108BOOL LLCharacter::addMotion( const LLUUID& id, LLMotionConstructor create ) 108BOOL LLCharacter::registerMotion( const LLUUID& id, LLMotionConstructor create )
109{ 109{
110 return mMotionController.addMotion(id, create); 110 return mMotionController.registerMotion(id, create);
111} 111}
112 112
113//----------------------------------------------------------------------------- 113//-----------------------------------------------------------------------------
@@ -119,7 +119,16 @@ void LLCharacter::removeMotion( const LLUUID& id )
119} 119}
120 120
121//----------------------------------------------------------------------------- 121//-----------------------------------------------------------------------------
122// getMotion() 122// findMotion()
123//-----------------------------------------------------------------------------
124LLMotion* LLCharacter::findMotion( const LLUUID &id )
125{
126 return mMotionController.findMotion( id );
127}
128
129//-----------------------------------------------------------------------------
130// createMotion()
131// NOTE: Always assign the result to a LLPointer!
123//----------------------------------------------------------------------------- 132//-----------------------------------------------------------------------------
124LLMotion* LLCharacter::createMotion( const LLUUID &id ) 133LLMotion* LLCharacter::createMotion( const LLUUID &id )
125{ 134{
@@ -168,26 +177,24 @@ void LLCharacter::requestStopMotion( LLMotion* motion)
168 177
169 178
170//----------------------------------------------------------------------------- 179//-----------------------------------------------------------------------------
171// updateMotion() 180// updateMotions()
172//----------------------------------------------------------------------------- 181//-----------------------------------------------------------------------------
173void LLCharacter::updateMotion(BOOL force_update) 182void LLCharacter::updateMotions(e_update_t update_type)
174{ 183{
175 // unpause if we're forcing an update or 184 LLFastTimer t(LLFastTimer::FTM_UPDATE_ANIMATION);
176 // number of outstanding pause requests has dropped 185 if (update_type == HIDDEN_UPDATE)
177 // to the initial one
178 if (mMotionController.isPaused() &&
179 (force_update || mPauseRequest->getNumRefs() == 1))
180 { 186 {
181 mMotionController.unpause(); 187 mMotionController.updateMotionsMinimal();
182 } 188 }
183 189 else
184 mMotionController.updateMotion();
185
186 // pause once again, after forced update, if there are outstanding
187 // pause requests
188 if (force_update && mPauseRequest->getNumRefs() > 1)
189 { 190 {
190 mMotionController.pause(); 191 // unpause if the number of outstanding pause requests has dropped to the initial one
192 if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1)
193 {
194 mMotionController.unpauseAllMotions();
195 }
196 bool force_update = (update_type == FORCE_UPDATE);
197 mMotionController.updateMotions(force_update);
191 } 198 }
192} 199}
193 200
@@ -499,7 +506,7 @@ void LLCharacter::updateVisualParams()
499 506
500LLAnimPauseRequest LLCharacter::requestPause() 507LLAnimPauseRequest LLCharacter::requestPause()
501{ 508{
502 mMotionController.pause(); 509 mMotionController.pauseAllMotions();
503 return mPauseRequest; 510 return mPauseRequest;
504} 511}
505 512
diff --git a/linden/indra/llcharacter/llcharacter.h b/linden/indra/llcharacter/llcharacter.h
index 7a841ef..ba807bc 100644
--- a/linden/indra/llcharacter/llcharacter.h
+++ b/linden/indra/llcharacter/llcharacter.h
@@ -137,13 +137,16 @@ public:
137 //------------------------------------------------------------------------- 137 //-------------------------------------------------------------------------
138 // registers a motion with the character 138 // registers a motion with the character
139 // returns true if successfull 139 // returns true if successfull
140 BOOL addMotion( const LLUUID& id, LLMotionConstructor create ); 140 BOOL registerMotion( const LLUUID& id, LLMotionConstructor create );
141 141
142 void removeMotion( const LLUUID& id ); 142 void removeMotion( const LLUUID& id );
143 143
144 // returns an instance of a registered motion 144 // returns an instance of a registered motion, creating one if necessary
145 LLMotion* createMotion( const LLUUID &id ); 145 LLMotion* createMotion( const LLUUID &id );
146 146
147 // returns an existing instance of a registered motion
148 LLMotion* findMotion( const LLUUID &id );
149
147 // start a motion 150 // start a motion
148 // returns true if successful, false if an error occurred 151 // returns true if successful, false if an error occurred
149 virtual BOOL startMotion( const LLUUID& id, F32 start_offset = 0.f); 152 virtual BOOL startMotion( const LLUUID& id, F32 start_offset = 0.f);
@@ -161,12 +164,16 @@ public:
161 virtual void requestStopMotion( LLMotion* motion ); 164 virtual void requestStopMotion( LLMotion* motion );
162 165
163 // periodic update function, steps the motion controller 166 // periodic update function, steps the motion controller
164 void updateMotion(BOOL force_update = FALSE); 167 enum e_update_t { NORMAL_UPDATE, HIDDEN_UPDATE, FORCE_UPDATE };
168 void updateMotions(e_update_t update_type);
165 169
166 LLAnimPauseRequest requestPause(); 170 LLAnimPauseRequest requestPause();
167 BOOL areAnimationsPaused() { return mMotionController.isPaused(); } 171 BOOL areAnimationsPaused() { return mMotionController.isPaused(); }
168 void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); } 172 void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); }
169 void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); } 173 void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); }
174
175 LLMotionController& getMotionController() { return mMotionController; }
176
170 // Releases all motion instances which should result in 177 // Releases all motion instances which should result in
171 // no cached references to character joint data. This is 178 // no cached references to character joint data. This is
172 // useful if a character wants to rebuild it's skeleton. 179 // useful if a character wants to rebuild it's skeleton.
diff --git a/linden/indra/llcharacter/llkeyframemotion.cpp b/linden/indra/llcharacter/llkeyframemotion.cpp
index 0138860..34decd6 100644
--- a/linden/indra/llcharacter/llkeyframemotion.cpp
+++ b/linden/indra/llcharacter/llkeyframemotion.cpp
@@ -1977,9 +1977,8 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
1977 1977
1978 LLCharacter* character = *char_iter; 1978 LLCharacter* character = *char_iter;
1979 1979
1980 // create an instance of this motion (it may or may not already exist) 1980 // look for an existing instance of this motion
1981 LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->createMotion(asset_uuid); 1981 LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->findMotion(asset_uuid);
1982
1983 if (motionp) 1982 if (motionp)
1984 { 1983 {
1985 if (0 == status) 1984 if (0 == status)
@@ -2008,7 +2007,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
2008 motionp->mAssetStatus = ASSET_FETCH_FAILED; 2007 motionp->mAssetStatus = ASSET_FETCH_FAILED;
2009 } 2008 }
2010 2009
2011 delete []buffer; 2010 delete[] buffer;
2012 } 2011 }
2013 else 2012 else
2014 { 2013 {
@@ -2018,8 +2017,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
2018 } 2017 }
2019 else 2018 else
2020 { 2019 {
2021 // motionp is NULL 2020 llwarns << "No existing motion for asset data. UUID: " << asset_uuid << llendl;
2022 llwarns << "Failed to createMotion() for asset UUID " << asset_uuid << llendl;
2023 } 2021 }
2024} 2022}
2025 2023
diff --git a/linden/indra/llcharacter/llkeyframemotionparam.cpp b/linden/indra/llcharacter/llkeyframemotionparam.cpp
index 106c02c..0e7388c 100644
--- a/linden/indra/llcharacter/llkeyframemotionparam.cpp
+++ b/linden/indra/llcharacter/llkeyframemotionparam.cpp
@@ -76,7 +76,7 @@ LLKeyframeMotionParam::~LLKeyframeMotionParam()
76 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) 76 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
77 { 77 {
78 const ParameterizedMotion& paramMotion = *iter2; 78 const ParameterizedMotion& paramMotion = *iter2;
79 delete paramMotion.first; // note - deletes the structure; ParameterizedMotion pair remains intact 79 delete paramMotion.mMotion;
80 } 80 }
81 motionList.clear(); 81 motionList.clear();
82 } 82 }
@@ -102,32 +102,32 @@ LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *ch
102 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) 102 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
103 { 103 {
104 const ParameterizedMotion& paramMotion = *iter2; 104 const ParameterizedMotion& paramMotion = *iter2;
105 LLMotion* motion = paramMotion.mMotion;
106 motion->onInitialize(character);
105 107
106 paramMotion.first->onInitialize(character); 108 if (motion->getDuration() > mEaseInDuration)
107
108 if (paramMotion.first->getDuration() > mEaseInDuration)
109 { 109 {
110 mEaseInDuration = paramMotion.first->getEaseInDuration(); 110 mEaseInDuration = motion->getEaseInDuration();
111 } 111 }
112 112
113 if (paramMotion.first->getEaseOutDuration() > mEaseOutDuration) 113 if (motion->getEaseOutDuration() > mEaseOutDuration)
114 { 114 {
115 mEaseOutDuration = paramMotion.first->getEaseOutDuration(); 115 mEaseOutDuration = motion->getEaseOutDuration();
116 } 116 }
117 117
118 if (paramMotion.first->getDuration() > mDuration) 118 if (motion->getDuration() > mDuration)
119 { 119 {
120 mDuration = paramMotion.first->getDuration(); 120 mDuration = motion->getDuration();
121 } 121 }
122 122
123 if (paramMotion.first->getPriority() > mPriority) 123 if (motion->getPriority() > mPriority)
124 { 124 {
125 mPriority = paramMotion.first->getPriority(); 125 mPriority = motion->getPriority();
126 } 126 }
127 127
128 LLPose *pose = paramMotion.first->getPose(); 128 LLPose *pose = motion->getPose();
129 129
130 mPoseBlender.addMotion(paramMotion.first); 130 mPoseBlender.addMotion(motion);
131 for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) 131 for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
132 { 132 {
133 LLPose *blendedPose = mPoseBlender.getBlendedPose(); 133 LLPose *blendedPose = mPoseBlender.getBlendedPose();
@@ -151,7 +151,7 @@ BOOL LLKeyframeMotionParam::onActivate()
151 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) 151 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
152 { 152 {
153 const ParameterizedMotion& paramMotion = *iter2; 153 const ParameterizedMotion& paramMotion = *iter2;
154 paramMotion.first->activate(); 154 paramMotion.mMotion->activate(mActivationTimestamp);
155 } 155 }
156 } 156 }
157 return TRUE; 157 return TRUE;
@@ -173,8 +173,8 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
173 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) 173 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
174 { 174 {
175 const ParameterizedMotion& paramMotion = *iter2; 175 const ParameterizedMotion& paramMotion = *iter2;
176// llinfos << "Weight for pose " << paramMotion.first->getName() << " is " << paramMotion.first->getPose()->getWeight() << llendl; 176// llinfos << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << llendl;
177 paramMotion.first->getPose()->setWeight(0.f); 177 paramMotion.mMotion->getPose()->setWeight(0.f);
178 } 178 }
179 } 179 }
180 180
@@ -190,6 +190,7 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
190 continue; 190 continue;
191 } 191 }
192 192
193 // DANGER! Do not modify mParameterizedMotions while using these pointers!
193 const ParameterizedMotion* firstMotion = NULL; 194 const ParameterizedMotion* firstMotion = NULL;
194 const ParameterizedMotion* secondMotion = NULL; 195 const ParameterizedMotion* secondMotion = NULL;
195 196
@@ -197,9 +198,9 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
197 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) 198 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
198 { 199 {
199 const ParameterizedMotion& paramMotion = *iter2; 200 const ParameterizedMotion& paramMotion = *iter2;
200 paramMotion.first->onUpdate(time, joint_mask); 201 paramMotion.mMotion->onUpdate(time, joint_mask);
201 202
202 F32 distToParam = paramMotion.second - *paramValue; 203 F32 distToParam = paramMotion.mParam - *paramValue;
203 204
204 if ( distToParam <= 0.f) 205 if ( distToParam <= 0.f)
205 { 206 {
@@ -227,12 +228,12 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
227 LLPose *secondPose; 228 LLPose *secondPose;
228 229
229 if (firstMotion) 230 if (firstMotion)
230 firstPose = firstMotion->first->getPose(); 231 firstPose = firstMotion->mMotion->getPose();
231 else 232 else
232 firstPose = NULL; 233 firstPose = NULL;
233 234
234 if (secondMotion) 235 if (secondMotion)
235 secondPose = secondMotion->first->getPose(); 236 secondPose = secondMotion->mMotion->getPose();
236 else 237 else
237 secondPose = NULL; 238 secondPose = NULL;
238 239
@@ -243,7 +244,7 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
243 { 244 {
244 firstPose->setWeight(weightFactor); 245 firstPose->setWeight(weightFactor);
245 } 246 }
246 else if (firstMotion->second == secondMotion->second) 247 else if (firstMotion->mParam == secondMotion->mParam)
247 { 248 {
248 firstPose->setWeight(0.5f * weightFactor); 249 firstPose->setWeight(0.5f * weightFactor);
249 secondPose->setWeight(0.5f * weightFactor); 250 secondPose->setWeight(0.5f * weightFactor);
@@ -251,8 +252,8 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
251 else 252 else
252 { 253 {
253 F32 first_weight = 1.f - 254 F32 first_weight = 1.f -
254 ((llclamp(*paramValue - firstMotion->second, 0.f, (secondMotion->second - firstMotion->second))) / 255 ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) /
255 (secondMotion->second - firstMotion->second)); 256 (secondMotion->mParam - firstMotion->mParam));
256 first_weight = llclamp(first_weight, 0.f, 1.f); 257 first_weight = llclamp(first_weight, 0.f, 1.f);
257 258
258 F32 second_weight = 1.f - first_weight; 259 F32 second_weight = 1.f - first_weight;
@@ -290,7 +291,7 @@ void LLKeyframeMotionParam::onDeactivate()
290 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) 291 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
291 { 292 {
292 const ParameterizedMotion& paramMotion = *iter2; 293 const ParameterizedMotion& paramMotion = *iter2;
293 paramMotion.first->onDeactivate(); 294 paramMotion.mMotion->onDeactivate();
294 } 295 }
295 } 296 }
296} 297}
@@ -328,9 +329,9 @@ void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name)
328 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) 329 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
329 { 330 {
330 const ParameterizedMotion& paramMotion = *iter2; 331 const ParameterizedMotion& paramMotion = *iter2;
331 if (paramMotion.first->getName() == name) 332 if (paramMotion.mMotion->getName() == name)
332 { 333 {
333 mDefaultKeyframeMotion = paramMotion.first; 334 mDefaultKeyframeMotion = paramMotion.mMotion;
334 } 335 }
335 } 336 }
336 } 337 }
diff --git a/linden/indra/llcharacter/llkeyframemotionparam.h b/linden/indra/llcharacter/llkeyframemotionparam.h
index f509e6a..0d17141 100644
--- a/linden/indra/llcharacter/llkeyframemotionparam.h
+++ b/linden/indra/llcharacter/llkeyframemotionparam.h
@@ -126,7 +126,12 @@ protected:
126 //------------------------------------------------------------------------- 126 //-------------------------------------------------------------------------
127 // new functions defined by this subclass 127 // new functions defined by this subclass
128 //------------------------------------------------------------------------- 128 //-------------------------------------------------------------------------
129 typedef std::pair<LLMotion*, F32> ParameterizedMotion; 129 struct ParameterizedMotion
130 {
131 ParameterizedMotion(LLMotion* motion, F32 param) : mMotion(motion), mParam(param) {}
132 LLMotion* mMotion;
133 F32 mParam;
134 };
130 135
131 // add a motion and associated parameter triplet 136 // add a motion and associated parameter triplet
132 BOOL addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value); 137 BOOL addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value);
@@ -134,8 +139,6 @@ protected:
134 // set default motion for LOD and retrieving blend constants 139 // set default motion for LOD and retrieving blend constants
135 void setDefaultKeyframeMotion(char *); 140 void setDefaultKeyframeMotion(char *);
136 141
137 static BOOL sortFunc(ParameterizedMotion *new_motion, ParameterizedMotion *tested_motion);
138
139 BOOL loadMotions(); 142 BOOL loadMotions();
140 143
141protected: 144protected:
@@ -147,10 +150,10 @@ protected:
147 { 150 {
148 bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const 151 bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const
149 { 152 {
150 if (a.second != b.second) 153 if (a.mParam != b.mParam)
151 return (a.second < b.second); 154 return (a.mParam < b.mParam);
152 else 155 else
153 return a.first < b.first; 156 return a.mMotion < b.mMotion;
154 } 157 }
155 }; 158 };
156 159
diff --git a/linden/indra/llcharacter/llmotion.cpp b/linden/indra/llcharacter/llmotion.cpp
index f7b8f1f..54fcaa5 100644
--- a/linden/indra/llcharacter/llmotion.cpp
+++ b/linden/indra/llcharacter/llmotion.cpp
@@ -127,6 +127,13 @@ void LLMotion::setDeactivateCallback( void (*cb)(void *), void* userdata )
127 mDeactivateCallbackUserData = userdata; 127 mDeactivateCallbackUserData = userdata;
128} 128}
129 129
130//virtual
131void LLMotion::setStopTime(F32 time)
132{
133 mStopTimestamp = time;
134 mStopped = TRUE;
135}
136
130BOOL LLMotion::isBlending() 137BOOL LLMotion::isBlending()
131{ 138{
132 return mPose.getWeight() < 1.f; 139 return mPose.getWeight() < 1.f;
@@ -135,8 +142,9 @@ BOOL LLMotion::isBlending()
135//----------------------------------------------------------------------------- 142//-----------------------------------------------------------------------------
136// activate() 143// activate()
137//----------------------------------------------------------------------------- 144//-----------------------------------------------------------------------------
138void LLMotion::activate() 145void LLMotion::activate(F32 time)
139{ 146{
147 mActivationTimestamp = time;
140 mStopped = FALSE; 148 mStopped = FALSE;
141 mActive = TRUE; 149 mActive = TRUE;
142 onActivate(); 150 onActivate();
@@ -150,7 +158,12 @@ void LLMotion::deactivate()
150 mActive = FALSE; 158 mActive = FALSE;
151 mPose.setWeight(0.f); 159 mPose.setWeight(0.f);
152 160
153 if (mDeactivateCallback) (*mDeactivateCallback)(mDeactivateCallbackUserData); 161 if (mDeactivateCallback)
162 {
163 (*mDeactivateCallback)(mDeactivateCallbackUserData);
164 mDeactivateCallback = NULL; // only call callback once
165 mDeactivateCallbackUserData = NULL;
166 }
154 167
155 onDeactivate(); 168 onDeactivate();
156} 169}
diff --git a/linden/indra/llcharacter/llmotion.h b/linden/indra/llcharacter/llmotion.h
index c7bb55d..5a622a8 100644
--- a/linden/indra/llcharacter/llmotion.h
+++ b/linden/indra/llcharacter/llmotion.h
@@ -48,6 +48,8 @@ class LLCharacter;
48//----------------------------------------------------------------------------- 48//-----------------------------------------------------------------------------
49class LLMotion 49class LLMotion
50{ 50{
51 friend class LLMotionController;
52
51public: 53public:
52 typedef enum LLMotionBlendType 54 typedef enum LLMotionBlendType
53 { 55 {
@@ -73,10 +75,6 @@ public:
73 // functions to support MotionController and MotionRegistry 75 // functions to support MotionController and MotionRegistry
74 //------------------------------------------------------------------------- 76 //-------------------------------------------------------------------------
75 77
76 // static constructor
77 // all subclasses must implement such a function and register it
78 static LLMotion *create(const LLUUID &id) { return NULL; }
79
80 // get the name of this instance 78 // get the name of this instance
81 const std::string &getName() const { return mName; } 79 const std::string &getName() const { return mName; }
82 80
@@ -96,7 +94,7 @@ public:
96 94
97 F32 getStopTime() const { return mStopTimestamp; } 95 F32 getStopTime() const { return mStopTimestamp; }
98 96
99 virtual void setStopTime(F32 time) { mStopTimestamp = time; mStopped = TRUE; } 97 virtual void setStopTime(F32 time);
100 98
101 BOOL isStopped() const { return mStopped; } 99 BOOL isStopped() const { return mStopped; }
102 100
@@ -104,12 +102,18 @@ public:
104 102
105 BOOL isBlending(); 103 BOOL isBlending();
106 104
107 void activate(); 105 // Activation functions.
108 106 // It is OK for other classes to activate a motion,
107 // but only the controller can deactivate it.
108 // Thus, if mActive == TRUE, the motion *may* be on the controllers active list,
109 // but if mActive == FALSE, the motion is gauranteed not to be on the active list.
110protected:
111 // Used by LLMotionController only
109 void deactivate(); 112 void deactivate();
110
111 BOOL isActive() { return mActive; } 113 BOOL isActive() { return mActive; }
112 114public:
115 void activate(F32 time);
116
113public: 117public:
114 //------------------------------------------------------------------------- 118 //-------------------------------------------------------------------------
115 // animation callbacks to be implemented by subclasses 119 // animation callbacks to be implemented by subclasses
@@ -170,14 +174,13 @@ protected:
170 BOOL mStopped; // motion has been stopped; 174 BOOL mStopped; // motion has been stopped;
171 BOOL mActive; // motion is on active list (can be stopped or not stopped) 175 BOOL mActive; // motion is on active list (can be stopped or not stopped)
172 176
173public:
174 //------------------------------------------------------------------------- 177 //-------------------------------------------------------------------------
175 // these are set implicitly by the motion controller and 178 // these are set implicitly by the motion controller and
176 // may be referenced (read only) in the above handlers. 179 // may be referenced (read only) in the above handlers.
177 //------------------------------------------------------------------------- 180 //-------------------------------------------------------------------------
178 std::string mName; // instance name assigned by motion controller 181 std::string mName; // instance name assigned by motion controller
179 LLUUID mID; 182 LLUUID mID;
180 183
181 F32 mActivationTimestamp; // time when motion was activated 184 F32 mActivationTimestamp; // time when motion was activated
182 F32 mStopTimestamp; // time when motion was told to stop 185 F32 mStopTimestamp; // time when motion was told to stop
183 F32 mSendStopTimestamp; // time when simulator should be told to stop this motion 186 F32 mSendStopTimestamp; // time when simulator should be told to stop this motion
diff --git a/linden/indra/llcharacter/llmotioncontroller.cpp b/linden/indra/llcharacter/llmotioncontroller.cpp
index 028cf22..90a3d74 100644
--- a/linden/indra/llcharacter/llmotioncontroller.cpp
+++ b/linden/indra/llcharacter/llmotioncontroller.cpp
@@ -34,6 +34,8 @@
34//----------------------------------------------------------------------------- 34//-----------------------------------------------------------------------------
35#include "linden_common.h" 35#include "linden_common.h"
36 36
37#include "llmemtype.h"
38
37#include "llmotioncontroller.h" 39#include "llmotioncontroller.h"
38#include "llkeyframemotion.h" 40#include "llkeyframemotion.h"
39#include "llmath.h" 41#include "llmath.h"
@@ -50,32 +52,6 @@ const U32 MAX_MOTION_INSTANCES = 32;
50LLMotionRegistry LLMotionController::sRegistry; 52LLMotionRegistry LLMotionController::sRegistry;
51 53
52//----------------------------------------------------------------------------- 54//-----------------------------------------------------------------------------
53// LLMotionTableEntry()
54//-----------------------------------------------------------------------------
55LLMotionTableEntry::LLMotionTableEntry()
56{
57 mConstructor = NULL;
58 mID.setNull();
59}
60
61LLMotionTableEntry::LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id)
62 : mConstructor(constructor), mID(id)
63{
64
65}
66
67//-----------------------------------------------------------------------------
68// create()
69//-----------------------------------------------------------------------------
70LLMotion* LLMotionTableEntry::create(const LLUUID &id)
71{
72 LLMotion* motionp = mConstructor(id);
73
74 return motionp;
75}
76
77
78//-----------------------------------------------------------------------------
79//----------------------------------------------------------------------------- 55//-----------------------------------------------------------------------------
80// LLMotionRegistry class 56// LLMotionRegistry class
81//----------------------------------------------------------------------------- 57//-----------------------------------------------------------------------------
@@ -85,7 +61,7 @@ LLMotion* LLMotionTableEntry::create(const LLUUID &id)
85// LLMotionRegistry() 61// LLMotionRegistry()
86// Class Constructor 62// Class Constructor
87//----------------------------------------------------------------------------- 63//-----------------------------------------------------------------------------
88LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, LLMotionTableEntry()) 64LLMotionRegistry::LLMotionRegistry()
89{ 65{
90 66
91} 67}
@@ -97,19 +73,19 @@ LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq,
97//----------------------------------------------------------------------------- 73//-----------------------------------------------------------------------------
98LLMotionRegistry::~LLMotionRegistry() 74LLMotionRegistry::~LLMotionRegistry()
99{ 75{
100 mMotionTable.removeAll(); 76 mMotionTable.clear();
101} 77}
102 78
103 79
104//----------------------------------------------------------------------------- 80//-----------------------------------------------------------------------------
105// addMotion() 81// addMotion()
106//----------------------------------------------------------------------------- 82//-----------------------------------------------------------------------------
107BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor constructor ) 83BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor )
108{ 84{
109// llinfos << "Registering motion: " << name << llendl; 85 // llinfos << "Registering motion: " << name << llendl;
110 if (!mMotionTable.check(id)) 86 if (!is_in_map(mMotionTable, id))
111 { 87 {
112 mMotionTable.set(id, LLMotionTableEntry(constructor, id)); 88 mMotionTable[id] = constructor;
113 return TRUE; 89 return TRUE;
114 } 90 }
115 91
@@ -121,7 +97,7 @@ BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor construc
121//----------------------------------------------------------------------------- 97//-----------------------------------------------------------------------------
122void LLMotionRegistry::markBad( const LLUUID& id ) 98void LLMotionRegistry::markBad( const LLUUID& id )
123{ 99{
124 mMotionTable.set(id, LLMotionTableEntry()); 100 mMotionTable[id] = LLMotionConstructor(NULL);
125} 101}
126 102
127//----------------------------------------------------------------------------- 103//-----------------------------------------------------------------------------
@@ -129,17 +105,17 @@ void LLMotionRegistry::markBad( const LLUUID& id )
129//----------------------------------------------------------------------------- 105//-----------------------------------------------------------------------------
130LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) 106LLMotion *LLMotionRegistry::createMotion( const LLUUID &id )
131{ 107{
132 LLMotionTableEntry motion_entry = mMotionTable.get(id); 108 LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL));
133 LLMotion* motion = NULL; 109 LLMotion* motion = NULL;
134 110
135 if ( motion_entry.getID().isNull() ) 111 if ( constructor == NULL )
136 { 112 {
137 // *FIX: need to replace with a better default scheme. RN 113 // *FIX: need to replace with a better default scheme. RN
138 motion = LLKeyframeMotion::create(id); 114 motion = LLKeyframeMotion::create(id);
139 } 115 }
140 else 116 else
141 { 117 {
142 motion = motion_entry.create(id); 118 motion = constructor(id);
143 } 119 }
144 120
145 return motion; 121 return motion;
@@ -155,18 +131,19 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id )
155// LLMotionController() 131// LLMotionController()
156// Class Constructor 132// Class Constructor
157//----------------------------------------------------------------------------- 133//-----------------------------------------------------------------------------
158LLMotionController::LLMotionController( ) 134LLMotionController::LLMotionController()
135 : mTimeFactor(1.f),
136 mCharacter(NULL),
137 mAnimTime(0.f),
138 mPrevTimerElapsed(0.f),
139 mLastTime(0.0f),
140 mHasRunOnce(FALSE),
141 mPaused(FALSE),
142 mPauseTime(0.f),
143 mTimeStep(0.f),
144 mTimeStepCount(0),
145 mLastInterp(0.f)
159{ 146{
160 mTime = 0.f;
161 mTimeOffset = 0.f;
162 mLastTime = 0.0f;
163 mHasRunOnce = FALSE;
164 mPaused = FALSE;
165 mPauseTime = 0.f;
166 mTimeStep = 0.f;
167 mTimeStepCount = 0;
168 mLastInterp = 0.f;
169 mTimeFactor = 1.f;
170} 147}
171 148
172 149
@@ -179,6 +156,15 @@ LLMotionController::~LLMotionController()
179 deleteAllMotions(); 156 deleteAllMotions();
180} 157}
181 158
159void LLMotionController::incMotionCounts(S32& num_motions, S32& num_loading_motions, S32& num_loaded_motions, S32& num_active_motions, S32& num_deprecated_motions)
160{
161 num_motions += mAllMotions.size();
162 num_loading_motions += mLoadingMotions.size();
163 num_loaded_motions += mLoadedMotions.size();
164 num_active_motions += mActiveMotions.size();
165 num_deprecated_motions += mDeprecatedMotions.size();
166}
167
182//----------------------------------------------------------------------------- 168//-----------------------------------------------------------------------------
183// deleteAllMotions() 169// deleteAllMotions()
184//----------------------------------------------------------------------------- 170//-----------------------------------------------------------------------------
@@ -193,24 +179,38 @@ void LLMotionController::deleteAllMotions()
193} 179}
194 180
195//----------------------------------------------------------------------------- 181//-----------------------------------------------------------------------------
196// addLoadedMotion() 182// purgeExcessMotion()
197//----------------------------------------------------------------------------- 183//-----------------------------------------------------------------------------
198void LLMotionController::addLoadedMotion(LLMotion* motionp) 184void LLMotionController::purgeExcessMotions()
199{ 185{
200 std::set<LLUUID> motions_to_kill; 186 if (mLoadedMotions.size() > MAX_MOTION_INSTANCES)
187 {
188 // clean up deprecated motions
189 for (motion_set_t::iterator deprecated_motion_it = mDeprecatedMotions.begin();
190 deprecated_motion_it != mDeprecatedMotions.end(); )
191 {
192 motion_set_t::iterator cur_iter = deprecated_motion_it++;
193 LLMotion* cur_motionp = *cur_iter;
194 if (!isMotionActive(cur_motionp))
195 {
196 // Motion is deprecated so we know it's not cannonical,
197 // we can safely remove the instance
198 removeMotionInstance(cur_motionp); // modifies mDeprecatedMotions
199 mDeprecatedMotions.erase(cur_iter);
200 }
201 }
202 }
201 203
202 // gather all inactive, loaded motions 204 std::set<LLUUID> motions_to_kill;
203 if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) 205 if (mLoadedMotions.size() > MAX_MOTION_INSTANCES)
204 { 206 {
205 // too many motions active this frame, kill all blenders 207 // too many motions active this frame, kill all blenders
206 mPoseBlender.clearBlenders(); 208 mPoseBlender.clearBlenders();
207 209 for (motion_set_t::iterator loaded_motion_it = mLoadedMotions.begin();
208 for (motion_list_t::iterator loaded_motion_it = mLoadedMotions.begin(); 210 loaded_motion_it != mLoadedMotions.end();
209 loaded_motion_it != mLoadedMotions.end(); 211 ++loaded_motion_it)
210 ++loaded_motion_it)
211 { 212 {
212 LLMotion* cur_motionp = *loaded_motion_it; 213 LLMotion* cur_motionp = *loaded_motion_it;
213
214 // motion isn't playing, delete it 214 // motion isn't playing, delete it
215 if (!isMotionActive(cur_motionp)) 215 if (!isMotionActive(cur_motionp))
216 { 216 {
@@ -218,7 +218,7 @@ void LLMotionController::addLoadedMotion(LLMotion* motionp)
218 } 218 }
219 } 219 }
220 } 220 }
221 221
222 // clean up all inactive, loaded motions 222 // clean up all inactive, loaded motions
223 for (std::set<LLUUID>::iterator motion_it = motions_to_kill.begin(); 223 for (std::set<LLUUID>::iterator motion_it = motions_to_kill.begin();
224 motion_it != motions_to_kill.end(); 224 motion_it != motions_to_kill.end();
@@ -234,8 +234,28 @@ void LLMotionController::addLoadedMotion(LLMotion* motionp)
234 } 234 }
235 } 235 }
236 236
237 // add new motion to loaded list 237 if (mLoadedMotions.size() > 2*MAX_MOTION_INSTANCES)
238 mLoadedMotions.push_back(motionp); 238 {
239 LL_WARNS_ONCE("Animation") << "> " << 2*MAX_MOTION_INSTANCES << " Loaded Motions" << llendl;
240 }
241}
242
243//-----------------------------------------------------------------------------
244// deactivateStoppedMotions()
245//-----------------------------------------------------------------------------
246void LLMotionController::deactivateStoppedMotions()
247{
248 // Since we're hidden, deactivate any stopped motions.
249 for (motion_list_t::iterator iter = mActiveMotions.begin();
250 iter != mActiveMotions.end(); )
251 {
252 motion_list_t::iterator curiter = iter++;
253 LLMotion* motionp = *curiter;
254 if (motionp->isStopped())
255 {
256 deactivateMotionInstance(motionp);
257 }
258 }
239} 259}
240 260
241//----------------------------------------------------------------------------- 261//-----------------------------------------------------------------------------
@@ -252,9 +272,10 @@ void LLMotionController::setTimeStep(F32 step)
252 iter != mActiveMotions.end(); ++iter) 272 iter != mActiveMotions.end(); ++iter)
253 { 273 {
254 LLMotion* motionp = *iter; 274 LLMotion* motionp = *iter;
255 motionp->mActivationTimestamp = (F32)llfloor(motionp->mActivationTimestamp / step) * step; 275 F32 activation_time = motionp->mActivationTimestamp;
276 motionp->mActivationTimestamp = (F32)(llfloor(activation_time / step)) * step;
256 BOOL stopped = motionp->isStopped(); 277 BOOL stopped = motionp->isStopped();
257 motionp->setStopTime((F32)llfloor(motionp->getStopTime() / step) * step); 278 motionp->setStopTime((F32)(llfloor(motionp->getStopTime() / step)) * step);
258 motionp->setStopped(stopped); 279 motionp->setStopped(stopped);
259 motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step; 280 motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step;
260 } 281 }
@@ -266,7 +287,6 @@ void LLMotionController::setTimeStep(F32 step)
266//----------------------------------------------------------------------------- 287//-----------------------------------------------------------------------------
267void LLMotionController::setTimeFactor(F32 time_factor) 288void LLMotionController::setTimeFactor(F32 time_factor)
268{ 289{
269 mTimeOffset += mTimer.getElapsedTimeAndResetF32() * mTimeFactor;
270 mTimeFactor = time_factor; 290 mTimeFactor = time_factor;
271} 291}
272 292
@@ -280,11 +300,11 @@ void LLMotionController::setCharacter(LLCharacter *character)
280 300
281 301
282//----------------------------------------------------------------------------- 302//-----------------------------------------------------------------------------
283// addMotion() 303// registerMotion()
284//----------------------------------------------------------------------------- 304//-----------------------------------------------------------------------------
285BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constructor ) 305BOOL LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor constructor )
286{ 306{
287 return sRegistry.addMotion(id, constructor); 307 return sRegistry.registerMotion(id, constructor);
288} 308}
289 309
290//----------------------------------------------------------------------------- 310//-----------------------------------------------------------------------------
@@ -293,10 +313,8 @@ BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constr
293void LLMotionController::removeMotion( const LLUUID& id) 313void LLMotionController::removeMotion( const LLUUID& id)
294{ 314{
295 LLMotion* motionp = findMotion(id); 315 LLMotion* motionp = findMotion(id);
296
297 removeMotionInstance(motionp);
298
299 mAllMotions.erase(id); 316 mAllMotions.erase(id);
317 removeMotionInstance(motionp);
300} 318}
301 319
302// removes instance of a motion from all runtime structures, but does 320// removes instance of a motion from all runtime structures, but does
@@ -306,10 +324,11 @@ void LLMotionController::removeMotionInstance(LLMotion* motionp)
306{ 324{
307 if (motionp) 325 if (motionp)
308 { 326 {
309 stopMotionInstance(motionp, TRUE); 327 llassert(findMotion(motionp->getID()) != motionp);
310 328 if (motionp->isActive())
329 motionp->deactivate();
311 mLoadingMotions.erase(motionp); 330 mLoadingMotions.erase(motionp);
312 mLoadedMotions.remove(motionp); 331 mLoadedMotions.erase(motionp);
313 mActiveMotions.remove(motionp); 332 mActiveMotions.remove(motionp);
314 delete motionp; 333 delete motionp;
315 } 334 }
@@ -320,6 +339,7 @@ void LLMotionController::removeMotionInstance(LLMotion* motionp)
320//----------------------------------------------------------------------------- 339//-----------------------------------------------------------------------------
321LLMotion* LLMotionController::createMotion( const LLUUID &id ) 340LLMotion* LLMotionController::createMotion( const LLUUID &id )
322{ 341{
342 LLMemType mt(LLMemType::MTYPE_ANIMATION);
323 // do we have an instance of this motion for this character? 343 // do we have an instance of this motion for this character?
324 LLMotion *motion = findMotion(id); 344 LLMotion *motion = findMotion(id);
325 345
@@ -353,8 +373,8 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id )
353 mLoadingMotions.insert(motion); 373 mLoadingMotions.insert(motion);
354 break; 374 break;
355 case LLMotion::STATUS_SUCCESS: 375 case LLMotion::STATUS_SUCCESS:
356 // add motion to our list 376 // add motion to our list
357 addLoadedMotion(motion); 377 mLoadedMotions.insert(motion);
358 break; 378 break;
359 default: 379 default:
360 llerrs << "Invalid initialization status" << llendl; 380 llerrs << "Invalid initialization status" << llendl;
@@ -377,6 +397,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset)
377 // motion that is stopping will be allowed to stop but 397 // motion that is stopping will be allowed to stop but
378 // replaced by a new instance of that motion 398 // replaced by a new instance of that motion
379 if (motion 399 if (motion
400 && !mPaused
380 && motion->canDeprecate() 401 && motion->canDeprecate()
381 && motion->getFadeWeight() > 0.01f // not LOD-ed out 402 && motion->getFadeWeight() > 0.01f // not LOD-ed out
382 && (motion->isBlending() || motion->getStopTime() != 0.f)) 403 && (motion->isBlending() || motion->getStopTime() != 0.f))
@@ -403,7 +424,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset)
403 } 424 }
404 425
405// llinfos << "Starting motion " << name << llendl; 426// llinfos << "Starting motion " << name << llendl;
406 return activateMotionInstance(motion, mTime - start_offset); 427 return activateMotionInstance(motion, mAnimTime - start_offset);
407} 428}
408 429
409 430
@@ -414,7 +435,6 @@ BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate
414{ 435{
415 // if already inactive, return false 436 // if already inactive, return false
416 LLMotion *motion = findMotion(id); 437 LLMotion *motion = findMotion(id);
417
418 return stopMotionInstance(motion, stop_immediate); 438 return stopMotionInstance(motion, stop_immediate);
419} 439}
420 440
@@ -428,12 +448,7 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat
428 // If on active list, stop it 448 // If on active list, stop it
429 if (isMotionActive(motion) && !motion->isStopped()) 449 if (isMotionActive(motion) && !motion->isStopped())
430 { 450 {
431 // when using timesteps, set stop time to last frame's time, otherwise grab current timer value 451 motion->setStopTime(mAnimTime);
432 // *FIX: should investigate this inconsistency...hints of obscure bugs
433
434 F32 stop_time = (mTimeStep != 0.f || mPaused) ? (mTime) : mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor);
435 motion->setStopTime(stop_time);
436
437 if (stop_immediate) 452 if (stop_immediate)
438 { 453 {
439 deactivateMotionInstance(motion); 454 deactivateMotionInstance(motion);
@@ -449,7 +464,6 @@ BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediat
449 return FALSE; 464 return FALSE;
450} 465}
451 466
452
453//----------------------------------------------------------------------------- 467//-----------------------------------------------------------------------------
454// updateRegularMotions() 468// updateRegularMotions()
455//----------------------------------------------------------------------------- 469//-----------------------------------------------------------------------------
@@ -476,6 +490,59 @@ void LLMotionController::resetJointSignatures()
476} 490}
477 491
478//----------------------------------------------------------------------------- 492//-----------------------------------------------------------------------------
493// updateIdleMotion()
494// minimal updates for active motions
495//-----------------------------------------------------------------------------
496void LLMotionController::updateIdleMotion(LLMotion* motionp)
497{
498 if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration())
499 {
500 deactivateMotionInstance(motionp);
501 }
502 else if (motionp->isStopped() && mAnimTime > motionp->getStopTime())
503 {
504 // is this the first iteration in the ease out phase?
505 if (mLastTime <= motionp->getStopTime())
506 {
507 // store residual weight for this motion
508 motionp->mResidualWeight = motionp->getPose()->getWeight();
509 }
510 }
511 else if (mAnimTime > motionp->mSendStopTimestamp)
512 {
513 // notify character of timed stop event on first iteration past sendstoptimestamp
514 // this will only be called when an animation stops itself (runs out of time)
515 if (mLastTime <= motionp->mSendStopTimestamp)
516 {
517 mCharacter->requestStopMotion( motionp );
518 stopMotionInstance(motionp, FALSE);
519 }
520 }
521 else if (mAnimTime >= motionp->mActivationTimestamp)
522 {
523 if (mLastTime < motionp->mActivationTimestamp)
524 {
525 motionp->mResidualWeight = motionp->getPose()->getWeight();
526 }
527 }
528}
529
530//-----------------------------------------------------------------------------
531// updateIdleActiveMotions()
532// Call this instead of updateMotionsByType for hidden avatars
533//-----------------------------------------------------------------------------
534void LLMotionController::updateIdleActiveMotions()
535{
536 for (motion_list_t::iterator iter = mActiveMotions.begin();
537 iter != mActiveMotions.end(); )
538 {
539 motion_list_t::iterator curiter = iter++;
540 LLMotion* motionp = *curiter;
541 updateIdleMotion(motionp);
542 }
543}
544
545//-----------------------------------------------------------------------------
479// updateMotionsByType() 546// updateMotionsByType()
480//----------------------------------------------------------------------------- 547//-----------------------------------------------------------------------------
481void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) 548void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type)
@@ -530,36 +597,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
530 597
531 if (!update_motion) 598 if (!update_motion)
532 { 599 {
533 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) 600 updateIdleMotion(motionp);
534 {
535 deactivateMotionInstance(motionp);
536 }
537 else if (motionp->isStopped() && mTime > motionp->getStopTime())
538 {
539 // is this the first iteration in the ease out phase?
540 if (mLastTime <= motionp->getStopTime())
541 {
542 // store residual weight for this motion
543 motionp->mResidualWeight = motionp->getPose()->getWeight();
544 }
545 }
546 else if (mTime > motionp->mSendStopTimestamp)
547 {
548 // notify character of timed stop event on first iteration past sendstoptimestamp
549 // this will only be called when an animation stops itself (runs out of time)
550 if (mLastTime <= motionp->mSendStopTimestamp)
551 {
552 mCharacter->requestStopMotion( motionp );
553 stopMotionInstance(motionp, FALSE);
554 }
555 }
556 else if (mTime >= motionp->mActivationTimestamp)
557 {
558 if (mLastTime < motionp->mActivationTimestamp)
559 {
560 motionp->mResidualWeight = motionp->getPose()->getWeight();
561 }
562 }
563 continue; 601 continue;
564 } 602 }
565 603
@@ -571,7 +609,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
571 motionp->fadeOut(); 609 motionp->fadeOut();
572 610
573 //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic) 611 //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic)
574 if (mTime > motionp->mSendStopTimestamp) 612 if (mAnimTime > motionp->mSendStopTimestamp)
575 { 613 {
576 // notify character of timed stop event on first iteration past sendstoptimestamp 614 // notify character of timed stop event on first iteration past sendstoptimestamp
577 // this will only be called when an animation stops itself (runs out of time) 615 // this will only be called when an animation stops itself (runs out of time)
@@ -584,7 +622,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
584 622
585 if (motionp->getFadeWeight() < 0.01f) 623 if (motionp->getFadeWeight() < 0.01f)
586 { 624 {
587 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) 625 if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration())
588 { 626 {
589 posep->setWeight(0.f); 627 posep->setWeight(0.f);
590 deactivateMotionInstance(motionp); 628 deactivateMotionInstance(motionp);
@@ -600,7 +638,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
600 //********************** 638 //**********************
601 // MOTION INACTIVE 639 // MOTION INACTIVE
602 //********************** 640 //**********************
603 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) 641 if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration())
604 { 642 {
605 // this motion has gone on too long, deactivate it 643 // this motion has gone on too long, deactivate it
606 // did we have a chance to stop it? 644 // did we have a chance to stop it?
@@ -622,7 +660,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
622 //********************** 660 //**********************
623 // MOTION EASE OUT 661 // MOTION EASE OUT
624 //********************** 662 //**********************
625 else if (motionp->isStopped() && mTime > motionp->getStopTime()) 663 else if (motionp->isStopped() && mAnimTime > motionp->getStopTime())
626 { 664 {
627 // is this the first iteration in the ease out phase? 665 // is this the first iteration in the ease out phase?
628 if (mLastTime <= motionp->getStopTime()) 666 if (mLastTime <= motionp->getStopTime())
@@ -637,22 +675,22 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
637 } 675 }
638 else 676 else
639 { 677 {
640 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mTime - motionp->getStopTime()) / motionp->getEaseOutDuration()))); 678 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mAnimTime - motionp->getStopTime()) / motionp->getEaseOutDuration())));
641 } 679 }
642 680
643 // perform motion update 681 // perform motion update
644 update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature); 682 update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
645 } 683 }
646 684
647 //********************** 685 //**********************
648 // MOTION ACTIVE 686 // MOTION ACTIVE
649 //********************** 687 //**********************
650 else if (mTime > motionp->mActivationTimestamp + motionp->getEaseInDuration()) 688 else if (mAnimTime > motionp->mActivationTimestamp + motionp->getEaseInDuration())
651 { 689 {
652 posep->setWeight(motionp->getFadeWeight()); 690 posep->setWeight(motionp->getFadeWeight());
653 691
654 //should we notify the simulator that this motion should be stopped? 692 //should we notify the simulator that this motion should be stopped?
655 if (mTime > motionp->mSendStopTimestamp) 693 if (mAnimTime > motionp->mSendStopTimestamp)
656 { 694 {
657 // notify character of timed stop event on first iteration past sendstoptimestamp 695 // notify character of timed stop event on first iteration past sendstoptimestamp
658 // this will only be called when an animation stops itself (runs out of time) 696 // this will only be called when an animation stops itself (runs out of time)
@@ -664,13 +702,13 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
664 } 702 }
665 703
666 // perform motion update 704 // perform motion update
667 update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature); 705 update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
668 } 706 }
669 707
670 //********************** 708 //**********************
671 // MOTION EASE IN 709 // MOTION EASE IN
672 //********************** 710 //**********************
673 else if (mTime >= motionp->mActivationTimestamp) 711 else if (mAnimTime >= motionp->mActivationTimestamp)
674 { 712 {
675 if (mLastTime < motionp->mActivationTimestamp) 713 if (mLastTime < motionp->mActivationTimestamp)
676 { 714 {
@@ -683,10 +721,10 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
683 else 721 else
684 { 722 {
685 // perform motion update 723 // perform motion update
686 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration())); 724 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mAnimTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration()));
687 } 725 }
688 // perform motion update 726 // perform motion update
689 update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature); 727 update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
690 } 728 }
691 else 729 else
692 { 730 {
@@ -697,7 +735,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
697 // allow motions to deactivate themselves 735 // allow motions to deactivate themselves
698 if (!update_result) 736 if (!update_result)
699 { 737 {
700 if (!motionp->isStopped() || motionp->getStopTime() > mTime) 738 if (!motionp->isStopped() || motionp->getStopTime() > mAnimTime)
701 { 739 {
702 // animation has stopped itself due to internal logic 740 // animation has stopped itself due to internal logic
703 // propagate this to the network 741 // propagate this to the network
@@ -713,18 +751,68 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
713 } 751 }
714} 752}
715 753
754//-----------------------------------------------------------------------------
755// updateLoadingMotions()
756//-----------------------------------------------------------------------------
757void LLMotionController::updateLoadingMotions()
758{
759 // query pending motions for completion
760 for (motion_set_t::iterator iter = mLoadingMotions.begin();
761 iter != mLoadingMotions.end(); )
762 {
763 motion_set_t::iterator curiter = iter++;
764 LLMotion* motionp = *curiter;
765 if( !motionp)
766 {
767 continue; // maybe shouldn't happen but i've seen it -MG
768 }
769 LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter);
770 if (status == LLMotion::STATUS_SUCCESS)
771 {
772 mLoadingMotions.erase(curiter);
773 // add motion to our loaded motion list
774 mLoadedMotions.insert(motionp);
775 // this motion should be playing
776 if (!motionp->isStopped())
777 {
778 activateMotionInstance(motionp, mAnimTime);
779 }
780 }
781 else if (status == LLMotion::STATUS_FAILURE)
782 {
783 llinfos << "Motion " << motionp->getID() << " init failed." << llendl;
784 sRegistry.markBad(motionp->getID());
785 mLoadingMotions.erase(curiter);
786 mAllMotions.erase(motionp->getID());
787 delete motionp;
788 }
789 }
790}
791
792//-----------------------------------------------------------------------------
793// call updateMotion() or updateMotionsMinimal() every frame
794//-----------------------------------------------------------------------------
716 795
717//----------------------------------------------------------------------------- 796//-----------------------------------------------------------------------------
718// updateMotion() 797// updateMotion()
719//----------------------------------------------------------------------------- 798//-----------------------------------------------------------------------------
720void LLMotionController::updateMotion() 799void LLMotionController::updateMotions(bool force_update)
721{ 800{
722 BOOL use_quantum = (mTimeStep != 0.f); 801 BOOL use_quantum = (mTimeStep != 0.f);
723 802
803 // Always update mPrevTimerElapsed
804 F32 cur_time = mTimer.getElapsedTimeF32();
805 F32 delta_time = cur_time - mPrevTimerElapsed;
806 mPrevTimerElapsed = cur_time;
807 mLastTime = mAnimTime;
808
809 // Always cap the number of loaded motions
810 purgeExcessMotions();
811
724 // Update timing info for this time step. 812 // Update timing info for this time step.
725 if (!mPaused) 813 if (!mPaused)
726 { 814 {
727 F32 update_time = mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor); 815 F32 update_time = mAnimTime + delta_time * mTimeFactor;
728 if (use_quantum) 816 if (use_quantum)
729 { 817 {
730 F32 time_interval = fmodf(update_time, mTimeStep); 818 F32 time_interval = fmodf(update_time, mTimeStep);
@@ -740,7 +828,8 @@ void LLMotionController::updateMotion()
740 mPoseBlender.interpolate(interp - mLastInterp); 828 mPoseBlender.interpolate(interp - mLastInterp);
741 mLastInterp = interp; 829 mLastInterp = interp;
742 } 830 }
743 831
832 updateLoadingMotions();
744 return; 833 return;
745 } 834 }
746 835
@@ -749,53 +838,24 @@ void LLMotionController::updateMotion()
749 clearBlenders(); 838 clearBlenders();
750 839
751 mTimeStepCount = quantum_count; 840 mTimeStepCount = quantum_count;
752 mLastTime = mTime; 841 mAnimTime = (F32)quantum_count * mTimeStep;
753 mTime = (F32)quantum_count * mTimeStep;
754 mLastInterp = 0.f; 842 mLastInterp = 0.f;
755 } 843 }
756 else 844 else
757 { 845 {
758 mLastTime = mTime; 846 mAnimTime = update_time;
759 mTime = update_time;
760 } 847 }
761 } 848 }
762 849
763 // query pending motions for completion 850 updateLoadingMotions();
764 for (motion_set_t::iterator iter = mLoadingMotions.begin();
765 iter != mLoadingMotions.end(); )
766 {
767 motion_set_t::iterator curiter = iter++;
768 LLMotion* motionp = *curiter;
769 if( !motionp)
770 {
771 continue; // maybe shouldn't happen but i've seen it -MG
772 }
773 LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter);
774 if (status == LLMotion::STATUS_SUCCESS)
775 {
776 mLoadingMotions.erase(curiter);
777 // add motion to our loaded motion list
778 addLoadedMotion(motionp);
779 // this motion should be playing
780 if (!motionp->isStopped())
781 {
782 activateMotionInstance(motionp, mTime);
783 }
784 }
785 else if (status == LLMotion::STATUS_FAILURE)
786 {
787 llinfos << "Motion " << motionp->getID() << " init failed." << llendl;
788 sRegistry.markBad(motionp->getID());
789 mLoadingMotions.erase(curiter);
790
791 mAllMotions.erase(motionp->getID());
792 delete motionp;
793 }
794 }
795 851
796 resetJointSignatures(); 852 resetJointSignatures();
797 853
798 if (!mPaused) 854 if (mPaused && !force_update)
855 {
856 updateIdleActiveMotions();
857 }
858 else
799 { 859 {
800 // update additive motions 860 // update additive motions
801 updateAdditiveMotions(); 861 updateAdditiveMotions();
@@ -818,6 +878,23 @@ void LLMotionController::updateMotion()
818// llinfos << "Motion controller time " << motionTimer.getElapsedTimeF32() << llendl; 878// llinfos << "Motion controller time " << motionTimer.getElapsedTimeF32() << llendl;
819} 879}
820 880
881//-----------------------------------------------------------------------------
882// updateMotionsMinimal()
883// minimal update (e.g. while hidden)
884//-----------------------------------------------------------------------------
885void LLMotionController::updateMotionsMinimal()
886{
887 // Always update mPrevTimerElapsed
888 mPrevTimerElapsed = mTimer.getElapsedTimeF32();
889
890 purgeExcessMotions();
891 updateLoadingMotions();
892 resetJointSignatures();
893
894 deactivateStoppedMotions();
895
896 mHasRunOnce = TRUE;
897}
821 898
822//----------------------------------------------------------------------------- 899//-----------------------------------------------------------------------------
823// activateMotionInstance() 900// activateMotionInstance()
@@ -840,7 +917,6 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time)
840 } 917 }
841 918
842 motion->mResidualWeight = motion->getPose()->getWeight(); 919 motion->mResidualWeight = motion->getPose()->getWeight();
843 motion->mActivationTimestamp = time;
844 920
845 // set stop time based on given duration and ease out time 921 // set stop time based on given duration and ease out time
846 if (motion->getDuration() != 0.f && !motion->getLoop()) 922 if (motion->getDuration() != 0.f && !motion->getLoop())
@@ -861,13 +937,26 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time)
861 { 937 {
862 motion->mSendStopTimestamp = F32_MAX; 938 motion->mSendStopTimestamp = F32_MAX;
863 } 939 }
864 940
865 mActiveMotions.remove(motion); // in case it is already in the active list 941 if (motion->isActive())
942 {
943 mActiveMotions.remove(motion);
944 }
866 mActiveMotions.push_front(motion); 945 mActiveMotions.push_front(motion);
867 946
868 motion->activate(); 947 motion->activate(time);
869 motion->onUpdate(0.f, mJointSignature[1]); 948 motion->onUpdate(0.f, mJointSignature[1]);
870 949
950 if (mAnimTime >= motion->mSendStopTimestamp)
951 {
952 motion->setStopTime(motion->mSendStopTimestamp);
953 if (motion->mResidualWeight == 0.0f)
954 {
955 // bit of a hack; if newly activating a motion while easing out, weight should = 1
956 motion->mResidualWeight = 1.f;
957 }
958 }
959
871 return TRUE; 960 return TRUE;
872} 961}
873 962
@@ -924,9 +1013,17 @@ bool LLMotionController::isMotionLoading(LLMotion* motion)
924//----------------------------------------------------------------------------- 1013//-----------------------------------------------------------------------------
925// findMotion() 1014// findMotion()
926//----------------------------------------------------------------------------- 1015//-----------------------------------------------------------------------------
927LLMotion *LLMotionController::findMotion(const LLUUID& id) 1016LLMotion* LLMotionController::findMotion(const LLUUID& id)
928{ 1017{
929 return get_if_there<LLUUID, LLMotion*>(mAllMotions, id, NULL); 1018 motion_map_t::iterator iter = mAllMotions.find(id);
1019 if(iter == mAllMotions.end())
1020 {
1021 return NULL;
1022 }
1023 else
1024 {
1025 return iter->second;
1026 }
930} 1027}
931 1028
932//----------------------------------------------------------------------------- 1029//-----------------------------------------------------------------------------
@@ -934,16 +1031,12 @@ LLMotion *LLMotionController::findMotion(const LLUUID& id)
934//----------------------------------------------------------------------------- 1031//-----------------------------------------------------------------------------
935void LLMotionController::deactivateAllMotions() 1032void LLMotionController::deactivateAllMotions()
936{ 1033{
937 //They must all die, precious. 1034 for (motion_map_t::iterator iter = mAllMotions.begin();
938 for (std::map<LLUUID, LLMotion*>::iterator iter = mAllMotions.begin();
939 iter != mAllMotions.end(); iter++) 1035 iter != mAllMotions.end(); iter++)
940 { 1036 {
941 LLMotion* motionp = iter->second; 1037 LLMotion* motionp = iter->second;
942 if (motionp) motionp->deactivate(); 1038 deactivateMotionInstance(motionp);
943 } 1039 }
944
945 // delete all motion instances
946 deleteAllMotions();
947} 1040}
948 1041
949 1042
@@ -959,11 +1052,12 @@ void LLMotionController::flushAllMotions()
959 { 1052 {
960 motion_list_t::iterator curiter = iter++; 1053 motion_list_t::iterator curiter = iter++;
961 LLMotion* motionp = *curiter; 1054 LLMotion* motionp = *curiter;
962 F32 dtime = mTime - motionp->mActivationTimestamp; 1055 F32 dtime = mAnimTime - motionp->mActivationTimestamp;
963 active_motions.push_back(std::make_pair(motionp->getID(),dtime)); 1056 active_motions.push_back(std::make_pair(motionp->getID(),dtime));
964 motionp->deactivate(); 1057 motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it
965 } 1058 }
966 1059 mActiveMotions.clear();
1060
967 // delete all motion instances 1061 // delete all motion instances
968 deleteAllMotions(); 1062 deleteAllMotions();
969 1063
@@ -982,12 +1076,11 @@ void LLMotionController::flushAllMotions()
982//----------------------------------------------------------------------------- 1076//-----------------------------------------------------------------------------
983// pause() 1077// pause()
984//----------------------------------------------------------------------------- 1078//-----------------------------------------------------------------------------
985void LLMotionController::pause() 1079void LLMotionController::pauseAllMotions()
986{ 1080{
987 if (!mPaused) 1081 if (!mPaused)
988 { 1082 {
989 //llinfos << "Pausing animations..." << llendl; 1083 //llinfos << "Pausing animations..." << llendl;
990 mPauseTime = mTimer.getElapsedTimeF32();
991 mPaused = TRUE; 1084 mPaused = TRUE;
992 } 1085 }
993 1086
@@ -996,13 +1089,11 @@ void LLMotionController::pause()
996//----------------------------------------------------------------------------- 1089//-----------------------------------------------------------------------------
997// unpause() 1090// unpause()
998//----------------------------------------------------------------------------- 1091//-----------------------------------------------------------------------------
999void LLMotionController::unpause() 1092void LLMotionController::unpauseAllMotions()
1000{ 1093{
1001 if (mPaused) 1094 if (mPaused)
1002 { 1095 {
1003 //llinfos << "Unpausing animations..." << llendl; 1096 //llinfos << "Unpausing animations..." << llendl;
1004 mTimer.reset();
1005 mTimer.setAge(mPauseTime);
1006 mPaused = FALSE; 1097 mPaused = FALSE;
1007 } 1098 }
1008} 1099}
diff --git a/linden/indra/llcharacter/llmotioncontroller.h b/linden/indra/llcharacter/llmotioncontroller.h
index 48e184d..209f689 100644
--- a/linden/indra/llcharacter/llmotioncontroller.h
+++ b/linden/indra/llcharacter/llmotioncontroller.h
@@ -57,30 +57,6 @@ class LLCharacter;
57//----------------------------------------------------------------------------- 57//-----------------------------------------------------------------------------
58typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id); 58typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id);
59 59
60class LLMotionTableEntry
61{
62public:
63 LLMotionTableEntry();
64 LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id);
65 ~LLMotionTableEntry(){};
66
67 LLMotion* create(const LLUUID& id);
68 static BOOL uuidEq(const LLUUID &uuid, const LLMotionTableEntry &id_pair)
69 {
70 if (uuid == id_pair.mID)
71 {
72 return TRUE;
73 }
74 return FALSE;
75 }
76
77 const LLUUID& getID() { return mID; }
78
79protected:
80 LLMotionConstructor mConstructor;
81 LLUUID mID;
82};
83
84class LLMotionRegistry 60class LLMotionRegistry
85{ 61{
86public: 62public:
@@ -92,7 +68,7 @@ public:
92 68
93 // adds motion classes to the registry 69 // adds motion classes to the registry
94 // returns true if successfull 70 // returns true if successfull
95 BOOL addMotion( const LLUUID& id, LLMotionConstructor create); 71 BOOL registerMotion( const LLUUID& id, LLMotionConstructor create);
96 72
97 // creates a new instance of a named motion 73 // creates a new instance of a named motion
98 // returns NULL motion is not registered 74 // returns NULL motion is not registered
@@ -103,7 +79,8 @@ public:
103 79
104 80
105protected: 81protected:
106 LLUUIDHashMap<LLMotionTableEntry, 32> mMotionTable; 82 typedef std::map<LLUUID, LLMotionConstructor> motion_map_t;
83 motion_map_t mMotionTable;
107}; 84};
108 85
109//----------------------------------------------------------------------------- 86//-----------------------------------------------------------------------------
@@ -130,7 +107,7 @@ public:
130 // registers a motion with the controller 107 // registers a motion with the controller
131 // (actually just forwards call to motion registry) 108 // (actually just forwards call to motion registry)
132 // returns true if successfull 109 // returns true if successfull
133 BOOL addMotion( const LLUUID& id, LLMotionConstructor create ); 110 BOOL registerMotion( const LLUUID& id, LLMotionConstructor create );
134 111
135 // creates a motion from the registry 112 // creates a motion from the registry
136 LLMotion *createMotion( const LLUUID &id ); 113 LLMotion *createMotion( const LLUUID &id );
@@ -151,11 +128,17 @@ public:
151 // returns true if successful 128 // returns true if successful
152 BOOL stopMotionLocally( const LLUUID &id, BOOL stop_immediate ); 129 BOOL stopMotionLocally( const LLUUID &id, BOOL stop_immediate );
153 130
131 // Move motions from loading to loaded
132 void updateLoadingMotions();
133
154 // update motions 134 // update motions
155 // invokes the update handlers for each active motion 135 // invokes the update handlers for each active motion
156 // activates sequenced motions 136 // activates sequenced motions
157 // deactivates terminated motions` 137 // deactivates terminated motions`
158 void updateMotion(); 138 void updateMotions(bool force_update = false);
139
140 // minimal update (e.g. while hidden)
141 void updateMotionsMinimal();
159 142
160 void clearBlenders() { mPoseBlender.clearBlenders(); } 143 void clearBlenders() { mPoseBlender.clearBlenders(); }
161 144
@@ -167,8 +150,8 @@ public:
167 void deactivateAllMotions(); 150 void deactivateAllMotions();
168 151
169 // pause and continue all motions 152 // pause and continue all motions
170 void pause(); 153 void pauseAllMotions();
171 void unpause(); 154 void unpauseAllMotions();
172 BOOL isPaused() { return mPaused; } 155 BOOL isPaused() { return mPaused; }
173 156
174 void setTimeStep(F32 step); 157 void setTimeStep(F32 step);
@@ -178,6 +161,8 @@ public:
178 161
179 motion_list_t& getActiveMotions() { return mActiveMotions; } 162 motion_list_t& getActiveMotions() { return mActiveMotions; }
180 163
164 void incMotionCounts(S32& num_motions, S32& num_loading_motions, S32& num_loaded_motions, S32& num_active_motions, S32& num_deprecated_motions);
165
181//protected: 166//protected:
182 bool isMotionActive( LLMotion *motion ); 167 bool isMotionActive( LLMotion *motion );
183 bool isMotionLoading( LLMotion *motion ); 168 bool isMotionLoading( LLMotion *motion );
@@ -187,7 +172,6 @@ protected:
187 // internal operations act on motion instances directly 172 // internal operations act on motion instances directly
188 // as there can be duplicate motions per id during blending overlap 173 // as there can be duplicate motions per id during blending overlap
189 void deleteAllMotions(); 174 void deleteAllMotions();
190 void addLoadedMotion(LLMotion *motion);
191 BOOL activateMotionInstance(LLMotion *motion, F32 time); 175 BOOL activateMotionInstance(LLMotion *motion, F32 time);
192 BOOL deactivateMotionInstance(LLMotion *motion); 176 BOOL deactivateMotionInstance(LLMotion *motion);
193 void deprecateMotionInstance(LLMotion* motion); 177 void deprecateMotionInstance(LLMotion* motion);
@@ -197,6 +181,10 @@ protected:
197 void updateAdditiveMotions(); 181 void updateAdditiveMotions();
198 void resetJointSignatures(); 182 void resetJointSignatures();
199 void updateMotionsByType(LLMotion::LLMotionBlendType motion_type); 183 void updateMotionsByType(LLMotion::LLMotionBlendType motion_type);
184 void updateIdleMotion(LLMotion* motionp);
185 void updateIdleActiveMotions();
186 void purgeExcessMotions();
187 void deactivateStoppedMotions();
200 188
201protected: 189protected:
202 F32 mTimeFactor; 190 F32 mTimeFactor;
@@ -210,20 +198,20 @@ protected:
210// Animations are instantiated and immediately put in the mAllMotions map for their entire lifetime. 198// Animations are instantiated and immediately put in the mAllMotions map for their entire lifetime.
211// If the animations depend on any asset data, the appropriate data is fetched from the data server, 199// If the animations depend on any asset data, the appropriate data is fetched from the data server,
212// and the animation is put on the mLoadingMotions list. 200// and the animation is put on the mLoadingMotions list.
213// Once an animations is loaded, it will be initialized and put on the mLoadedMotions deque. 201// Once an animations is loaded, it will be initialized and put on the mLoadedMotions list.
214// Any animation that is currently playing also sits in the mActiveMotions list. 202// Any animation that is currently playing also sits in the mActiveMotions list.
215 203
216 typedef std::map<LLUUID, LLMotion*> motion_map_t; 204 typedef std::map<LLUUID, LLMotion*> motion_map_t;
217 motion_map_t mAllMotions; 205 motion_map_t mAllMotions;
218 206
219 motion_set_t mLoadingMotions; 207 motion_set_t mLoadingMotions;
220 motion_list_t mLoadedMotions; 208 motion_set_t mLoadedMotions;
221 motion_list_t mActiveMotions; 209 motion_list_t mActiveMotions;
222 motion_set_t mDeprecatedMotions; 210 motion_set_t mDeprecatedMotions;
223 211
224 LLFrameTimer mTimer; 212 LLFrameTimer mTimer;
225 F32 mTime; 213 F32 mPrevTimerElapsed;
226 F32 mTimeOffset; 214 F32 mAnimTime;
227 F32 mLastTime; 215 F32 mLastTime;
228 BOOL mHasRunOnce; 216 BOOL mHasRunOnce;
229 BOOL mPaused; 217 BOOL mPaused;