From 4ea347ac523d8de20484fb241df23b72c6cafd5f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 11 May 2013 19:38:23 -0700 Subject: [PATCH] Use shared pointers to store animation sources This ensures references to the sources stay valid as long it the object is, rather than becoming invalidated whenever one is added or removed. --- apps/openmw/mwrender/animation.cpp | 49 ++++++++++++++++-------------- apps/openmw/mwrender/animation.hpp | 7 +++-- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 58be60a450..30b05d7a03 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -189,19 +189,17 @@ void Animation::addAnimSource(const std::string &model) return; std::vector > ctrls; - mAnimSources.push_back(AnimSource()); - NifOgre::Loader::createKfControllers(mSkelBase, kfname, mAnimSources.back().mTextKeys, ctrls); - if(mAnimSources.back().mTextKeys.size() == 0 || ctrls.size() == 0) - { - mAnimSources.pop_back(); + Ogre::SharedPtr animsrc(OGRE_NEW AnimSource); + NifOgre::Loader::createKfControllers(mSkelBase, kfname, animsrc->mTextKeys, ctrls); + if(animsrc->mTextKeys.size() == 0 || ctrls.size() == 0) return; - } - std::vector > *grpctrls = mAnimSources.back().mControllers; - NifOgre::NodeTargetValue *dstval; + mAnimSources.push_back(animsrc); + std::vector > *grpctrls = animsrc->mControllers; for(size_t i = 0;i < ctrls.size();i++) { + NifOgre::NodeTargetValue *dstval; dstval = static_cast*>(ctrls[i].getDestination().getPointer()); size_t grp = detectAnimGroup(dstval->getNode()); @@ -264,7 +262,7 @@ bool Animation::hasAnimation(const std::string &anim) AnimSourceList::const_iterator iter(mAnimSources.begin()); for(;iter != mAnimSources.end();iter++) { - const NifOgre::TextKeyMap &keys = iter->mTextKeys; + const NifOgre::TextKeyMap &keys = (*iter)->mTextKeys; if(findGroupStart(keys, anim) != keys.end()) return true; } @@ -510,9 +508,9 @@ bool Animation::play(const std::string &groupname, Priority priority, int groups for(;iter != mAnimSources.rend();iter++) { AnimState state; - if(reset(state, iter->mTextKeys, groupname, start, stop, startpoint)) + if(reset(state, (*iter)->mTextKeys, groupname, start, stop, startpoint)) { - state.mSource = &*iter; + state.mSource = *iter; state.mLoopCount = loops; state.mPlaying = true; state.mPriority = priority; @@ -561,7 +559,7 @@ bool Animation::resetActiveGroups() bool ismoving = false; - const AnimSource *animsrc = state->second.mSource; + const Ogre::SharedPtr &animsrc = state->second.mSource; const NifOgre::TextKeyMap &keys = animsrc->mTextKeys; const std::vector >&ctrls = animsrc->mControllers[0]; for(size_t i = 0;i < ctrls.size();i++) @@ -579,18 +577,25 @@ bool Animation::resetActiveGroups() } // If there's no velocity, keep looking - while(!(mAnimVelocity > 1.0f) && animsrc-- != &mAnimSources[0]) + if(!(mAnimVelocity > 1.0f)) { - const NifOgre::TextKeyMap &keys = animsrc->mTextKeys; - const std::vector >&ctrls = animsrc->mControllers[0]; - for(size_t i = 0;i < ctrls.size();i++) + AnimSourceList::const_reverse_iterator animiter = mAnimSources.rbegin(); + while(*animiter != animsrc) + ++animiter; + + while(!(mAnimVelocity > 1.0f) && ++animiter != mAnimSources.rend()) { - NifOgre::NodeTargetValue *dstval; - dstval = static_cast*>(ctrls[i].getDestination().getPointer()); - if(dstval->getNode() == mNonAccumRoot) + const NifOgre::TextKeyMap &keys = (*animiter)->mTextKeys; + const std::vector >&ctrls = (*animiter)->mControllers[0]; + for(size_t i = 0;i < ctrls.size();i++) { - mAnimVelocity = calcAnimVelocity(keys, dstval, mAccumulate, state->first); - break; + NifOgre::NodeTargetValue *dstval; + dstval = static_cast*>(ctrls[i].getDestination().getPointer()); + if(dstval->getNode() == mNonAccumRoot) + { + mAnimVelocity = calcAnimVelocity(keys, dstval, mAccumulate, state->first); + break; + } } } } @@ -675,7 +680,7 @@ Ogre::Vector3 Animation::runAnimation(float duration) const std::string &name = mAnimationValuePtr[grp]->getAnimName(); if(!name.empty() && (stateiter=mStates.find(name)) != mStates.end()) { - AnimSource *src = stateiter->second.mSource; + const Ogre::SharedPtr &src = stateiter->second.mSource; for(size_t i = 0;i < src->mControllers[grp].size();i++) src->mControllers[grp][i].update(); } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 9667862457..f570d24a10 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -57,10 +57,10 @@ protected: NifOgre::TextKeyMap mTextKeys; std::vector > mControllers[sNumGroups]; }; - typedef std::vector AnimSourceList; + typedef std::vector< Ogre::SharedPtr > AnimSourceList; struct AnimState { - AnimSource *mSource; + Ogre::SharedPtr mSource; NifOgre::TextKeyMap::const_iterator mStartKey; NifOgre::TextKeyMap::const_iterator mLoopStartKey; NifOgre::TextKeyMap::const_iterator mStopKey; @@ -75,7 +75,8 @@ protected: int mGroups; bool mAutoDisable; - AnimState() : mSource(NULL), mTime(0.0f), mPlaying(false), mLoopCount(0) + AnimState() : mTime(0.0f), mPlaying(false), mLoopCount(0), + mPriority(0), mGroups(0), mAutoDisable(true) { } }; typedef std::map AnimStateMap;