diff options
Diffstat (limited to 'indra/llcharacter/llkeyframemotion.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/llcharacter/llkeyframemotion.cpp | 372 |
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 + |