Skip to content

Commit 80a22b2

Browse files
authored
Merge pull request #140 from DaveGreen-Games/fixed-physics-double-precision
FixedPhysics now uses Double instead of Float for increased precision.
2 parents b8f9d22 + 17180d3 commit 80a22b2

File tree

3 files changed

+23
-11
lines changed

3 files changed

+23
-11
lines changed

ShapeEngine/Core/GameDef/Game.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public partial class Game
111111
/// This value is calculated as 1.0 / FixedPhysicsFramerate and represents
112112
/// the duration of each physics step in seconds.
113113
/// </remarks>
114-
public float FixedPhysicsTimestep { get; private set; }
114+
public double FixedPhysicsTimestep { get; private set; }
115115

116116
/// <summary>
117117
/// Gets the game time information for the variable update loop.
@@ -348,7 +348,7 @@ private bool IsIdleFrameRateLimitActive()
348348
private readonly List<ShapeFlash> shapeFlashes = [];
349349
private readonly List<DeferredInfo> deferred = [];
350350

351-
private float physicsAccumulator;
351+
private double physicsAccumulator;
352352

353353
private List<ScreenTexture>? customScreenTextures;
354354
#endregion
@@ -540,7 +540,7 @@ public Game(GameSettings gameSettings, WindowSettings windowSettings, InputSetti
540540
{
541541
if (fixedFramerate < 30) fixedFramerate = 30;
542542
FixedPhysicsFramerate = fixedFramerate;
543-
FixedPhysicsTimestep = 1f / FixedPhysicsFramerate;
543+
FixedPhysicsTimestep = 1.0 / FixedPhysicsFramerate;
544544
FixedPhysicsEnabled = true;
545545
}
546546

ShapeEngine/Core/GameDef/GameGameloop.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ private void RunGameloop()
164164
if (FixedPhysicsEnabled)
165165
{
166166
ResolveUpdate(true);
167-
AdvanceFixedUpdate(dt);
167+
// Use double-precision frameDelta for more accurate fixed-step physics timing
168+
AdvanceFixedUpdate(frameDelta);
168169
}
169170
else ResolveUpdate(false);
170171

@@ -341,25 +342,27 @@ private void GameTextureOnTextureResized(int w, int h)
341342
ResolveOnGameTextureResized(w, h);
342343
}
343344

344-
private void AdvanceFixedUpdate(float dt)
345+
private void AdvanceFixedUpdate(double dt)
345346
{
346-
const float maxFrameTime = 1f / 30f;
347-
float frameTime = dt;
348-
// var t = 0.0f;
347+
const double maxFrameTime = 1.0 / 30.0;
348+
double frameTime = dt;
349349

350350
if (frameTime > maxFrameTime) frameTime = maxFrameTime;
351351

352352
physicsAccumulator += frameTime;
353353
while (physicsAccumulator >= FixedPhysicsTimestep)
354354
{
355-
FixedTime = FixedTime.TickF(FixedPhysicsFramerate);
355+
FixedTime = FixedTime.Tick(FixedPhysicsTimestep);
356356
ResolveFixedUpdate();
357357
// t += FixedPhysicsTimestep;
358358
physicsAccumulator -= FixedPhysicsTimestep;
359359
}
360360

361-
float alpha = physicsAccumulator / FixedPhysicsTimestep;
362-
ResolveInterpolateFixedUpdate(alpha);
361+
double alpha = physicsAccumulator / FixedPhysicsTimestep;
362+
// alpha is computed in double precision for timing accuracy, but interpolation
363+
// uses float because ResolveInterpolateFixedUpdate (e.g., via IUpdateable) has
364+
// a float-based public API. This precision downgrade is intentional.
365+
ResolveInterpolateFixedUpdate((float)alpha);
363366
}
364367

365368
}

ShapeEngine/Core/Structs/GameTime.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ public GameTime(double totalSeconds, int totalFrames, double elapsedSeconds)
107107
/// </summary>
108108
public readonly float Delta => (float)ElapsedSeconds;
109109

110+
/// <summary>
111+
/// Gets the elapsed time since the last frame as a double-precision value.
112+
/// </summary>
113+
/// <remarks>
114+
/// Use <see cref="DeltaDouble"/> when double precision is required instead of the single-precision <see cref="Delta"/>.
115+
/// This property simply returns the underlying <see cref="ElapsedSeconds"/> value.
116+
/// </remarks>
117+
public readonly double DeltaDouble => ElapsedSeconds;
118+
110119
/// <summary>
111120
/// Gets the current frames per second (FPS) based on the elapsed time between frames.
112121
/// </summary>

0 commit comments

Comments
 (0)