diff --git a/Core/GameEngine/Include/Common/GameDefines.h b/Core/GameEngine/Include/Common/GameDefines.h index 7a6f4be4d11..07a3dee5de7 100644 --- a/Core/GameEngine/Include/Common/GameDefines.h +++ b/Core/GameEngine/Include/Common/GameDefines.h @@ -87,6 +87,10 @@ #define PRESERVE_RETAIL_SCRIPTED_CAMERA (1) // Retain scripted camera behavior present in retail Generals 1.08 and Zero Hour 1.04 #endif +#ifndef PRESERVE_RETAIL_PHYSICS_FORWARD_SPEED +#define PRESERVE_RETAIL_PHYSICS_FORWARD_SPEED (1) +#endif + #ifndef RETAIL_COMPATIBLE_CRC #define RETAIL_COMPATIBLE_CRC (1) // Game is expected to be CRC compatible with retail Generals 1.08, Zero Hour 1.04 #endif diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index 78b256e5b88..b3705178c6a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -963,15 +963,22 @@ Real PhysicsBehavior::getForwardSpeed2D() const Real dot = vx + vy; - Real speedSquared = vx*vx + vy*vy; -// DEBUG_ASSERTCRASH( speedSquared != 0, ("zero speedSquared will overflow sqrtf()!") );// lorenzen... sanity check - - Real speed = (Real)sqrtf( speedSquared ); +#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_PHYSICS_FORWARD_SPEED + Real speed = (Real)sqrtf( vx*vx + vy*vy ); if (dot >= 0.0f) return speed; return -speed; +#else + // Inverse scale len by (1 + sqrt(2)) / 2 to adjust to the average of the former min/max movement speed. + // The inverse looks intuitively wrong, but it is correct, because the value returned by this function is + // used to determine the additional velocity needed to reach the target speed. + constexpr const Real DiagonalCompensation = 1.0f / 1.20710678f; + dot *= DiagonalCompensation; + + return dot; +#endif } //------------------------------------------------------------------------------------------------- @@ -989,12 +996,22 @@ Real PhysicsBehavior::getForwardSpeed3D() const Real dot = vx + vy + vz; +#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_PHYSICS_FORWARD_SPEED Real speed = (Real)sqrtf( vx*vx + vy*vy + vz*vz ); if (dot >= 0.0f) return speed; return -speed; +#else + // Inverse scale len by (1 + sqrt(3)) / 2 to adjust to the average of the former min/max movement speed. + // The inverse looks intuitively wrong, but it is correct, because the value returned by this function is + // used to determine the additional velocity needed to reach the target speed. + constexpr const Real DiagonalCompensation = 1.0f / 1.36602540f; + dot *= DiagonalCompensation; + + return dot; +#endif } //-------------------------------------------------------------------------------------------------