diff options
| author | Howard Stearns <aech@lindenlab.com> | 2022-01-24 16:53:00 +0000 | 
|---|---|---|
| committer | Howard Stearns <aech@lindenlab.com> | 2022-01-24 16:53:00 +0000 | 
| commit | b6029c4c34782b8c423ea2625712e8b8604af442 (patch) | |
| tree | 358eca34c63a9256a26acadd0b3e379cb60dc0be | |
| parent | 5ab34ccc5a5ec0abd6526b16379d7e29d8668ec4 (diff) | |
| parent | fec246a2e6d380971080d95446cc55059be01352 (diff) | |
Merged in SL-316 (pull request #838)
SL-316 - Fix fencepost errors in computing keyframe start times of .bvh loader.
| -rw-r--r-- | indra/llcharacter/llbvhloader.cpp | 32 | 
1 files changed, 25 insertions, 7 deletions
| diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index e906d81ce1..7f99d22a17 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -44,6 +44,14 @@ using namespace std;  #define INCHES_TO_METERS 0.02540005f +/// The .bvh does not have a formal spec, and different readers interpret things in their own way. +/// In OUR usage, frame 0 is used in optimization and is not considered to be part of the animation. +const S32 NUMBER_OF_IGNORED_FRAMES_AT_START = 1; +/// In our usage, the last frame is used only to indicate what the penultimate frame should be interpolated towards. +///  I.e., the animation only plays up to the start of the last frame. There is no hold or exptrapolation past that point.. +/// Thus there are two frame of the total that do not contribute to the total running time of the animation. +const S32 NUMBER_OF_UNPLAYED_FRAMES = NUMBER_OF_IGNORED_FRAMES_AT_START + 1; +  const F32 POSITION_KEYFRAME_THRESHOLD_SQUARED = 0.03f * 0.03f;  const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f; @@ -865,7 +873,8 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &  		return E_ST_NO_FRAME_TIME;  	} -	mDuration = (F32)mNumFrames * mFrameTime; +	// If the user only supplies one animation frame (after the ignored reference frame 0), hold for mFrameTime. +	mDuration = llmax((F32)(mNumFrames - NUMBER_OF_UNPLAYED_FRAMES), 1.0f) * mFrameTime;  	if (!mLoop)  	{  		mLoopOutPoint = mDuration; @@ -1355,12 +1364,13 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)  		LLQuaternion::Order order = bvhStringToOrder( joint->mOrder );  		S32 outcount = 0; -		S32 frame = 1; +		S32 frame = 0;  		for (	ki = joint->mKeys.begin();  				ki != joint->mKeys.end();  				++ki )  		{ -			if ((frame == 1) && joint->mRelativeRotationKey) + +			if ((frame == 0) && joint->mRelativeRotationKey)  			{  				first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order); @@ -1373,7 +1383,11 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)  				continue;  			} -			time = (F32)frame * mFrameTime; +			if (frame == 0) { +				LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] Joint " << ki - joint->mKeys.begin() << " not marked to ignore rotation for initial frame. Not serializing." << LL_ENDL; +				return FALSE; +			} +			time = (F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START) * mFrameTime; // Time elapsed before this frame starts.  			if (mergeParent)  			{ @@ -1433,12 +1447,12 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)  			LLVector3 relPos = joint->mRelativePosition;  			LLVector3 relKey; -			frame = 1; +			frame = 0;  			for (	ki = joint->mKeys.begin();  					ki != joint->mKeys.end();  					++ki )  			{ -				if ((frame == 1) && joint->mRelativePositionKey) +				if ((frame == 0) && joint->mRelativePositionKey)  				{  					relKey.setVec(ki->mPos);  				} @@ -1449,7 +1463,11 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)  					continue;  				} -				time = (F32)frame * mFrameTime; +				if (frame == 0) { +					LL_WARNS("BVH") << "ERROR: [line: " << getLineNumber() << "] Joint " << ki - joint->mKeys.begin() << " not marked to ignore position for initial frame. Not serializing." << LL_ENDL; +					return FALSE; +				} +				time = (F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START) * mFrameTime; // Time elapsed before this frame starts.  				LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot;  				LLVector3 outPos = inPos * frameRot * offsetRot; | 
