diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 104c2bae3..fe316b768 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -416,7 +416,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat speedmult = mMovementSpeed / vel; } else if (mMovementState == CharState_TurnLeft || mMovementState == CharState_TurnRight) - speedmult = 1.f; // TODO: should get a speed mult depending on the current turning speed + speedmult = 1.f; // adjusted each frame else if (mMovementSpeed > 0.0f) { // The first person anims don't have any velocity to calculate a speed multiplier from. @@ -592,6 +592,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim , mSkipAnim(false) , mSecondsOfRunning(0) , mSecondsOfSwimming(0) + , mTurnAnimationThreshold(0) { if(!mAnimation) return; @@ -1480,6 +1481,15 @@ void CharacterController::update(float duration) } } + mTurnAnimationThreshold -= duration; + if (movestate == CharState_TurnRight || movestate == CharState_TurnLeft) + mTurnAnimationThreshold = 0.05; + else if (movestate == CharState_None && (mMovementState == CharState_TurnRight || mMovementState == CharState_TurnLeft) + && mTurnAnimationThreshold > 0) + { + movestate = mMovementState; + } + if (onground) cls.getCreatureStats(mPtr).land(); @@ -1510,6 +1520,12 @@ void CharacterController::update(float duration) if (inJump) mMovementAnimationControlled = false; + if (mMovementState == CharState_TurnLeft || mMovementState == CharState_TurnRight) + { + if (duration > 0) + mAnimation->adjustSpeedMult(mCurrentMovement, std::min(1.5f, std::abs(rot.z) / duration / Ogre::Math::PI)); + } + if (!mSkipAnim) { rot *= Ogre::Math::RadiansToDegrees(1.0f); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 6528c041f..550cae5fc 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -171,6 +171,8 @@ class CharacterController float mSecondsOfSwimming; float mSecondsOfRunning; + float mTurnAnimationThreshold; // how long to continue playing turning animation after actor stopped turning + std::string mAttackType; // slash, chop or thrust void determineAttackType(); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 81b92dcbf..e2f3ce62f 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -914,6 +914,13 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo } } +void Animation::adjustSpeedMult(const std::string &groupname, float speedmult) +{ + AnimStateMap::iterator state(mStates.find(groupname)); + if(state != mStates.end()) + state->second.mSpeedMult = speedmult; +} + bool Animation::isPlaying(const std::string &groupname) const { AnimStateMap::const_iterator state(mStates.find(groupname)); diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 4f53a737b..8ca3582dc 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -260,6 +260,10 @@ public: float speedmult, const std::string &start, const std::string &stop, float startpoint, size_t loops); + /** Adjust the speed multiplier of an already playing animation. + */ + void adjustSpeedMult (const std::string& groupname, float speedmult); + /** Returns true if the named animation group is playing. */ bool isPlaying(const std::string &groupname) const;