diff options
Diffstat (limited to 'indra/llcharacter')
-rw-r--r-- | indra/llcharacter/CMakeLists.txt | 1 | ||||
-rw-r--r-- | indra/llcharacter/llbvhconsts.h | 52 | ||||
-rw-r--r-- | indra/llcharacter/llbvhloader.h | 8 | ||||
-rw-r--r-- | indra/llcharacter/llkeyframemotion.cpp | 107 | ||||
-rw-r--r-- | indra/llcharacter/llkeyframemotion.h | 17 |
5 files changed, 149 insertions, 36 deletions
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index 63010626e1..612229d16b 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -46,6 +46,7 @@ set(llcharacter_HEADER_FILES llanimationstates.h llbvhloader.h + llbvhconsts.h llcharacter.h lleditingmotion.h llgesture.h diff --git a/indra/llcharacter/llbvhconsts.h b/indra/llcharacter/llbvhconsts.h new file mode 100644 index 0000000000..d5876aa077 --- /dev/null +++ b/indra/llcharacter/llbvhconsts.h @@ -0,0 +1,52 @@ +/** + * @file llbvhconsts.h + * @brief Consts and types useful to BVH files and LindenLabAnimation format. + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLBVHCONSTS_H +#define LL_LLBVHCONSTS_H + +const F32 MAX_ANIM_DURATION = 30.f; + +typedef enum e_constraint_type + { + CONSTRAINT_TYPE_POINT, + CONSTRAINT_TYPE_PLANE, + NUM_CONSTRAINT_TYPES + } EConstraintType; + +typedef enum e_constraint_target_type + { + CONSTRAINT_TARGET_TYPE_BODY, + CONSTRAINT_TARGET_TYPE_GROUND, + NUM_CONSTRAINT_TARGET_TYPES + } EConstraintTargetType; + +#endif // LL_LLBVHCONSTS_H diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h index 13801939db..6937b9d835 100644 --- a/indra/llcharacter/llbvhloader.h +++ b/indra/llcharacter/llbvhloader.h @@ -37,9 +37,9 @@ #include "m3math.h" #include "llmath.h" #include "llapr.h" +#include "llbvhconsts.h" const S32 BVH_PARSER_LINE_SIZE = 2048; -const F32 MAX_ANIM_DURATION = 30.f; class LLDataPacker; //------------------------------------------------------------------------ @@ -132,12 +132,6 @@ struct Joint }; -typedef enum e_constraint_type -{ - CONSTRAINT_TYPE_POINT, - CONSTRAINT_TYPE_PLANE -} EConstraintType; - struct Constraint { char mSourceJointName[16]; /* Flawfinder: ignore */ diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 19d8386255..5a2e3f73f9 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -862,7 +862,7 @@ void LLKeyframeMotion::activateConstraint(JointConstraint* constraint) S32 joint_num; // grab ground position if we need to - if (shared_data->mConstraintTargetType == TYPE_GROUND) + if (shared_data->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) { LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset); LLVector3 ground_pos_agent; @@ -889,7 +889,7 @@ void LLKeyframeMotion::deactivateConstraint(JointConstraint *constraintp) constraintp->mSourceVolume->mUpdateXform = FALSE; } - if (!constraintp->mSharedData->mConstraintTargetType == TYPE_GROUND) + if (!constraintp->mSharedData->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) { if (constraintp->mTargetVolume) { @@ -959,11 +959,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 switch(shared_data->mConstraintTargetType) { - case TYPE_GROUND: + case CONSTRAINT_TARGET_TYPE_GROUND: target_pos = mCharacter->getPosAgentFromGlobal(constraint->mGroundPos); // llinfos << "Target Pos " << constraint->mGroundPos << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl; break; - case TYPE_BODY: + case CONSTRAINT_TARGET_TYPE_BODY: target_pos = mCharacter->getVolumePos(shared_data->mTargetConstraintVolume, shared_data->mTargetConstraintOffset); break; default: @@ -974,14 +974,14 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 LLJoint *source_jointp = NULL; LLJoint *target_jointp = NULL; - if (shared_data->mConstraintType == TYPE_PLANE) + if (shared_data->mConstraintType == CONSTRAINT_TYPE_PLANE) { switch(shared_data->mConstraintTargetType) { - case TYPE_GROUND: + case CONSTRAINT_TARGET_TYPE_GROUND: norm = constraint->mGroundNorm; break; - case TYPE_BODY: + case CONSTRAINT_TARGET_TYPE_BODY: target_jointp = mCharacter->findCollisionVolume(shared_data->mTargetConstraintVolume); if (target_jointp) { @@ -1227,6 +1227,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) llwarns << "can't read duration" << llendl; return FALSE; } + + if (mJointMotionList->mDuration > MAX_ANIM_DURATION ) + { + llwarns << "invalid animation duration" << llendl; + return FALSE; + } //------------------------------------------------------------------------- // get emote (optional) @@ -1282,6 +1288,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) llwarns << "can't read hand pose" << llendl; return FALSE; } + + if(word > LLHandMotion::NUM_HAND_POSES) + { + llwarns << "invalid LLHandMotion::eHandPose index: " << word << llendl; + return FALSE; + } + mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word; //------------------------------------------------------------------------- @@ -1325,7 +1338,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) llwarns << "can't read joint name" << llendl; return FALSE; } - + + if (joint_name == "mScreen" || joint_name == "mRoot") + { + llwarns << "attempted to animate special " << joint_name << " joint" << llendl; + return FALSE; + } + //--------------------------------------------------------------------- // find the corresponding joint //--------------------------------------------------------------------- @@ -1409,6 +1428,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) } time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + + if (time < 0 || time > mJointMotionList->mDuration) + { + llwarns << "invalid frame time" << llendl; + return FALSE; + } } RotationKey rot_key; @@ -1438,6 +1463,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) rot_key.mRotation.unpackFromVector3(rot_vec); } + if( !(rot_key.mRotation.isFinite()) ) + { + llwarns << "non-finite angle in rotation key" << llendl; + success = FALSE; + } + if (!success) { llwarns << "can't read rotation key (" << k << ")" << llendl; @@ -1509,7 +1540,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); } - + + if( !(pos_key.mPosition.isFinite()) ) + { + llwarns << "non-finite position in key" << llendl; + success = FALSE; + } + if (!success) { llwarns << "can't read position key (" << k << ")" << llendl; @@ -1539,7 +1576,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (num_constraints > MAX_CONSTRAINTS) { - llwarns << "Too many constraints...ignoring" << llendl; + llwarns << "Too many constraints... ignoring" << llendl; } else { @@ -1561,12 +1598,26 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) } constraintp->mChainLength = (S32) byte; + if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions()) + { + llwarns << "invalid constraint chain length" << llendl; + delete constraintp; + return FALSE; + } + if (!dp.unpackU8(byte, "constraint_type")) { llwarns << "can't read constraint type" << llendl; delete constraintp; return FALSE; } + + if( byte >= NUM_CONSTRAINT_TYPES ) + { + llwarns << "invalid constraint type" << llendl; + delete constraintp; + return FALSE; + } constraintp->mConstraintType = (EConstraintType)byte; const S32 BIN_DATA_LENGTH = 16; @@ -1588,7 +1639,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) delete constraintp; return FALSE; } - + + if( !(constraintp->mSourceConstraintOffset.isFinite()) ) + { + llwarns << "non-finite constraint source offset" << llendl; + delete constraintp; + return FALSE; + } + if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "target_volume")) { llwarns << "can't read target volume name" << llendl; @@ -1601,11 +1659,11 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (str == "GROUND") { // constrain to ground - constraintp->mConstraintTargetType = TYPE_GROUND; + constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_GROUND; } else { - constraintp->mConstraintTargetType = TYPE_BODY; + constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_BODY; constraintp->mTargetConstraintVolume = mCharacter->getCollisionVolumeID(str); } @@ -1616,6 +1674,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } + if( !(constraintp->mTargetConstraintOffset.isFinite()) ) + { + llwarns << "non-finite constraint target offset" << llendl; + delete constraintp; + return FALSE; + } + if (!dp.unpackVector3(constraintp->mTargetConstraintDir, "target_dir")) { llwarns << "can't read constraint target direction" << llendl; @@ -1623,6 +1688,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) return FALSE; } + if( !(constraintp->mTargetConstraintDir.isFinite()) ) + { + llwarns << "non-finite constraint target direction" << llendl; + delete constraintp; + return FALSE; + } + if (!constraintp->mTargetConstraintDir.isExactlyZero()) { constraintp->mUseTargetOffset = TRUE; @@ -1686,8 +1758,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) break; } } + if (constraintp->mJointStateIndices[i] < 0 ) + { + llwarns << "No joint index for constraint " << i << llendl; + delete constraintp; + return FALSE; + } } - } } @@ -1777,7 +1854,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str()); success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "source_volume"); success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset"); - if (shared_constraintp->mConstraintTargetType == TYPE_GROUND) + if (shared_constraintp->mConstraintTargetType == CONSTRAINT_TARGET_TYPE_GROUND) { snprintf(volume_name,sizeof(volume_name), "%s", "GROUND"); /* Flawfinder: ignore */ } diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 298b5f6be6..7e8c84488c 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -48,6 +48,7 @@ #include "v3dmath.h" #include "v3math.h" #include "llapr.h" +#include "llbvhconsts.h" class LLKeyframeDataCache; class LLVFS; @@ -198,18 +199,6 @@ public: static void flushKeyframeCache(); - typedef enum e_constraint_type - { - TYPE_POINT, - TYPE_PLANE - } EConstraintType; - - typedef enum e_constraint_target_type - { - TYPE_BODY, - TYPE_GROUND - } EConstraintTargetType; - protected: //------------------------------------------------------------------------- // JointConstraintSharedData @@ -224,8 +213,8 @@ protected: mEaseOutStartTime(0.f), mEaseOutStopTime(0.f), mUseTargetOffset(FALSE), - mConstraintType(TYPE_POINT), - mConstraintTargetType(TYPE_BODY), + mConstraintType(CONSTRAINT_TYPE_POINT), + mConstraintTargetType(CONSTRAINT_TARGET_TYPE_BODY), mSourceConstraintVolume(0), mTargetConstraintVolume(0), mJointStateIndices(NULL) |