diff --git a/addons/ofxAssimp/src/ofxAssimpAnimationMixer.cpp b/addons/ofxAssimp/src/ofxAssimpAnimationMixer.cpp index 49f9bada09c..21dfde11f47 100644 --- a/addons/ofxAssimp/src/ofxAssimpAnimationMixer.cpp +++ b/addons/ofxAssimp/src/ofxAssimpAnimationMixer.cpp @@ -6,7 +6,7 @@ using namespace ofxAssimp; //-------------------------------------------------------------- bool AnimationClip::shouldRemove( const AnimationClip& ac ) { - return ac.bRemove; + return (ac.animationWeak.expired() || ac.bRemove); } //-------------------------------------------------------------- @@ -31,8 +31,11 @@ AnimationClip& AnimationMixer::getAnimationClip(const std::string& aname) { return dummy; } for( auto& anim : mAnimationClips ) { - if( anim.animation.getName() == aname ) { - return anim; + if(anim.animationWeak.expired()) {continue;} + if( auto alock = anim.animationWeak.lock() ) { + if( alock->getName() == aname ) { + return anim; + } } } ofLogWarning("ofxAssimp::AnimationMixer::getAnimationClip") << " could not find clip " << aname; @@ -57,9 +60,12 @@ bool AnimationMixer::remove( int aindex ) { bool AnimationMixer::remove( const std::string& aname ) { int tindex = -1; for(int i = 0; i < (int)mAnimationClips.size(); i++) { - if( mAnimationClips[i].animation.getName() == aname ) { - tindex = i; - break; + if(mAnimationClips[i].animationWeak.expired()) {continue;} + if( auto alock = mAnimationClips[i].animationWeak.lock() ) { + if( alock->getName() == aname ) { + tindex = i; + break; + } } } if( tindex > -1 ) { @@ -76,14 +82,20 @@ void AnimationMixer::removeAll() { //-------------------------------------------------------------- void AnimationMixer::playAll() { for( auto& anim : mAnimationClips ) { - anim.animation.play(); + if(anim.animationWeak.expired()) {continue;} + if( auto alock = anim.animationWeak.lock() ) { + alock->play(); + } } } //-------------------------------------------------------------- void AnimationMixer::stopAll() { for( auto& anim : mAnimationClips ) { - anim.animation.stop(); + if(anim.animationWeak.expired()) {continue;} + if( auto alock = anim.animationWeak.lock() ) { + alock->stop(); + } } } @@ -91,7 +103,10 @@ void AnimationMixer::stopAll() { void AnimationMixer::update(float aElapsedTimef) { for(auto& anim : mAnimationClips ) { // std::cout << "AnimationMixer :: update : " << anim.animation.getName() << " position: " << anim.animation.getPositionInSeconds() << std::endl; - anim.animation.update(); + if(anim.animationWeak.expired()) {continue;} + if( auto alock = anim.animationWeak.lock() ) { + alock->update(); + } } float tdelta = std::max( std::min(aElapsedTimef-mLastUpdateTime, 10.f), ai_epsilon); @@ -166,9 +181,13 @@ void AnimationMixer::transition( const std::string& aname, float aduration, bool // first get the targeted animation // int animIndex = -1; for( int i = 0; i < (int)mAnimationClips.size(); i++ ) { - if( mAnimationClips[i].animation.getName() == aname ) { - animIndex = i; - break; +// if( mAnimationClips[i].animation.getName() == aname ) { + if(mAnimationClips[i].animationWeak.expired()) {continue;} + if( auto alock = mAnimationClips[i].animationWeak.lock() ) { + if( alock->getName() == aname ) { + animIndex = i; + break; + } } } if( animIndex < 0 ) { diff --git a/addons/ofxAssimp/src/ofxAssimpAnimationMixer.h b/addons/ofxAssimp/src/ofxAssimpAnimationMixer.h index f1f673afefb..810beda9d60 100644 --- a/addons/ofxAssimp/src/ofxAssimpAnimationMixer.h +++ b/addons/ofxAssimp/src/ofxAssimpAnimationMixer.h @@ -12,8 +12,8 @@ class AnimationClip { static bool shouldRemove( const AnimationClip& ac ); AnimationClip() {} - AnimationClip(Animation anim, float aweight) { - animation = anim; + AnimationClip(std::shared_ptr anim, float aweight) { + animationWeak = anim; weight = aweight; } // AnimationClip(const Animation& anim, float aweight, bool abOneShot) { @@ -39,8 +39,15 @@ class AnimationClip { void tagForRemoval() {bRemove=true;} + void resetAnimation() { + if( auto alock = animationWeak.lock() ) { + alock->reset(); + } + } + float weight = 1.0f; - Animation animation; +// Animation animation; + std::weak_ptr animationWeak; //protected: float mTargetWeight = -1.f; diff --git a/addons/ofxAssimp/src/ofxAssimpNode.cpp b/addons/ofxAssimp/src/ofxAssimpNode.cpp index 3a6638af00d..b6b221e4931 100644 --- a/addons/ofxAssimp/src/ofxAssimpNode.cpp +++ b/addons/ofxAssimp/src/ofxAssimpNode.cpp @@ -50,10 +50,14 @@ void Node::update( const std::shared_ptr& aAnimMixer bool bHasSomeKeys = false; int clipWithKeysIndex = 0; for( auto& animClip : mixer->getAnimationClips() ) { - auto& keyCollection = mSrcNode->getKeyCollection(animClip.animation.getUid()); + + auto animation = animClip.animationWeak.lock(); + if( !animation ) {continue;} + + auto& keyCollection = mSrcNode->getKeyCollection(animation->getUid()); if( keyCollection.hasKeys() ) { - auto animTime = animClip.animation.getPositionInTicks() + animClip.animation.getStartTick(); + auto animTime = animation->getPositionInTicks() + animation->getStartTick(); tempPos += animClip.weight * keyCollection.getPosition( animTime ); tempScale += animClip.weight * keyCollection.getScale( animTime ); // TODO: Keep an eye on this :O diff --git a/addons/ofxAssimp/src/ofxAssimpScene.cpp b/addons/ofxAssimp/src/ofxAssimpScene.cpp index de4401e6ce8..fd23de24941 100644 --- a/addons/ofxAssimp/src/ofxAssimpScene.cpp +++ b/addons/ofxAssimp/src/ofxAssimpScene.cpp @@ -79,12 +79,17 @@ bool Scene::processScene() { if(mSrcScene){ if( mSrcScene->getImportSettings().importAnimations ) { - mAnimations = mSrcScene->getAnimations(); + mAnimations.clear(); + // mAnimations = mSrcScene->getAnimations(); + auto& srcAnims = mSrcScene->getAnimations(); + for( auto& srcA : srcAnims ) { + auto nanim = std::make_shared( srcA ); + mAnimations.push_back(nanim); + } if(mAnimations.size() > 0 ) { - // add a default mixer - mAnimMixer = std::make_shared(); - mAnimMixer->add( AnimationClip( mAnimations[0], 1.0f )); - mAnimMixer->getAnimationClip(0).animation.play(); + mAnimationIndex = -1; // set to -1 so it will trigger playing + setCurrentAnimation(0); + getCurrentAnimation().play(); } } @@ -354,6 +359,13 @@ void Scene::flagSceneDirty() { mBSceneDirty = true; } +std::shared_ptr Scene::_getAnimationMixer() { + if( !mAnimMixer ) { + mAnimMixer = std::make_shared(); + } + return mAnimMixer; +} + void Scene::updateAnimations() { if( mAnimMixer ) { mAnimMixer->update(ofGetElapsedTimef()); @@ -480,7 +492,10 @@ ofxAssimp::Animation& Scene::getCurrentAnimation() { return dummyAnimation; } if( mAnimMixer && mAnimMixer->getNumAnimationClips() > 0 ) { - return mAnimMixer->getAnimationClips().back().animation; + // return mAnimMixer->getAnimationClips().back().animation; + if( auto alock = mAnimMixer->getAnimationClips().back().animationWeak.lock() ) { + return *alock; + } } ofLogWarning("ofxAssimp::Scene::getCurrentAnimation") << " does not have current animation!"; return dummyAnimation; @@ -495,10 +510,11 @@ bool Scene::setCurrentAnimation( int aindex ) { ofLogWarning("ofxAssimp::Scene::setAnimation") << " already have this as the index!"; return false; } + _getAnimationMixer(); mAnimationIndex = ofClamp(aindex, 0, mAnimations.size()-1); mAnimMixer->removeAll(); mAnimMixer->add( AnimationClip( mAnimations[mAnimationIndex], 1.0f )); - mAnimMixer->getAnimationClips().back().animation.reset(); + mAnimMixer->getAnimationClips().back().resetAnimation(); return true; } @@ -516,10 +532,11 @@ bool Scene::transitionCurrentAnimation( int aTargetAnimIndex, float aduration ) ofLogWarning("ofxAssimp::Scene::setAnimation") << " no animations!!"; return false; } + _getAnimationMixer(); mAnimationIndex = ofClamp(aTargetAnimIndex, 0, mAnimations.size()-1); mAnimMixer->add( AnimationClip( mAnimations[mAnimationIndex], 1.f-mAnimMixer->getTotalClipWeights() )); - mAnimMixer->transition(mAnimations[mAnimationIndex].getName(), aduration ); - mAnimMixer->getAnimationClips().back().animation.reset(); + mAnimMixer->transition(mAnimations[mAnimationIndex]->getName(), aduration ); + mAnimMixer->getAnimationClips().back().resetAnimation(); return true; } @@ -539,7 +556,7 @@ bool Scene::hasAnimation( const std::string& aname ) { int Scene::getAnimationIndex( const std::string& aname ) { int tindex = -1; for( int i = 0; i < (int)mAnimations.size(); i++ ) { - if( mAnimations[i].getName() == aname ) { + if( mAnimations[i] && mAnimations[i]->getName() == aname ) { tindex = i; break; } @@ -553,7 +570,7 @@ ofxAssimp::Animation& Scene::getAnimation(int aindex) { return dummyAnimation; } aindex = ofClamp(aindex, 0, mAnimations.size()-1); - return mAnimations[aindex]; + return *mAnimations[aindex]; } ofxAssimp::Animation& Scene::getAnimation(const std::string& aname) { @@ -579,10 +596,11 @@ bool Scene::addAnimation( int aSrcAnimIndex, const std::string& aNewAnimName, fl return false; } auto& canim = mAnimations[aSrcAnimIndex]; - ofxAssimp::Animation nanim = mAnimations[aSrcAnimIndex]; - nanim.setup(aStartTick, aEndTick); - nanim.setName(aNewAnimName); - nanim.setLoopType(aLoopType); + // ofxAssimp::Animation nanim = mAnimations[aSrcAnimIndex]; + auto nanim = std::make_shared( *mAnimations[aSrcAnimIndex] ); + nanim->setup(aStartTick, aEndTick); + nanim->setName(aNewAnimName); + nanim->setLoopType(aLoopType); mAnimations.push_back(nanim); return true; } diff --git a/addons/ofxAssimp/src/ofxAssimpScene.h b/addons/ofxAssimp/src/ofxAssimpScene.h index 97d1b6ebcd0..15a8732991d 100644 --- a/addons/ofxAssimp/src/ofxAssimpScene.h +++ b/addons/ofxAssimp/src/ofxAssimpScene.h @@ -273,6 +273,7 @@ class Scene : public ofxAssimp::Node { protected: + std::shared_ptr _getAnimationMixer(); void updateAnimations(); void updateMeshesFromBones(); @@ -292,7 +293,8 @@ class Scene : public ofxAssimp::Node { // the skeletons are the root bones std::vector< std::shared_ptr > mSkeletons; std::vector< std::shared_ptr > mNullNodes; - std::vector mAnimations; +// std::vector mAnimations; + std::vector< std::shared_ptr > mAnimations; int mAnimationIndex = 0;