diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index d0cbf04776..83326d25af 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -61,8 +61,9 @@ static void getStateInfo(CharacterState state, std::string *group, Ogre::Vector3 throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(state)); } + CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop) - : mPtr(ptr), mAnimation(anim), mDirection(Ogre::Vector3::ZERO), mState(state), mSkipAnim(false), mLoop(loop) + : mPtr(ptr), mAnimation(anim), mDirection(Ogre::Vector3::ZERO), mState(state), mSkipAnim(false) { if(!mAnimation) return; @@ -73,13 +74,13 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim getStateInfo(mState, &mCurrentGroup, &accum); mAnimation->setAccumulation(accum); if(mAnimation->hasAnimation(mCurrentGroup)) - mAnimation->play(mCurrentGroup, "stop"); + mAnimation->play(mCurrentGroup, "stop", loop); } CharacterController::CharacterController(const CharacterController &rhs) : mPtr(rhs.mPtr), mAnimation(rhs.mAnimation), mAnimQueue(rhs.mAnimQueue) , mCurrentGroup(rhs.mCurrentGroup), mDirection(rhs.mDirection) - , mState(rhs.mState), mSkipAnim(rhs.mSkipAnim), mLoop(rhs.mLoop) + , mState(rhs.mState), mSkipAnim(rhs.mSkipAnim) { if(!mAnimation) return; @@ -103,32 +104,12 @@ void CharacterController::markerEvent(float time, const std::string &evt) return; } - if(evt == "loop stop") - { - if(mAnimQueue.size() == 0) - { - if(time > 0.0f && mLoop) - mAnimation->play(mCurrentGroup, "loop start"); - } - else if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1]) - { - mAnimQueue.pop_front(); - mAnimation->play(mCurrentGroup, "loop start"); - } - return; - } - if(evt == "stop") { - if(mAnimQueue.size() == 0) - { - if(time > 0.0f && mLoop) - mAnimation->play(mCurrentGroup, "loop start"); - } - else if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1]) + if(mAnimQueue.size() >= 2 && mAnimQueue[0] == mAnimQueue[1]) { mAnimQueue.pop_front(); - mAnimation->play(mCurrentGroup, "loop start"); + mAnimation->play(mCurrentGroup, "loop start", false); } else if(mAnimQueue.size() > 0) { @@ -136,7 +117,7 @@ void CharacterController::markerEvent(float time, const std::string &evt) if(mAnimQueue.size() > 0) { mCurrentGroup = mAnimQueue.front(); - mAnimation->play(mCurrentGroup, "start"); + mAnimation->play(mCurrentGroup, "start", false); } } return; @@ -185,9 +166,8 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int mAnimQueue.push_back(groupname); mCurrentGroup = groupname; mState = CharState_Idle; - mLoop = false; mAnimation->setAccumulation(Ogre::Vector3::ZERO); - mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start")); + mAnimation->play(mCurrentGroup, ((mode==2) ? "loop start" : "start"), false); } else if(mode == 0) { @@ -208,11 +188,7 @@ void CharacterController::setState(CharacterState state, bool loop) { if(mState == state) return; - else - { - mState = state; - mLoop = loop; - } + mState = state; if(!mAnimation) return; @@ -225,7 +201,7 @@ void CharacterController::setState(CharacterState state, bool loop) { mCurrentGroup = anim; mAnimation->setAccumulation(accum); - mAnimation->play(mCurrentGroup, "start"); + mAnimation->play(mCurrentGroup, "start", loop); } } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index ec9102f9f6..53349c841e 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -37,7 +37,6 @@ class CharacterController std::string mCurrentGroup; CharacterState mState; bool mSkipAnim; - bool mLoop; protected: /* Called by the animation whenever a new text key is reached. */ diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 75a441a9c9..45f7ab2e44 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -26,6 +26,7 @@ Animation::Animation(const MWWorld::Ptr &ptr) , mLastPosition(0.0f) , mCurrentKeys(NULL) , mAnimState(NULL) + , mLooping(false) , mAnimSpeedMult(1.0f) { } @@ -173,7 +174,7 @@ float Animation::findStart(const std::string &groupname, const std::string &star } -void Animation::play(const std::string &groupname, const std::string &start) +void Animation::play(const std::string &groupname, const std::string &start, bool loop) { try { if(mAnimState) @@ -181,6 +182,7 @@ void Animation::play(const std::string &groupname, const std::string &start) mAnimState = mEntityList.mSkelBase->getAnimationState(groupname); mAnimState->setEnabled(true); mCurrentKeys = &mTextKeys[groupname]; + mLooping = loop; resetPosition(findStart(groupname, start)); } @@ -209,6 +211,33 @@ Ogre::Vector3 Animation::runAnimation(float timepassed) movement += updatePosition(time); timepassed = targetTime - time; + if(evt == "start" || evt == "loop start") + { + /* Do nothing */ + continue; + } + if(evt == "loop stop") + { + if(mLooping) + { + resetPosition(findStart(mAnimState->getAnimationName(), "loop start")); + if(mAnimState->getTimePosition() >= time) + break; + } + continue; + } + if(evt == "stop") + { + if(mLooping) + { + resetPosition(findStart(mAnimState->getAnimationName(), "loop start")); + if(mAnimState->getTimePosition() >= time) + break; + } + else if(mController) + mController->markerEvent(time, evt); + continue; + } if(mController) mController->markerEvent(time, evt); } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 50ddc34d5c..8398135764 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -31,6 +31,8 @@ protected: NifOgre::TextKeyMap *mCurrentKeys; NifOgre::TextKeyMap::const_iterator mNextKey; Ogre::AnimationState *mAnimState; + bool mLooping; + float mAnimSpeedMult; /* Updates the animation to the specified time, and returns the movement @@ -59,7 +61,7 @@ public: void setSpeedMult(float speedmult) { mAnimSpeedMult = speedmult; } - void play(const std::string &groupname, const std::string &start); + void play(const std::string &groupname, const std::string &start, bool loop); virtual Ogre::Vector3 runAnimation(float timepassed); }; diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index cbee9c8659..5a1a93311b 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -144,7 +144,7 @@ namespace MWRender { mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview); - mAnimation->play("inventoryhandtohand", "start"); + mAnimation->play("inventoryhandtohand", "start", false); } // --------------------------------------------------------------------------------------------------