summaryrefslogtreecommitdiff
path: root/indra/llcharacter/llkeyframemotion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcharacter/llkeyframemotion.cpp')
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframemotion.cpp372
1 files changed, 228 insertions, 144 deletions
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index 5a2e3f73f9..cd201a65b4 100644..100755
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -2,31 +2,25 @@
* @file llkeyframemotion.cpp
* @brief Implementation of LLKeyframeMotion class.
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -87,7 +81,9 @@ LLKeyframeMotion::JointMotionList::JointMotionList()
LLKeyframeMotion::JointMotionList::~JointMotionList()
{
for_each(mConstraints.begin(), mConstraints.end(), DeletePointer());
+ mConstraints.clear();
for_each(mJointMotionArray.begin(), mJointMotionArray.end(), DeletePointer());
+ mJointMotionArray.clear();
}
U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo()
@@ -98,30 +94,30 @@ U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo()
{
LLKeyframeMotion::JointMotion* joint_motion_p = mJointMotionArray[i];
- llinfos << "\tJoint " << joint_motion_p->mJointName << llendl;
+ LL_INFOS() << "\tJoint " << joint_motion_p->mJointName << LL_ENDL;
if (joint_motion_p->mUsage & LLJointState::SCALE)
{
- llinfos << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at "
- << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << llendl;
+ LL_INFOS() << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at "
+ << joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << LL_ENDL;
total_size += joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey);
}
if (joint_motion_p->mUsage & LLJointState::ROT)
{
- llinfos << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at "
- << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << llendl;
+ LL_INFOS() << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at "
+ << joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << LL_ENDL;
total_size += joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey);
}
if (joint_motion_p->mUsage & LLJointState::POS)
{
- llinfos << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at "
- << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << llendl;
+ LL_INFOS() << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at "
+ << joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << LL_ENDL;
total_size += joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey);
}
}
- llinfos << "Size: " << total_size << " bytes" << llendl;
+ LL_INFOS() << "Size: " << total_size << " bytes" << LL_ENDL;
return total_size;
}
@@ -453,6 +449,7 @@ LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id)
LLKeyframeMotion::~LLKeyframeMotion()
{
for_each(mConstraints.begin(), mConstraints.end(), DeletePointer());
+ mConstraints.clear();
}
//-----------------------------------------------------------------------------
@@ -473,13 +470,15 @@ LLPointer<LLJointState>& LLKeyframeMotion::getJointState(U32 index)
}
//-----------------------------------------------------------------------------
-// getJoin()
+// getJoint()
//-----------------------------------------------------------------------------
LLJoint* LLKeyframeMotion::getJoint(U32 index)
{
llassert_always (index < mJointStates.size());
LLJoint* joint = mJointStates[index]->getJoint();
- llassert_always (joint);
+
+ //Commented out 06-28-11 by Aura.
+ //llassert_always (joint);
return joint;
}
@@ -561,7 +560,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
if (!sVFS)
{
- llerrs << "Must call LLKeyframeMotion::setVFS() first before loading a keyframe file!" << llendl;
+ LL_ERRS() << "Must call LLKeyframeMotion::setVFS() first before loading a keyframe file!" << LL_ENDL;
}
BOOL success = FALSE;
@@ -587,18 +586,18 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
if (!success)
{
- llwarns << "Can't open animation file " << mID << llendl;
+ LL_WARNS() << "Can't open animation file " << mID << LL_ENDL;
mAssetStatus = ASSET_FETCH_FAILED;
return STATUS_FAILURE;
}
- lldebugs << "Loading keyframe data for: " << getName() << ":" << getID() << " (" << anim_file_size << " bytes)" << llendl;
+ LL_DEBUGS() << "Loading keyframe data for: " << getName() << ":" << getID() << " (" << anim_file_size << " bytes)" << LL_ENDL;
LLDataPackerBinaryBuffer dp(anim_data, anim_file_size);
if (!deserialize(dp))
{
- llwarns << "Failed to decode asset for animation " << getName() << ":" << getID() << llendl;
+ LL_WARNS() << "Failed to decode asset for animation " << getName() << ":" << getID() << LL_ENDL;
mAssetStatus = ASSET_FETCH_FAILED;
return STATUS_FAILURE;
}
@@ -658,7 +657,12 @@ BOOL LLKeyframeMotion::onActivate()
// If the keyframe anim has an associated emote, trigger it.
if( mJointMotionList->mEmoteName.length() > 0 )
{
- mCharacter->startMotion( gAnimLibrary.stringToAnimState(mJointMotionList->mEmoteName) );
+ LLUUID emote_anim_id = gAnimLibrary.stringToAnimState(mJointMotionList->mEmoteName);
+ // don't start emote if already active to avoid recursion
+ if (!mCharacter->isMotionActive(emote_anim_id))
+ {
+ mCharacter->startMotion( emote_anim_id );
+ }
}
mLastLoopedTime = 0.f;
@@ -671,7 +675,8 @@ BOOL LLKeyframeMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotion::onUpdate(F32 time, U8* joint_mask)
{
- llassert(time >= 0.f);
+ // llassert(time >= 0.f); // This will fire
+ time = llmax(0.f, time);
if (mJointMotionList->mLoop)
{
@@ -822,7 +827,11 @@ void LLKeyframeMotion::initializeConstraint(JointConstraint* constraint)
S32 joint_num;
LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);
LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[0]);
-
+ if ( !cur_joint )
+ {
+ return;
+ }
+
F32 source_pos_offset = dist_vec(source_pos, cur_joint->getWorldPosition());
constraint->mTotalLength = constraint->mJointLengths[0] = dist_vec(cur_joint->getParent()->getWorldPosition(), source_pos);
@@ -873,6 +882,10 @@ void LLKeyframeMotion::activateConstraint(JointConstraint* constraint)
for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
{
LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]);
+ if ( !cur_joint )
+ {
+ return;
+ }
constraint->mPositions[joint_num] = (cur_joint->getWorldPosition() - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation();
}
@@ -889,7 +902,7 @@ void LLKeyframeMotion::deactivateConstraint(JointConstraint *constraintp)
constraintp->mSourceVolume->mUpdateXform = FALSE;
}
- if (!constraintp->mSharedData->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND)
+ if (constraintp->mSharedData->mConstraintTargetType != CONSTRAINT_TARGET_TYPE_GROUND)
{
if (constraintp->mTargetVolume)
{
@@ -933,6 +946,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
}
LLJoint* root_joint = getJoint(shared_data->mJointStateIndices[shared_data->mChainLength]);
+ if (! root_joint)
+ {
+ return;
+ }
+
LLVector3 root_pos = root_joint->getWorldPosition();
// LLQuaternion root_rot =
root_joint->getParent()->getWorldRotation();
@@ -944,6 +962,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++)
{
LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]);
+ if (!cur_joint)
+ {
+ return;
+ }
+
if (joint_mask[cur_joint->getJointNum()] >= (0xff >> (7 - getPriority())))
{
// skip constraint
@@ -961,7 +984,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
{
case CONSTRAINT_TARGET_TYPE_GROUND:
target_pos = mCharacter->getPosAgentFromGlobal(constraint->mGroundPos);
-// llinfos << "Target Pos " << constraint->mGroundPos << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
+// LL_INFOS() << "Target Pos " << constraint->mGroundPos << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << LL_ENDL;
break;
case CONSTRAINT_TARGET_TYPE_BODY:
target_pos = mCharacter->getVolumePos(shared_data->mTargetConstraintVolume, shared_data->mTargetConstraintOffset);
@@ -1012,11 +1035,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
if (constraint->mSharedData->mChainLength != 0 &&
dist_vec_squared(root_pos, target_pos) * 0.95f > constraint->mTotalLength * constraint->mTotalLength)
{
- constraint->mWeight = lerp(constraint->mWeight, 0.f, LLCriticalDamp::getInterpolant(0.1f));
+ constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 0.f, 0.1f);
}
else
{
- constraint->mWeight = lerp(constraint->mWeight, 1.f, LLCriticalDamp::getInterpolant(0.3f));
+ constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 1.f, 0.3f);
}
F32 weight = constraint->mWeight * ((shared_data->mEaseOutStopTime == 0.f) ? 1.f :
@@ -1025,7 +1048,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
LLVector3 source_to_target = target_pos - keyframe_source_pos;
- S32 max_iteration_count = llround(clamp_rescale(
+ S32 max_iteration_count = ll_round(clamp_rescale(
mCharacter->getPixelArea(),
MAX_PIXEL_AREA_CONSTRAINTS,
MIN_PIXEL_AREA_CONSTRAINTS,
@@ -1034,7 +1057,14 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
if (shared_data->mChainLength)
{
- LLQuaternion end_rot = getJoint(shared_data->mJointStateIndices[0])->getWorldRotation();
+ LLJoint* end_joint = getJoint(shared_data->mJointStateIndices[0]);
+
+ if (!end_joint)
+ {
+ return;
+ }
+
+ LLQuaternion end_rot = end_joint->getWorldRotation();
// slam start and end of chain to the proper positions (rest of chain stays put)
positions[0] = lerp(keyframe_source_pos, target_pos, weight);
@@ -1043,15 +1073,22 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
// grab keyframe-specified positions of joints
for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)
{
- LLVector3 kinematic_position = getJoint(shared_data->mJointStateIndices[joint_num])->getWorldPosition() +
+ LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]);
+
+ if (!cur_joint)
+ {
+ return;
+ }
+
+ LLVector3 kinematic_position = cur_joint->getWorldPosition() +
(source_to_target * constraint->mJointLengthFractions[joint_num]);
// convert intermediate joint positions to world coordinates
positions[joint_num] = ( constraint->mPositions[joint_num] * mPelvisp->getWorldRotation()) + mPelvisp->getWorldPosition();
F32 time_constant = 1.f / clamp_rescale(constraint->mFixupDistanceRMS, 0.f, 0.5f, 0.2f, 8.f);
-// llinfos << "Interpolant " << LLCriticalDamp::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
+// LL_INFOS() << "Interpolant " << LLSmoothInterpolation::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << LL_ENDL;
positions[joint_num] = lerp(positions[joint_num], kinematic_position,
- LLCriticalDamp::getInterpolant(time_constant, FALSE));
+ LLSmoothInterpolation::getInterpolant(time_constant, FALSE));
}
S32 iteration_count;
@@ -1080,8 +1117,8 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
if ((iteration_count >= MIN_ITERATION_COUNT) &&
(num_joints_finished == shared_data->mChainLength - 1))
{
-// llinfos << iteration_count << " iterations on " <<
-// mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
+// LL_INFOS() << iteration_count << " iterations on " <<
+// mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << LL_ENDL;
break;
}
}
@@ -1089,7 +1126,17 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
for (joint_num = shared_data->mChainLength; joint_num > 0; joint_num--)
{
LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]);
+
+ if (!cur_joint)
+ {
+ return;
+ }
LLJoint* child_joint = getJoint(shared_data->mJointStateIndices[joint_num - 1]);
+ if (!child_joint)
+ {
+ return;
+ }
+
LLQuaternion parent_rot = cur_joint->getParent()->getWorldRotation();
LLQuaternion cur_rot = cur_joint->getWorldRotation();
@@ -1123,7 +1170,6 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
cur_joint->setRotation(target_rot);
}
- LLJoint* end_joint = getJoint(shared_data->mJointStateIndices[0]);
LLQuaternion end_local_rot = end_rot * ~end_joint->getParent()->getWorldRotation();
if (weight == 1.f)
@@ -1146,12 +1192,18 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
constraint->mPositions[joint_num] = new_pos;
}
constraint->mFixupDistanceRMS *= 1.f / (constraint->mTotalLength * (F32)(shared_data->mChainLength - 1));
- constraint->mFixupDistanceRMS = fsqrtf(constraint->mFixupDistanceRMS);
+ constraint->mFixupDistanceRMS = (F32) sqrt(constraint->mFixupDistanceRMS);
//reset old joint rots
for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++)
{
- getJoint(shared_data->mJointStateIndices[joint_num])->setRotation(old_rots[joint_num]);
+ LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]);
+ if (!cur_joint)
+ {
+ return;
+ }
+
+ cur_joint->setRotation(old_rots[joint_num]);
}
}
// simple positional constraint (pelvis only)
@@ -1182,13 +1234,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (!dp.unpackU16(version, "version"))
{
- llwarns << "can't read version number" << llendl;
+ LL_WARNS() << "can't read version number" << LL_ENDL;
return FALSE;
}
if (!dp.unpackU16(sub_version, "sub_version"))
{
- llwarns << "can't read sub version number" << llendl;
+ LL_WARNS() << "can't read sub version number" << LL_ENDL;
return FALSE;
}
@@ -1199,38 +1251,44 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
else if (version != KEYFRAME_MOTION_VERSION || sub_version != KEYFRAME_MOTION_SUBVERSION)
{
#if LL_RELEASE
- llwarns << "Bad animation version " << version << "." << sub_version << llendl;
+ LL_WARNS() << "Bad animation version " << version << "." << sub_version << LL_ENDL;
return FALSE;
#else
- llerrs << "Bad animation version " << version << "." << sub_version << llendl;
+ LL_ERRS() << "Bad animation version " << version << "." << sub_version << LL_ENDL;
#endif
}
if (!dp.unpackS32(temp_priority, "base_priority"))
{
- llwarns << "can't read priority" << llendl;
+ LL_WARNS() << "can't read animation base_priority" << LL_ENDL;
return FALSE;
}
mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority;
if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY)
{
- mJointMotionList->mBasePriority = (LLJoint::JointPriority)((int)LLJoint::ADDITIVE_PRIORITY-1);
+ mJointMotionList->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1);
mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority;
}
+ else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY)
+ {
+ LL_WARNS() << "bad animation base_priority " << mJointMotionList->mBasePriority << LL_ENDL;
+ return FALSE;
+ }
//-------------------------------------------------------------------------
// get duration
//-------------------------------------------------------------------------
if (!dp.unpackF32(mJointMotionList->mDuration, "duration"))
{
- llwarns << "can't read duration" << llendl;
+ LL_WARNS() << "can't read duration" << LL_ENDL;
return FALSE;
}
- if (mJointMotionList->mDuration > MAX_ANIM_DURATION )
+ if (mJointMotionList->mDuration > MAX_ANIM_DURATION ||
+ !llfinite(mJointMotionList->mDuration))
{
- llwarns << "invalid animation duration" << llendl;
+ LL_WARNS() << "invalid animation duration" << LL_ENDL;
return FALSE;
}
@@ -1239,43 +1297,53 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
//-------------------------------------------------------------------------
if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name"))
{
- llwarns << "can't read optional_emote_animation" << llendl;
+ LL_WARNS() << "can't read optional_emote_animation" << LL_ENDL;
+ return FALSE;
+ }
+
+ if(mJointMotionList->mEmoteName==mID.asString())
+ {
+ LL_WARNS() << "Malformed animation mEmoteName==mID" << LL_ENDL;
return FALSE;
}
//-------------------------------------------------------------------------
// get loop
//-------------------------------------------------------------------------
- if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point"))
+ if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") ||
+ !llfinite(mJointMotionList->mLoopInPoint))
{
- llwarns << "can't read loop point" << llendl;
+ LL_WARNS() << "can't read loop point" << LL_ENDL;
return FALSE;
}
- if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point"))
+ if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") ||
+ !llfinite(mJointMotionList->mLoopOutPoint))
{
- llwarns << "can't read loop point" << llendl;
+ LL_WARNS() << "can't read loop point" << LL_ENDL;
return FALSE;
}
if (!dp.unpackS32(mJointMotionList->mLoop, "loop"))
{
- llwarns << "can't read loop" << llendl;
+ LL_WARNS() << "can't read loop" << LL_ENDL;
return FALSE;
}
//-------------------------------------------------------------------------
// get easeIn and easeOut
//-------------------------------------------------------------------------
- if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration"))
+ if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") ||
+ !llfinite(mJointMotionList->mEaseInDuration))
{
- llwarns << "can't read easeIn" << llendl;
+ LL_WARNS() << "can't read easeIn" << LL_ENDL;
return FALSE;
}
- if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration"))
+ if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") ||
+ !llfinite(mJointMotionList->mEaseOutDuration))
{
- llwarns << "can't read easeOut" << llendl;
+ LL_WARNS() << "can't read easeOut" << LL_ENDL;
return FALSE;
}
@@ -1285,13 +1353,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
U32 word;
if (!dp.unpackU32(word, "hand_pose"))
{
- llwarns << "can't read hand pose" << llendl;
+ LL_WARNS() << "can't read hand pose" << LL_ENDL;
return FALSE;
}
if(word > LLHandMotion::NUM_HAND_POSES)
{
- llwarns << "invalid LLHandMotion::eHandPose index: " << word << llendl;
+ LL_WARNS() << "invalid LLHandMotion::eHandPose index: " << word << LL_ENDL;
return FALSE;
}
@@ -1303,18 +1371,18 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
U32 num_motions = 0;
if (!dp.unpackU32(num_motions, "num_joints"))
{
- llwarns << "can't read number of joints" << llendl;
+ LL_WARNS() << "can't read number of joints" << LL_ENDL;
return FALSE;
}
if (num_motions == 0)
{
- llwarns << "no joints in animation" << llendl;
+ LL_WARNS() << "no joints in animation" << LL_ENDL;
return FALSE;
}
else if (num_motions > LL_CHARACTER_MAX_JOINTS)
{
- llwarns << "too many joints in animation" << llendl;
+ LL_WARNS() << "too many joints in animation" << LL_ENDL;
return FALSE;
}
@@ -1335,13 +1403,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
std::string joint_name;
if (!dp.unpackString(joint_name, "joint_name"))
{
- llwarns << "can't read joint name" << llendl;
+ LL_WARNS() << "can't read joint name" << LL_ENDL;
return FALSE;
}
if (joint_name == "mScreen" || joint_name == "mRoot")
{
- llwarns << "attempted to animate special " << joint_name << " joint" << llendl;
+ LL_WARNS() << "attempted to animate special " << joint_name << " joint" << LL_ENDL;
return FALSE;
}
@@ -1351,11 +1419,11 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
LLJoint *joint = mCharacter->getJoint( joint_name );
if (joint)
{
-// llinfos << " joint: " << joint_name << llendl;
+// LL_INFOS() << " joint: " << joint_name << LL_ENDL;
}
else
{
- llwarns << "joint not found: " << joint_name << llendl;
+ LL_WARNS() << "joint not found: " << joint_name << LL_ENDL;
//return FALSE;
}
@@ -1363,7 +1431,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
LLPointer<LLJointState> joint_state = new LLJointState;
mJointStates.push_back(joint_state);
- joint_state->setJoint( joint );
+ joint_state->setJoint( joint ); // note: can accept NULL
joint_state->setUsage( 0 );
//---------------------------------------------------------------------
@@ -1372,13 +1440,19 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
S32 joint_priority;
if (!dp.unpackS32(joint_priority, "joint_priority"))
{
- llwarns << "can't read joint priority." << llendl;
+ LL_WARNS() << "can't read joint priority." << LL_ENDL;
+ return FALSE;
+ }
+
+ if (joint_priority < LLJoint::USE_MOTION_PRIORITY)
+ {
+ LL_WARNS() << "joint priority unknown - too low." << LL_ENDL;
return FALSE;
}
joint_motion->mPriority = (LLJoint::JointPriority)joint_priority;
if (joint_priority != LLJoint::USE_MOTION_PRIORITY &&
- joint_priority > mJointMotionList->mMaxPriority)
+ joint_priority > mJointMotionList->mMaxPriority)
{
mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority;
}
@@ -1388,9 +1462,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
//---------------------------------------------------------------------
// scan rotation curve header
//---------------------------------------------------------------------
- if (!dp.unpackS32(joint_motion->mRotationCurve.mNumKeys, "num_rot_keys"))
+ if (!dp.unpackS32(joint_motion->mRotationCurve.mNumKeys, "num_rot_keys") || joint_motion->mRotationCurve.mNumKeys < 0)
{
- llwarns << "can't read number of rotation keys" << llendl;
+ LL_WARNS() << "can't read number of rotation keys" << LL_ENDL;
return FALSE;
}
@@ -1412,9 +1486,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (old_version)
{
- if (!dp.unpackF32(time, "time"))
+ if (!dp.unpackF32(time, "time") ||
+ !llfinite(time))
{
- llwarns << "can't read rotation key (" << k << ")" << llendl;
+ LL_WARNS() << "can't read rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
@@ -1423,7 +1498,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
{
if (!dp.unpackU16(time_short, "time"))
{
- llwarns << "can't read rotation key (" << k << ")" << llendl;
+ LL_WARNS() << "can't read rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
@@ -1431,7 +1506,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (time < 0 || time > mJointMotionList->mDuration)
{
- llwarns << "invalid frame time" << llendl;
+ LL_WARNS() << "invalid frame time" << LL_ENDL;
return FALSE;
}
}
@@ -1445,7 +1520,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (old_version)
{
- success = dp.unpackVector3(rot_angles, "rot_angles");
+ success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite();
LLQuaternion::Order ro = StringToOrder("ZYX");
rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro);
@@ -1465,13 +1540,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if( !(rot_key.mRotation.isFinite()) )
{
- llwarns << "non-finite angle in rotation key" << llendl;
+ LL_WARNS() << "non-finite angle in rotation key" << LL_ENDL;
success = FALSE;
}
if (!success)
{
- llwarns << "can't read rotation key (" << k << ")" << llendl;
+ LL_WARNS() << "can't read rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
@@ -1481,9 +1556,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
//---------------------------------------------------------------------
// scan position curve header
//---------------------------------------------------------------------
- if (!dp.unpackS32(joint_motion->mPositionCurve.mNumKeys, "num_pos_keys"))
+ if (!dp.unpackS32(joint_motion->mPositionCurve.mNumKeys, "num_pos_keys") || joint_motion->mPositionCurve.mNumKeys < 0)
{
- llwarns << "can't read number of position keys" << llendl;
+ LL_WARNS() << "can't read number of position keys" << LL_ENDL;
return FALSE;
}
@@ -1505,9 +1580,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (old_version)
{
- if (!dp.unpackF32(pos_key.mTime, "time"))
+ if (!dp.unpackF32(pos_key.mTime, "time") ||
+ !llfinite(pos_key.mTime))
{
- llwarns << "can't read position key (" << k << ")" << llendl;
+ LL_WARNS() << "can't read position key (" << k << ")" << LL_ENDL;
return FALSE;
}
}
@@ -1515,7 +1591,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
{
if (!dp.unpackU16(time_short, "time"))
{
- llwarns << "can't read position key (" << k << ")" << llendl;
+ LL_WARNS() << "can't read position key (" << k << ")" << LL_ENDL;
return FALSE;
}
@@ -1543,13 +1619,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if( !(pos_key.mPosition.isFinite()) )
{
- llwarns << "non-finite position in key" << llendl;
+ LL_WARNS() << "non-finite position in key" << LL_ENDL;
success = FALSE;
}
if (!success)
{
- llwarns << "can't read position key (" << k << ")" << llendl;
+ LL_WARNS() << "can't read position key (" << k << ")" << LL_ENDL;
return FALSE;
}
@@ -1570,13 +1646,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
S32 num_constraints = 0;
if (!dp.unpackS32(num_constraints, "num_constraints"))
{
- llwarns << "can't read number of constraints" << llendl;
+ LL_WARNS() << "can't read number of constraints" << LL_ENDL;
return FALSE;
}
- if (num_constraints > MAX_CONSTRAINTS)
+ if (num_constraints > MAX_CONSTRAINTS || num_constraints < 0)
{
- llwarns << "Too many constraints... ignoring" << llendl;
+ LL_WARNS() << "Bad number of constraints... ignoring: " << num_constraints << LL_ENDL;
}
else
{
@@ -1592,7 +1668,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (!dp.unpackU8(byte, "chain_length"))
{
- llwarns << "can't read constraint chain length" << llendl;
+ LL_WARNS() << "can't read constraint chain length" << LL_ENDL;
delete constraintp;
return FALSE;
}
@@ -1600,61 +1676,61 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions())
{
- llwarns << "invalid constraint chain length" << llendl;
+ LL_WARNS() << "invalid constraint chain length" << LL_ENDL;
delete constraintp;
return FALSE;
}
if (!dp.unpackU8(byte, "constraint_type"))
{
- llwarns << "can't read constraint type" << llendl;
+ LL_WARNS() << "can't read constraint type" << LL_ENDL;
delete constraintp;
return FALSE;
}
if( byte >= NUM_CONSTRAINT_TYPES )
{
- llwarns << "invalid constraint type" << llendl;
+ LL_WARNS() << "invalid constraint type" << LL_ENDL;
delete constraintp;
return FALSE;
}
constraintp->mConstraintType = (EConstraintType)byte;
const S32 BIN_DATA_LENGTH = 16;
- U8 bin_data[BIN_DATA_LENGTH];
+ U8 bin_data[BIN_DATA_LENGTH+1];
if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "source_volume"))
{
- llwarns << "can't read source volume name" << llendl;
+ LL_WARNS() << "can't read source volume name" << LL_ENDL;
delete constraintp;
return FALSE;
}
- bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination
+ bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination
str = (char*)bin_data;
constraintp->mSourceConstraintVolume = mCharacter->getCollisionVolumeID(str);
if (!dp.unpackVector3(constraintp->mSourceConstraintOffset, "source_offset"))
{
- llwarns << "can't read constraint source offset" << llendl;
+ LL_WARNS() << "can't read constraint source offset" << LL_ENDL;
delete constraintp;
return FALSE;
}
if( !(constraintp->mSourceConstraintOffset.isFinite()) )
{
- llwarns << "non-finite constraint source offset" << llendl;
+ LL_WARNS() << "non-finite constraint source offset" << LL_ENDL;
delete constraintp;
return FALSE;
}
if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "target_volume"))
{
- llwarns << "can't read target volume name" << llendl;
+ LL_WARNS() << "can't read target volume name" << LL_ENDL;
delete constraintp;
return FALSE;
}
- bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination
+ bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination
str = (char*)bin_data;
if (str == "GROUND")
{
@@ -1669,28 +1745,28 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (!dp.unpackVector3(constraintp->mTargetConstraintOffset, "target_offset"))
{
- llwarns << "can't read constraint target offset" << llendl;
+ LL_WARNS() << "can't read constraint target offset" << LL_ENDL;
delete constraintp;
return FALSE;
}
if( !(constraintp->mTargetConstraintOffset.isFinite()) )
{
- llwarns << "non-finite constraint target offset" << llendl;
+ LL_WARNS() << "non-finite constraint target offset" << LL_ENDL;
delete constraintp;
return FALSE;
}
if (!dp.unpackVector3(constraintp->mTargetConstraintDir, "target_dir"))
{
- llwarns << "can't read constraint target direction" << llendl;
+ LL_WARNS() << "can't read constraint target direction" << LL_ENDL;
delete constraintp;
return FALSE;
}
if( !(constraintp->mTargetConstraintDir.isFinite()) )
{
- llwarns << "non-finite constraint target direction" << llendl;
+ LL_WARNS() << "non-finite constraint target direction" << LL_ENDL;
delete constraintp;
return FALSE;
}
@@ -1701,37 +1777,37 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
// constraintp->mTargetConstraintDir *= constraintp->mSourceConstraintOffset.magVec();
}
- if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start"))
+ if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start") || !llfinite(constraintp->mEaseInStartTime))
{
- llwarns << "can't read constraint ease in start time" << llendl;
+ LL_WARNS() << "can't read constraint ease in start time" << LL_ENDL;
delete constraintp;
return FALSE;
}
- if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop"))
+ if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop") || !llfinite(constraintp->mEaseInStopTime))
{
- llwarns << "can't read constraint ease in stop time" << llendl;
+ LL_WARNS() << "can't read constraint ease in stop time" << LL_ENDL;
delete constraintp;
return FALSE;
}
- if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start"))
+ if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start") || !llfinite(constraintp->mEaseOutStartTime))
{
- llwarns << "can't read constraint ease out start time" << llendl;
+ LL_WARNS() << "can't read constraint ease out start time" << LL_ENDL;
delete constraintp;
return FALSE;
}
- if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop"))
+ if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop") || !llfinite(constraintp->mEaseOutStopTime))
{
- llwarns << "can't read constraint ease out stop time" << llendl;
+ LL_WARNS() << "can't read constraint ease out stop time" << LL_ENDL;
delete constraintp;
return FALSE;
}
mJointMotionList->mConstraints.push_front(constraintp);
- constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1];
+ constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte
LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume);
// get joint to which this collision volume is attached
@@ -1744,15 +1820,23 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
LLJoint* parent = joint->getParent();
if (!parent)
{
- llwarns << "Joint with no parent: " << joint->getName()
- << " Emote: " << mJointMotionList->mEmoteName << llendl;
+ LL_WARNS() << "Joint with no parent: " << joint->getName()
+ << " Emote: " << mJointMotionList->mEmoteName << LL_ENDL;
return FALSE;
}
joint = parent;
constraintp->mJointStateIndices[i] = -1;
for (U32 j = 0; j < mJointMotionList->getNumJointMotions(); j++)
{
- if(getJoint(j) == joint)
+ LLJoint* constraint_joint = getJoint(j);
+
+ if ( !constraint_joint )
+ {
+ LL_WARNS() << "Invalid joint " << j << LL_ENDL;
+ return FALSE;
+ }
+
+ if(constraint_joint == joint)
{
constraintp->mJointStateIndices[i] = (S32)j;
break;
@@ -1760,7 +1844,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
}
if (constraintp->mJointStateIndices[i] < 0 )
{
- llwarns << "No joint index for constraint " << i << llendl;
+ LL_WARNS() << "No joint index for constraint " << i << LL_ENDL;
delete constraintp;
return FALSE;
}
@@ -2081,7 +2165,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
U8* buffer = new U8[size];
file.read((U8*)buffer, size); /*Flawfinder: ignore*/
- lldebugs << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << llendl;
+ LL_DEBUGS() << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL;
LLDataPackerBinaryBuffer dp(buffer, size);
if (motionp->deserialize(dp))
@@ -2090,7 +2174,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
}
else
{
- llwarns << "Failed to decode asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl;
+ LL_WARNS() << "Failed to decode asset for animation " << motionp->getName() << ":" << motionp->getID() << LL_ENDL;
motionp->mAssetStatus = ASSET_FETCH_FAILED;
}
@@ -2098,13 +2182,13 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
}
else
{
- llwarns << "Failed to load asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl;
+ LL_WARNS() << "Failed to load asset for animation " << motionp->getName() << ":" << motionp->getID() << LL_ENDL;
motionp->mAssetStatus = ASSET_FETCH_FAILED;
}
}
else
{
- llwarns << "No existing motion for asset data. UUID: " << asset_uuid << llendl;
+ LL_WARNS() << "No existing motion for asset data. UUID: " << asset_uuid << LL_ENDL;
}
}
@@ -2118,9 +2202,9 @@ void LLKeyframeDataCache::dumpDiagInfo()
char buf[1024]; /* Flawfinder: ignore */
- llinfos << "-----------------------------------------------------" << llendl;
- llinfos << " Global Motion Table (DEBUG only)" << llendl;
- llinfos << "-----------------------------------------------------" << llendl;
+ LL_INFOS() << "-----------------------------------------------------" << LL_ENDL;
+ LL_INFOS() << " Global Motion Table (DEBUG only)" << LL_ENDL;
+ LL_INFOS() << "-----------------------------------------------------" << LL_ENDL;
// print each loaded mesh, and it's memory usage
for (keyframe_data_map_t::iterator map_it = sKeyframeDataMap.begin();
@@ -2130,18 +2214,18 @@ void LLKeyframeDataCache::dumpDiagInfo()
LLKeyframeMotion::JointMotionList *motion_list_p = map_it->second;
- llinfos << "Motion: " << map_it->first << llendl;
+ LL_INFOS() << "Motion: " << map_it->first << LL_ENDL;
joint_motion_kb = motion_list_p->dumpDiagInfo();
total_size += joint_motion_kb;
}
- llinfos << "-----------------------------------------------------" << llendl;
- llinfos << "Motions\tTotal Size" << llendl;
+ LL_INFOS() << "-----------------------------------------------------" << LL_ENDL;
+ LL_INFOS() << "Motions\tTotal Size" << LL_ENDL;
snprintf(buf, sizeof(buf), "%d\t\t%d bytes", (S32)sKeyframeDataMap.size(), total_size ); /* Flawfinder: ignore */
- llinfos << buf << llendl;
- llinfos << "-----------------------------------------------------" << llendl;
+ LL_INFOS() << buf << LL_ENDL;
+ LL_INFOS() << "-----------------------------------------------------" << LL_ENDL;
}
@@ -2208,8 +2292,7 @@ LLKeyframeMotion::JointConstraint::JointConstraint(JointConstraintSharedData* sh
mTargetVolume = NULL;
mFixupDistanceRMS = 0.f;
- int i;
- for (i=0; i<MAX_CHAIN_LENGTH; ++i)
+ for (S32 i=0; i<MAX_CHAIN_LENGTH; ++i)
{
mJointLengths[i] = 0.f;
mJointLengthFractions[i] = 0.f;
@@ -2224,3 +2307,4 @@ LLKeyframeMotion::JointConstraint::~JointConstraint()
}
// End
+