aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcharacter/llmotioncontroller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcharacter/llmotioncontroller.cpp')
-rw-r--r--linden/indra/llcharacter/llmotioncontroller.cpp157
1 files changed, 106 insertions, 51 deletions
diff --git a/linden/indra/llcharacter/llmotioncontroller.cpp b/linden/indra/llcharacter/llmotioncontroller.cpp
index 2427fd8..aebfaf6 100644
--- a/linden/indra/llcharacter/llmotioncontroller.cpp
+++ b/linden/indra/llcharacter/llmotioncontroller.cpp
@@ -194,34 +194,44 @@ void LLMotionController::deleteAllMotions()
194//----------------------------------------------------------------------------- 194//-----------------------------------------------------------------------------
195void LLMotionController::addLoadedMotion(LLMotion* motionp) 195void LLMotionController::addLoadedMotion(LLMotion* motionp)
196{ 196{
197 std::set<LLUUID> motions_to_kill;
198
199 // gather all inactive, loaded motions
197 if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) 200 if (mLoadedMotions.size() > MAX_MOTION_INSTANCES)
198 { 201 {
199 // too many motions active this frame, kill all blenders 202 // too many motions active this frame, kill all blenders
200 mPoseBlender.clearBlenders(); 203 mPoseBlender.clearBlenders();
201 204
202 for (U32 i = 0; i < mLoadedMotions.size(); i++) 205 for (motion_list_t::iterator loaded_motion_it = mLoadedMotions.begin();
206 loaded_motion_it != mLoadedMotions.end();
207 ++loaded_motion_it)
203 { 208 {
204 LLMotion* cur_motionp = mLoadedMotions.front(); 209 LLMotion* cur_motionp = *loaded_motion_it;
205 mLoadedMotions.pop_front();
206 210
207 // motion isn't playing, delete it 211 // motion isn't playing, delete it
208 if (!isMotionActive(cur_motionp)) 212 if (!isMotionActive(cur_motionp))
209 { 213 {
210 mCharacter->requestStopMotion(cur_motionp); 214 motions_to_kill.insert(cur_motionp->getID());
211 mAllMotions.erase(cur_motionp->getID());
212 delete cur_motionp;
213 if (mLoadedMotions.size() <= MAX_MOTION_INSTANCES)
214 {
215 break;
216 }
217 }
218 else
219 {
220 // put active motion on back
221 mLoadedMotions.push_back(cur_motionp);
222 } 215 }
223 } 216 }
224 } 217 }
218
219 // clean up all inactive, loaded motions
220 for (std::set<LLUUID>::iterator motion_it = motions_to_kill.begin();
221 motion_it != motions_to_kill.end();
222 ++motion_it)
223 {
224 // look up the motion again by ID to get canonical instance
225 // and kill it only if that one is inactive
226 LLUUID motion_id = *motion_it;
227 LLMotion* motionp = findMotion(motion_id);
228 if (motionp && !isMotionActive(motionp))
229 {
230 removeMotion(motion_id);
231 }
232 }
233
234 // add new motion to loaded list
225 mLoadedMotions.push_back(motionp); 235 mLoadedMotions.push_back(motionp);
226} 236}
227 237
@@ -280,14 +290,24 @@ BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constr
280void LLMotionController::removeMotion( const LLUUID& id) 290void LLMotionController::removeMotion( const LLUUID& id)
281{ 291{
282 LLMotion* motionp = findMotion(id); 292 LLMotion* motionp = findMotion(id);
293
294 removeMotionInstance(motionp);
295
296 mAllMotions.erase(id);
297}
298
299// removes instance of a motion from all runtime structures, but does
300// not erase entry by ID, as this could be a duplicate instance
301// use removeMotion(id) to remove all references to a given motion by id.
302void LLMotionController::removeMotionInstance(LLMotion* motionp)
303{
283 if (motionp) 304 if (motionp)
284 { 305 {
285 stopMotionLocally(id, TRUE); 306 stopMotionInstance(motionp, TRUE);
286 307
287 mLoadingMotions.erase(motionp); 308 mLoadingMotions.erase(motionp);
288 mLoadedMotions.remove(motionp); 309 mLoadedMotions.remove(motionp);
289 mActiveMotions.remove(motionp); 310 mActiveMotions.remove(motionp);
290 mAllMotions.erase(id);
291 delete motionp; 311 delete motionp;
292 } 312 }
293} 313}
@@ -348,28 +368,39 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id )
348//----------------------------------------------------------------------------- 368//-----------------------------------------------------------------------------
349BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) 369BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset)
350{ 370{
351 // look for motion in our list of created motions 371 // do we have an instance of this motion for this character?
352 LLMotion *motion = createMotion(id); 372 LLMotion *motion = findMotion(id);
373
374 // motion that is stopping will be allowed to stop but
375 // replaced by a new instance of that motion
376 if (motion
377 && motion->canDeprecate()
378 && motion->getFadeWeight() > 0.01f // not LOD-ed out
379 && (motion->isBlending() || motion->getStopTime() != 0.f))
380 {
381 deprecateMotionInstance(motion);
382 // force creation of new instance
383 motion = NULL;
384 }
385
386 // create new motion instance
387 if (!motion)
388 {
389 motion = createMotion(id);
390 }
353 391
354 if (!motion) 392 if (!motion)
355 { 393 {
356 return FALSE; 394 return FALSE;
357 } 395 }
358 //if the motion is already active, then we're done 396 //if the motion is already active and allows deprecation, then let it keep playing
359 else if (isMotionActive(motion)) // motion is playing and... 397 else if (motion->canDeprecate() && isMotionActive(motion))
360 { 398 {
361 if (motion->isStopped()) // motion has been stopped 399 return TRUE;
362 {
363 deactivateMotion(motion, false);
364 }
365 else if (mTime < motion->mSendStopTimestamp) // motion is still active
366 {
367 return TRUE;
368 }
369 } 400 }
370 401
371// llinfos << "Starting motion " << name << llendl; 402// llinfos << "Starting motion " << name << llendl;
372 return activateMotion(motion, mTime - start_offset); 403 return activateMotionInstance(motion, mTime - start_offset);
373} 404}
374 405
375 406
@@ -380,6 +411,12 @@ BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate
380{ 411{
381 // if already inactive, return false 412 // if already inactive, return false
382 LLMotion *motion = findMotion(id); 413 LLMotion *motion = findMotion(id);
414
415 return stopMotionInstance(motion, stop_immediate);
416}
417
418BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediate)
419{
383 if (!motion) 420 if (!motion)
384 { 421 {
385 return FALSE; 422 return FALSE;
@@ -396,7 +433,7 @@ BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate
396 433
397 if (stop_immediate) 434 if (stop_immediate)
398 { 435 {
399 deactivateMotion(motion, false); 436 deactivateMotionInstance(motion);
400 } 437 }
401 return TRUE; 438 return TRUE;
402 } 439 }
@@ -492,7 +529,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
492 { 529 {
493 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) 530 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
494 { 531 {
495 deactivateMotion(motionp, false); 532 deactivateMotionInstance(motionp);
496 } 533 }
497 else if (motionp->isStopped() && mTime > motionp->getStopTime()) 534 else if (motionp->isStopped() && mTime > motionp->getStopTime())
498 { 535 {
@@ -510,7 +547,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
510 if (mLastTime <= motionp->mSendStopTimestamp) 547 if (mLastTime <= motionp->mSendStopTimestamp)
511 { 548 {
512 mCharacter->requestStopMotion( motionp ); 549 mCharacter->requestStopMotion( motionp );
513 stopMotionLocally(motionp->getID(), FALSE); 550 stopMotionInstance(motionp, FALSE);
514 } 551 }
515 } 552 }
516 else if (mTime >= motionp->mActivationTimestamp) 553 else if (mTime >= motionp->mActivationTimestamp)
@@ -538,7 +575,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
538 if (mLastTime <= motionp->mSendStopTimestamp) 575 if (mLastTime <= motionp->mSendStopTimestamp)
539 { 576 {
540 mCharacter->requestStopMotion( motionp ); 577 mCharacter->requestStopMotion( motionp );
541 stopMotionLocally(motionp->getID(), FALSE); 578 stopMotionInstance(motionp, FALSE);
542 } 579 }
543 } 580 }
544 581
@@ -546,7 +583,8 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
546 { 583 {
547 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) 584 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
548 { 585 {
549 deactivateMotion(motionp, true); 586 posep->setWeight(0.f);
587 deactivateMotionInstance(motionp);
550 } 588 }
551 continue; 589 continue;
552 } 590 }
@@ -572,7 +610,8 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
572 } 610 }
573 else 611 else
574 { 612 {
575 deactivateMotion(motionp, true); 613 posep->setWeight(0.f);
614 deactivateMotionInstance(motionp);
576 continue; 615 continue;
577 } 616 }
578 } 617 }
@@ -617,7 +656,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
617 if (mLastTime <= motionp->mSendStopTimestamp) 656 if (mLastTime <= motionp->mSendStopTimestamp)
618 { 657 {
619 mCharacter->requestStopMotion( motionp ); 658 mCharacter->requestStopMotion( motionp );
620 stopMotionLocally(motionp->getID(), FALSE); 659 stopMotionInstance(motionp, FALSE);
621 } 660 }
622 } 661 }
623 662
@@ -661,7 +700,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
661 // propagate this to the network 700 // propagate this to the network
662 // as not all viewers are guaranteed to have access to the same logic 701 // as not all viewers are guaranteed to have access to the same logic
663 mCharacter->requestStopMotion( motionp ); 702 mCharacter->requestStopMotion( motionp );
664 stopMotionLocally(motionp->getID(), FALSE); 703 stopMotionInstance(motionp, FALSE);
665 } 704 }
666 705
667 } 706 }
@@ -733,7 +772,7 @@ void LLMotionController::updateMotion()
733 // this motion should be playing 772 // this motion should be playing
734 if (!motionp->isStopped()) 773 if (!motionp->isStopped())
735 { 774 {
736 activateMotion(motionp, mTime); 775 activateMotionInstance(motionp, mTime);
737 } 776 }
738 } 777 }
739 else if (status == LLMotion::STATUS_FAILURE) 778 else if (status == LLMotion::STATUS_FAILURE)
@@ -741,6 +780,7 @@ void LLMotionController::updateMotion()
741 llinfos << "Motion " << motionp->getID() << " init failed." << llendl; 780 llinfos << "Motion " << motionp->getID() << " init failed." << llendl;
742 sRegistry.markBad(motionp->getID()); 781 sRegistry.markBad(motionp->getID());
743 mLoadingMotions.erase(curiter); 782 mLoadingMotions.erase(curiter);
783
744 mAllMotions.erase(motionp->getID()); 784 mAllMotions.erase(motionp->getID());
745 delete motionp; 785 delete motionp;
746 } 786 }
@@ -773,9 +813,9 @@ void LLMotionController::updateMotion()
773 813
774 814
775//----------------------------------------------------------------------------- 815//-----------------------------------------------------------------------------
776// activateMotion() 816// activateMotionInstance()
777//----------------------------------------------------------------------------- 817//-----------------------------------------------------------------------------
778BOOL LLMotionController::activateMotion(LLMotion *motion, F32 time) 818BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time)
779{ 819{
780 if (mLoadingMotions.find(motion) != mLoadingMotions.end()) 820 if (mLoadingMotions.find(motion) != mLoadingMotions.end())
781 { 821 {
@@ -818,23 +858,38 @@ BOOL LLMotionController::activateMotion(LLMotion *motion, F32 time)
818} 858}
819 859
820//----------------------------------------------------------------------------- 860//-----------------------------------------------------------------------------
821// deactivateMotion() 861// deactivateMotionInstance()
822//----------------------------------------------------------------------------- 862//-----------------------------------------------------------------------------
823BOOL LLMotionController::deactivateMotion(LLMotion *motion, bool remove_weight) 863BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion)
824{ 864{
825 if( remove_weight ) 865 motion->deactivate();
866
867 motion_set_t::iterator found_it = mDeprecatedMotions.find(motion);
868 if (found_it != mDeprecatedMotions.end())
826 { 869 {
827 // immediately remove pose weighting instead of letting it time out 870 // deprecated motions need to be completely excised
828 LLPose *posep = motion->getPose(); 871 removeMotionInstance(motion);
829 posep->setWeight(0.f); 872 mDeprecatedMotions.erase(found_it);
873 }
874 else
875 {
876 // for motions that we are keeping, simply remove from active queue
877 mActiveMotions.remove(motion);
830 } 878 }
831
832 motion->deactivate();
833 mActiveMotions.remove(motion);
834 879
835 return TRUE; 880 return TRUE;
836} 881}
837 882
883void LLMotionController::deprecateMotionInstance(LLMotion* motion)
884{
885 mDeprecatedMotions.insert(motion);
886
887 //fade out deprecated motion
888 stopMotionInstance(motion, FALSE);
889 //no longer canonical
890 mAllMotions.erase(motion->getID());
891}
892
838//----------------------------------------------------------------------------- 893//-----------------------------------------------------------------------------
839// isMotionActive() 894// isMotionActive()
840//----------------------------------------------------------------------------- 895//-----------------------------------------------------------------------------
@@ -857,7 +912,7 @@ bool LLMotionController::isMotionLoading(LLMotion* motion)
857//----------------------------------------------------------------------------- 912//-----------------------------------------------------------------------------
858LLMotion *LLMotionController::findMotion(const LLUUID& id) 913LLMotion *LLMotionController::findMotion(const LLUUID& id)
859{ 914{
860 return mAllMotions[id]; 915 return get_if_there<LLUUID, LLMotion*>(mAllMotions, id, NULL);
861} 916}
862 917
863//----------------------------------------------------------------------------- 918//-----------------------------------------------------------------------------