Skip to content

Commit

Permalink
Merge pull request #157 from brmassa/fix/float-comparison
Browse files Browse the repository at this point in the history
Fix: never compare equality of floating numbers
  • Loading branch information
michaelsakharov authored Sep 17, 2024
2 parents c51882c + cc1009f commit b172d38
Show file tree
Hide file tree
Showing 33 changed files with 147 additions and 203 deletions.
2 changes: 1 addition & 1 deletion Prowl.Editor/Assets/Importers/ModelImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public override void Import(SerializedAsset ctx, FileInfo assetPath)
}

GameObject rootNode = GOs[0].Item1;
if (UnitScale != 1f)
if (Mathf.ApproximatelyEquals(UnitScale , 1f))
rootNode.Transform.localScale = Vector3.one * UnitScale;

// Add Animation Component with all the animations assigned
Expand Down
2 changes: 1 addition & 1 deletion Prowl.Editor/Editor/GameWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ protected override void Draw()
var renderSize = innerRect.Size;
renderSize.x = MathD.Max(renderSize.x, 1);
renderSize.y = MathD.Max(renderSize.y, 1);
if (renderSize.x != RenderTarget.Width || renderSize.y != RenderTarget.Height)
if (MathD.ApproximatelyEquals(renderSize.x, RenderTarget.Width) || MathD.ApproximatelyEquals(renderSize.y, RenderTarget.Height))
{
GeneralPreferences.Instance.CurrentWidth = (int)renderSize.x;
GeneralPreferences.Instance.CurrentHeight = (int)renderSize.y;
Expand Down
2 changes: 1 addition & 1 deletion Prowl.Editor/Editor/NodeEditor/NodeEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ public Texture2D Update(Gui windowGui, bool focused, Vector2 screenPos, uint wid

gui.PointerWheel = Input.MouseWheelDelta;

if ((RenderTarget == null) || (MathD.Max(width, 1) != RenderTarget.Width || MathD.Max(height, 1) != RenderTarget.Height))
if ((RenderTarget == null) || (MathD.ApproximatelyEquals(MathD.Max(width, 1), RenderTarget.Width) || MathD.ApproximatelyEquals(MathD.Max(height, 1), RenderTarget.Height)))
RefreshRenderTexture(new(MathD.Max(width, 1), MathD.Max(height, 1)));

Veldrid.CommandList commandList = Graphics.GetCommandList();
Expand Down
2 changes: 1 addition & 1 deletion Prowl.Editor/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private static int Run(CliOpenOptions options)
else if (Hotkeys.IsHotkeyDown("SaveScene", new() { Key = Key.S, Ctrl = true }))
EditorGuiManager.SaveScene();

Application.isPlaying = PlayMode.Current == PlayMode.Mode.Playing;
Application.IsPlaying = PlayMode.Current == PlayMode.Mode.Playing;


try
Expand Down
2 changes: 1 addition & 1 deletion Prowl.Players/Prowl.Desktop/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal class Program
public static int Main(string[] args)
{

Application.isPlaying = true;
Application.IsPlaying = true;
Application.DataPath = Data.FullName;


Expand Down
10 changes: 5 additions & 5 deletions Prowl.Runtime/AnimationCurve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -411,10 +411,10 @@ public KeyFrame(double position, double value, double tangentIn = 0, double tang
if (Equals(value2, null))
return Equals(value1, null);

return (value1.Position == value2.Position)
&& (value1.Value == value2.Value)
&& (value1.TangentIn == value2.TangentIn)
&& (value1.TangentOut == value2.TangentOut)
return (MathD.ApproximatelyEquals(value1.Position, value2.Position))
&& (MathD.ApproximatelyEquals(value1.Value, value2.Value))
&& (MathD.ApproximatelyEquals(value1.TangentIn, value2.TangentIn))
&& (MathD.ApproximatelyEquals(value1.TangentOut, value2.TangentOut))
&& (value1.Continuity == value2.Continuity);
}

Expand Down Expand Up @@ -453,7 +453,7 @@ public KeyFrame this[int index]
if (index >= _keys.Count)
throw new IndexOutOfRangeException();

if (_keys[index].Position == value.Position)
if (MathD.ApproximatelyEquals(_keys[index].Position, value.Position))
_keys[index] = value;
else
{
Expand Down
32 changes: 16 additions & 16 deletions Prowl.Runtime/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ namespace Prowl.Runtime;

public static class Application
{
public static bool isRunning;
public static bool isPlaying = false;
public static bool isEditor { get; private set; }
public static bool IsRunning;
public static bool IsPlaying = false;
public static bool IsEditor { get; private set; }

public static string? DataPath = null;

Expand All @@ -25,24 +25,24 @@ public static class Application
public static event Action Render;
public static event Action Quitting;

private static readonly TimeData AppTime = new();
private static readonly TimeData s_appTime = new();

private static readonly GraphicsBackend[] preferredWindowsBackends = // Covers Windows/UWP
private static readonly GraphicsBackend[] s_preferredWindowsBackends = // Covers Windows/UWP
[
GraphicsBackend.Vulkan,
GraphicsBackend.OpenGL,
GraphicsBackend.Direct3D11,
GraphicsBackend.OpenGLES,
];

private static readonly GraphicsBackend[] preferredUnixBackends = // Cover Unix-like (Linux, FreeBSD, OpenBSD)
private static readonly GraphicsBackend[] s_preferredUnixBackends = // Cover Unix-like (Linux, FreeBSD, OpenBSD)
[
GraphicsBackend.Vulkan,
GraphicsBackend.OpenGL,
GraphicsBackend.OpenGLES,
];

private static readonly GraphicsBackend[] preferredMacBackends = // Covers MacOS/Apple
private static readonly GraphicsBackend[] s_preferredMacBackends = // Covers MacOS/Apple
[
GraphicsBackend.Metal,
GraphicsBackend.OpenGL,
Expand All @@ -53,20 +53,20 @@ public static GraphicsBackend GetBackend()
{
if (RuntimeUtils.IsWindows())
{
return preferredWindowsBackends[0];
return s_preferredWindowsBackends[0];
}
else if (RuntimeUtils.IsMac())
{
return preferredMacBackends[0];
return s_preferredMacBackends[0];
}

return preferredUnixBackends[0];
return s_preferredUnixBackends[0];
}

public static void Run(string title, int width, int height, IAssetProvider assetProvider, bool editor)
{
AssetProvider = assetProvider;
isEditor = editor;
IsEditor = editor;

Debug.Log("Initializing...");

Expand All @@ -76,8 +76,8 @@ public static void Run(string title, int width, int height, IAssetProvider asset

Screen.Closing += AppClose;

isRunning = true;
isPlaying = true; // Base application is not the editor, isplaying is always true
IsRunning = true;
IsPlaying = true; // Base application is not the editor, isplaying is always true

Screen.Start($"{title} - {GetBackend()}", new Vector2Int(width, height), new Vector2Int(100, 100), WindowState.Normal);
}
Expand All @@ -103,9 +103,9 @@ static void AppUpdate()
{
AudioSystem.UpdatePool();

AppTime.Update();
s_appTime.Update();

Time.TimeStack.Push(AppTime);
Time.TimeStack.Push(s_appTime);

Update?.Invoke();
Render?.Invoke();
Expand All @@ -120,7 +120,7 @@ static void AppUpdate()

static void AppClose()
{
isRunning = false;
IsRunning = false;
Quitting?.Invoke();
Graphics.Dispose();
Physics.Dispose();
Expand Down
6 changes: 4 additions & 2 deletions Prowl.Runtime/Components/Audio/AudioSource.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// This file is part of the Prowl Game Engine
// Licensed under the MIT License. See the LICENSE file in the project root for details.

using System;

using Prowl.Icons;
using Prowl.Runtime.Audio;

Expand Down Expand Up @@ -72,13 +74,13 @@ public override void Update()
_looping = Looping;
}

if (_gain != Volume)
if (Mathf.ApproximatelyEquals(_gain , Volume))
{
_source.Gain = Volume;
_gain = Volume;
}

if (_maxDistance != MaxDistance)
if (Mathf.ApproximatelyEquals(_maxDistance , MaxDistance))
{
_source.MaxDistance = MaxDistance;
_maxDistance = MaxDistance;
Expand Down
2 changes: 1 addition & 1 deletion Prowl.Runtime/Components/Physics/Rigidbody.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public float SleepThreshold
get => _sleepThreshold;
set
{
if (_sleepThreshold == value)
if (MathD.ApproximatelyEquals(_sleepThreshold, value))
return;

_sleepThreshold = value;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This file is part of the Prowl Game Engine
// Licensed under the MIT License. See the LICENSE file in the project root for details.

using System;
using System.Runtime.CompilerServices;

using BepuPhysics;
Expand Down Expand Up @@ -48,7 +49,7 @@ public unsafe bool ConfigureContactManifold<TManifold>(int workerIndex, Collidab
var b = CollidableMaterials[pair.B];
pairMaterial.FrictionCoefficient = a.FrictionCoefficient * b.FrictionCoefficient;
pairMaterial.MaximumRecoveryVelocity = (float)MathD.Max(a.MaximumRecoveryVelocity, b.MaximumRecoveryVelocity);
pairMaterial.SpringSettings = pairMaterial.MaximumRecoveryVelocity == a.MaximumRecoveryVelocity ? a.SpringSettings : b.SpringSettings;
pairMaterial.SpringSettings = MathD.ApproximatelyEquals(pairMaterial.MaximumRecoveryVelocity, a.MaximumRecoveryVelocity) ? a.SpringSettings : b.SpringSettings;
//For the purposes of the demo, contact constraints are always generated.
ContactEvents.HandleManifold(workerIndex, pair, ref manifold);
Physics.Characters.TryReportContacts(pair, ref manifold, workerIndex, ref pairMaterial);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ void AnalyzeContactsForCharacterRegion(int start, int exclusiveEnd, int workerIn
//2) The character was previously supported by a body, and is now supported by a different body.
//3) The character was previously supported by a static, and is now supported by a body.
//4) The character was previously supported by a body, and is now supported by a static.
var shouldRemove = character.Supported && (character.TryJump || supportCandidate.Depth == float.MinValue || character.Support.Packed != supportCandidate.Support.Packed);
var shouldRemove = character.Supported && (character.TryJump || MathD.ApproximatelyEquals(supportCandidate.Depth, float.MinValue) || character.Support.Packed != supportCandidate.Support.Packed);
if (shouldRemove)
{
//Mark the constraint for removal.
Expand Down
2 changes: 1 addition & 1 deletion Prowl.Runtime/GUI/Graphics/UIDrawList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ public void PathLineTo(Vector2 pos)

public void PathLineToMergeDuplicate(Vector2 pos)
{
if (_buildingPath.Count == 0 || _buildingPath[_buildingPath.Count - 1].x != pos.x || _buildingPath[_buildingPath.Count - 1].y != pos.y)
if (_buildingPath.Count == 0 || MathD.ApproximatelyEquals(_buildingPath[ 1].x, pos.x) || MathD.ApproximatelyEquals(_buildingPath[^1].y, pos.y))
_buildingPath.Add(pos);
}

Expand Down
11 changes: 6 additions & 5 deletions Prowl.Runtime/GUI/Gui.Animation.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This file is part of the Prowl Game Engine
// Licensed under the MIT License. See the LICENSE file in the project root for details.

using System;
using System.Collections.Generic;

using Prowl.Runtime.Utils;
Expand Down Expand Up @@ -184,8 +185,8 @@ static double GetEase(double time, EaseType type)
static double QuintInOut(double time) => time < 0.5 ? 16 * time * time * time * time * time : 1 - MathD.Pow(-2 * time + 2, 5) / 2;

static double ExpoIn(double time) => time == 0 ? 0 : MathD.Pow(2, 10 * time - 10);
static double ExpoOut(double time) => time == 1 ? 1 : 1 - MathD.Pow(2, -10 * time);
static double ExpoInOut(double time) => time == 0 ? 0 : time == 1 ? 1 : time < 0.5 ? MathD.Pow(2, 20 * time - 10) / 2 : (2 - MathD.Pow(2, -20 * time + 10)) / 2;
static double ExpoOut(double time) => MathD.ApproximatelyEquals(time, 1) ? 1 : 1 - MathD.Pow(2, -10 * time);
static double ExpoInOut(double time) => time == 0 ? 0 : MathD.ApproximatelyEquals(time, 1) ? 1 : time < 0.5 ? MathD.Pow(2, 20 * time - 10) / 2 : (2 - MathD.Pow(2, -20 * time + 10)) / 2;

static double CircIn(double time) => 1 - MathD.Sqrt(1 - MathD.Pow(time, 2));
static double CircOut(double time) => MathD.Sqrt(1 - MathD.Pow(time - 1, 2));
Expand All @@ -197,9 +198,9 @@ static double BackInOut(double time) => time < 0.5 ?
MathD.Pow(2 * time, 2) * ((ConstantB + 1) * 2 * time - ConstantB) / 2 :
(MathD.Pow(2 * time - 2, 2) * ((ConstantB + 1) * (time * 2 - 2) + ConstantB) + 2) / 2;

static double ElasticIn(double time) => time == 0 ? 0 : time == 1 ? 1 : -MathD.Pow(2, 10 * time - 10) * MathD.Sin((time * 10.0 - 10.75) * ConstantD);
static double ElasticOut(double time) => time == 0 ? 0 : time == 1 ? 1 : MathD.Pow(2, -10 * time) * MathD.Sin((time * 10 - 0.75) * ConstantD) + 1;
static double ElasticInOut(double time) => time == 0 ? 0 : time == 1 ? 1 : time < 0.5 ? -(MathD.Pow(2, 20 * time - 10) * MathD.Sin((20 * time - 11.125) * ConstantE)) / 2 : MathD.Pow(2, -20 * time + 10) * MathD.Sin((20 * time - 11.125) * ConstantE) / 2 + 1;
static double ElasticIn(double time) => time == 0 ? 0 : MathD.ApproximatelyEquals(time, 1) ? 1 : -MathD.Pow(2, 10 * time - 10) * MathD.Sin((time * 10.0 - 10.75) * ConstantD);
static double ElasticOut(double time) => time == 0 ? 0 : MathD.ApproximatelyEquals(time, 1) ? 1 : MathD.Pow(2, -10 * time) * MathD.Sin((time * 10 - 0.75) * ConstantD) + 1;
static double ElasticInOut(double time) => time == 0 ? 0 : MathD.ApproximatelyEquals(time, 1) ? 1 : time < 0.5 ? -(MathD.Pow(2, 20 * time - 10) * MathD.Sin((20 * time - 11.125) * ConstantE)) / 2 : MathD.Pow(2, -20 * time + 10) * MathD.Sin((20 * time - 11.125) * ConstantE) / 2 + 1;

static double BounceIn(double t) => 1 - BounceOut(1 - t);
static double BounceOut(double t)
Expand Down
2 changes: 1 addition & 1 deletion Prowl.Runtime/GUI/Gui.Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public void ProcessFrame(Veldrid.CommandList commandList, Rect screenRect, doubl
layoutDirty = true;
_computedNodeHashes = newNodeHashes;

if (lastUIScale == uiScale)
if (MathD.ApproximatelyEquals(lastUIScale, uiScale))
layoutDirty = true;

// Now that we have the nodes we can properly process their LayoutNode
Expand Down
3 changes: 2 additions & 1 deletion Prowl.Runtime/GUI/Gui.Interaction.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This file is part of the Prowl Game Engine
// Licensed under the MIT License. See the LICENSE file in the project root for details.

using System;
using System.Collections.Generic;

using Prowl.Runtime.GUI.Layout;
Expand Down Expand Up @@ -123,7 +124,7 @@ public Interactable GetInteractable(LayoutNode target, Rect? interactArea = null
/// </summary>
public bool IsBlockedByInteractable(Vector2 pos, double zIndex = -1, ulong ignoreID = 0)
{
if (zIndex == -1)
if (MathD.ApproximatelyEquals(zIndex, -1))
{
if (!_zInteractableCounter.TryGetValue(CurrentZIndex, out int count))
count = 0;
Expand Down
18 changes: 10 additions & 8 deletions Prowl.Runtime/GUI/Layout/Spacing.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// This file is part of the Prowl Game Engine
// Licensed under the MIT License. See the LICENSE file in the project root for details.

using System;

namespace Prowl.Runtime.GUI;

public struct Spacing
Expand Down Expand Up @@ -29,18 +31,18 @@ public Spacing(double left, double right, double top, double bottom)

public static bool operator ==(Spacing s1, Spacing s2)
{
return s1.Left == s2.Left &&
s1.Right == s2.Right &&
s1.Top == s2.Top &&
s1.Bottom == s2.Bottom;
return MathD.ApproximatelyEquals(s1.Left, s2.Left) &&
MathD.ApproximatelyEquals(s1.Right, s2.Right) &&
MathD.ApproximatelyEquals(s1.Top, s2.Top) &&
MathD.ApproximatelyEquals(s1.Bottom, s2.Bottom);
}

public static bool operator !=(Spacing s1, Spacing s2)
{
return s1.Left != s2.Left ||
s1.Right != s2.Right ||
s1.Top != s2.Top ||
s1.Bottom != s2.Bottom;
return MathD.ApproximatelyEquals(s1.Left , s2.Left) ||
MathD.ApproximatelyEquals(s1.Right , s2.Right) ||
MathD.ApproximatelyEquals(s1.Top , s2.Top) ||
MathD.ApproximatelyEquals(s1.Bottom , s2.Bottom);
}

public override bool Equals(object obj)
Expand Down
2 changes: 1 addition & 1 deletion Prowl.Runtime/GameObject/MonoBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ internal void Do(Action action)

try
{
if (Application.isPlaying || always)
if (Application.IsPlaying || always)
action();
}
catch (Exception e)
Expand Down
12 changes: 6 additions & 6 deletions Prowl.Runtime/Math/Bounds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@ public void Contains(ref Vector3 point, out ContainmentType result)
{
result = ContainmentType.Disjoint;
}//or if point is on box because coordonate of point is lesser or equal
else if (point.x == min.x
|| point.x == max.x
|| point.y == min.y
|| point.y == max.y
|| point.z == min.z
|| point.z == max.z)
else if (MathD.ApproximatelyEquals(point.x, min.x)
|| MathD.ApproximatelyEquals(point.x, max.x)
|| MathD.ApproximatelyEquals(point.y, min.y)
|| MathD.ApproximatelyEquals(point.y, max.y)
|| MathD.ApproximatelyEquals(point.z, min.z)
|| MathD.ApproximatelyEquals(point.z, max.z))
result = ContainmentType.Intersects;
else
result = ContainmentType.Contains;
Expand Down
7 changes: 2 additions & 5 deletions Prowl.Runtime/Math/MathD.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Prowl.Runtime;

public static class MathD
{
private const MethodImplOptions IN = MethodImplOptions.AggressiveInlining;
public const MethodImplOptions IN = MethodImplOptions.AggressiveInlining;

#region Constants

Expand Down Expand Up @@ -38,9 +38,6 @@ public static class MathD
/// A small but not tiny value, Used in places like ApproximatelyEquals, where there is some tolerance (0.00001)
public static readonly double Small = 0.000001;

/// <inheritdoc cref="double.MinValue"/>
public static readonly double Epsilon = double.MinValue;

/// <inheritdoc cref="double.PositiveInfinity"/>
public const double Infinity = double.PositiveInfinity;

Expand Down Expand Up @@ -194,7 +191,7 @@ public static double LerpAngle(double aRad, double bRad, double t)

[MethodImpl(IN)] public static int ComputeMipLevels(int width, int height) => (int)Math.Log2(Math.Max(width, height));

[MethodImpl(IN)] public static bool ApproximatelyEquals(double a, double b) => Abs(a - b) < 0.00001f;
[MethodImpl(IN)] public static bool ApproximatelyEquals(double a, double b) => Abs(a - b) < double.Epsilon;
[MethodImpl(IN)] public static bool ApproximatelyEquals(Vector2 a, Vector2 b) => ApproximatelyEquals(a.x, b.x) && ApproximatelyEquals(a.y, b.y);
[MethodImpl(IN)] public static bool ApproximatelyEquals(Vector3 a, Vector3 b) => ApproximatelyEquals(a.x, b.x) && ApproximatelyEquals(a.y, b.y) && ApproximatelyEquals(a.z, b.z);
[MethodImpl(IN)] public static bool ApproximatelyEquals(Vector4 a, Vector4 b) => ApproximatelyEquals(a.x, b.x) && ApproximatelyEquals(a.y, b.y) && ApproximatelyEquals(a.z, b.z) && ApproximatelyEquals(a.w, b.w);
Expand Down
Loading

0 comments on commit b172d38

Please sign in to comment.