[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48090] branches/soc-2012-bratwurst/source /blender/assimp: - bf_assimp: resample bone animations to be in blender' s bone coordinate space.

Alexander Gessler alexander.gessler at gmx.net
Tue Jun 19 19:56:38 CEST 2012


Revision: 48090
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48090
Author:   aramis_acg
Date:     2012-06-19 17:56:30 +0000 (Tue, 19 Jun 2012)
Log Message:
-----------
- bf_assimp: resample bone animations to be in blender's bone coordinate space. This is a slow operation since we need to evaluate all animations, calculate world space matrices, change coordinate space and decompose again. It is also wasteful/destructive because it involves adding new keyframes (if parent bones have different keyframe positions than the bones by themselves). Don't have a choice, though.

Modified Paths:
--------------
    branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.cpp
    branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.h
    branches/soc-2012-bratwurst/source/blender/assimp/CMakeLists.txt

Added Paths:
-----------
    branches/soc-2012-bratwurst/source/blender/assimp/AnimEvaluator.cpp
    branches/soc-2012-bratwurst/source/blender/assimp/AnimEvaluator.h

Added: branches/soc-2012-bratwurst/source/blender/assimp/AnimEvaluator.cpp
===================================================================
--- branches/soc-2012-bratwurst/source/blender/assimp/AnimEvaluator.cpp	                        (rev 0)
+++ branches/soc-2012-bratwurst/source/blender/assimp/AnimEvaluator.cpp	2012-06-19 17:56:30 UTC (rev 48090)
@@ -0,0 +1,174 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2012, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, 
+with or without modification, are permitted provided that the following 
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+#include "AnimEvaluator.h"
+
+namespace bassimp {
+
+// ------------------------------------------------------------------------------------------------
+// Constructor on a given animation. 
+AnimEvaluator::AnimEvaluator( const aiAnimation* pAnim)
+{
+	mAnim = pAnim;
+	mLastTime = 0.0;
+	mLastPositions.resize( pAnim->mNumChannels,PositionTuple());
+}
+
+// ------------------------------------------------------------------------------------------------
+// Evaluates the animation tracks for a given time stamp. 
+void AnimEvaluator::EvaluateSingle(double time, unsigned int channel_index)
+{
+	// note: unlike the original AnimEvaluator from assimp, this one thinks in ticks, not seconds.
+	if( mTransforms.size() != mAnim->mNumChannels) {
+		mTransforms.resize( mAnim->mNumChannels);
+	}
+
+	const aiNodeAnim* const channel = mAnim->mChannels[channel_index];
+
+	// ******** Position *****
+	aiVector3D presentPosition( 0, 0, 0);
+	if( channel->mNumPositionKeys > 0)
+	{
+		// Look for present frame number. Search from last position if time is after the last time, else from beginning
+		// Should be much quicker than always looking from start for the average use case.
+		unsigned int frame = (time >= mLastTime) ? mLastPositions[channel_index].i0 : 0;
+		while( frame < channel->mNumPositionKeys - 1)	{
+			if( time < channel->mPositionKeys[frame+1].mTime) {
+				break;
+			}
+			frame++;
+		}
+
+		// interpolate between this frame's value and next frame's value
+		unsigned int nextFrame = (frame + 1) % channel->mNumPositionKeys;
+		const aiVectorKey& key = channel->mPositionKeys[frame];
+		const aiVectorKey& nextKey = channel->mPositionKeys[nextFrame];
+		double diffTime = nextKey.mTime - key.mTime;
+		if( diffTime < 0.0) {
+			diffTime += mAnim->mDuration;
+		}
+
+		if( diffTime > 0)	{
+			const float factor = float( (time - key.mTime) / diffTime);
+			presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
+		} 
+		else	{
+			presentPosition = key.mValue;
+		}
+
+		mLastPositions[channel_index].i0 = frame;
+	}
+
+	// ******** Rotation *********
+	aiQuaternion presentRotation( 1, 0, 0, 0);
+	if( channel->mNumRotationKeys > 0)	{
+		unsigned int frame = (time >= mLastTime) ? mLastPositions[channel_index].i1 : 0;
+		while( frame < channel->mNumRotationKeys - 1)	{
+
+			if( time < channel->mRotationKeys[frame+1].mTime) {
+				break;
+			}
+			frame++;
+		}
+
+		// interpolate between this frame's value and next frame's value
+		unsigned int nextFrame = (frame + 1) % channel->mNumRotationKeys;
+		const aiQuatKey& key = channel->mRotationKeys[frame];
+		const aiQuatKey& nextKey = channel->mRotationKeys[nextFrame];
+		double diffTime = nextKey.mTime - key.mTime;
+		if( diffTime < 0.0) {
+			diffTime += mAnim->mDuration;
+		}
+
+		if( diffTime > 0)	{
+			const float factor = float( (time - key.mTime) / diffTime);
+			aiQuaternion::Interpolate( presentRotation, key.mValue, nextKey.mValue, factor);
+		} 
+		else {
+			presentRotation = key.mValue;
+		}
+
+		mLastPositions[channel_index].i1 = frame;
+	}
+
+	// ******** Scaling **********
+	aiVector3D presentScaling( 1, 1, 1);
+	if( channel->mNumScalingKeys > 0) {
+		unsigned int frame = (time >= mLastTime) ? mLastPositions[channel_index].i2 : 0;
+		while( frame < channel->mNumScalingKeys - 1)	{
+
+			if( time < channel->mScalingKeys[frame+1].mTime) {
+				break;
+			}
+			frame++;
+		}
+
+		// TODO: (thom) interpolation maybe? This time maybe even logarithmic, not linear
+		presentScaling = channel->mScalingKeys[frame].mValue;
+		mLastPositions[channel_index].i2 = frame;
+	}
+
+	// build a transformation matrix from it
+	aiMatrix4x4& mat = mTransforms[channel_index];
+	mat = aiMatrix4x4( presentRotation.GetMatrix());
+	mat.a1 *= presentScaling.x; mat.b1 *= presentScaling.x; mat.c1 *= presentScaling.x;
+	mat.a2 *= presentScaling.y; mat.b2 *= presentScaling.y; mat.c2 *= presentScaling.y;
+	mat.a3 *= presentScaling.z; mat.b3 *= presentScaling.z; mat.c3 *= presentScaling.z;
+	mat.a4 = presentPosition.x; mat.b4 = presentPosition.y; mat.c4 = presentPosition.z;
+
+	mLastTime = time;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// Evaluates the animation tracks for a given time stamp. 
+void AnimEvaluator::Evaluate( double pTime)
+{
+	// note: unlike the original AnimEvaluator from assimp, this one thinks in ticks, not seconds.
+
+	// calculate the transformations for each animation channel
+	for( unsigned int a = 0; a < mAnim->mNumChannels; a++)	{
+		EvaluateSingle(pTime, a);		
+	}
+}
+
+}
+

Added: branches/soc-2012-bratwurst/source/blender/assimp/AnimEvaluator.h
===================================================================
--- branches/soc-2012-bratwurst/source/blender/assimp/AnimEvaluator.h	                        (rev 0)
+++ branches/soc-2012-bratwurst/source/blender/assimp/AnimEvaluator.h	2012-06-19 17:56:30 UTC (rev 48090)
@@ -0,0 +1,110 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2012, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, 
+with or without modification, are permitted provided that the following 
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** Calculates a pose for a given time of an animation */
+
+#ifndef INCLUDED_ANIM_EVALUATOR_H
+#define INCLUDED_ANIM_EVALUATOR_H
+
+#include <vector>
+#include "bassimp_shared.h"
+
+namespace bassimp
+{
+
+/** Calculates transformations for a given timestamp from a set of animation tracks. Not directly useful,
+ * better use the AnimPlayer class.
+ */
+class AnimEvaluator
+{
+public:
+	/** Constructor on a given animation. The animation is fixed throughout the lifetime of
+	 * the object.
+	 * @param pAnim The animation to calculate poses for. Ownership of the animation object stays
+	 *   at the caller, the evaluator just keeps a reference to it as long as it persists.
+	 */
+	AnimEvaluator( const aiAnimation* pAnim);
+
+	/** Evaluates the animation tracks for a given time stamp. The calculated pose can be retrieved as a
+	 * array of transformation matrices afterwards by calling GetTransformations().
+	 * @param pTime The time for which you want to evaluate the animation, in TICKS. Must be in-range.
+	 */
+	void Evaluate( double pTicks);
+
+	/** Same as @Evaluate, but only evaluates a single node animation channel */
+	void EvaluateSingle( double pTicks, unsigned int channel);
+
+	/** Returns the transform matrices calculated at the last Evaluate() call. The array matches the mChannels array of
+	 * the aiAnimation. */
+	const std::vector<aiMatrix4x4>& GetTransformations() const { return mTransforms; }
+
+protected:
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list