Преглед изворни кода

* Combining single-channel animations like the previous code did, except now it has been deferred until after all nodes have been read. This makes the regression tests pass for a database created before these code changes.
* Changed name of ColladaParser::RebuildRootAnimationsFromClips to ColladaParser::PostProcessRootAnimations as it now does more than it did before.

Trond Abusdal пре 9 година
родитељ
комит
7e58a47ba0
3 измењених фајлова са 45 додато и 11 уклоњено
  1. 30 0
      code/ColladaHelper.h
  2. 13 9
      code/ColladaParser.cpp
  3. 2 2
      code/ColladaParser.h

+ 30 - 0
code/ColladaHelper.h

@@ -598,6 +598,7 @@ struct Animation
             delete *it;
             delete *it;
     }
     }
 
 
+	/** Collect all channels in the animation hierarchy into a single channel list. */
 	void CollectChannelsRecursively(std::vector<AnimationChannel> &channels)
 	void CollectChannelsRecursively(std::vector<AnimationChannel> &channels)
 	{
 	{
 		channels.insert(channels.end(), mChannels.begin(), mChannels.end());
 		channels.insert(channels.end(), mChannels.begin(), mChannels.end());
@@ -609,6 +610,35 @@ struct Animation
 			pAnim->CollectChannelsRecursively(channels);
 			pAnim->CollectChannelsRecursively(channels);
 		}
 		}
 	}
 	}
+
+	/** Combine all single-channel animations' channel into the same (parent) animation channel list. */
+	void CombineSingleChannelAnimations()
+	{
+		CombineSingleChannelAnimationsRecursively(this);
+	}
+
+	void CombineSingleChannelAnimationsRecursively(Animation *pParent)
+	{
+		for (std::vector<Animation*>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();)
+		{
+			Animation *anim = *it;
+
+			CombineSingleChannelAnimationsRecursively(anim);
+
+			if (anim->mChannels.size() == 1)
+			{
+				pParent->mChannels.push_back(anim->mChannels[0]);
+
+				it = pParent->mSubAnims.erase(it);
+
+				delete anim;
+			}
+			else
+			{
+				++it;
+			}
+		}
+	}
 };
 };
 
 
 /** Description of a collada animation channel which has been determined to affect the current node */
 /** Description of a collada animation channel which has been determined to affect the current node */

+ 13 - 9
code/ColladaParser.cpp

@@ -217,6 +217,8 @@ void ColladaParser::ReadStructure()
             break;
             break;
         }
         }
     }
     }
+
+	PostProcessRootAnimations();
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -356,8 +358,8 @@ void ColladaParser::ReadAnimationClipLibrary()
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-// Re-build animations from animation clip library, if present.
-void ColladaParser::RebuildRootAnimationsFromClips()
+// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
+void ColladaParser::PostProcessRootAnimations()
 {
 {
 	if (mAnimationClipLibrary.size() > 0)
 	if (mAnimationClipLibrary.size() > 0)
 	{
 	{
@@ -367,8 +369,6 @@ void ColladaParser::RebuildRootAnimationsFromClips()
 		{
 		{
 			std::string clipName = it->first;
 			std::string clipName = it->first;
 
 
-			printf("Clip: %s\n", clipName.c_str());
-
 			Animation *clip = new Animation();
 			Animation *clip = new Animation();
 			clip->mName = clipName;
 			clip->mName = clipName;
 
 
@@ -378,8 +378,6 @@ void ColladaParser::RebuildRootAnimationsFromClips()
 			{
 			{
 				std::string animationID = *a;
 				std::string animationID = *a;
 
 
-				printf("  Animation instance: %s\n", animationID.c_str());
-
 				AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
 				AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
 
 
 				if (animation != mAnimationLibrary.end())
 				if (animation != mAnimationLibrary.end())
@@ -396,6 +394,10 @@ void ColladaParser::RebuildRootAnimationsFromClips()
 		// Ensure no double deletes.
 		// Ensure no double deletes.
 		temp.mSubAnims.clear();
 		temp.mSubAnims.clear();
 	}
 	}
+	else
+	{
+		mAnims.CombineSingleChannelAnimations();
+	}
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -528,9 +530,11 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent)
     if( !channels.empty())
     if( !channels.empty())
     {
     {
 		// FIXME: Is this essentially doing the same as "single-anim-node" codepath in 
 		// FIXME: Is this essentially doing the same as "single-anim-node" codepath in 
-		//        ColladaLoader::StoreAnimations? If not, defer this to where animation
-		//        clip instances are set up. Due to handling of <library_animation_clips>
-		//        this cannot be done here, as the channel owner is lost.
+		//        ColladaLoader::StoreAnimations? For now, this has been deferred to after
+		//        all animations and all clips have been read. Due to handling of 
+		//        <library_animation_clips> this cannot be done here, as the channel owner 
+		//        is lost, and some exporters make up animations by referring to multiple
+		//        single-channel animations from an <instance_animation>.
 /*
 /*
         // special filtering for stupid exporters packing each channel into a separate animation
         // special filtering for stupid exporters packing each channel into a separate animation
         if( channels.size() == 1)
         if( channels.size() == 1)

+ 2 - 2
code/ColladaParser.h

@@ -86,8 +86,8 @@ namespace Assimp
 		/** Reads the animation clip library */
 		/** Reads the animation clip library */
 		void ReadAnimationClipLibrary();
 		void ReadAnimationClipLibrary();
 
 
-		/** Re-build animations from animation clip library, if present */
-		void RebuildRootAnimationsFromClips();
+		/** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
+		void PostProcessRootAnimations();
         
         
         /** Reads an animation into the given parent structure */
         /** Reads an animation into the given parent structure */
         void ReadAnimation( Collada::Animation* pParent);
         void ReadAnimation( Collada::Animation* pParent);