summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-10-02 13:15:49 +0200
committerRémi Verschelde <rverschelde@gmail.com>2023-10-02 13:15:49 +0200
commit7588e3ff0dd7f5e522009f770f99fe593d1ebdb0 (patch)
tree10f196c218e21815984cdfcd45e53c016d7285c1 /modules
parentce236a6d03bfb4ccd81fc60b859b28122edaa20d (diff)
parent3a39de4e2f18c8b9764166e9f6cb882d8e2c7017 (diff)
downloadredot-engine-7588e3ff0dd7f5e522009f770f99fe593d1ebdb0.tar.gz
Merge pull request #80225 from ettiSurreal/rotate-toward
Add `rotate_toward` and `angle_difference` methods.
Diffstat (limited to 'modules')
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs72
1 files changed, 66 insertions, 6 deletions
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index 81b2ffef34..09269508b7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -134,6 +134,38 @@ namespace Godot
}
/// <summary>
+ /// Returns the difference between the two angles,
+ /// in range of -<see cref="Pi"/>, <see cref="Pi"/>.
+ /// When <paramref name="from"/> and <paramref name="to"/> are opposite,
+ /// returns -<see cref="Pi"/> if <paramref name="from"/> is smaller than <paramref name="to"/>,
+ /// or <see cref="Pi"/> otherwise.
+ /// </summary>
+ /// <param name="from">The start angle.</param>
+ /// <param name="to">The destination angle.</param>
+ /// <returns>The difference between the two angles.</returns>
+ public static float AngleDifference(float from, float to)
+ {
+ float difference = (to - from) % MathF.Tau;
+ return ((2.0f * difference) % MathF.Tau) - difference;
+ }
+
+ /// <summary>
+ /// Returns the difference between the two angles,
+ /// in range of -<see cref="Pi"/>, <see cref="Pi"/>.
+ /// When <paramref name="from"/> and <paramref name="to"/> are opposite,
+ /// returns -<see cref="Pi"/> if <paramref name="from"/> is smaller than <paramref name="to"/>,
+ /// or <see cref="Pi"/> otherwise.
+ /// </summary>
+ /// <param name="from">The start angle.</param>
+ /// <param name="to">The destination angle.</param>
+ /// <returns>The difference between the two angles.</returns>
+ public static double AngleDifference(double from, double to)
+ {
+ double difference = (to - from) % Math.Tau;
+ return ((2.0 * difference) % Math.Tau) - difference;
+ }
+
+ /// <summary>
/// Returns the arc sine of <paramref name="s"/> in radians.
/// Use to get the angle of sine <paramref name="s"/>.
/// </summary>
@@ -1093,9 +1125,7 @@ namespace Godot
/// <returns>The resulting angle of the interpolation.</returns>
public static float LerpAngle(float from, float to, float weight)
{
- float difference = (to - from) % MathF.Tau;
- float distance = ((2 * difference) % MathF.Tau) - difference;
- return from + (distance * weight);
+ return from + AngleDifference(from, to) * weight;
}
/// <summary>
@@ -1110,9 +1140,7 @@ namespace Godot
/// <returns>The resulting angle of the interpolation.</returns>
public static double LerpAngle(double from, double to, double weight)
{
- double difference = (to - from) % Math.Tau;
- double distance = ((2 * difference) % Math.Tau) - difference;
- return from + (distance * weight);
+ return from + AngleDifference(from, to) * weight;
}
/// <summary>
@@ -1429,6 +1457,38 @@ namespace Godot
}
/// <summary>
+ /// Rotates <paramref name="from"/> toward <paramref name="to"/> by the <paramref name="delta"/> amount. Will not go past <paramref name="to"/>.
+ /// Similar to <see cref="MoveToward(float, float, float)"/> but interpolates correctly when the angles wrap around <see cref="Tau"/>.
+ /// If <paramref name="delta"/> is negative, this function will rotate away from <paramref name="to"/>, toward the opposite angle, and will not go past the opposite angle.
+ /// </summary>
+ /// <param name="from">The start angle.</param>
+ /// <param name="to">The angle to move towards.</param>
+ /// <param name="delta">The amount to move by.</param>
+ /// <returns>The angle after moving.</returns>
+ public static float RotateToward(float from, float to, float delta)
+ {
+ float difference = AngleDifference(from, to);
+ float absDifference = Math.Abs(difference);
+ return from + Math.Clamp(delta, absDifference - MathF.PI, absDifference) * (difference >= 0.0f ? 1.0f : -1.0f);
+ }
+
+ /// <summary>
+ /// Rotates <paramref name="from"/> toward <paramref name="to"/> by the <paramref name="delta"/> amount. Will not go past <paramref name="to"/>.
+ /// Similar to <see cref="MoveToward(double, double, double)"/> but interpolates correctly when the angles wrap around <see cref="Tau"/>.
+ /// If <paramref name="delta"/> is negative, this function will rotate away from <paramref name="to"/>, toward the opposite angle, and will not go past the opposite angle.
+ /// </summary>
+ /// <param name="from">The start angle.</param>
+ /// <param name="to">The angle to move towards.</param>
+ /// <param name="delta">The amount to move by.</param>
+ /// <returns>The angle after moving.</returns>
+ public static double RotateToward(double from, double to, double delta)
+ {
+ double difference = AngleDifference(from, to);
+ double absDifference = Math.Abs(difference);
+ return from + Math.Clamp(delta, absDifference - Math.PI, absDifference) * (difference >= 0.0 ? 1.0 : -1.0);
+ }
+
+ /// <summary>
/// Rounds <paramref name="s"/> to the nearest whole number,
/// with halfway cases rounded towards the nearest multiple of two.
/// </summary>