diff options
author | Raul Santos <raulsntos@gmail.com> | 2022-07-06 21:35:37 +0200 |
---|---|---|
committer | Raul Santos <raulsntos@gmail.com> | 2022-07-06 21:59:42 +0200 |
commit | 71f99c6d402547e2c92643c0676d9ce0a9a12213 (patch) | |
tree | 00af5425174e2b3cb3f20ff64ca47376c4dd352f /modules/mono/glue/GodotSharp | |
parent | 76d0a99707949c1c19363451ebfd59c3ac68a4b9 (diff) |
C#: Add `BezierInterpolate` method
Adds a `BezierInterpolate` method for floats in `Mathf` and for vectors
in `Vector2` and `Vector3`.
Diffstat (limited to 'modules/mono/glue/GodotSharp')
3 files changed, 72 insertions, 6 deletions
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index 2b820070d6..36b7d0f80f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -198,6 +198,28 @@ namespace Godot } /// <summary> + /// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by + /// the given <paramref name="control1"/>, <paramref name="control2"/> and <paramref name="end"/> points. + /// </summary> + /// <param name="start">The start value for the interpolation.</param> + /// <param name="control1">Control point that defines the bezier curve.</param> + /// <param name="control2">Control point that defines the bezier curve.</param> + /// <param name="end">The destination value for the interpolation.</param> + /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The resulting value of the interpolation.</returns> + public static real_t BezierInterpolate(real_t start, real_t control1, real_t control2, real_t end, real_t t) + { + // Formula from Wikipedia article on Bezier curves + real_t omt = 1 - t; + real_t omt2 = omt * omt; + real_t omt3 = omt2 * omt; + real_t t2 = t * t; + real_t t3 = t2 * t; + + return start * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3; + } + + /// <summary> /// Converts an angle expressed in degrees to radians. /// </summary> /// <param name="deg">An angle expressed in degrees.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index 9e990ce83e..7bdbe1c28b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -221,6 +221,27 @@ namespace Godot } /// <summary> + /// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by this vector + /// and the given <paramref name="control1"/>, <paramref name="control2"/> and <paramref name="end"/> points. + /// </summary> + /// <param name="control1">Control point that defines the bezier curve.</param> + /// <param name="control2">Control point that defines the bezier curve.</param> + /// <param name="end">The destination vector.</param> + /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The interpolated vector.</returns> + public Vector2 BezierInterpolate(Vector2 control1, Vector2 control2, Vector2 end, real_t t) + { + // Formula from Wikipedia article on Bezier curves + real_t omt = 1 - t; + real_t omt2 = omt * omt; + real_t omt3 = omt2 * omt; + real_t t2 = t * t; + real_t t3 = t2 * t; + + return this * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3; + } + + /// <summary> /// Returns the normalized vector pointing from this vector to <paramref name="to"/>. /// </summary> /// <param name="to">The other vector to point towards.</param> @@ -522,9 +543,10 @@ namespace Godot { real_t startLengthSquared = LengthSquared(); real_t endLengthSquared = to.LengthSquared(); - if (startLengthSquared == 0.0 || endLengthSquared == 0.0) { - // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. - return Lerp(to, weight); + if (startLengthSquared == 0.0 || endLengthSquared == 0.0) + { + // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. + return Lerp(to, weight); } real_t startLength = Mathf.Sqrt(startLengthSquared); real_t resultLength = Mathf.Lerp(startLength, Mathf.Sqrt(endLengthSquared), weight); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 56859da7f2..480165d44a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -214,6 +214,27 @@ namespace Godot } /// <summary> + /// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by this vector + /// and the given <paramref name="control1"/>, <paramref name="control2"/> and <paramref name="end"/> points. + /// </summary> + /// <param name="control1">Control point that defines the bezier curve.</param> + /// <param name="control2">Control point that defines the bezier curve.</param> + /// <param name="end">The destination vector.</param> + /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The interpolated vector.</returns> + public Vector3 BezierInterpolate(Vector3 control1, Vector3 control2, Vector3 end, real_t t) + { + // Formula from Wikipedia article on Bezier curves + real_t omt = 1 - t; + real_t omt2 = omt * omt; + real_t omt3 = omt2 * omt; + real_t t2 = t * t; + real_t t3 = t2 * t; + + return this * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3; + } + + /// <summary> /// Returns the normalized vector pointing from this vector to <paramref name="to"/>. /// </summary> /// <param name="to">The other vector to point towards.</param> @@ -562,9 +583,10 @@ namespace Godot { real_t startLengthSquared = LengthSquared(); real_t endLengthSquared = to.LengthSquared(); - if (startLengthSquared == 0.0 || endLengthSquared == 0.0) { - // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. - return Lerp(to, weight); + if (startLengthSquared == 0.0 || endLengthSquared == 0.0) + { + // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. + return Lerp(to, weight); } real_t startLength = Mathf.Sqrt(startLengthSquared); real_t resultLength = Mathf.Lerp(startLength, Mathf.Sqrt(endLengthSquared), weight); |