aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcharacter/llkeyframemotion.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcharacter/llkeyframemotion.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llcharacter/llkeyframemotion.cpp')
-rw-r--r--linden/indra/llcharacter/llkeyframemotion.cpp2138
1 files changed, 2138 insertions, 0 deletions
diff --git a/linden/indra/llcharacter/llkeyframemotion.cpp b/linden/indra/llcharacter/llkeyframemotion.cpp
new file mode 100644
index 0000000..e5b0d99
--- /dev/null
+++ b/linden/indra/llcharacter/llkeyframemotion.cpp
@@ -0,0 +1,2138 @@
1/**
2 * @file llkeyframemotion.cpp
3 * @brief Implementation of LLKeyframeMotion 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 "llmath.h"
34#include "llanimationstates.h"
35#include "llassetstorage.h"
36#include "lldatapacker.h"
37#include "llcharacter.h"
38#include "llcriticaldamp.h"
39#include "lldir.h"
40#include "llendianswizzle.h"
41#include "llkeyframemotion.h"
42#include "llquantize.h"
43#include "llvfile.h"
44#include "m3math.h"
45#include "message.h"
46
47//-----------------------------------------------------------------------------
48// Static Definitions
49//-----------------------------------------------------------------------------
50LLVFS* LLKeyframeMotion::sVFS = NULL;
51LLKeyframeDataCache::LLKeyframeDataMap LLKeyframeDataCache::sKeyframeDataMap;
52
53//-----------------------------------------------------------------------------
54// Globals
55//-----------------------------------------------------------------------------
56static F32 JOINT_LENGTH_K = 0.7f;
57static S32 MAX_ITERATIONS = 20;
58static S32 MIN_ITERATIONS = 1;
59static S32 MIN_ITERATION_COUNT = 2;
60static F32 MAX_PIXEL_AREA_CONSTRAINTS = 80000.f;
61static F32 MIN_PIXEL_AREA_CONSTRAINTS = 1000.f;
62static F32 MIN_ACCELERATION_SQUARED = 0.0005f * 0.0005f;
63
64static F32 MAX_CONSTRAINTS = 10;
65
66//-----------------------------------------------------------------------------
67// JointMotionList::dumpDiagInfo()
68//-----------------------------------------------------------------------------
69U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo()
70{
71 S32 total_size = sizeof(JointMotionList);
72
73 for (U32 i = 0; i < mNumJointMotions; i++)
74 {
75 LLKeyframeMotion::JointMotion* joint_motion_p = &mJointMotionArray[i];
76
77 llinfos << "\tJoint " << joint_motion_p->mJointName << llendl;
78 if (joint_motion_p->mUsage & LLJointState::SCALE)
79 {
80 llinfos << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at "
81 << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << llendl;
82
83 total_size += joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey);
84 }
85 if (joint_motion_p->mUsage & LLJointState::ROT)
86 {
87 llinfos << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at "
88 << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << llendl;
89
90 total_size += joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey);
91 }
92 if (joint_motion_p->mUsage & LLJointState::POS)
93 {
94 llinfos << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at "
95 << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << llendl;
96
97 total_size += joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey);
98 }
99 }
100 llinfos << "Size: " << total_size << " bytes" << llendl;
101
102 return total_size;
103}
104
105//-----------------------------------------------------------------------------
106//-----------------------------------------------------------------------------
107// ****Curve classes
108//-----------------------------------------------------------------------------
109//-----------------------------------------------------------------------------
110
111//-----------------------------------------------------------------------------
112// ScaleCurve::ScaleCurve()
113//-----------------------------------------------------------------------------
114LLKeyframeMotion::ScaleCurve::ScaleCurve()
115{
116 mInterpolationType = LLKeyframeMotion::IT_LINEAR;
117 mNumKeys = 0;
118}
119
120//-----------------------------------------------------------------------------
121// ScaleCurve::~ScaleCurve()
122//-----------------------------------------------------------------------------
123LLKeyframeMotion::ScaleCurve::~ScaleCurve()
124{
125 mKeys.deleteAllData();
126 mNumKeys = 0;
127}
128
129//-----------------------------------------------------------------------------
130// getValue()
131//-----------------------------------------------------------------------------
132LLVector3 LLKeyframeMotion::ScaleCurve::getValue(F32 time, F32 duration)
133{
134 LLVector3 value;
135 F32 index_before, index_after;
136 ScaleKey* scale_before;
137 ScaleKey* scale_after;
138
139 mKeys.getInterval(time, index_before, index_after, scale_before, scale_after);
140 if (scale_before)
141 {
142 if (!scale_after)
143 {
144 scale_after = &mLoopInKey;
145 index_after = duration;
146 }
147
148 if (index_after == index_before)
149 {
150 value = scale_after->mScale;
151 }
152 else
153 {
154 F32 u = (time - index_before) / (index_after - index_before);
155 value = interp(u, *scale_before, *scale_after);
156 }
157 }
158 else
159 {
160 // before first key
161 if (scale_after)
162 {
163 value = scale_after->mScale;
164 }
165 // no keys?
166 else
167 {
168 value.clearVec();
169 }
170 }
171
172 return value;
173}
174
175//-----------------------------------------------------------------------------
176// interp()
177//-----------------------------------------------------------------------------
178LLVector3 LLKeyframeMotion::ScaleCurve::interp(F32 u, ScaleKey& before, ScaleKey& after)
179{
180 switch (mInterpolationType)
181 {
182 case IT_STEP:
183 return before.mScale;
184
185 default:
186 case IT_LINEAR:
187 case IT_SPLINE:
188 return lerp(before.mScale, after.mScale, u);
189 }
190}
191
192//-----------------------------------------------------------------------------
193// RotationCurve::RotationCurve()
194//-----------------------------------------------------------------------------
195LLKeyframeMotion::RotationCurve::RotationCurve()
196{
197 mInterpolationType = LLKeyframeMotion::IT_LINEAR;
198 mNumKeys = 0;
199}
200
201//-----------------------------------------------------------------------------
202// RotationCurve::~RotationCurve()
203//-----------------------------------------------------------------------------
204LLKeyframeMotion::RotationCurve::~RotationCurve()
205{
206 mKeys.deleteAllData();
207 mNumKeys = 0;
208}
209
210//-----------------------------------------------------------------------------
211// RotationCurve::getValue()
212//-----------------------------------------------------------------------------
213LLQuaternion LLKeyframeMotion::RotationCurve::getValue(F32 time, F32 duration)
214{
215 LLQuaternion value;
216 F32 index_before, index_after;
217 RotationKey* rot_before;
218 RotationKey* rot_after;
219
220 mKeys.getInterval(time, index_before, index_after, rot_before, rot_after);
221
222 if (rot_before)
223 {
224 if (!rot_after)
225 {
226 rot_after = &mLoopInKey;
227 index_after = duration;
228 }
229
230 if (index_after == index_before)
231 {
232 value = rot_after->mRotation;
233 }
234 else
235 {
236 F32 u = (time - index_before) / (index_after - index_before);
237 value = interp(u, *rot_before, *rot_after);
238 }
239 }
240 else
241 {
242 // before first key
243 if (rot_after)
244 {
245 value = rot_after->mRotation;
246 }
247 // no keys?
248 else
249 {
250 value = LLQuaternion::DEFAULT;
251 }
252 }
253
254 return value;
255}
256
257//-----------------------------------------------------------------------------
258// interp()
259//-----------------------------------------------------------------------------
260LLQuaternion LLKeyframeMotion::RotationCurve::interp(F32 u, RotationKey& before, RotationKey& after)
261{
262 switch (mInterpolationType)
263 {
264 case IT_STEP:
265 return before.mRotation;
266
267 default:
268 case IT_LINEAR:
269 case IT_SPLINE:
270 return nlerp(u, before.mRotation, after.mRotation);
271 }
272}
273
274
275//-----------------------------------------------------------------------------
276// PositionCurve::PositionCurve()
277//-----------------------------------------------------------------------------
278LLKeyframeMotion::PositionCurve::PositionCurve()
279{
280 mInterpolationType = LLKeyframeMotion::IT_LINEAR;
281 mNumKeys = 0;
282}
283
284//-----------------------------------------------------------------------------
285// PositionCurve::~PositionCurve()
286//-----------------------------------------------------------------------------
287LLKeyframeMotion::PositionCurve::~PositionCurve()
288{
289 mKeys.deleteAllData();
290 mNumKeys = 0;
291}
292
293//-----------------------------------------------------------------------------
294// PositionCurve::getValue()
295//-----------------------------------------------------------------------------
296LLVector3 LLKeyframeMotion::PositionCurve::getValue(F32 time, F32 duration)
297{
298 LLVector3 value;
299 F32 index_before, index_after;
300 PositionKey* pos_before;
301 PositionKey* pos_after;
302
303 mKeys.getInterval(time, index_before, index_after, pos_before, pos_after);
304
305 if (pos_before)
306 {
307 if (!pos_after)
308 {
309 pos_after = &mLoopInKey;
310 index_after = duration;
311 }
312
313 if (index_after == index_before)
314 {
315 value = pos_after->mPosition;
316 }
317 else
318 {
319 F32 u = (time - index_before) / (index_after - index_before);
320 value = interp(u, *pos_before, *pos_after);
321 }
322 }
323 else
324 {
325 // before first key
326 if (pos_after)
327 {
328 value = pos_after->mPosition;
329 }
330 // no keys?
331 else
332 {
333 value.clearVec();
334 }
335 }
336
337 llassert(value.isFinite());
338
339 return value;
340}
341
342//-----------------------------------------------------------------------------
343// interp()
344//-----------------------------------------------------------------------------
345LLVector3 LLKeyframeMotion::PositionCurve::interp(F32 u, PositionKey& before, PositionKey& after)
346{
347 switch (mInterpolationType)
348 {
349 case IT_STEP:
350 return before.mPosition;
351 default:
352 case IT_LINEAR:
353 case IT_SPLINE:
354 return lerp(before.mPosition, after.mPosition, u);
355 }
356}
357
358
359//-----------------------------------------------------------------------------
360//-----------------------------------------------------------------------------
361// JointMotion class
362//-----------------------------------------------------------------------------
363//-----------------------------------------------------------------------------
364
365//-----------------------------------------------------------------------------
366// JointMotion::update()
367//-----------------------------------------------------------------------------
368void LLKeyframeMotion::JointMotion::update(LLJointState* joint_state, F32 time, F32 duration)
369{
370 // this value being 0 is the cause of https://jira.lindenlab.com/browse/SL-22678 but I haven't
371 // managed to get a stack to see how it got here. Testing for 0 here will stop the crash.
372 if ( joint_state == 0 )
373 {
374 return;
375 };
376
377 U32 usage = joint_state->getUsage();
378
379 //-------------------------------------------------------------------------
380 // update scale component of joint state
381 //-------------------------------------------------------------------------
382 if ((usage & LLJointState::SCALE) && mScaleCurve.mNumKeys)
383 {
384 joint_state->setScale( mScaleCurve.getValue( time, duration ) );
385 }
386
387 //-------------------------------------------------------------------------
388 // update rotation component of joint state
389 //-------------------------------------------------------------------------
390 if ((usage & LLJointState::ROT) && mRotationCurve.mNumKeys)
391 {
392 joint_state->setRotation( mRotationCurve.getValue( time, duration ) );
393 }
394
395 //-------------------------------------------------------------------------
396 // update position component of joint state
397 //-------------------------------------------------------------------------
398 if ((usage & LLJointState::POS) && mPositionCurve.mNumKeys)
399 {
400 joint_state->setPosition( mPositionCurve.getValue( time, duration ) );
401 }
402}
403
404
405//-----------------------------------------------------------------------------
406//-----------------------------------------------------------------------------
407// LLKeyframeMotion class
408//-----------------------------------------------------------------------------
409//-----------------------------------------------------------------------------
410
411//-----------------------------------------------------------------------------
412// LLKeyframeMotion()
413// Class Constructor
414//-----------------------------------------------------------------------------
415LLKeyframeMotion::LLKeyframeMotion( const LLUUID &id) : LLMotion(id)
416{
417 mJointMotionList = NULL;
418 mJointStates = NULL;
419 mLastSkeletonSerialNum = 0;
420 mLastLoopedTime = 0.f;
421 mLastUpdateTime = 0.f;
422 mAssetStatus = ASSET_UNDEFINED;
423 mPelvisp = NULL;
424}
425
426
427//-----------------------------------------------------------------------------
428// ~LLKeyframeMotion()
429// Class Destructor
430//-----------------------------------------------------------------------------
431LLKeyframeMotion::~LLKeyframeMotion()
432{
433 if (mJointStates)
434 {
435 delete [] mJointStates;
436 }
437 mConstraints.deleteAllData();
438}
439
440//-----------------------------------------------------------------------------
441// create()
442//-----------------------------------------------------------------------------
443LLMotion *LLKeyframeMotion::create(const LLUUID &id)
444{
445 return new LLKeyframeMotion(id);
446}
447
448//-----------------------------------------------------------------------------
449// LLKeyframeMotion::onInitialize(LLCharacter *character)
450//-----------------------------------------------------------------------------
451LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *character)
452{
453 mCharacter = character;
454
455 LLUUID* character_id;
456
457 // asset already loaded?
458 switch(mAssetStatus)
459 {
460 case ASSET_NEEDS_FETCH:
461 // request asset
462 mAssetStatus = ASSET_FETCHED;
463
464 character_id = new LLUUID(mCharacter->getID());
465 gAssetStorage->getAssetData(mID,
466 LLAssetType::AT_ANIMATION,
467 onLoadComplete,
468 (void *)character_id,
469 FALSE);
470
471 return STATUS_HOLD;
472 case ASSET_FETCHED:
473 return STATUS_HOLD;
474 case ASSET_FETCH_FAILED:
475 return STATUS_FAILURE;
476 case ASSET_LOADED:
477 return STATUS_SUCCESS;
478 default:
479 // we don't know what state the asset is in yet, so keep going
480 // check keyframe cache first then static vfs then asset request
481 break;
482 }
483
484 LLKeyframeMotion::JointMotionList* joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID());
485
486 if(joint_motion_list)
487 {
488 // motion already existed in cache, so grab it
489 mJointMotionList = joint_motion_list;
490
491 // don't forget to allocate joint states
492 mJointStates = new LLJointState[mJointMotionList->mNumJointMotions];
493
494 // set up joint states to point to character joints
495 for(U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
496 {
497 if (LLJoint *jointp = mCharacter->getJoint(mJointMotionList->mJointMotionArray[i].mJointName))
498 {
499 mJointStates[i].setJoint(jointp);
500 mJointStates[i].setUsage(mJointMotionList->mJointMotionArray[i].mUsage);
501 mJointStates[i].setPriority(joint_motion_list->mJointMotionArray[i].mPriority);
502 }
503 }
504 mAssetStatus = ASSET_LOADED;
505 setupPose();
506 return STATUS_SUCCESS;
507 }
508
509 //-------------------------------------------------------------------------
510 // Load named file by concatenating the character prefix with the motion name.
511 // Load data into a buffer to be parsed.
512 //-------------------------------------------------------------------------
513 U8 *anim_data;
514 S32 anim_file_size;
515
516 if (!sVFS)
517 {
518 llerrs << "Must call LLKeyframeMotion::setVFS() first before loading a keyframe file!" << llendl;
519 }
520
521 BOOL success = FALSE;
522 LLVFile* anim_file = new LLVFile(sVFS, mID, LLAssetType::AT_ANIMATION);
523 if (!anim_file || !anim_file->getSize())
524 {
525 delete anim_file;
526 anim_file = NULL;
527
528 // request asset over network on next call to load
529 mAssetStatus = ASSET_NEEDS_FETCH;
530
531 return STATUS_HOLD;
532 }
533 else
534 {
535 anim_file_size = anim_file->getSize();
536 anim_data = new U8[anim_file_size];
537 success = anim_file->read(anim_data, anim_file_size); /*Flawfinder: ignore*/
538 delete anim_file;
539 anim_file = NULL;
540 }
541
542 if (!success)
543 {
544 llwarns << "Can't open animation file " << mID << llendl;
545 mAssetStatus = ASSET_FETCH_FAILED;
546 return STATUS_FAILURE;
547 }
548
549 lldebugs << "Loading keyframe data for: " << getName() << ":" << getID() << " (" << anim_file_size << " bytes)" << llendl;
550
551 LLDataPackerBinaryBuffer dp(anim_data, anim_file_size);
552
553 if (!deserialize(dp))
554 {
555 llwarns << "Failed to decode asset for animation " << getName() << ":" << getID() << llendl;
556 mAssetStatus = ASSET_FETCH_FAILED;
557 return STATUS_FAILURE;
558 }
559
560 delete []anim_data;
561
562 mAssetStatus = ASSET_LOADED;
563 return STATUS_SUCCESS;
564}
565
566//-----------------------------------------------------------------------------
567// setupPose()
568//-----------------------------------------------------------------------------
569BOOL LLKeyframeMotion::setupPose()
570{
571 // add all valid joint states to the pose
572 U32 jm;
573 for (jm=0; jm<mJointMotionList->mNumJointMotions; jm++)
574 {
575 if ( mJointStates[jm].getJoint() )
576 {
577 addJointState( &mJointStates[jm] );
578 }
579 }
580
581 // initialize joint constraints
582 for (JointConstraintSharedData* shared_constraintp = mJointMotionList->mConstraints.getFirstData();
583 shared_constraintp;
584 shared_constraintp = mJointMotionList->mConstraints.getNextData())
585 {
586 JointConstraint* constraintp = new JointConstraint(shared_constraintp);
587 initializeConstraint(constraintp);
588 mConstraints.addData(constraintp);
589 }
590
591 if (mJointMotionList->mConstraints.getLength())
592 {
593 mPelvisp = mCharacter->getJoint("mPelvis");
594 if (!mPelvisp)
595 {
596 return FALSE;
597 }
598 }
599
600 // setup loop keys
601 setLoopIn(mJointMotionList->mLoopInPoint);
602 setLoopOut(mJointMotionList->mLoopOutPoint);
603
604 return TRUE;
605}
606
607//-----------------------------------------------------------------------------
608// LLKeyframeMotion::onActivate()
609//-----------------------------------------------------------------------------
610BOOL LLKeyframeMotion::onActivate()
611{
612 // If the keyframe anim has an associated emote, trigger it.
613 if( mEmoteName.length() > 0 )
614 {
615 mCharacter->startMotion( gAnimLibrary.stringToAnimState(mEmoteName.c_str()) );
616 }
617
618 mLastLoopedTime = 0.f;
619
620 return TRUE;
621}
622
623//-----------------------------------------------------------------------------
624// LLKeyframeMotion::onUpdate()
625//-----------------------------------------------------------------------------
626BOOL LLKeyframeMotion::onUpdate(F32 time, U8* joint_mask)
627{
628 llassert(time >= 0.f);
629
630 if (mJointMotionList->mLoop)
631 {
632 if (mJointMotionList->mDuration == 0.0f)
633 {
634 time = 0.f;
635 mLastLoopedTime = 0.0f;
636 }
637 else if (mStopped)
638 {
639 mLastLoopedTime = llmin(mJointMotionList->mDuration, mLastLoopedTime + time - mLastUpdateTime);
640 }
641 else if (time > mJointMotionList->mLoopOutPoint)
642 {
643 if ((mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint) == 0.f)
644 {
645 mLastLoopedTime = mJointMotionList->mLoopOutPoint;
646 }
647 else
648 {
649 mLastLoopedTime = mJointMotionList->mLoopInPoint +
650 fmod(time - mJointMotionList->mLoopOutPoint,
651 mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint);
652 }
653 }
654 else
655 {
656 mLastLoopedTime = time;
657 }
658 }
659 else
660 {
661 mLastLoopedTime = time;
662 }
663
664 applyKeyframes(mLastLoopedTime);
665
666 applyConstraints(mLastLoopedTime, joint_mask);
667
668 mLastUpdateTime = time;
669
670 return mLastLoopedTime <= mJointMotionList->mDuration;
671}
672
673//-----------------------------------------------------------------------------
674// applyKeyframes()
675//-----------------------------------------------------------------------------
676void LLKeyframeMotion::applyKeyframes(F32 time)
677{
678 U32 i;
679 for (i=0; i<mJointMotionList->mNumJointMotions; i++)
680 {
681 mJointMotionList->mJointMotionArray[i].update(
682 &mJointStates[i],
683 time,
684 mJointMotionList->mDuration );
685 }
686
687 LLJoint::JointPriority* pose_priority = (LLJoint::JointPriority* )mCharacter->getAnimationData("Hand Pose Priority");
688 if (pose_priority)
689 {
690 if (mJointMotionList->mMaxPriority >= *pose_priority)
691 {
692 mCharacter->setAnimationData("Hand Pose", &mJointMotionList->mHandPose);
693 mCharacter->setAnimationData("Hand Pose Priority", &mJointMotionList->mMaxPriority);
694 }
695 }
696 else
697 {
698 mCharacter->setAnimationData("Hand Pose", &mJointMotionList->mHandPose);
699 mCharacter->setAnimationData("Hand Pose Priority", &mJointMotionList->mMaxPriority);
700 }
701}
702
703//-----------------------------------------------------------------------------
704// applyConstraints()
705//-----------------------------------------------------------------------------
706void LLKeyframeMotion::applyConstraints(F32 time, U8* joint_mask)
707{
708 //TODO: investigate replacing spring simulation with critically damped motion
709
710 // re-init constraints if skeleton has changed
711 if (mCharacter->getSkeletonSerialNum() != mLastSkeletonSerialNum)
712 {
713 mLastSkeletonSerialNum = mCharacter->getSkeletonSerialNum();
714 for (JointConstraint* constraintp = mConstraints.getFirstData();
715 constraintp;
716 constraintp = mConstraints.getNextData())
717 {
718 initializeConstraint(constraintp);
719 }
720 }
721
722 // apply constraints
723 for (JointConstraint* constraintp = mConstraints.getFirstData();
724 constraintp;
725 constraintp = mConstraints.getNextData())
726 {
727 applyConstraint(constraintp, time, joint_mask);
728 }
729}
730
731//-----------------------------------------------------------------------------
732// LLKeyframeMotion::onDeactivate()
733//-----------------------------------------------------------------------------
734void LLKeyframeMotion::onDeactivate()
735{
736 for (JointConstraint* constraintp = mConstraints.getFirstData();
737 constraintp;
738 constraintp = mConstraints.getNextData())
739 {
740 deactivateConstraint(constraintp);
741 }
742}
743
744//-----------------------------------------------------------------------------
745// setStopTime()
746//-----------------------------------------------------------------------------
747// time is in seconds since character creation
748void LLKeyframeMotion::setStopTime(F32 time)
749{
750 LLMotion::setStopTime(time);
751
752 if (mJointMotionList->mLoop && mJointMotionList->mLoopOutPoint != mJointMotionList->mDuration)
753 {
754 F32 start_loop_time = mActivationTimestamp + mJointMotionList->mLoopInPoint;
755 F32 loop_fraction_time;
756 if (mJointMotionList->mLoopOutPoint == mJointMotionList->mLoopInPoint)
757 {
758 loop_fraction_time = 0.f;
759 }
760 else
761 {
762 loop_fraction_time = fmod(time - start_loop_time,
763 mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint);
764 }
765 mStopTimestamp = llmax(time,
766 (time - loop_fraction_time) + (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint) - getEaseOutDuration());
767 }
768}
769
770//-----------------------------------------------------------------------------
771// initializeConstraint()
772//-----------------------------------------------------------------------------
773void LLKeyframeMotion::initializeConstraint(JointConstraint* constraint)
774{
775 JointConstraintSharedData *shared_data = constraint->mSharedData;
776
777 S32 joint_num;
778 LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);
779 LLJoint* cur_joint = mJointStates[shared_data->mJointStateIndices[0]].getJoint();
780
781 F32 source_pos_offset = dist_vec(source_pos, cur_joint->getWorldPosition());
782
783 constraint->mTotalLength = constraint->mJointLengths[0] = dist_vec(cur_joint->getParent()->getWorldPosition(), source_pos);
784
785 // grab joint lengths
786 for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
787 {
788 cur_joint = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint();
789 if (!cur_joint)
790 {
791 return;
792 }
793 constraint->mJointLengths[joint_num] = dist_vec(cur_joint->getWorldPosition(), cur_joint->getParent()->getWorldPosition());
794 constraint->mTotalLength += constraint->mJointLengths[joint_num];
795 }
796
797 // store fraction of total chain length so we know how to shear the entire chain towards the goal position
798 for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
799 {
800 constraint->mJointLengthFractions[joint_num] = constraint->mJointLengths[joint_num] / constraint->mTotalLength;
801 }
802
803 // add last step in chain, from final joint to constraint position
804 constraint->mTotalLength += source_pos_offset;
805
806 constraint->mSourceVolume = mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume);
807 constraint->mTargetVolume = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume);
808}
809
810//-----------------------------------------------------------------------------
811// activateConstraint()
812//-----------------------------------------------------------------------------
813void LLKeyframeMotion::activateConstraint(JointConstraint* constraint)
814{
815 JointConstraintSharedData *shared_data = constraint->mSharedData;
816 constraint->mActive = TRUE;
817 S32 joint_num;
818
819 // grab ground position if we need to
820 if (shared_data->mConstraintTargetType == TYPE_GROUND)
821 {
822 LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);
823 LLVector3 ground_pos_agent;
824 mCharacter->getGround(source_pos, ground_pos_agent, constraint->mGroundNorm);
825 constraint->mGroundPos = mCharacter->getPosGlobalFromAgent(ground_pos_agent + shared_data->mTargetConstraintOffset);
826 }
827
828 for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
829 {
830 LLJoint* cur_joint = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint();
831 constraint->mPositions[joint_num] = (cur_joint->getWorldPosition() - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation();
832 }
833
834 constraint->mWeight = 1.f;
835}
836
837//-----------------------------------------------------------------------------
838// deactivateConstraint()
839//-----------------------------------------------------------------------------
840void LLKeyframeMotion::deactivateConstraint(JointConstraint *constraintp)
841{
842 if (constraintp->mSourceVolume)
843 {
844 constraintp->mSourceVolume->mUpdateXform = FALSE;
845 }
846
847 if (!constraintp->mSharedData->mConstraintTargetType == TYPE_GROUND)
848 {
849 if (constraintp->mTargetVolume)
850 {
851 constraintp->mTargetVolume->mUpdateXform = FALSE;
852 }
853 }
854 constraintp->mActive = FALSE;
855}
856
857//-----------------------------------------------------------------------------
858// applyConstraint()
859//-----------------------------------------------------------------------------
860void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8* joint_mask)
861{
862 JointConstraintSharedData *shared_data = constraint->mSharedData;
863 if (!shared_data) return;
864
865 LLVector3 positions[MAX_CHAIN_LENGTH];
866 const F32* joint_lengths = constraint->mJointLengths;
867 LLVector3 velocities[MAX_CHAIN_LENGTH - 1];
868 LLQuaternion old_rots[MAX_CHAIN_LENGTH];
869 S32 joint_num;
870 LLJoint* cur_joint;
871
872 if (time < shared_data->mEaseInStartTime)
873 {
874 return;
875 }
876
877 if (time > shared_data->mEaseOutStopTime)
878 {
879 if (constraint->mActive)
880 {
881 deactivateConstraint(constraint);
882 }
883 return;
884 }
885
886 if (!constraint->mActive || time < shared_data->mEaseInStopTime)
887 {
888 activateConstraint(constraint);
889 }
890
891 LLJoint* root_joint = mJointStates[shared_data->mJointStateIndices[shared_data->mChainLength]].getJoint();
892 LLVector3 root_pos = root_joint->getWorldPosition();
893// LLQuaternion root_rot =
894 root_joint->getParent()->getWorldRotation();
895// LLQuaternion inv_root_rot = ~root_rot;
896
897// LLVector3 current_source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);
898
899 //apply underlying keyframe animation to get nominal "kinematic" joint positions
900 for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++)
901 {
902 cur_joint = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint();
903 if (joint_mask[cur_joint->getJointNum()] >= (0xff >> (7 - getPriority())))
904 {
905 // skip constraint
906 return;
907 }
908 old_rots[joint_num] = cur_joint->getRotation();
909 cur_joint->setRotation(mJointStates[shared_data->mJointStateIndices[joint_num]].getRotation());
910 }
911
912
913 LLVector3 keyframe_source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);
914 LLVector3 target_pos;
915
916 switch(shared_data->mConstraintTargetType)
917 {
918 case TYPE_GROUND:
919 target_pos = mCharacter->getPosAgentFromGlobal(constraint->mGroundPos);
920// llinfos << "Target Pos " << constraint->mGroundPos << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
921 break;
922 case TYPE_BODY:
923 target_pos = mCharacter->getVolumePos(shared_data->mTargetConstraintVolume, shared_data->mTargetConstraintOffset);
924 break;
925 default:
926 break;
927 }
928
929 LLVector3 norm;
930 LLJoint *source_jointp = NULL;
931 LLJoint *target_jointp = NULL;
932
933 if (shared_data->mConstraintType == TYPE_PLANE)
934 {
935 switch(shared_data->mConstraintTargetType)
936 {
937 case TYPE_GROUND:
938 norm = constraint->mGroundNorm;
939 break;
940 case TYPE_BODY:
941 target_jointp = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume);
942 if (target_jointp)
943 {
944 // *FIX: do proper normal calculation for stretched
945 // spheres (inverse transpose)
946 norm = target_pos - target_jointp->getWorldPosition();
947 }
948
949 if (norm.isExactlyZero())
950 {
951 source_jointp = mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume);
952 norm = -1.f * shared_data->mSourceConstraintOffset;
953 if (source_jointp)
954 {
955 norm = norm * source_jointp->getWorldRotation();
956 }
957 }
958 norm.normVec();
959 break;
960 default:
961 norm.clearVec();
962 break;
963 }
964
965 target_pos = keyframe_source_pos + (norm * ((target_pos - keyframe_source_pos) * norm));
966 }
967
968 if (constraint->mSharedData->mChainLength != 0 &&
969 dist_vec_squared(root_pos, target_pos) * 0.95f > constraint->mTotalLength * constraint->mTotalLength)
970 {
971 constraint->mWeight = lerp(constraint->mWeight, 0.f, LLCriticalDamp::getInterpolant(0.1f));
972 }
973 else
974 {
975 constraint->mWeight = lerp(constraint->mWeight, 1.f, LLCriticalDamp::getInterpolant(0.3f));
976 }
977
978 F32 weight = constraint->mWeight * ((shared_data->mEaseOutStopTime == 0.f) ? 1.f :
979 llmin(clamp_rescale(time, shared_data->mEaseInStartTime, shared_data->mEaseInStopTime, 0.f, 1.f),
980 clamp_rescale(time, shared_data->mEaseOutStartTime, shared_data->mEaseOutStopTime, 1.f, 0.f)));
981
982 LLVector3 source_to_target = target_pos - keyframe_source_pos;
983
984 S32 max_iteration_count = llround(clamp_rescale(
985 mCharacter->getPixelArea(),
986 MAX_PIXEL_AREA_CONSTRAINTS,
987 MIN_PIXEL_AREA_CONSTRAINTS,
988 (F32)MAX_ITERATIONS,
989 (F32)MIN_ITERATIONS));
990
991 if (shared_data->mChainLength)
992 {
993 LLQuaternion end_rot = mJointStates[shared_data->mJointStateIndices[0]].getJoint()->getWorldRotation();
994
995 // slam start and end of chain to the proper positions (rest of chain stays put)
996 positions[0] = lerp(keyframe_source_pos, target_pos, weight);
997 positions[shared_data->mChainLength] = root_pos;
998
999 // grab keyframe-specified positions of joints
1000 for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
1001 {
1002 LLVector3 kinematic_position = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint()->getWorldPosition() +
1003 (source_to_target * constraint->mJointLengthFractions[joint_num]);
1004
1005 // convert intermediate joint positions to world coordinates
1006 positions[joint_num] = ( constraint->mPositions[joint_num] * mPelvisp->getWorldRotation()) + mPelvisp->getWorldPosition();
1007 F32 time_constant = 1.f / clamp_rescale(constraint->mFixupDistanceRMS, 0.f, 0.5f, 0.2f, 8.f);
1008// llinfos << "Interpolant " << LLCriticalDamp::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
1009 positions[joint_num] = lerp(positions[joint_num], kinematic_position,
1010 LLCriticalDamp::getInterpolant(time_constant, FALSE));
1011 }
1012
1013 S32 iteration_count;
1014 for (iteration_count = 0; iteration_count < max_iteration_count; iteration_count++)
1015 {
1016 S32 num_joints_finished = 0;
1017 for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
1018 {
1019 // constraint to child
1020 LLVector3 acceleration = (positions[joint_num - 1] - positions[joint_num]) *
1021 (dist_vec(positions[joint_num], positions[joint_num - 1]) - joint_lengths[joint_num - 1]) * JOINT_LENGTH_K;
1022 // constraint to parent
1023 acceleration += (positions[joint_num + 1] - positions[joint_num]) *
1024 (dist_vec(positions[joint_num + 1], positions[joint_num]) - joint_lengths[joint_num]) * JOINT_LENGTH_K;
1025
1026 if (acceleration.magVecSquared() < MIN_ACCELERATION_SQUARED)
1027 {
1028 num_joints_finished++;
1029 }
1030
1031 velocities[joint_num - 1] = velocities[joint_num - 1] * 0.7f;
1032 positions[joint_num] += velocities[joint_num - 1] + (acceleration * 0.5f);
1033 velocities[joint_num - 1] += acceleration;
1034 }
1035
1036 if ((iteration_count >= MIN_ITERATION_COUNT) &&
1037 (num_joints_finished == shared_data->mChainLength - 1))
1038 {
1039// llinfos << iteration_count << " iterations on " <<
1040// mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
1041 break;
1042 }
1043 }
1044
1045 for (joint_num = shared_data->mChainLength; joint_num > 0; joint_num--)
1046 {
1047 LLQuaternion parent_rot = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint()->getParent()->getWorldRotation();
1048 cur_joint = mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint();
1049 LLJoint* child_joint = mJointStates[shared_data->mJointStateIndices[joint_num - 1]].getJoint();
1050
1051 LLQuaternion cur_rot = cur_joint->getWorldRotation();
1052 LLQuaternion fixup_rot;
1053
1054 LLVector3 target_at = positions[joint_num - 1] - positions[joint_num];
1055 LLVector3 current_at;
1056
1057 // at bottom of chain, use point on collision volume, not joint position
1058 if (joint_num == 1)
1059 {
1060 current_at = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset) -
1061 cur_joint->getWorldPosition();
1062 }
1063 else
1064 {
1065 current_at = child_joint->getPosition() * cur_rot;
1066 }
1067 fixup_rot.shortestArc(current_at, target_at);
1068
1069 LLQuaternion target_rot = cur_rot * fixup_rot;
1070 target_rot = target_rot * ~parent_rot;
1071
1072 if (weight != 1.f)
1073 {
1074 LLQuaternion cur_rot = mJointStates[shared_data->mJointStateIndices[joint_num]].getRotation();
1075 target_rot = nlerp(weight, cur_rot, target_rot);
1076 }
1077
1078 mJointStates[shared_data->mJointStateIndices[joint_num]].setRotation(target_rot);
1079 cur_joint->setRotation(target_rot);
1080 }
1081
1082 LLJoint* end_joint = mJointStates[shared_data->mJointStateIndices[0]].getJoint();
1083 LLQuaternion end_local_rot = end_rot * ~end_joint->getParent()->getWorldRotation();
1084
1085 if (weight == 1.f)
1086 {
1087 mJointStates[shared_data->mJointStateIndices[0]].setRotation(end_local_rot);
1088 }
1089 else
1090 {
1091 LLQuaternion cur_rot = mJointStates[shared_data->mJointStateIndices[0]].getRotation();
1092 mJointStates[shared_data->mJointStateIndices[0]].setRotation(nlerp(weight, cur_rot, end_local_rot));
1093 }
1094
1095 // save simulated positions in pelvis-space and calculate total fixup distance
1096 constraint->mFixupDistanceRMS = 0.f;
1097 F32 delta_time = llmax(0.02f, llabs(time - mLastUpdateTime));
1098 for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
1099 {
1100 LLVector3 new_pos = (positions[joint_num] - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation();
1101 constraint->mFixupDistanceRMS += dist_vec_squared(new_pos, constraint->mPositions[joint_num]) / delta_time;
1102 constraint->mPositions[joint_num] = new_pos;
1103 }
1104 constraint->mFixupDistanceRMS *= 1.f / (constraint->mTotalLength * (F32)(shared_data->mChainLength - 1));
1105 constraint->mFixupDistanceRMS = fsqrtf(constraint->mFixupDistanceRMS);
1106
1107 //reset old joint rots
1108 for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++)
1109 {
1110 mJointStates[shared_data->mJointStateIndices[joint_num]].getJoint()->setRotation(old_rots[joint_num]);
1111 }
1112 }
1113 // simple positional constraint (pelvis only)
1114 else if (mJointStates[shared_data->mJointStateIndices[0]].getUsage() & LLJointState::POS)
1115 {
1116 LLVector3 delta = source_to_target * weight;
1117 LLJointState* current_joint_statep = &mJointStates[shared_data->mJointStateIndices[0]];
1118 LLQuaternion parent_rot = current_joint_statep->getJoint()->getParent()->getWorldRotation();
1119 delta = delta * ~parent_rot;
1120 current_joint_statep->setPosition(current_joint_statep->getJoint()->getPosition() + delta);
1121 }
1122}
1123
1124//-----------------------------------------------------------------------------
1125// deserialize()
1126//-----------------------------------------------------------------------------
1127BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
1128{
1129 BOOL old_version = FALSE;
1130 mJointMotionList = new LLKeyframeMotion::JointMotionList;
1131 mJointMotionList->mNumJointMotions = 0;
1132
1133 //-------------------------------------------------------------------------
1134 // get base priority
1135 //-------------------------------------------------------------------------
1136 S32 temp_priority;
1137 U16 version;
1138 U16 sub_version;
1139
1140 if (!dp.unpackU16(version, "version"))
1141 {
1142 llwarns << "can't read version number" << llendl;
1143 return FALSE;
1144 }
1145
1146 if (!dp.unpackU16(sub_version, "sub_version"))
1147 {
1148 llwarns << "can't read sub version number" << llendl;
1149 return FALSE;
1150 }
1151
1152 if (version == 0 && sub_version == 1)
1153 {
1154 old_version = TRUE;
1155 }
1156 else if (version != KEYFRAME_MOTION_VERSION || sub_version != KEYFRAME_MOTION_SUBVERSION)
1157 {
1158#if LL_RELEASE
1159 llwarns << "Bad animation version " << version << "." << sub_version << llendl;
1160 return FALSE;
1161#else
1162 llerrs << "Bad animation version " << version << "." << sub_version << llendl;
1163#endif
1164 }
1165
1166 if (!dp.unpackS32(temp_priority, "base_priority"))
1167 {
1168 llwarns << "can't read priority" << llendl;
1169 return FALSE;
1170 }
1171 mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority;
1172
1173 if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY)
1174 {
1175 mJointMotionList->mBasePriority = (LLJoint::JointPriority)((int)LLJoint::ADDITIVE_PRIORITY-1);
1176 mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority;
1177 }
1178
1179 //-------------------------------------------------------------------------
1180 // get duration
1181 //-------------------------------------------------------------------------
1182 if (!dp.unpackF32(mJointMotionList->mDuration, "duration"))
1183 {
1184 llwarns << "can't read duration" << llendl;
1185 return FALSE;
1186 }
1187
1188 //-------------------------------------------------------------------------
1189 // get emote (optional)
1190 //-------------------------------------------------------------------------
1191 if (!dp.unpackString(mEmoteName, "emote_name"))
1192 {
1193 llwarns << "can't read optional_emote_animation" << llendl;
1194 return FALSE;
1195 }
1196
1197 //-------------------------------------------------------------------------
1198 // get loop
1199 //-------------------------------------------------------------------------
1200 if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point"))
1201 {
1202 llwarns << "can't read loop point" << llendl;
1203 return FALSE;
1204 }
1205
1206 if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point"))
1207 {
1208 llwarns << "can't read loop point" << llendl;
1209 return FALSE;
1210 }
1211
1212 if (!dp.unpackS32(mJointMotionList->mLoop, "loop"))
1213 {
1214 llwarns << "can't read loop" << llendl;
1215 return FALSE;
1216 }
1217
1218 //-------------------------------------------------------------------------
1219 // get easeIn and easeOut
1220 //-------------------------------------------------------------------------
1221 if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration"))
1222 {
1223 llwarns << "can't read easeIn" << llendl;
1224 return FALSE;
1225 }
1226
1227 if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration"))
1228 {
1229 llwarns << "can't read easeOut" << llendl;
1230 return FALSE;
1231 }
1232
1233 //-------------------------------------------------------------------------
1234 // get hand pose
1235 //-------------------------------------------------------------------------
1236 U32 word;
1237 if (!dp.unpackU32(word, "hand_pose"))
1238 {
1239 llwarns << "can't read hand pose" << llendl;
1240 return FALSE;
1241 }
1242 mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word;
1243
1244 //-------------------------------------------------------------------------
1245 // get number of joint motions
1246 //-------------------------------------------------------------------------
1247 if (!dp.unpackU32(mJointMotionList->mNumJointMotions, "num_joints"))
1248 {
1249 llwarns << "can't read number of joints" << llendl;
1250 return FALSE;
1251 }
1252
1253 if (mJointMotionList->mNumJointMotions == 0)
1254 {
1255 llwarns << "no joints in animation" << llendl;
1256 return FALSE;
1257 }
1258 else if (mJointMotionList->mNumJointMotions > LL_CHARACTER_MAX_JOINTS)
1259 {
1260 llwarns << "too many joints in animation" << llendl;
1261 return FALSE;
1262 }
1263
1264 mJointMotionList->mJointMotionArray = new JointMotion[mJointMotionList->mNumJointMotions];
1265 mJointStates = new LLJointState[mJointMotionList->mNumJointMotions];
1266
1267 if (!mJointMotionList->mJointMotionArray)
1268 {
1269 mJointMotionList->mDuration = 0.0f;
1270 mJointMotionList->mEaseInDuration = 0.0f;
1271 mJointMotionList->mEaseOutDuration = 0.0f;
1272 return FALSE;
1273 }
1274
1275 //-------------------------------------------------------------------------
1276 // initialize joint motions
1277 //-------------------------------------------------------------------------
1278 S32 k;
1279 for(U32 i=0; i<mJointMotionList->mNumJointMotions; ++i)
1280 {
1281 std::string joint_name;
1282 if (!dp.unpackString(joint_name, "joint_name"))
1283 {
1284 llwarns << "can't read joint name" << llendl;
1285 return FALSE;
1286 }
1287
1288 //---------------------------------------------------------------------
1289 // find the corresponding joint
1290 //---------------------------------------------------------------------
1291 LLJoint *joint = mCharacter->getJoint( joint_name );
1292 if (joint)
1293 {
1294// llinfos << " joint: " << joint_name << llendl;
1295 }
1296 else
1297 {
1298 llwarns << "joint not found: " << joint_name << llendl;
1299 //return FALSE;
1300 }
1301
1302 mJointMotionList->mJointMotionArray[i].mJointName = joint_name;
1303 mJointStates[i].setJoint( joint );
1304 mJointStates[i].setUsage( 0 );
1305
1306 //---------------------------------------------------------------------
1307 // get joint priority
1308 //---------------------------------------------------------------------
1309 S32 joint_priority;
1310 if (!dp.unpackS32(joint_priority, "joint_priority"))
1311 {
1312 llwarns << "can't read joint priority." << llendl;
1313 return FALSE;
1314 }
1315
1316 mJointMotionList->mJointMotionArray[i].mPriority = (LLJoint::JointPriority)joint_priority;
1317 if (joint_priority != LLJoint::USE_MOTION_PRIORITY &&
1318 joint_priority > mJointMotionList->mMaxPriority)
1319 {
1320 mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority;
1321 }
1322
1323 mJointStates[i].setPriority((LLJoint::JointPriority)joint_priority);
1324
1325 //---------------------------------------------------------------------
1326 // scan rotation curve header
1327 //---------------------------------------------------------------------
1328 if (!dp.unpackS32(mJointMotionList->mJointMotionArray[i].mRotationCurve.mNumKeys, "num_rot_keys"))
1329 {
1330 llwarns << "can't read number of rotation keys" << llendl;
1331 return FALSE;
1332 }
1333
1334 mJointMotionList->mJointMotionArray[i].mRotationCurve.mInterpolationType = IT_LINEAR;
1335 if (mJointMotionList->mJointMotionArray[i].mRotationCurve.mNumKeys != 0)
1336 {
1337 mJointStates[i].setUsage(mJointStates[i].getUsage() | LLJointState::ROT );
1338 }
1339
1340 //---------------------------------------------------------------------
1341 // scan rotation curve keys
1342 //---------------------------------------------------------------------
1343 RotationCurve *rCurve = &mJointMotionList->mJointMotionArray[i].mRotationCurve;
1344
1345 for (k = 0; k < mJointMotionList->mJointMotionArray[i].mRotationCurve.mNumKeys; k++)
1346 {
1347 F32 time;
1348 U16 time_short;
1349
1350 if (old_version)
1351 {
1352 if (!dp.unpackF32(time, "time"))
1353 {
1354 llwarns << "can't read rotation key (" << k << ")" << llendl;
1355 return FALSE;
1356 }
1357
1358 }
1359 else
1360 {
1361 if (!dp.unpackU16(time_short, "time"))
1362 {
1363 llwarns << "can't read rotation key (" << k << ")" << llendl;
1364 return FALSE;
1365 }
1366
1367 time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration);
1368 }
1369
1370 RotationKey *rot_key = new RotationKey;
1371 rot_key->mTime = time;
1372 LLVector3 rot_angles;
1373 U16 x, y, z;
1374
1375 BOOL success = TRUE;
1376
1377 if (old_version)
1378 {
1379 success = dp.unpackVector3(rot_angles, "rot_angles");
1380
1381 LLQuaternion::Order ro = StringToOrder("ZYX");
1382 rot_key->mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro);
1383 }
1384 else
1385 {
1386 success &= dp.unpackU16(x, "rot_angle_x");
1387 success &= dp.unpackU16(y, "rot_angle_y");
1388 success &= dp.unpackU16(z, "rot_angle_z");
1389
1390 LLVector3 rot_vec;
1391 rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f);
1392 rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f);
1393 rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f);
1394 rot_key->mRotation.unpackFromVector3(rot_vec);
1395 }
1396
1397 if (!success)
1398 {
1399 llwarns << "can't read rotation key (" << k << ")" << llendl;
1400 return FALSE;
1401 }
1402
1403 rCurve->mKeys[time] = rot_key;
1404 }
1405
1406 //---------------------------------------------------------------------
1407 // scan position curve header
1408 //---------------------------------------------------------------------
1409 if (!dp.unpackS32(mJointMotionList->mJointMotionArray[i].mPositionCurve.mNumKeys, "num_pos_keys"))
1410 {
1411 llwarns << "can't read number of position keys" << llendl;
1412 return FALSE;
1413 }
1414
1415 mJointMotionList->mJointMotionArray[i].mPositionCurve.mInterpolationType = IT_LINEAR;
1416 if (mJointMotionList->mJointMotionArray[i].mPositionCurve.mNumKeys != 0)
1417 {
1418 mJointStates[i].setUsage(mJointStates[i].getUsage() | LLJointState::POS );
1419 }
1420
1421 //---------------------------------------------------------------------
1422 // scan position curve keys
1423 //---------------------------------------------------------------------
1424 PositionCurve *pCurve = &mJointMotionList->mJointMotionArray[i].mPositionCurve;
1425 BOOL is_pelvis = mJointMotionList->mJointMotionArray[i].mJointName == "mPelvis";
1426 for (k = 0; k < mJointMotionList->mJointMotionArray[i].mPositionCurve.mNumKeys; k++)
1427 {
1428 U16 time_short;
1429 PositionKey* pos_key = new PositionKey;
1430
1431 if (old_version)
1432 {
1433 if (!dp.unpackF32(pos_key->mTime, "time"))
1434 {
1435 llwarns << "can't read position key (" << k << ")" << llendl;
1436 delete pos_key;
1437 return FALSE;
1438 }
1439 }
1440 else
1441 {
1442 if (!dp.unpackU16(time_short, "time"))
1443 {
1444 llwarns << "can't read position key (" << k << ")" << llendl;
1445 delete pos_key;
1446 return FALSE;
1447 }
1448
1449 pos_key->mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration);
1450 }
1451
1452 BOOL success = TRUE;
1453
1454 if (old_version)
1455 {
1456 success = dp.unpackVector3(pos_key->mPosition, "pos");
1457 }
1458 else
1459 {
1460 U16 x, y, z;
1461
1462 success &= dp.unpackU16(x, "pos_x");
1463 success &= dp.unpackU16(y, "pos_y");
1464 success &= dp.unpackU16(z, "pos_z");
1465
1466 pos_key->mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
1467 pos_key->mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
1468 pos_key->mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
1469 }
1470
1471 if (!success)
1472 {
1473 llwarns << "can't read position key (" << k << ")" << llendl;
1474 delete pos_key;
1475 return FALSE;
1476 }
1477
1478 pCurve->mKeys[pos_key->mTime] = pos_key;
1479
1480 if (is_pelvis)
1481 {
1482 mJointMotionList->mPelvisBBox.addPoint(pos_key->mPosition);
1483 }
1484 }
1485
1486 mJointMotionList->mJointMotionArray[i].mUsage = mJointStates[i].getUsage();
1487 }
1488
1489 //-------------------------------------------------------------------------
1490 // get number of constraints
1491 //-------------------------------------------------------------------------
1492 S32 num_constraints = 0;
1493 if (!dp.unpackS32(num_constraints, "num_constraints"))
1494 {
1495 llwarns << "can't read number of constraints" << llendl;
1496 return FALSE;
1497 }
1498
1499 if (num_constraints > MAX_CONSTRAINTS)
1500 {
1501 llwarns << "Too many constraints...ignoring" << llendl;
1502 }
1503 else
1504 {
1505 //-------------------------------------------------------------------------
1506 // get constraints
1507 //-------------------------------------------------------------------------
1508 std::string str;
1509 for(S32 i = 0; i < num_constraints; ++i)
1510 {
1511 // read in constraint data
1512 JointConstraintSharedData* constraintp = new JointConstraintSharedData;
1513 U8 byte = 0;
1514
1515 if (!dp.unpackU8(byte, "chain_length"))
1516 {
1517 llwarns << "can't read constraint chain length" << llendl;
1518 return FALSE;
1519 }
1520 constraintp->mChainLength = (S32) byte;
1521
1522 if (!dp.unpackU8(byte, "constraint_type"))
1523 {
1524 llwarns << "can't read constraint type" << llendl;
1525 return FALSE;
1526 }
1527 constraintp->mConstraintType = (EConstraintType)byte;
1528
1529 const S32 BIN_DATA_LENGTH = 16;
1530 U8 bin_data[BIN_DATA_LENGTH];
1531 if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "source_volume"))
1532 {
1533 llwarns << "can't read source volume name" << llendl;
1534 return FALSE;
1535 }
1536
1537 bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination
1538 str = (char*)bin_data;
1539 constraintp->mSourceConstraintVolume = mCharacter->getCollisionVolumeID(str);
1540
1541 if (!dp.unpackVector3(constraintp->mSourceConstraintOffset, "source_offset"))
1542 {
1543 llwarns << "can't read constraint source offset" << llendl;
1544 return FALSE;
1545 }
1546
1547 if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "target_volume"))
1548 {
1549 llwarns << "can't read target volume name" << llendl;
1550 return FALSE;
1551 }
1552
1553 bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination
1554 str = (char*)bin_data;
1555 if (str == "GROUND")
1556 {
1557 // constrain to ground
1558 constraintp->mConstraintTargetType = TYPE_GROUND;
1559 }
1560 else
1561 {
1562 constraintp->mConstraintTargetType = TYPE_BODY;
1563 constraintp->mTargetConstraintVolume = mCharacter->getCollisionVolumeID(str);
1564 }
1565
1566 if (!dp.unpackVector3(constraintp->mTargetConstraintOffset, "target_offset"))
1567 {
1568 llwarns << "can't read constraint target offset" << llendl;
1569 return FALSE;
1570 }
1571
1572 if (!dp.unpackVector3(constraintp->mTargetConstraintDir, "target_dir"))
1573 {
1574 llwarns << "can't read constraint target direction" << llendl;
1575 return FALSE;
1576 }
1577
1578 if (!constraintp->mTargetConstraintDir.isExactlyZero())
1579 {
1580 constraintp->mUseTargetOffset = TRUE;
1581 // constraintp->mTargetConstraintDir *= constraintp->mSourceConstraintOffset.magVec();
1582 }
1583
1584 if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start"))
1585 {
1586 llwarns << "can't read constraint ease in start time" << llendl;
1587 return FALSE;
1588 }
1589
1590 if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop"))
1591 {
1592 llwarns << "can't read constraint ease in stop time" << llendl;
1593 return FALSE;
1594 }
1595
1596 if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start"))
1597 {
1598 llwarns << "can't read constraint ease out start time" << llendl;
1599 return FALSE;
1600 }
1601
1602 if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop"))
1603 {
1604 llwarns << "can't read constraint ease out stop time" << llendl;
1605 return FALSE;
1606 }
1607
1608 mJointMotionList->mConstraints.addData(constraintp);
1609
1610 constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1];
1611
1612 LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume);
1613 // get joint to which this collision volume is attached
1614 if (!joint)
1615 {
1616 return FALSE;
1617 }
1618 for (S32 i = 0; i < constraintp->mChainLength + 1; i++)
1619 {
1620 LLJoint* parent = joint->getParent();
1621 if (!parent)
1622 {
1623 llwarns << "Joint with no parent: " << joint->getName()
1624 << " Emote: " << mEmoteName << llendl;
1625 return FALSE;
1626 }
1627 joint = parent;
1628 constraintp->mJointStateIndices[i] = -1;
1629 for (U32 j = 0; j < mJointMotionList->mNumJointMotions; j++)
1630 {
1631 if(mJointStates[j].getJoint() == joint)
1632 {
1633 constraintp->mJointStateIndices[i] = (S32)j;
1634 break;
1635 }
1636 }
1637 }
1638
1639 }
1640 }
1641
1642 // *FIX: support cleanup of old keyframe data
1643 LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList);
1644 mAssetStatus = ASSET_LOADED;
1645
1646 setupPose();
1647
1648 return TRUE;
1649}
1650
1651//-----------------------------------------------------------------------------
1652// serialize()
1653//-----------------------------------------------------------------------------
1654BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
1655{
1656 BOOL success = TRUE;
1657
1658 success &= dp.packU16(KEYFRAME_MOTION_VERSION, "version");
1659 success &= dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version");
1660 success &= dp.packS32(mJointMotionList->mBasePriority, "base_priority");
1661 success &= dp.packF32(mJointMotionList->mDuration, "duration");
1662 success &= dp.packString(mEmoteName.c_str(), "emote_name");
1663 success &= dp.packF32(mJointMotionList->mLoopInPoint, "loop_in_point");
1664 success &= dp.packF32(mJointMotionList->mLoopOutPoint, "loop_out_point");
1665 success &= dp.packS32(mJointMotionList->mLoop, "loop");
1666 success &= dp.packF32(mJointMotionList->mEaseInDuration, "ease_in_duration");
1667 success &= dp.packF32(mJointMotionList->mEaseOutDuration, "ease_out_duration");
1668 success &= dp.packU32(mJointMotionList->mHandPose, "hand_pose");
1669 success &= dp.packU32(mJointMotionList->mNumJointMotions, "num_joints");
1670
1671 for (U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
1672 {
1673 JointMotion* joint_motionp = &mJointMotionList->mJointMotionArray[i];
1674 success &= dp.packString(joint_motionp->mJointName.c_str(), "joint_name");
1675 success &= dp.packS32(joint_motionp->mPriority, "joint_priority");
1676 success &= dp.packS32(joint_motionp->mRotationCurve.mNumKeys, "num_rot_keys");
1677
1678 for (RotationKey* rot_keyp = joint_motionp->mRotationCurve.mKeys.getFirstData();
1679 rot_keyp;
1680 rot_keyp = joint_motionp->mRotationCurve.mKeys.getNextData())
1681 {
1682 U16 time_short = F32_to_U16(rot_keyp->mTime, 0.f, mJointMotionList->mDuration);
1683 success &= dp.packU16(time_short, "time");
1684
1685 LLVector3 rot_angles = rot_keyp->mRotation.packToVector3();
1686
1687 U16 x, y, z;
1688 rot_angles.quantize16(-1.f, 1.f, -1.f, 1.f);
1689 x = F32_to_U16(rot_angles.mV[VX], -1.f, 1.f);
1690 y = F32_to_U16(rot_angles.mV[VY], -1.f, 1.f);
1691 z = F32_to_U16(rot_angles.mV[VZ], -1.f, 1.f);
1692 success &= dp.packU16(x, "rot_angle_x");
1693 success &= dp.packU16(y, "rot_angle_y");
1694 success &= dp.packU16(z, "rot_angle_z");
1695 }
1696
1697 success &= dp.packS32(joint_motionp->mPositionCurve.mNumKeys, "num_pos_keys");
1698 for (PositionKey* pos_keyp = joint_motionp->mPositionCurve.mKeys.getFirstData();
1699 pos_keyp;
1700 pos_keyp = joint_motionp->mPositionCurve.mKeys.getNextData())
1701 {
1702 U16 time_short = F32_to_U16(pos_keyp->mTime, 0.f, mJointMotionList->mDuration);
1703 success &= dp.packU16(time_short, "time");
1704
1705 U16 x, y, z;
1706 pos_keyp->mPosition.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
1707 x = F32_to_U16(pos_keyp->mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
1708 y = F32_to_U16(pos_keyp->mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
1709 z = F32_to_U16(pos_keyp->mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
1710 success &= dp.packU16(x, "pos_x");
1711 success &= dp.packU16(y, "pos_y");
1712 success &= dp.packU16(z, "pos_z");
1713 }
1714 }
1715
1716 success &= dp.packS32(mJointMotionList->mConstraints.getLength(), "num_constraints");
1717 for (JointConstraintSharedData* shared_constraintp = mJointMotionList->mConstraints.getFirstData();
1718 shared_constraintp;
1719 shared_constraintp = mJointMotionList->mConstraints.getNextData())
1720 {
1721 success &= dp.packU8(shared_constraintp->mChainLength, "chain_length");
1722 success &= dp.packU8(shared_constraintp->mConstraintType, "constraint_type");
1723 char volume_name[16];
1724 snprintf(volume_name, sizeof(volume_name), "%s",
1725 mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str()); /* Flawfinder: ignore */
1726 success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "source_volume");
1727 success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset");
1728 if (shared_constraintp->mConstraintTargetType == TYPE_GROUND)
1729 {
1730 snprintf(volume_name,sizeof(volume_name), "%s", "GROUND"); /* Flawfinder: ignore */
1731 }
1732 else
1733 {
1734 snprintf(volume_name, sizeof(volume_name),"%s",
1735 mCharacter->findCollisionVolume(shared_constraintp->mTargetConstraintVolume)->getName().c_str()); /* Flawfinder: ignore */
1736 }
1737 success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "target_volume");
1738 success &= dp.packVector3(shared_constraintp->mTargetConstraintOffset, "target_offset");
1739 success &= dp.packVector3(shared_constraintp->mTargetConstraintDir, "target_dir");
1740 success &= dp.packF32(shared_constraintp->mEaseInStartTime, "ease_in_start");
1741 success &= dp.packF32(shared_constraintp->mEaseInStopTime, "ease_in_stop");
1742 success &= dp.packF32(shared_constraintp->mEaseOutStartTime, "ease_out_start");
1743 success &= dp.packF32(shared_constraintp->mEaseOutStopTime, "ease_out_stop");
1744 }
1745
1746 return success;
1747}
1748
1749//-----------------------------------------------------------------------------
1750// getFileSize()
1751//-----------------------------------------------------------------------------
1752U32 LLKeyframeMotion::getFileSize()
1753{
1754 // serialize into a dummy buffer to calculate required size
1755 LLDataPackerBinaryBuffer dp;
1756 serialize(dp);
1757
1758 return dp.getCurrentSize();
1759}
1760
1761//-----------------------------------------------------------------------------
1762// getPelvisBBox()
1763//-----------------------------------------------------------------------------
1764const LLBBoxLocal &LLKeyframeMotion::getPelvisBBox()
1765{
1766 return mJointMotionList->mPelvisBBox;
1767}
1768
1769//-----------------------------------------------------------------------------
1770// setPriority()
1771//-----------------------------------------------------------------------------
1772void LLKeyframeMotion::setPriority(S32 priority)
1773{
1774 if (mJointMotionList)
1775 {
1776 S32 priority_delta = priority - mJointMotionList->mBasePriority;
1777 mJointMotionList->mBasePriority = (LLJoint::JointPriority)priority;
1778 mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority;
1779
1780 for (U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
1781 {
1782 mJointMotionList->mJointMotionArray[i].mPriority = (LLJoint::JointPriority)llclamp(
1783 (S32)mJointMotionList->mJointMotionArray[i].mPriority + priority_delta,
1784 (S32)LLJoint::LOW_PRIORITY,
1785 (S32)LLJoint::HIGHEST_PRIORITY);
1786 mJointStates[i].setPriority(mJointMotionList->mJointMotionArray[i].mPriority);
1787 }
1788 }
1789}
1790
1791//-----------------------------------------------------------------------------
1792// setEmote()
1793//-----------------------------------------------------------------------------
1794void LLKeyframeMotion::setEmote(const LLUUID& emote_id)
1795{
1796 const char* emote_name = gAnimLibrary.animStateToString(emote_id);
1797 if (emote_name)
1798 {
1799 mEmoteName = emote_name;
1800 }
1801 else
1802 {
1803 mEmoteName = "";
1804 }
1805}
1806
1807//-----------------------------------------------------------------------------
1808// setEaseIn()
1809//-----------------------------------------------------------------------------
1810void LLKeyframeMotion::setEaseIn(F32 ease_in)
1811{
1812 if (mJointMotionList)
1813 {
1814 mJointMotionList->mEaseInDuration = llmax(ease_in, 0.f);
1815 }
1816}
1817
1818//-----------------------------------------------------------------------------
1819// setEaseOut()
1820//-----------------------------------------------------------------------------
1821void LLKeyframeMotion::setEaseOut(F32 ease_in)
1822{
1823 if (mJointMotionList)
1824 {
1825 mJointMotionList->mEaseOutDuration = llmax(ease_in, 0.f);
1826 }
1827}
1828
1829
1830//-----------------------------------------------------------------------------
1831// flushKeyframeCache()
1832//-----------------------------------------------------------------------------
1833void LLKeyframeMotion::flushKeyframeCache()
1834{
1835 LLKeyframeDataCache::clear();
1836}
1837
1838//-----------------------------------------------------------------------------
1839// setLoop()
1840//-----------------------------------------------------------------------------
1841void LLKeyframeMotion::setLoop(BOOL loop)
1842{
1843 if (mJointMotionList)
1844 {
1845 mJointMotionList->mLoop = loop;
1846 mSendStopTimestamp = F32_MAX;
1847 }
1848}
1849
1850
1851//-----------------------------------------------------------------------------
1852// setLoopIn()
1853//-----------------------------------------------------------------------------
1854void LLKeyframeMotion::setLoopIn(F32 in_point)
1855{
1856 if (mJointMotionList)
1857 {
1858 mJointMotionList->mLoopInPoint = in_point;
1859
1860 // set up loop keys
1861 for (U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
1862 {
1863 PositionCurve* pos_curve = &mJointMotionList->mJointMotionArray[i].mPositionCurve;
1864 RotationCurve* rot_curve = &mJointMotionList->mJointMotionArray[i].mRotationCurve;
1865 ScaleCurve* scale_curve = &mJointMotionList->mJointMotionArray[i].mScaleCurve;
1866
1867 pos_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint;
1868 rot_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint;
1869 scale_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint;
1870
1871 pos_curve->mLoopInKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
1872 rot_curve->mLoopInKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
1873 scale_curve->mLoopInKey.mScale = scale_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
1874 }
1875 }
1876}
1877
1878//-----------------------------------------------------------------------------
1879// setLoopOut()
1880//-----------------------------------------------------------------------------
1881void LLKeyframeMotion::setLoopOut(F32 out_point)
1882{
1883 if (mJointMotionList)
1884 {
1885 mJointMotionList->mLoopOutPoint = out_point;
1886
1887 // set up loop keys
1888 for (U32 i = 0; i < mJointMotionList->mNumJointMotions; i++)
1889 {
1890 PositionCurve* pos_curve = &mJointMotionList->mJointMotionArray[i].mPositionCurve;
1891 RotationCurve* rot_curve = &mJointMotionList->mJointMotionArray[i].mRotationCurve;
1892 ScaleCurve* scale_curve = &mJointMotionList->mJointMotionArray[i].mScaleCurve;
1893
1894 pos_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint;
1895 rot_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint;
1896 scale_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint;
1897
1898 pos_curve->mLoopOutKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
1899 rot_curve->mLoopOutKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
1900 scale_curve->mLoopOutKey.mScale = scale_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
1901 }
1902 }
1903}
1904
1905//-----------------------------------------------------------------------------
1906// onLoadComplete()
1907//-----------------------------------------------------------------------------
1908void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
1909 const LLUUID& asset_uuid,
1910 LLAssetType::EType type,
1911 void* user_data, S32 status)
1912{
1913 LLUUID* id = (LLUUID*)user_data;
1914
1915 LLCharacter* character = NULL;
1916
1917 for(character = LLCharacter::sInstances.getFirstData();
1918 character;
1919 character = LLCharacter::sInstances.getNextData())
1920 {
1921 if (character->getID() == *id)
1922 {
1923 break;
1924 }
1925 }
1926
1927 delete id;
1928
1929 if (!character)
1930 {
1931 return;
1932 }
1933
1934 // create an instance of this motion (it may or may not already exist)
1935 LLKeyframeMotion* motionp = (LLKeyframeMotion*)character->createMotion(asset_uuid);
1936
1937 if (0 == status && motionp)
1938 {
1939 if (motionp->mAssetStatus == ASSET_LOADED)
1940 {
1941 // asset already loaded
1942 return;
1943 }
1944 LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
1945 S32 size = file.getSize();
1946
1947 U8* buffer = new U8[size];
1948 file.read((U8*)buffer, size); /*Flawfinder: ignore*/
1949
1950 lldebugs << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << llendl;
1951
1952 LLDataPackerBinaryBuffer dp(buffer, size);
1953 if (motionp->deserialize(dp))
1954 {
1955 motionp->mAssetStatus = ASSET_LOADED;
1956 }
1957 else
1958 {
1959 llwarns << "Failed to decode asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl;
1960 motionp->mAssetStatus = ASSET_FETCH_FAILED;
1961 }
1962
1963 delete []buffer;
1964
1965 }
1966 else
1967 {
1968 llwarns << "Failed to load asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl;
1969 motionp->mAssetStatus = ASSET_FETCH_FAILED;
1970 }
1971}
1972
1973
1974//-----------------------------------------------------------------------------
1975// writeCAL3D()
1976//-----------------------------------------------------------------------------
1977void LLKeyframeMotion::writeCAL3D(apr_file_t* fp)
1978{
1979// <ANIMATION VERSION="1000" DURATION="1.03333" NUMTRACKS="58">
1980// <TRACK BONEID="0" NUMKEYFRAMES="31">
1981// <KEYFRAME TIME="0">
1982// <TRANSLATION>0 0 48.8332</TRANSLATION>
1983// <ROTATION>0.0512905 0.05657 0.66973 0.738668</ROTATION>
1984// </KEYFRAME>
1985// </TRACK>
1986// </ANIMATION>
1987
1988 apr_file_printf(fp, "<ANIMATION VERSION=\"1000\" DURATION=\"%.5f\" NUMTRACKS=\"%d\">\n", getDuration(), mJointMotionList->mNumJointMotions);
1989 for (U32 joint_index = 0; joint_index < mJointMotionList->mNumJointMotions; joint_index++)
1990 {
1991 JointMotion* joint_motionp = &mJointMotionList->mJointMotionArray[joint_index];
1992 LLJoint* animated_joint = mCharacter->getJoint(joint_motionp->mJointName);
1993 S32 joint_num = animated_joint->mJointNum + 1;
1994
1995 apr_file_printf(fp, " <TRACK BONEID=\"%d\" NUMKEYFRAMES=\"%d\">\n", joint_num, joint_motionp->mRotationCurve.mNumKeys );
1996 PositionKey* pos_keyp = joint_motionp->mPositionCurve.mKeys.getFirstData();
1997 for (RotationKey* rot_keyp = joint_motionp->mRotationCurve.mKeys.getFirstData();
1998 rot_keyp;
1999 rot_keyp = joint_motionp->mRotationCurve.mKeys.getNextData())
2000 {
2001 apr_file_printf(fp, " <KEYFRAME TIME=\"%0.3f\">\n", rot_keyp->mTime);
2002 LLVector3 nominal_pos = animated_joint->getPosition();
2003 if (animated_joint->getParent())
2004 {
2005 nominal_pos.scaleVec(animated_joint->getParent()->getScale());
2006 }
2007 nominal_pos = nominal_pos * 100.f;
2008
2009 if (joint_motionp->mUsage & LLJointState::POS && pos_keyp)
2010 {
2011 LLVector3 pos_val = pos_keyp->mPosition;
2012 pos_val = pos_val * 100.f;
2013 pos_val += nominal_pos;
2014 apr_file_printf(fp, " <TRANSLATION>%0.4f %0.4f %0.4f</TRANSLATION>\n", pos_val.mV[VX], pos_val.mV[VY], pos_val.mV[VZ]);
2015 pos_keyp = joint_motionp->mPositionCurve.mKeys.getNextData();
2016 }
2017 else
2018 {
2019 apr_file_printf(fp, " <TRANSLATION>%0.4f %0.4f %0.4f</TRANSLATION>\n", nominal_pos.mV[VX], nominal_pos.mV[VY], nominal_pos.mV[VZ]);
2020 }
2021
2022 LLQuaternion rot_val = ~rot_keyp->mRotation;
2023 apr_file_printf(fp, " <ROTATION>%0.4f %0.4f %0.4f %0.4f</ROTATION>\n", rot_val.mQ[VX], rot_val.mQ[VY], rot_val.mQ[VZ], rot_val.mQ[VW]);
2024 apr_file_printf(fp, " </KEYFRAME>\n");
2025 }
2026 apr_file_printf(fp, " </TRACK>\n");
2027 }
2028 apr_file_printf(fp, "</ANIMATION>\n");
2029}
2030
2031//--------------------------------------------------------------------
2032// LLKeyframeDataCache::dumpDiagInfo()
2033//--------------------------------------------------------------------
2034void LLKeyframeDataCache::dumpDiagInfo()
2035{
2036 // keep track of totals
2037 U32 total_size = 0;
2038
2039 char buf[1024]; /* Flawfinder: ignore */
2040
2041 llinfos << "-----------------------------------------------------" << llendl;
2042 llinfos << " Global Motion Table (DEBUG only)" << llendl;
2043 llinfos << "-----------------------------------------------------" << llendl;
2044
2045 // print each loaded mesh, and it's memory usage
2046 LLKeyframeDataMap::iterator map_it;
2047 for (map_it = sKeyframeDataMap.begin(); map_it != sKeyframeDataMap.end(); ++map_it)
2048 {
2049 U32 joint_motion_kb;
2050
2051 LLKeyframeMotion::JointMotionList *motion_list_p = map_it->second;
2052
2053 llinfos << "Motion: " << map_it->first << llendl;
2054
2055 joint_motion_kb = motion_list_p->dumpDiagInfo();
2056
2057 total_size += joint_motion_kb;
2058 }
2059
2060 llinfos << "-----------------------------------------------------" << llendl;
2061 llinfos << "Motions\tTotal Size" << llendl;
2062 snprintf(buf, sizeof(buf), "%d\t\t%d bytes", (S32)sKeyframeDataMap.size(), total_size ); /* Flawfinder: ignore */
2063 llinfos << buf << llendl;
2064 llinfos << "-----------------------------------------------------" << llendl;
2065}
2066
2067
2068//--------------------------------------------------------------------
2069// LLKeyframeDataCache::addKeyframeData()
2070//--------------------------------------------------------------------
2071void LLKeyframeDataCache::addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList* joint_motion_listp)
2072{
2073 sKeyframeDataMap[id] = joint_motion_listp;
2074}
2075
2076//--------------------------------------------------------------------
2077// LLKeyframeDataCache::removeKeyframeData()
2078//--------------------------------------------------------------------
2079void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id)
2080{
2081 LLKeyframeMotion::JointMotionList* joint_motion_listp = getKeyframeData(id);
2082 if (joint_motion_listp)
2083 {
2084 delete joint_motion_listp;
2085 }
2086 sKeyframeDataMap.erase(id);
2087}
2088
2089//--------------------------------------------------------------------
2090// LLKeyframeDataCache::getKeyframeData()
2091//--------------------------------------------------------------------
2092LLKeyframeMotion::JointMotionList* LLKeyframeDataCache::getKeyframeData(const LLUUID& id)
2093{
2094 LLKeyframeDataMap::iterator found_data = sKeyframeDataMap.find(id);
2095 if (found_data == sKeyframeDataMap.end())
2096 {
2097 return NULL;
2098 }
2099 return found_data->second;
2100}
2101
2102//--------------------------------------------------------------------
2103// ~LLKeyframeDataCache::LLKeyframeDataCache()
2104//--------------------------------------------------------------------
2105LLKeyframeDataCache::~LLKeyframeDataCache()
2106{
2107 clear();
2108}
2109
2110//-----------------------------------------------------------------------------
2111// clear()
2112//-----------------------------------------------------------------------------
2113void LLKeyframeDataCache::clear()
2114{
2115 for_each(sKeyframeDataMap.begin(), sKeyframeDataMap.end(), DeletePairedPointer());
2116 sKeyframeDataMap.clear();
2117}
2118
2119//-----------------------------------------------------------------------------
2120// JointConstraint()
2121//-----------------------------------------------------------------------------
2122LLKeyframeMotion::JointConstraint::JointConstraint(JointConstraintSharedData* shared_data) : mSharedData(shared_data)
2123{
2124 mTotalLength = 0.f;
2125 mActive = FALSE;
2126 mSourceVolume = NULL;
2127 mTargetVolume = NULL;
2128 mFixupDistanceRMS = 0.f;
2129}
2130
2131//-----------------------------------------------------------------------------
2132// ~JointConstraint()
2133//-----------------------------------------------------------------------------
2134LLKeyframeMotion::JointConstraint::~JointConstraint()
2135{
2136}
2137
2138// End