From 01d778c2bcc55e7f066fcecc031a799868f943b1 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Thu, 27 Jun 2024 04:12:44 +0200 Subject: [PATCH] Framerate-independent idPlayer::Move() and idAI::AdjustFlyingAngles() thanks to Github user tyuah8: https://github.com/dhewm/dhewm3/pull/584#issuecomment-2192836172 --- neo/d3xp/Player.cpp | 6 +++++- neo/d3xp/ai/AI.cpp | 11 +++++++++-- neo/game/Player.cpp | 6 +++++- neo/game/ai/AI.cpp | 8 ++++++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/neo/d3xp/Player.cpp b/neo/d3xp/Player.cpp index 0a19451b4..f716e00d5 100644 --- a/neo/d3xp/Player.cpp +++ b/neo/d3xp/Player.cpp @@ -7117,8 +7117,12 @@ void idPlayer::Move( void ) { if ( spectating ) { SetEyeHeight( newEyeOffset ); } else { + // DG: make this framerate-independent, code suggested by tyuah8 on Github + // https://en.wikipedia.org/wiki/Exponential_smoothing#Time_constant + const float tau = -16.0f / idMath::Log( pm_crouchrate.GetFloat() ); + const float a = 1.0f - idMath::Exp( -gameLocal.gameMsec / tau ); // smooth out duck height changes - SetEyeHeight( EyeHeight() * pm_crouchrate.GetFloat() + newEyeOffset * ( 1.0f - pm_crouchrate.GetFloat() ) ); + SetEyeHeight( EyeHeight() * (1.0f - a) + newEyeOffset * a ); } } diff --git a/neo/d3xp/ai/AI.cpp b/neo/d3xp/ai/AI.cpp index 887594b66..064a7e41a 100644 --- a/neo/d3xp/ai/AI.cpp +++ b/neo/d3xp/ai/AI.cpp @@ -2984,8 +2984,15 @@ void idAI::AdjustFlyingAngles( void ) { } } - fly_roll = fly_roll * 0.95f + roll * 0.05f; - fly_pitch = fly_pitch * 0.95f + pitch * 0.05f; + // DG: make this framerate-independent, code suggested by tyuah8 on Github + // https://en.wikipedia.org/wiki/Exponential_smoothing#Time_constant + static const float tau = -16.0f / idMath::Log( 0.95f ); + // TODO: use gameLocal.gameMsec instead, so it's not affected by slow motion? + // enemies turning slower in slowmo seems logical, but the original code + // just increased every tic and thus was independent of slowmo + const float a = 1.0f - idMath::Exp( -gameLocal.msec / tau ); + fly_roll = fly_roll * (1.0f - a) + roll * a; + fly_pitch = fly_pitch * (1.0f - a) + pitch * a; if ( flyTiltJoint != INVALID_JOINT ) { animator.SetJointAxis( flyTiltJoint, JOINTMOD_WORLD, idAngles( fly_pitch, 0.0f, fly_roll ).ToMat3() ); diff --git a/neo/game/Player.cpp b/neo/game/Player.cpp index 84740f6c6..d5656b301 100644 --- a/neo/game/Player.cpp +++ b/neo/game/Player.cpp @@ -6014,8 +6014,12 @@ void idPlayer::Move( void ) { if ( spectating ) { SetEyeHeight( newEyeOffset ); } else { + // DG: make this framerate-independent, code suggested by tyuah8 on Github + // https://en.wikipedia.org/wiki/Exponential_smoothing#Time_constant + const float tau = -16.0f / idMath::Log( pm_crouchrate.GetFloat() ); + const float a = 1.0f - idMath::Exp( -gameLocal.gameMsec / tau ); // smooth out duck height changes - SetEyeHeight( EyeHeight() * pm_crouchrate.GetFloat() + newEyeOffset * ( 1.0f - pm_crouchrate.GetFloat() ) ); + SetEyeHeight( EyeHeight() * (1.0f - a) + newEyeOffset * a ); } } diff --git a/neo/game/ai/AI.cpp b/neo/game/ai/AI.cpp index 2ac99486d..b025bd9ca 100644 --- a/neo/game/ai/AI.cpp +++ b/neo/game/ai/AI.cpp @@ -2896,8 +2896,12 @@ void idAI::AdjustFlyingAngles( void ) { } } - fly_roll = fly_roll * 0.95f + roll * 0.05f; - fly_pitch = fly_pitch * 0.95f + pitch * 0.05f; + // DG: make this framerate-independent, code suggested by tyuah8 on Github + // https://en.wikipedia.org/wiki/Exponential_smoothing#Time_constant + static const float tau = -16.0f / idMath::Log( 0.95f ); + const float a = 1.0f - idMath::Exp( -gameLocal.msec / tau ); + fly_roll = fly_roll * (1.0f - a) + roll * a; + fly_pitch = fly_pitch * (1.0f - a) + pitch * a; if ( flyTiltJoint != INVALID_JOINT ) { animator.SetJointAxis( flyTiltJoint, JOINTMOD_WORLD, idAngles( fly_pitch, 0.0f, fly_roll ).ToMat3() );