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.cpp946
1 files changed, 946 insertions, 0 deletions
diff --git a/linden/indra/llcharacter/llmotioncontroller.cpp b/linden/indra/llcharacter/llmotioncontroller.cpp
new file mode 100644
index 0000000..3e1456b
--- /dev/null
+++ b/linden/indra/llcharacter/llmotioncontroller.cpp
@@ -0,0 +1,946 @@
1/**
2 * @file llmotioncontroller.cpp
3 * @brief Implementation of LLMotionController class.
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28//-----------------------------------------------------------------------------
29// Header Files
30//-----------------------------------------------------------------------------
31#include "linden_common.h"
32
33#include "llmotioncontroller.h"
34#include "llkeyframemotion.h"
35#include "llmath.h"
36#include "lltimer.h"
37#include "llanimationstates.h"
38#include "llstl.h"
39
40const S32 NUM_JOINT_SIGNATURE_STRIDES = LL_CHARACTER_MAX_JOINTS / 4;
41const U32 MAX_MOTION_INSTANCES = 32;
42
43//-----------------------------------------------------------------------------
44// Constants and statics
45//-----------------------------------------------------------------------------
46LLMotionRegistry LLMotionController::sRegistry;
47
48//-----------------------------------------------------------------------------
49// LLMotionTableEntry()
50//-----------------------------------------------------------------------------
51LLMotionTableEntry::LLMotionTableEntry()
52{
53 mConstructor = NULL;
54 mID.setNull();
55}
56
57LLMotionTableEntry::LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id)
58 : mConstructor(constructor), mID(id)
59{
60
61}
62
63//-----------------------------------------------------------------------------
64// create()
65//-----------------------------------------------------------------------------
66LLMotion* LLMotionTableEntry::create(const LLUUID &id)
67{
68 LLMotion* motionp = mConstructor(id);
69
70 return motionp;
71}
72
73
74//-----------------------------------------------------------------------------
75//-----------------------------------------------------------------------------
76// LLMotionRegistry class
77//-----------------------------------------------------------------------------
78//-----------------------------------------------------------------------------
79
80//-----------------------------------------------------------------------------
81// LLMotionRegistry()
82// Class Constructor
83//-----------------------------------------------------------------------------
84LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, LLMotionTableEntry())
85{
86
87}
88
89
90//-----------------------------------------------------------------------------
91// ~LLMotionRegistry()
92// Class Destructor
93//-----------------------------------------------------------------------------
94LLMotionRegistry::~LLMotionRegistry()
95{
96 mMotionTable.removeAll();
97}
98
99
100//-----------------------------------------------------------------------------
101// addMotion()
102//-----------------------------------------------------------------------------
103BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor constructor )
104{
105// llinfos << "Registering motion: " << name << llendl;
106 if (!mMotionTable.check(id))
107 {
108 mMotionTable.set(id, LLMotionTableEntry(constructor, id));
109 return TRUE;
110 }
111
112 return FALSE;
113}
114
115//-----------------------------------------------------------------------------
116// markBad()
117//-----------------------------------------------------------------------------
118void LLMotionRegistry::markBad( const LLUUID& id )
119{
120 mMotionTable.set(id, LLMotionTableEntry());
121}
122
123//-----------------------------------------------------------------------------
124// createMotion()
125//-----------------------------------------------------------------------------
126LLMotion *LLMotionRegistry::createMotion( const LLUUID &id )
127{
128 LLMotionTableEntry motion_entry = mMotionTable.get(id);
129 LLMotion* motion = NULL;
130
131 if ( motion_entry.getID().isNull() )
132 {
133 // *FIX: need to replace with a better default scheme. RN
134 motion = LLKeyframeMotion::create(id);
135 }
136 else
137 {
138 motion = motion_entry.create(id);
139 }
140
141 return motion;
142}
143
144//-----------------------------------------------------------------------------
145//-----------------------------------------------------------------------------
146// LLMotionController class
147//-----------------------------------------------------------------------------
148//-----------------------------------------------------------------------------
149
150//-----------------------------------------------------------------------------
151// LLMotionController()
152// Class Constructor
153//-----------------------------------------------------------------------------
154LLMotionController::LLMotionController( )
155{
156 mTime = 0.f;
157 mTimeOffset = 0.f;
158 mLastTime = 0.0f;
159 mHasRunOnce = FALSE;
160 mPaused = FALSE;
161 mPauseTime = 0.f;
162 mTimeStep = 0.f;
163 mTimeStepCount = 0;
164 mLastInterp = 0.f;
165 mTimeFactor = 1.f;
166}
167
168
169//-----------------------------------------------------------------------------
170// ~LLMotionController()
171// Class Destructor
172//-----------------------------------------------------------------------------
173LLMotionController::~LLMotionController()
174{
175 deleteAllMotions();
176}
177
178//-----------------------------------------------------------------------------
179// deleteAllMotions()
180//-----------------------------------------------------------------------------
181void LLMotionController::deleteAllMotions()
182{
183 mLoadingMotions.removeAllNodes();
184 mLoadedMotions.clear();
185 mActiveMotions.removeAllNodes();
186
187 for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer());
188 mAllMotions.clear();
189}
190
191//-----------------------------------------------------------------------------
192// addLoadedMotion()
193//-----------------------------------------------------------------------------
194void LLMotionController::addLoadedMotion(LLMotion* motionp)
195{
196 if (mLoadedMotions.size() > MAX_MOTION_INSTANCES)
197 {
198 // too many motions active this frame, kill all blenders
199 mPoseBlender.clearBlenders();
200
201 for (U32 i = 0; i < mLoadedMotions.size(); i++)
202 {
203 LLMotion* cur_motionp = mLoadedMotions.front();
204 mLoadedMotions.pop_front();
205
206 // motion isn't playing, delete it
207 if (!isMotionActive(cur_motionp))
208 {
209 mCharacter->requestStopMotion(cur_motionp);
210 mAllMotions.erase(cur_motionp->getID());
211 delete cur_motionp;
212 if (mLoadedMotions.size() <= MAX_MOTION_INSTANCES)
213 {
214 break;
215 }
216 }
217 else
218 {
219 // put active motion on back
220 mLoadedMotions.push_back(cur_motionp);
221 }
222 }
223 }
224 mLoadedMotions.push_back(motionp);
225}
226
227//-----------------------------------------------------------------------------
228// setTimeStep()
229//-----------------------------------------------------------------------------
230void LLMotionController::setTimeStep(F32 step)
231{
232 mTimeStep = step;
233
234 if (step != 0.f)
235 {
236 // make sure timestamps conform to new quantum
237 for( LLMotion* motionp = mActiveMotions.getFirstData();
238 motionp != NULL;
239 motionp = mActiveMotions.getNextData() )
240 {
241 motionp->mActivationTimestamp = (F32)llfloor(motionp->mActivationTimestamp / step) * step;
242 BOOL stopped = motionp->isStopped();
243 motionp->setStopTime((F32)llfloor(motionp->getStopTime() / step) * step);
244 motionp->setStopped(stopped);
245 motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step;
246 }
247 }
248}
249
250//-----------------------------------------------------------------------------
251// setTimeFactor()
252//-----------------------------------------------------------------------------
253void LLMotionController::setTimeFactor(F32 time_factor)
254{
255 mTimeOffset += mTimer.getElapsedTimeAndResetF32() * mTimeFactor;
256 mTimeFactor = time_factor;
257}
258
259//-----------------------------------------------------------------------------
260// getFirstActiveMotion()
261//-----------------------------------------------------------------------------
262LLMotion* LLMotionController::getFirstActiveMotion()
263{
264 return mActiveMotions.getFirstData();
265}
266
267//-----------------------------------------------------------------------------
268// getNextActiveMotion()
269//-----------------------------------------------------------------------------
270LLMotion* LLMotionController::getNextActiveMotion()
271{
272 return mActiveMotions.getNextData();
273}
274
275
276//-----------------------------------------------------------------------------
277// setCharacter()
278//-----------------------------------------------------------------------------
279void LLMotionController::setCharacter(LLCharacter *character)
280{
281 mCharacter = character;
282}
283
284
285//-----------------------------------------------------------------------------
286// addMotion()
287//-----------------------------------------------------------------------------
288BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constructor )
289{
290 return sRegistry.addMotion(id, constructor);
291}
292
293//-----------------------------------------------------------------------------
294// removeMotion()
295//-----------------------------------------------------------------------------
296void LLMotionController::removeMotion( const LLUUID& id)
297{
298 LLMotion* motionp = findMotion(id);
299 if (motionp)
300 {
301 stopMotionLocally(id, TRUE);
302
303 mLoadingMotions.deleteData(motionp);
304 std::deque<LLMotion*>::iterator motion_it;
305 for (motion_it = mLoadedMotions.begin(); motion_it != mLoadedMotions.end(); ++motion_it)
306 {
307 if(*motion_it == motionp)
308 {
309 mLoadedMotions.erase(motion_it);
310 break;
311 }
312 }
313 mActiveMotions.deleteData(motionp);
314 mAllMotions.erase(id);
315 delete motionp;
316 }
317}
318
319//-----------------------------------------------------------------------------
320// createMotion()
321//-----------------------------------------------------------------------------
322LLMotion* LLMotionController::createMotion( const LLUUID &id )
323{
324 // do we have an instance of this motion for this character?
325 LLMotion *motion = findMotion(id);
326
327 // if not, we need to create one
328 if (!motion)
329 {
330 // look up constructor and create it
331 motion = sRegistry.createMotion(id);
332 if (!motion)
333 {
334 return NULL;
335 }
336
337 // look up name for default motions
338 const char* motion_name = gAnimLibrary.animStateToString(id);
339 if (motion_name)
340 {
341 motion->setName(motion_name);
342 }
343
344 // initialize the new instance
345 LLMotion::LLMotionInitStatus stat = motion->onInitialize(mCharacter);
346 switch(stat)
347 {
348 case LLMotion::STATUS_FAILURE:
349 llinfos << "Motion " << id << " init failed." << llendl;
350 sRegistry.markBad(id);
351 delete motion;
352 return NULL;
353 case LLMotion::STATUS_HOLD:
354 mLoadingMotions.addData(motion);
355 break;
356 case LLMotion::STATUS_SUCCESS:
357 // add motion to our list
358 addLoadedMotion(motion);
359 break;
360 default:
361 llerrs << "Invalid initialization status" << llendl;
362 break;
363 }
364
365 mAllMotions[id] = motion;
366 }
367 return motion;
368}
369
370//-----------------------------------------------------------------------------
371// startMotion()
372//-----------------------------------------------------------------------------
373BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset)
374{
375 // look for motion in our list of created motions
376 LLMotion *motion = createMotion(id);
377
378 if (!motion)
379 {
380 return FALSE;
381 }
382 //if the motion is already active, then we're done
383 else if (isMotionActive(motion)) // motion is playing and...
384 {
385 if (motion->isStopped()) // motion has been stopped
386 {
387 deactivateMotion(motion);
388 }
389 else if (mTime < motion->mSendStopTimestamp) // motion is still active
390 {
391 return TRUE;
392 }
393 }
394
395// llinfos << "Starting motion " << name << llendl;
396 return activateMotion(motion, mTime - start_offset);
397}
398
399
400//-----------------------------------------------------------------------------
401// stopMotionLocally()
402//-----------------------------------------------------------------------------
403BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate)
404{
405 // if already inactive, return false
406 LLMotion *motion = findMotion(id);
407 if (!motion)
408 {
409 return FALSE;
410 }
411
412 // If on active list, stop it
413 if (isMotionActive(motion) && !motion->isStopped())
414 {
415 // when using timesteps, set stop time to last frame's time, otherwise grab current timer value
416 // *FIX: should investigate this inconsistency...hints of obscure bugs
417
418 F32 stop_time = (mTimeStep != 0.f || mPaused) ? (mTime) : mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor);
419 motion->setStopTime(stop_time);
420
421 if (stop_immediate)
422 {
423 deactivateMotion(motion);
424 }
425 return TRUE;
426 }
427 else if (isMotionLoading(motion))
428 {
429 motion->setStopped(TRUE);
430 return TRUE;
431 }
432
433 return FALSE;
434}
435
436
437//-----------------------------------------------------------------------------
438// updateRegularMotions()
439//-----------------------------------------------------------------------------
440void LLMotionController::updateRegularMotions()
441{
442 updateMotionsByType(LLMotion::NORMAL_BLEND);
443}
444
445//-----------------------------------------------------------------------------
446// updateAdditiveMotions()
447//-----------------------------------------------------------------------------
448void LLMotionController::updateAdditiveMotions()
449{
450 updateMotionsByType(LLMotion::ADDITIVE_BLEND);
451}
452
453//-----------------------------------------------------------------------------
454// resetJointSignatures()
455//-----------------------------------------------------------------------------
456void LLMotionController::resetJointSignatures()
457{
458 memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS);
459 memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS);
460}
461
462//-----------------------------------------------------------------------------
463// updateMotionsByType()
464//-----------------------------------------------------------------------------
465void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type)
466{
467 BOOL update_result = TRUE;
468 U8 last_joint_signature[LL_CHARACTER_MAX_JOINTS];
469
470 memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS);
471
472 // iterate through active motions in chronological order
473 for(LLMotion* motionp = mActiveMotions.getFirstData();
474 motionp != NULL;
475 motionp = mActiveMotions.getNextData())
476 {
477 if (motionp->getBlendType() != anim_type)
478 {
479 continue;
480 }
481
482 BOOL update_motion = FALSE;
483
484 if (motionp->getPose()->getWeight() < 1.f)
485 {
486 update_motion = TRUE;
487 }
488 else
489 {
490 S32 i;
491 // NUM_JOINT_SIGNATURE_STRIDES should be multiple of 4
492 for (i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++)
493 {
494 U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]);
495 U32 test_signature = *(U32*)&(motionp->mJointSignature[0][i * 4]);
496
497 if ((*current_signature | test_signature) > (*current_signature))
498 {
499 *current_signature |= test_signature;
500 update_motion = TRUE;
501 }
502
503 *((U32*)&last_joint_signature[i * 4]) = *(U32*)&(mJointSignature[1][i * 4]);
504 current_signature = (U32*)&(mJointSignature[1][i * 4]);
505 test_signature = *(U32*)&(motionp->mJointSignature[1][i * 4]);
506
507 if ((*current_signature | test_signature) > (*current_signature))
508 {
509 *current_signature |= test_signature;
510 update_motion = TRUE;
511 }
512 }
513 }
514
515 if (!update_motion)
516 {
517 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
518 {
519 deactivateMotion(motionp);
520 }
521 else if (motionp->isStopped() && mTime > motionp->getStopTime())
522 {
523 // is this the first iteration in the ease out phase?
524 if (mLastTime <= motionp->getStopTime())
525 {
526 // store residual weight for this motion
527 motionp->mResidualWeight = motionp->getPose()->getWeight();
528 }
529 }
530 else if (mTime > motionp->mSendStopTimestamp)
531 {
532 // notify character of timed stop event on first iteration past sendstoptimestamp
533 // this will only be called when an animation stops itself (runs out of time)
534 if (mLastTime <= motionp->mSendStopTimestamp)
535 {
536 mCharacter->requestStopMotion( motionp );
537 stopMotionLocally(motionp->getID(), FALSE);
538 }
539 }
540 else if (mTime >= motionp->mActivationTimestamp)
541 {
542 if (mLastTime < motionp->mActivationTimestamp)
543 {
544 motionp->mResidualWeight = motionp->getPose()->getWeight();
545 }
546 }
547 continue;
548 }
549
550 LLPose *posep = motionp->getPose();
551
552 // only filter by LOD after running every animation at least once (to prime the avatar state)
553 if (mHasRunOnce && motionp->getMinPixelArea() > mCharacter->getPixelArea())
554 {
555 motionp->fadeOut();
556
557 //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic)
558 if (mTime > motionp->mSendStopTimestamp)
559 {
560 // notify character of timed stop event on first iteration past sendstoptimestamp
561 // this will only be called when an animation stops itself (runs out of time)
562 if (mLastTime <= motionp->mSendStopTimestamp)
563 {
564 mCharacter->requestStopMotion( motionp );
565 stopMotionLocally(motionp->getID(), FALSE);
566 }
567 }
568
569 if (motionp->getFadeWeight() < 0.01f)
570 {
571 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
572 {
573 posep->setWeight(0.f);
574 deactivateMotion(motionp);
575 }
576 continue;
577 }
578 }
579 else
580 {
581 motionp->fadeIn();
582 }
583
584 //**********************
585 // MOTION INACTIVE
586 //**********************
587 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
588 {
589 // this motion has gone on too long, deactivate it
590 // did we have a chance to stop it?
591 if (mLastTime <= motionp->getStopTime())
592 {
593 // if not, let's stop it this time through and deactivate it the next
594
595 posep->setWeight(motionp->getFadeWeight());
596 motionp->onUpdate(motionp->getStopTime() - motionp->mActivationTimestamp, last_joint_signature);
597 }
598 else
599 {
600 posep->setWeight(0.f);
601 deactivateMotion(motionp);
602 continue;
603 }
604 }
605
606 //**********************
607 // MOTION EASE OUT
608 //**********************
609 else if (motionp->isStopped() && mTime > motionp->getStopTime())
610 {
611 // is this the first iteration in the ease out phase?
612 if (mLastTime <= motionp->getStopTime())
613 {
614 // store residual weight for this motion
615 motionp->mResidualWeight = motionp->getPose()->getWeight();
616 }
617
618 if (motionp->getEaseOutDuration() == 0.f)
619 {
620 posep->setWeight(0.f);
621 }
622 else
623 {
624 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mTime - motionp->getStopTime()) / motionp->getEaseOutDuration())));
625 }
626
627 // perform motion update
628 update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature);
629 }
630
631 //**********************
632 // MOTION ACTIVE
633 //**********************
634 else if (mTime > motionp->mActivationTimestamp + motionp->getEaseInDuration())
635 {
636 posep->setWeight(motionp->getFadeWeight());
637
638 //should we notify the simulator that this motion should be stopped?
639 if (mTime > motionp->mSendStopTimestamp)
640 {
641 // notify character of timed stop event on first iteration past sendstoptimestamp
642 // this will only be called when an animation stops itself (runs out of time)
643 if (mLastTime <= motionp->mSendStopTimestamp)
644 {
645 mCharacter->requestStopMotion( motionp );
646 stopMotionLocally(motionp->getID(), FALSE);
647 }
648 }
649
650 // perform motion update
651 update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature);
652 }
653
654 //**********************
655 // MOTION EASE IN
656 //**********************
657 else if (mTime >= motionp->mActivationTimestamp)
658 {
659 if (mLastTime < motionp->mActivationTimestamp)
660 {
661 motionp->mResidualWeight = motionp->getPose()->getWeight();
662 }
663 if (motionp->getEaseInDuration() == 0.f)
664 {
665 posep->setWeight(motionp->getFadeWeight());
666 }
667 else
668 {
669 // perform motion update
670 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration()));
671 }
672 // perform motion update
673 update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature);
674 }
675 else
676 {
677 posep->setWeight(0.f);
678 update_result = motionp->onUpdate(0.f, last_joint_signature);
679 }
680
681 // allow motions to deactivate themselves
682 if (!update_result)
683 {
684 if (!motionp->isStopped() || motionp->getStopTime() > mTime)
685 {
686 // animation has stopped itself due to internal logic
687 // propagate this to the network
688 // as not all viewers are guaranteed to have access to the same logic
689 mCharacter->requestStopMotion( motionp );
690 stopMotionLocally(motionp->getID(), FALSE);
691 }
692
693 }
694
695 // even if onupdate returns FALSE, add this motion in to the blend one last time
696 mPoseBlender.addMotion(motionp);
697 }
698}
699
700
701//-----------------------------------------------------------------------------
702// updateMotion()
703//-----------------------------------------------------------------------------
704void LLMotionController::updateMotion()
705{
706 BOOL use_quantum = (mTimeStep != 0.f);
707
708 // Update timing info for this time step.
709 if (!mPaused)
710 {
711 F32 update_time = mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor);
712 if (use_quantum)
713 {
714 F32 time_interval = fmodf(update_time, mTimeStep);
715
716 // always animate *ahead* of actual time
717 S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1;
718 if (quantum_count == mTimeStepCount)
719 {
720 // we're still in same time quantum as before, so just interpolate and exit
721 if (!mPaused)
722 {
723 F32 interp = time_interval / mTimeStep;
724 mPoseBlender.interpolate(interp - mLastInterp);
725 mLastInterp = interp;
726 }
727
728 return;
729 }
730
731 // is calculating a new keyframe pose, make sure the last one gets applied
732 mPoseBlender.interpolate(1.f);
733 mPoseBlender.clearBlenders();
734
735 mTimeStepCount = quantum_count;
736 mLastTime = mTime;
737 mTime = (F32)quantum_count * mTimeStep;
738 mLastInterp = 0.f;
739 }
740 else
741 {
742 mLastTime = mTime;
743 mTime = update_time;
744 }
745 }
746
747 // query pending motions for completion
748 LLMotion* motionp;
749
750 for ( motionp = mLoadingMotions.getFirstData();
751 motionp != NULL;
752 motionp = mLoadingMotions.getNextData() )
753 {
754 LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter);
755 if (status == LLMotion::STATUS_SUCCESS)
756 {
757 mLoadingMotions.removeCurrentData();
758 // add motion to our loaded motion list
759 addLoadedMotion(motionp);
760 // this motion should be playing
761 if (!motionp->isStopped())
762 {
763 activateMotion(motionp, mTime);
764 }
765 }
766 else if (status == LLMotion::STATUS_FAILURE)
767 {
768 llinfos << "Motion " << motionp->getID() << " init failed." << llendl;
769 sRegistry.markBad(motionp->getID());
770 mLoadingMotions.removeCurrentData();
771 mAllMotions.erase(motionp->getID());
772 delete motionp;
773 }
774 }
775
776 resetJointSignatures();
777
778 if (!mPaused)
779 {
780 // update additive motions
781 updateAdditiveMotions();
782 resetJointSignatures();
783
784 // update all regular motions
785 updateRegularMotions();
786
787 if (use_quantum)
788 {
789 mPoseBlender.blendAndCache(TRUE);
790 }
791 else
792 {
793 mPoseBlender.blendAndApply();
794 }
795 }
796
797 mHasRunOnce = TRUE;
798// llinfos << "Motion controller time " << motionTimer.getElapsedTimeF32() << llendl;
799}
800
801
802//-----------------------------------------------------------------------------
803// activateMotion()
804//-----------------------------------------------------------------------------
805BOOL LLMotionController::activateMotion(LLMotion *motion, F32 time)
806{
807 if (mLoadingMotions.checkData(motion))
808 {
809 // we want to start this motion, but we can't yet, so flag it as started
810 motion->setStopped(FALSE);
811 // report pending animations as activated
812 return TRUE;
813 }
814
815 motion->mResidualWeight = motion->getPose()->getWeight();
816 motion->mActivationTimestamp = time;
817
818 // set stop time based on given duration and ease out time
819 if (motion->getDuration() != 0.f && !motion->getLoop())
820 {
821 F32 ease_out_time;
822 F32 motion_duration;
823
824 // should we stop at the end of motion duration, or a bit earlier
825 // to allow it to ease out while moving?
826 ease_out_time = motion->getEaseOutDuration();
827
828 // is the clock running when the motion is easing in?
829 // if not (POSTURE_EASE) then we need to wait that much longer before triggering the stop
830 motion_duration = llmax(motion->getDuration() - ease_out_time, 0.f);
831 motion->mSendStopTimestamp = time + motion_duration;
832 }
833 else
834 {
835 motion->mSendStopTimestamp = F32_MAX;
836 }
837
838 mActiveMotions.addData(motion);
839
840 motion->activate();
841 motion->onUpdate(0.f, mJointSignature[1]);
842
843 return TRUE;
844}
845
846//-----------------------------------------------------------------------------
847// deactivateMotion()
848//-----------------------------------------------------------------------------
849BOOL LLMotionController::deactivateMotion(LLMotion *motion)
850{
851 motion->deactivate();
852 mActiveMotions.removeData(motion);
853
854 return TRUE;
855}
856
857//-----------------------------------------------------------------------------
858// isMotionActive()
859//-----------------------------------------------------------------------------
860BOOL LLMotionController::isMotionActive(LLMotion *motion)
861{
862 if (motion && motion->isActive())
863 {
864 return TRUE;
865 }
866
867 return FALSE;
868}
869
870//-----------------------------------------------------------------------------
871// isMotionLoading()
872//-----------------------------------------------------------------------------
873BOOL LLMotionController::isMotionLoading(LLMotion* motion)
874{
875 return mLoadingMotions.checkData(motion);
876}
877
878
879//-----------------------------------------------------------------------------
880// findMotion()
881//-----------------------------------------------------------------------------
882LLMotion *LLMotionController::findMotion(const LLUUID& id)
883{
884 return mAllMotions[id];
885}
886
887
888//-----------------------------------------------------------------------------
889// flushAllMotions()
890//-----------------------------------------------------------------------------
891void LLMotionController::flushAllMotions()
892{
893 LLDynamicArray<LLUUID> active_motions;
894 LLDynamicArray<F32> active_motion_times;
895
896 for (LLMotion* motionp = mActiveMotions.getFirstData();
897 motionp;
898 motionp = mActiveMotions.getNextData())
899 {
900 active_motions.put(motionp->getID());
901 active_motion_times.put(mTime - motionp->mActivationTimestamp);
902 motionp->deactivate();
903 }
904
905 // delete all motion instances
906 deleteAllMotions();
907
908 // kill current hand pose that was previously called out by
909 // keyframe motion
910 mCharacter->removeAnimationData("Hand Pose");
911
912 // restart motions
913 for (S32 i = 0; i < active_motions.count(); i++)
914 {
915 startMotion(active_motions[i], active_motion_times[i]);
916 }
917}
918
919//-----------------------------------------------------------------------------
920// pause()
921//-----------------------------------------------------------------------------
922void LLMotionController::pause()
923{
924 if (!mPaused)
925 {
926 //llinfos << "Pausing animations..." << llendl;
927 mPauseTime = mTimer.getElapsedTimeF32();
928 mPaused = TRUE;
929 }
930
931}
932
933//-----------------------------------------------------------------------------
934// unpause()
935//-----------------------------------------------------------------------------
936void LLMotionController::unpause()
937{
938 if (mPaused)
939 {
940 //llinfos << "Unpausing animations..." << llendl;
941 mTimer.reset();
942 mTimer.setAge(mPauseTime);
943 mPaused = FALSE;
944 }
945}
946// End