Allow C# Vector2/3 slerp values to have any length

This commit is contained in:
Andrew Jacob 2022-02-07 22:58:43 -07:00
parent 26facc0543
commit 8675ff0a74
2 changed files with 24 additions and 25 deletions

View file

@ -512,24 +512,24 @@ namespace Godot
/// Returns the result of the spherical linear interpolation between /// Returns the result of the spherical linear interpolation between
/// this vector and <paramref name="to"/> by amount <paramref name="weight"/>. /// this vector and <paramref name="to"/> by amount <paramref name="weight"/>.
/// ///
/// Note: Both vectors must be normalized. /// This method also handles interpolating the lengths if the input vectors have different lengths.
/// For the special case of one or both input vectors having zero length, this method behaves like [method lerp].
/// </summary> /// </summary>
/// <param name="to">The destination vector for interpolation. Must be normalized.</param> /// <param name="to">The destination vector for interpolation.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The resulting vector of the interpolation.</returns> /// <returns>The resulting vector of the interpolation.</returns>
public Vector2 Slerp(Vector2 to, real_t weight) public Vector2 Slerp(Vector2 to, real_t weight)
{ {
#if DEBUG real_t startLengthSquared = LengthSquared();
if (!IsNormalized()) real_t endLengthSquared = to.LengthSquared();
{ if (startLengthSquared == 0.0 || endLengthSquared == 0.0) {
throw new InvalidOperationException("Vector2.Slerp: From vector is not normalized."); // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
return Lerp(to, weight);
} }
if (!to.IsNormalized()) real_t startLength = Mathf.Sqrt(startLengthSquared);
{ real_t resultLength = Mathf.Lerp(startLength, Mathf.Sqrt(endLengthSquared), weight);
throw new InvalidOperationException($"Vector2.Slerp: `{nameof(to)}` is not normalized."); real_t angle = AngleTo(to);
} return Rotated(angle * weight) * (resultLength / startLength);
#endif
return Rotated(AngleTo(to) * weight);
} }
/// <summary> /// <summary>

View file

@ -549,25 +549,24 @@ namespace Godot
/// Returns the result of the spherical linear interpolation between /// Returns the result of the spherical linear interpolation between
/// this vector and <paramref name="to"/> by amount <paramref name="weight"/>. /// this vector and <paramref name="to"/> by amount <paramref name="weight"/>.
/// ///
/// Note: Both vectors must be normalized. /// This method also handles interpolating the lengths if the input vectors have different lengths.
/// For the special case of one or both input vectors having zero length, this method behaves like [method lerp].
/// </summary> /// </summary>
/// <param name="to">The destination vector for interpolation. Must be normalized.</param> /// <param name="to">The destination vector for interpolation.</param>
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The resulting vector of the interpolation.</returns> /// <returns>The resulting vector of the interpolation.</returns>
public Vector3 Slerp(Vector3 to, real_t weight) public Vector3 Slerp(Vector3 to, real_t weight)
{ {
#if DEBUG real_t startLengthSquared = LengthSquared();
if (!IsNormalized()) real_t endLengthSquared = to.LengthSquared();
{ if (startLengthSquared == 0.0 || endLengthSquared == 0.0) {
throw new InvalidOperationException("Vector3.Slerp: From vector is not normalized."); // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
return Lerp(to, weight);
} }
if (!to.IsNormalized()) real_t startLength = Mathf.Sqrt(startLengthSquared);
{ real_t resultLength = Mathf.Lerp(startLength, Mathf.Sqrt(endLengthSquared), weight);
throw new InvalidOperationException($"Vector3.Slerp: `{nameof(to)}` is not normalized."); real_t angle = AngleTo(to);
} return Rotated(Cross(to).Normalized(), angle * weight) * (resultLength / startLength);
#endif
real_t theta = AngleTo(to);
return Rotated(Cross(to), theta * weight);
} }
/// <summary> /// <summary>