diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index aedc131890..b4bfd06841 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -16,18 +16,16 @@ namespace MWRender Animation::Animation(const MWWorld::Ptr &ptr) : mPtr(ptr) , mInsert(NULL) - , mTime(0.0f) - , mAnimState(NULL) - , mSkipFrame(false) , mAccumRoot(NULL) , mNonAccumRoot(NULL) , mStartPosition(0.0f) , mLastPosition(0.0f) + , mTime(0.0f) + , mCurGroup(mTextKeys.end()) + , mNextGroup(mTextKeys.end()) + , mAnimState(NULL) + , mSkipFrame(false) { - mCurGroup.mStart = mCurGroup.mLoopStart = 0.0f; - mCurGroup.mLoopStop = mCurGroup.mStop = 0.0f; - mNextGroup.mStart = mNextGroup.mLoopStart = 0.0f; - mNextGroup.mLoopStop = mNextGroup.mStop = 0.0f; } Animation::~Animation() @@ -74,9 +72,12 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model if(!data.isEmpty()) { mTextKeys = Ogre::any_cast(data); + mNextGroup = mCurGroup = GroupTimes(mTextKeys.end()); + mAccumRoot = skelinst->getRootBone(); mAccumRoot->setManuallyControlled(true); mNonAccumRoot = skelinst->getBone(bone->getHandle()); + mStartPosition = mNonAccumRoot->getPosition(); mLastPosition = mStartPosition; break; @@ -141,60 +142,57 @@ bool Animation::findGroupTimes(const std::string &groupname, Animation::GroupTim NifOgre::TextKeyMap::const_iterator iter; for(iter = mTextKeys.begin();iter != mTextKeys.end();iter++) { - if(times->mStart >= 0.0f && times->mLoopStart >= 0.0f && times->mLoopStop >= 0.0f && times->mStop >= 0.0f) - return true; - if(start == iter->second) { - times->mStart = iter->first; - times->mLoopStart = iter->first; + times->mStart = iter; + times->mLoopStart = iter; } else if(startloop == iter->second) - { - times->mLoopStart = iter->first; - } + times->mLoopStart = iter; else if(stoploop == iter->second) - { - times->mLoopStop = iter->first; - } + times->mLoopStop = iter; else if(stop == iter->second) { - times->mStop = iter->first; - if(times->mLoopStop < 0.0f) - times->mLoopStop = iter->first; - break; + times->mStop = iter; + if(times->mLoopStop == mTextKeys.end()) + times->mLoopStop = iter; + return (times->mStart != mTextKeys.end()); } } - return (times->mStart >= 0.0f && times->mLoopStart >= 0.0f && times->mLoopStop >= 0.0f && times->mStop >= 0.0f); + return false; } void Animation::playGroup(std::string groupname, int mode, int loops) { - GroupTimes times; + if(mTextKeys.size() == 0) + { + std::cerr<< "Trying to animate an unanimate object" <first; + times.mStart = times.mLoopStart = mTextKeys.begin(); + times.mLoopStop = times.mStop = mTextKeys.end(); } else if(!findGroupTimes(groupname, ×)) - throw std::runtime_error("Failed to find animation group "+groupname); + { + std::cerr<< "Failed to find animation group "< 0) mNextGroup = times; else { mCurGroup = times; - mNextGroup = GroupTimes(); - mTime = ((mode==2) ? mCurGroup.mLoopStart : mCurGroup.mStart); + mNextGroup = GroupTimes(mTextKeys.end()); + mTime = ((mode==2) ? mCurGroup.mLoopStart : mCurGroup.mStart)->first; resetPosition(mTime); } } @@ -210,28 +208,28 @@ void Animation::runAnimation(float timepassed) { mTime += timepassed; recheck: - if(mTime >= mCurGroup.mLoopStop) + if(mTime >= mCurGroup.mLoopStop->first) { if(mCurGroup.mLoops > 1) { mCurGroup.mLoops--; - updatePosition(mCurGroup.mLoopStop); - mTime = mTime - mCurGroup.mLoopStop + mCurGroup.mLoopStart; - resetPosition(mCurGroup.mLoopStart); + updatePosition(mCurGroup.mLoopStop->first); + mTime = mTime - mCurGroup.mLoopStop->first + mCurGroup.mLoopStart->first; + resetPosition(mCurGroup.mLoopStart->first); goto recheck; } - else if(mTime >= mCurGroup.mStop) + else if(mTime >= mCurGroup.mStop->first) { if(mNextGroup.mLoops > 0) { - updatePosition(mCurGroup.mStop); - mTime = mTime - mCurGroup.mStop + mNextGroup.mStart; - resetPosition(mNextGroup.mStart); + updatePosition(mCurGroup.mStop->first); + mTime = mTime - mCurGroup.mStop->first + mNextGroup.mStart->first; + resetPosition(mNextGroup.mStart->first); mCurGroup = mNextGroup; - mNextGroup = GroupTimes(); + mNextGroup = GroupTimes(mTextKeys.end()); goto recheck; } - mTime = mCurGroup.mStop; + mTime = mCurGroup.mStop->first; } } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 73e34befeb..44a2eaf3ee 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -11,15 +11,15 @@ namespace MWRender class Animation { struct GroupTimes { - float mStart; - float mStop; - float mLoopStart; - float mLoopStop; + NifOgre::TextKeyMap::const_iterator mStart; + NifOgre::TextKeyMap::const_iterator mStop; + NifOgre::TextKeyMap::const_iterator mLoopStart; + NifOgre::TextKeyMap::const_iterator mLoopStop; size_t mLoops; - GroupTimes() - : mStart(-1.0f), mStop(-1.0f), mLoopStart(-1.0f), mLoopStop(-1.0f), + GroupTimes(NifOgre::TextKeyMap::const_iterator iter) + : mStart(iter), mStop(iter), mLoopStart(iter), mLoopStop(iter), mLoops(0) { } }; @@ -28,13 +28,6 @@ protected: MWWorld::Ptr mPtr; Ogre::SceneNode* mInsert; - float mTime; - GroupTimes mCurGroup; - GroupTimes mNextGroup; - Ogre::AnimationState *mAnimState; - - bool mSkipFrame; - NifOgre::EntityList mEntityList; NifOgre::TextKeyMap mTextKeys; Ogre::Bone *mAccumRoot; @@ -42,6 +35,13 @@ protected: Ogre::Vector3 mStartPosition; Ogre::Vector3 mLastPosition; + float mTime; + GroupTimes mCurGroup; + GroupTimes mNextGroup; + Ogre::AnimationState *mAnimState; + + bool mSkipFrame; + /* Updates the animation to the specified time, and moves the mPtr object * based on the change since the last update or reset. */ void updatePosition(float time);