From 7e58a47ba0f88758ba87dee453120b5e25dae1af Mon Sep 17 00:00:00 2001 From: Trond Abusdal Date: Wed, 10 Feb 2016 23:57:29 +0100 Subject: [PATCH] * 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. --- code/ColladaHelper.h | 30 ++++++++++++++++++++++++++++++ code/ColladaParser.cpp | 22 +++++++++++++--------- code/ColladaParser.h | 4 ++-- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/code/ColladaHelper.h b/code/ColladaHelper.h index a741ef705..0a635a559 100644 --- a/code/ColladaHelper.h +++ b/code/ColladaHelper.h @@ -598,6 +598,7 @@ struct Animation delete *it; } + /** Collect all channels in the animation hierarchy into a single channel list. */ void CollectChannelsRecursively(std::vector &channels) { channels.insert(channels.end(), mChannels.begin(), mChannels.end()); @@ -609,6 +610,35 @@ struct Animation 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::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 */ diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index 915947504..41a56e24a 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -217,6 +217,8 @@ void ColladaParser::ReadStructure() 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) { @@ -367,8 +369,6 @@ void ColladaParser::RebuildRootAnimationsFromClips() { std::string clipName = it->first; - printf("Clip: %s\n", clipName.c_str()); - Animation *clip = new Animation(); clip->mName = clipName; @@ -378,8 +378,6 @@ void ColladaParser::RebuildRootAnimationsFromClips() { std::string animationID = *a; - printf(" Animation instance: %s\n", animationID.c_str()); - AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID); if (animation != mAnimationLibrary.end()) @@ -396,6 +394,10 @@ void ColladaParser::RebuildRootAnimationsFromClips() // Ensure no double deletes. temp.mSubAnims.clear(); } + else + { + mAnims.CombineSingleChannelAnimations(); + } } // ------------------------------------------------------------------------------------------------ @@ -528,9 +530,11 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent) if( !channels.empty()) { // 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 - // 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 + // 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 . /* // special filtering for stupid exporters packing each channel into a separate animation if( channels.size() == 1) diff --git a/code/ColladaParser.h b/code/ColladaParser.h index 1ea4a13d7..b2ff92701 100644 --- a/code/ColladaParser.h +++ b/code/ColladaParser.h @@ -86,8 +86,8 @@ namespace Assimp /** Reads the animation clip library */ 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 */ void ReadAnimation( Collada::Animation* pParent);