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. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to