From 6a03aa6fdb34cf2bf4d440780fc87471629b810f Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 12 Jul 2018 12:43:49 +0400 Subject: [PATCH] Reduce jittering during turning animations for player --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/character.cpp | 34 +++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a6621bf2..1f3c0f7ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,7 @@ Bug #4563: Fast travel price logic checks destination cell instead of service actor cell Bug #4565: Underwater view distance should be limited Bug #4573: Player uses headtracking in the 1st-person mode + Bug #4574: Player turning animations are twitchy Feature #2606: Editor: Implemented (optional) case sensitive global search Feature #3083: Play animation when NPC is casting spell via script Feature #3103: Provide option for disposition to get increased by successful trade diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index f5d6f8584..054f0b64d 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1992,13 +1992,31 @@ void CharacterController::update(float duration) } } - mTurnAnimationThreshold -= duration; - if (isTurning()) - mTurnAnimationThreshold = 0.05f; - else if (movestate == CharState_None && isTurning() - && mTurnAnimationThreshold > 0) + // Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering + if (mPtr == getPlayer()) { - movestate = mMovementState; + float threshold = mCurrentMovement.find("swim") == std::string::npos ? 0.4f : 0.8f; + float complete; + bool animPlaying = mAnimation->getInfo(mCurrentMovement, &complete); + if (movestate == CharState_None && isTurning()) + { + if ((animPlaying && complete < threshold) || mJumpState != jumpstate) + movestate = mMovementState; + } + } + else + { + mTurnAnimationThreshold -= duration; + if (movestate == CharState_TurnRight || movestate == CharState_TurnLeft || + movestate == CharState_SwimTurnRight || movestate == CharState_SwimTurnLeft) + { + mTurnAnimationThreshold = 0.05f; + } + else if (movestate == CharState_None && isTurning() + && mTurnAnimationThreshold > 0) + { + movestate = mMovementState; + } } if(movestate != CharState_None && !isTurning()) @@ -2028,8 +2046,10 @@ void CharacterController::update(float duration) if (isTurning()) { + // Adjust animation speed from 1.0 to 1.5 multiplier + float turnSpeed = std::min(1.5f, std::abs(rot.z()) / duration / static_cast(osg::PI)); if (duration > 0) - mAnimation->adjustSpeedMult(mCurrentMovement, std::min(1.5f, std::abs(rot.z()) / duration / static_cast(osg::PI))); + mAnimation->adjustSpeedMult(mCurrentMovement, std::max(turnSpeed, 1.0f)); } else if (mMovementState != CharState_None && mAdjustMovementAnimSpeed) {