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 OpenMW/openmw!245
pull/578/head
psi29a 5 years ago
commit e83fb8c3fd

@ -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).

Loading…
Cancel
Save