* 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.
pull/791/head
Trond Abusdal 2016-02-10 23:57:29 +01:00
parent c34717639e
commit 7e58a47ba0
3 changed files with 45 additions and 11 deletions

View File

@ -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 */

View File

@ -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. // Re-build animations from animation clip library, if present, otherwise combine single-channel animations
void ColladaParser::RebuildRootAnimationsFromClips() 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 // ColladaLoader::StoreAnimations? For now, this has been deferred to after
// clip instances are set up. Due to handling of <library_animation_clips> // all animations and all clips have been read. Due to handling of
// this cannot be done here, as the channel owner is lost. // <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)

View File

@ -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 */ /** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
void RebuildRootAnimationsFromClips(); 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);