From 71f99c6d402547e2c92643c0676d9ce0a9a12213 Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Wed, 6 Jul 2022 21:35:37 +0200 Subject: [PATCH] C#: Add `BezierInterpolate` method Adds a `BezierInterpolate` method for floats in `Mathf` and for vectors in `Vector2` and `Vector3`. --- .../glue/GodotSharp/GodotSharp/Core/Mathf.cs | 22 +++++++++++++++ .../GodotSharp/GodotSharp/Core/Vector2.cs | 28 +++++++++++++++++-- .../GodotSharp/GodotSharp/Core/Vector3.cs | 28 +++++++++++++++++-- 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 2b820070d66..36b7d0f80f5 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -197,6 +197,28 @@ namespace Godot (-pre + 3.0f * from - 3.0f * to + post) * (weight * weight * weight)); } + /// + /// Returns the point at the given on a one-dimensional Bezier curve defined by + /// the given , and points. + /// + /// The start value for the interpolation. + /// Control point that defines the bezier curve. + /// Control point that defines the bezier curve. + /// The destination value for the interpolation. + /// A value on the range of 0.0 to 1.0, representing the amount of interpolation. + /// The resulting value of the interpolation. + 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; + } + /// /// Converts an angle expressed in degrees to radians. /// diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index 9e990ce83e1..7bdbe1c28b8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -220,6 +220,27 @@ namespace Godot ); } + /// + /// Returns the point at the given on a one-dimensional Bezier curve defined by this vector + /// and the given , and points. + /// + /// Control point that defines the bezier curve. + /// Control point that defines the bezier curve. + /// The destination vector. + /// A value on the range of 0.0 to 1.0, representing the amount of interpolation. + /// The interpolated vector. + 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; + } + /// /// Returns the normalized vector pointing from this vector to . /// @@ -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 56859da7f25..480165d44a0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -213,6 +213,27 @@ namespace Godot ); } + /// + /// Returns the point at the given on a one-dimensional Bezier curve defined by this vector + /// and the given , and points. + /// + /// Control point that defines the bezier curve. + /// Control point that defines the bezier curve. + /// The destination vector. + /// A value on the range of 0.0 to 1.0, representing the amount of interpolation. + /// The interpolated vector. + 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; + } + /// /// Returns the normalized vector pointing from this vector to . /// @@ -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);