Browse Source

Make sure animation start time adjustment happens with tick conversion, tabs to spaces, some code reordering + added comments.

Lasse Öörni 11 years ago
parent
commit
f3e18e6412
1 changed files with 28 additions and 18 deletions
  1. 28 18
      Source/Tools/AssetImporter/AssetImporter.cpp

+ 28 - 18
Source/Tools/AssetImporter/AssetImporter.cpp

@@ -984,32 +984,42 @@ void BuildAndSaveAnimations(OutModel* model)
     for (unsigned i = 0; i < animations.Size(); ++i)
     for (unsigned i = 0; i < animations.Size(); ++i)
     {
     {
         aiAnimation* anim = animations[i];
         aiAnimation* anim = animations[i];
+        
+        float duration = (float)anim->mDuration;
         String animName = FromAIString(anim->mName);
         String animName = FromAIString(anim->mName);
+        String animOutName;
+        
         if (animName.Empty())
         if (animName.Empty())
             animName = "Anim" + String(i + 1);
             animName = "Anim" + String(i + 1);
-        String animOutName;
         if (model)
         if (model)
             animOutName = GetPath(model->outName_) + GetFileName(model->outName_) + "_" + SanitateAssetName(animName) + ".ani";
             animOutName = GetPath(model->outName_) + GetFileName(model->outName_) + "_" + SanitateAssetName(animName) + ".ani";
         else
         else
             animOutName = outPath_ + SanitateAssetName(animName) + ".ani";
             animOutName = outPath_ + SanitateAssetName(animName) + ".ani";
         
         
-		double startTime = anim->mDuration;
-        for (unsigned j = 0; j < anim->mNumChannels; ++j)
-        {
-            aiNodeAnim* channel = anim->mChannels[j];
-			if (channel->mNumPositionKeys > 0) startTime = std::min(startTime, channel->mPositionKeys[0].mTime);
-			if (channel->mNumRotationKeys > 0) startTime = std::min(startTime, channel->mRotationKeys[0].mTime);
-			if (channel->mScalingKeys > 0) startTime = std::min(startTime, channel->mScalingKeys[0].mTime);
-		}
-		
-        SharedPtr<Animation> outAnim(new Animation(context_));
         float ticksPerSecond = (float)anim->mTicksPerSecond;
         float ticksPerSecond = (float)anim->mTicksPerSecond;
         // If ticks per second not specified, it's probably a .X file. In this case use the default tick rate
         // If ticks per second not specified, it's probably a .X file. In this case use the default tick rate
         if (ticksPerSecond < M_EPSILON)
         if (ticksPerSecond < M_EPSILON)
             ticksPerSecond = defaultTicksPerSecond_;
             ticksPerSecond = defaultTicksPerSecond_;
         float tickConversion = 1.0f / ticksPerSecond;
         float tickConversion = 1.0f / ticksPerSecond;
+        
+        // Find out the start time of animation from each channel's first keyframe for adjusting the keyframe times
+        // to start from zero
+        float startTime = duration;
+        for (unsigned j = 0; j < anim->mNumChannels; ++j)
+        {
+            aiNodeAnim* channel = anim->mChannels[j];
+            if (channel->mNumPositionKeys > 0)
+                startTime = Min(startTime, (float)channel->mPositionKeys[0].mTime);
+            if (channel->mNumRotationKeys > 0)
+                startTime = Min(startTime, (float)channel->mRotationKeys[0].mTime);
+            if (channel->mScalingKeys > 0)
+                startTime = Min(startTime, (float)channel->mScalingKeys[0].mTime);
+        }
+        duration -= startTime;
+
+        SharedPtr<Animation> outAnim(new Animation(context_));
         outAnim->SetAnimationName(animName);
         outAnim->SetAnimationName(animName);
-        outAnim->SetLength((float)(anim->mDuration - startTime) * tickConversion);
+        outAnim->SetLength(duration * tickConversion);
         
         
         PrintLine("Writing animation " + animName + " length " + String(outAnim->GetLength()));
         PrintLine("Writing animation " + animName + " length " + String(outAnim->GetLength()));
         Vector<AnimationTrack> tracks;
         Vector<AnimationTrack> tracks;
@@ -1099,16 +1109,16 @@ void BuildAndSaveAnimations(OutModel* model)
                 kf.rotation_ = Quaternion::IDENTITY;
                 kf.rotation_ = Quaternion::IDENTITY;
                 kf.scale_ = Vector3::ONE;
                 kf.scale_ = Vector3::ONE;
                 
                 
-                // Get time for the keyframe
+                // Get time for the keyframe. Adjust with animation's start time
                 if (track.channelMask_ & CHANNEL_POSITION && k < channel->mNumPositionKeys)
                 if (track.channelMask_ & CHANNEL_POSITION && k < channel->mNumPositionKeys)
-                    kf.time_ = (float)channel->mPositionKeys[k].mTime * tickConversion;
+                    kf.time_ = ((float)channel->mPositionKeys[k].mTime - startTime) * tickConversion;
                 else if (track.channelMask_ & CHANNEL_ROTATION && k < channel->mNumRotationKeys)
                 else if (track.channelMask_ & CHANNEL_ROTATION && k < channel->mNumRotationKeys)
-                    kf.time_ = (float)channel->mRotationKeys[k].mTime * tickConversion;
+                    kf.time_ = ((float)channel->mRotationKeys[k].mTime - startTime) * tickConversion;
                 else if (track.channelMask_ & CHANNEL_SCALE && k < channel->mNumScalingKeys)
                 else if (track.channelMask_ & CHANNEL_SCALE && k < channel->mNumScalingKeys)
-                    kf.time_ = (float)channel->mScalingKeys[k].mTime * tickConversion;
+                    kf.time_ = ((float)channel->mScalingKeys[k].mTime - startTime) * tickConversion;
                 
                 
-				// offset time
-				kf.time_ -= startTime;
+                // Make sure time stays positive
+                kf.time_ = Max(kf.time_, 0.0f);
                 
                 
                 // Start with the bone's base transform
                 // Start with the bone's base transform
                 aiMatrix4x4 boneTransform = boneNode->mTransformation;
                 aiMatrix4x4 boneTransform = boneNode->mTransformation;