[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