Commit e83fb8c3 authored by psi29a's avatar psi29a

Merge branch 'fix_turn_to_movement' into 'master'

Bugfix for "turn to movement direction"

Fix for #5457.

Users complain that movement is not smooth enough when the character turns from "straight right" to "straight right and a bit backward" movement.

This MR fixes it.

The problem was mostly caused by the logic that at first changes animation speed to match movement speed, and then adjusts the movement speed to match the animation. IMHO it is a doubtful logic because then the real movement speed may be not consistent with the result of getSpeed.

Also I've removed the setting "turn to movement direction speed coef" because:
1) It was added as a workaround for this "non smooth movement" problem. After the fix it is not needed.
2) Users mistakenly think that it is somehow related to movement speed for diagonal movement.

See merge request !245
parents c94d6336 63f828fe
Pipeline #160606493 passed with stage
in 45 minutes and 38 seconds
......@@ -853,6 +853,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
, mAttackingOrSpell(false)
, mCastingManualSpell(false)
, mTimeUntilWake(0.f)
, mIsMovingBackward(false)
{
if(!mAnimation)
return;
......@@ -1976,7 +1977,6 @@ void CharacterController::update(float duration, bool animationOnly)
float effectiveRotation = rot.z();
static const bool turnToMovementDirection = Settings::Manager::getBool("turn to movement direction", "Game");
static const float turnToMovementDirectionSpeedCoef = Settings::Manager::getFloat("turn to movement direction speed coef", "Game");
if (turnToMovementDirection && !(isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson()))
{
float targetMovementAngle = vec.y() >= 0 ? std::atan2(-vec.x(), vec.y()) : std::atan2(vec.x(), -vec.y());
......@@ -1986,10 +1986,14 @@ void CharacterController::update(float duration, bool animationOnly)
targetMovementAngle = 0;
float delta = targetMovementAngle - stats.getSideMovementAngle();
float cosDelta = cosf(delta);
movementSettings.mSpeedFactor *= std::min(std::max(cosDelta, 0.f) + 0.3f, 1.f); // slow down when turn
float maxDelta = turnToMovementDirectionSpeedCoef * osg::PI * duration * (2.5f - cosDelta);
delta = std::min(delta, maxDelta);
delta = std::max(delta, -maxDelta);
if ((vec.y() < 0) == mIsMovingBackward)
movementSettings.mSpeedFactor *= std::min(std::max(cosDelta, 0.f) + 0.3f, 1.f); // slow down when turn
if (std::abs(delta) < osg::DegreesToRadians(20.0f))
mIsMovingBackward = vec.y() < 0;
float maxDelta = osg::PI * duration * (2.5f - cosDelta);
delta = osg::clampBetween(delta, -maxDelta, maxDelta);
stats.setSideMovementAngle(stats.getSideMovementAngle() + delta);
effectiveRotation += delta;
}
......@@ -2364,20 +2368,8 @@ void CharacterController::update(float duration, bool animationOnly)
moved.y() *= scale;
// Ensure we're moving in generally the right direction...
if(speed > 0.f)
{
float l = moved.length();
if (std::abs(movement.x() - moved.x()) > std::abs(moved.x()) / 2)
moved.x() = movement.x();
if (std::abs(movement.y() - moved.y()) > std::abs(moved.y()) / 2)
moved.y() = movement.y();
if (std::abs(movement.z() - moved.z()) > std::abs(moved.z()) / 2)
moved.z() = movement.z();
// but keep the original speed
float newLength = moved.length();
if (newLength > 0)
moved *= (l / newLength);
}
if(speed > 0.f && (movement - moved).length2() * 4 > moved.length2())
moved = movement;
if (mFloatToSurface && cls.isActor() && cls.getCreatureStats(mPtr).isDead() && cls.canSwim(mPtr))
moved.z() = 1.0;
......
......@@ -195,6 +195,8 @@ class CharacterController : public MWRender::Animation::TextKeyListener
float mTimeUntilWake;
bool mIsMovingBackward;
void setAttackTypeBasedOnMovement();
void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force=false);
......
......@@ -330,15 +330,3 @@ If disabled then the whole character's body is pointed to the direction of view.
If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it also changes straight right and straight left movement.
This setting can only be configured by editing the settings configuration file.
turn to movement direction speed coef
-------------------------------------
:Type: floating point
:Range: >0
:Default: 1.0
Makes difference only if 'turn to movement direction' is enabled. Modifies turning speed.
This setting can only be configured by editing the settings configuration file.
......@@ -310,9 +310,6 @@ uncapped damage fatigue = false
# Turn lower body to movement direction. 'true' makes diagonal movement more realistic.
turn to movement direction = false
# Turning speed multiplier. Makes difference only if 'turn to movement direction' is enabled.
turn to movement direction speed coef = 1.0
[General]
# Anisotropy reduces distortion in textures at low angles (e.g. 0 to 16).
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment