diff options
author | Jacek Antonelli | 2008-08-15 23:45:57 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:57 -0500 |
commit | 7e3007b63521c4b0c5bbad1c3964a557fc526ce2 (patch) | |
tree | ab231ed574db618873d6ebb25293cf7c0cb6d26e /linden/indra/llcharacter | |
parent | Second Life viewer sources 1.20.10 (diff) | |
download | meta-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.cpp | 47 | ||||
-rw-r--r-- | linden/indra/llcharacter/llcharacter.h | 13 | ||||
-rw-r--r-- | linden/indra/llcharacter/llkeyframemotion.cpp | 10 | ||||
-rw-r--r-- | linden/indra/llcharacter/llkeyframemotionparam.cpp | 53 | ||||
-rw-r--r-- | linden/indra/llcharacter/llkeyframemotionparam.h | 15 | ||||
-rw-r--r-- | linden/indra/llcharacter/llmotion.cpp | 17 | ||||
-rw-r--r-- | linden/indra/llcharacter/llmotion.h | 25 | ||||
-rw-r--r-- | linden/indra/llcharacter/llmotioncontroller.cpp | 461 | ||||
-rw-r--r-- | linden/indra/llcharacter/llmotioncontroller.h | 58 |
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 | //----------------------------------------------------------------------------- |
108 | BOOL LLCharacter::addMotion( const LLUUID& id, LLMotionConstructor create ) | 108 | BOOL 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 | //----------------------------------------------------------------------------- | ||
124 | LLMotion* 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 | //----------------------------------------------------------------------------- |
124 | LLMotion* LLCharacter::createMotion( const LLUUID &id ) | 133 | LLMotion* 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 | //----------------------------------------------------------------------------- |
173 | void LLCharacter::updateMotion(BOOL force_update) | 182 | void 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 | ||
500 | LLAnimPauseRequest LLCharacter::requestPause() | 507 | LLAnimPauseRequest 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 | ||
141 | protected: | 144 | protected: |
@@ -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 | ||
131 | void LLMotion::setStopTime(F32 time) | ||
132 | { | ||
133 | mStopTimestamp = time; | ||
134 | mStopped = TRUE; | ||
135 | } | ||
136 | |||
130 | BOOL LLMotion::isBlending() | 137 | BOOL 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 | //----------------------------------------------------------------------------- |
138 | void LLMotion::activate() | 145 | void 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 | //----------------------------------------------------------------------------- |
49 | class LLMotion | 49 | class LLMotion |
50 | { | 50 | { |
51 | friend class LLMotionController; | ||
52 | |||
51 | public: | 53 | public: |
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. | ||
110 | protected: | ||
111 | // Used by LLMotionController only | ||
109 | void deactivate(); | 112 | void deactivate(); |
110 | |||
111 | BOOL isActive() { return mActive; } | 113 | BOOL isActive() { return mActive; } |
112 | 114 | public: | |
115 | void activate(F32 time); | ||
116 | |||
113 | public: | 117 | public: |
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 | ||
173 | public: | ||
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; | |||
50 | LLMotionRegistry LLMotionController::sRegistry; | 52 | LLMotionRegistry LLMotionController::sRegistry; |
51 | 53 | ||
52 | //----------------------------------------------------------------------------- | 54 | //----------------------------------------------------------------------------- |
53 | // LLMotionTableEntry() | ||
54 | //----------------------------------------------------------------------------- | ||
55 | LLMotionTableEntry::LLMotionTableEntry() | ||
56 | { | ||
57 | mConstructor = NULL; | ||
58 | mID.setNull(); | ||
59 | } | ||
60 | |||
61 | LLMotionTableEntry::LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id) | ||
62 | : mConstructor(constructor), mID(id) | ||
63 | { | ||
64 | |||
65 | } | ||
66 | |||
67 | //----------------------------------------------------------------------------- | ||
68 | // create() | ||
69 | //----------------------------------------------------------------------------- | ||
70 | LLMotion* 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 | //----------------------------------------------------------------------------- |
88 | LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, LLMotionTableEntry()) | 64 | LLMotionRegistry::LLMotionRegistry() |
89 | { | 65 | { |
90 | 66 | ||
91 | } | 67 | } |
@@ -97,19 +73,19 @@ LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, | |||
97 | //----------------------------------------------------------------------------- | 73 | //----------------------------------------------------------------------------- |
98 | LLMotionRegistry::~LLMotionRegistry() | 74 | LLMotionRegistry::~LLMotionRegistry() |
99 | { | 75 | { |
100 | mMotionTable.removeAll(); | 76 | mMotionTable.clear(); |
101 | } | 77 | } |
102 | 78 | ||
103 | 79 | ||
104 | //----------------------------------------------------------------------------- | 80 | //----------------------------------------------------------------------------- |
105 | // addMotion() | 81 | // addMotion() |
106 | //----------------------------------------------------------------------------- | 82 | //----------------------------------------------------------------------------- |
107 | BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor constructor ) | 83 | BOOL 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 | //----------------------------------------------------------------------------- |
122 | void LLMotionRegistry::markBad( const LLUUID& id ) | 98 | void 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 | //----------------------------------------------------------------------------- |
130 | LLMotion *LLMotionRegistry::createMotion( const LLUUID &id ) | 106 | LLMotion *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 | //----------------------------------------------------------------------------- |
158 | LLMotionController::LLMotionController( ) | 134 | LLMotionController::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 | ||
159 | void 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 | //----------------------------------------------------------------------------- |
198 | void LLMotionController::addLoadedMotion(LLMotion* motionp) | 184 | void 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 | //----------------------------------------------------------------------------- | ||
246 | void 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 | //----------------------------------------------------------------------------- |
267 | void LLMotionController::setTimeFactor(F32 time_factor) | 288 | void 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 | //----------------------------------------------------------------------------- |
285 | BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constructor ) | 305 | BOOL 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 | |||
293 | void LLMotionController::removeMotion( const LLUUID& id) | 313 | void 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 | //----------------------------------------------------------------------------- |
321 | LLMotion* LLMotionController::createMotion( const LLUUID &id ) | 340 | LLMotion* 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 | //----------------------------------------------------------------------------- | ||
496 | void 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 | //----------------------------------------------------------------------------- | ||
534 | void 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 | //----------------------------------------------------------------------------- |
481 | void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) | 548 | void 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 | //----------------------------------------------------------------------------- | ||
757 | void 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 | //----------------------------------------------------------------------------- |
720 | void LLMotionController::updateMotion() | 799 | void 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 | //----------------------------------------------------------------------------- | ||
885 | void 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 | //----------------------------------------------------------------------------- |
927 | LLMotion *LLMotionController::findMotion(const LLUUID& id) | 1016 | LLMotion* 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 | //----------------------------------------------------------------------------- |
935 | void LLMotionController::deactivateAllMotions() | 1032 | void 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 | //----------------------------------------------------------------------------- |
985 | void LLMotionController::pause() | 1079 | void 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 | //----------------------------------------------------------------------------- |
999 | void LLMotionController::unpause() | 1092 | void 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 | //----------------------------------------------------------------------------- |
58 | typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id); | 58 | typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id); |
59 | 59 | ||
60 | class LLMotionTableEntry | ||
61 | { | ||
62 | public: | ||
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 | |||
79 | protected: | ||
80 | LLMotionConstructor mConstructor; | ||
81 | LLUUID mID; | ||
82 | }; | ||
83 | |||
84 | class LLMotionRegistry | 60 | class LLMotionRegistry |
85 | { | 61 | { |
86 | public: | 62 | public: |
@@ -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 | ||
105 | protected: | 81 | protected: |
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 | ||
201 | protected: | 189 | protected: |
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; |