diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-08-05 00:26:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-05 00:26:53 +0200 |
commit | 453fbcf2f96931d4055f3efd9b1a0003c81711d6 (patch) | |
tree | ffc33ee2a21802f1ff00c1d6b286d3500dbe5021 /core | |
parent | daa1220a8605be05a2d0cd1c2def71238fcb15ac (diff) | |
parent | 88f5b0d563e0c116c7f2d7d16daf52a9cad9439e (diff) |
Merge pull request #63912 from aaronfranke/vec3-slerp-colinear
Diffstat (limited to 'core')
-rw-r--r-- | core/math/vector3.h | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/core/math/vector3.h b/core/math/vector3.h index 970416234d..4ce01da60e 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -217,16 +217,25 @@ Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const { } Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const { + // This method seems more complicated than it really is, since we write out + // the internals of some methods for efficiency (mainly, checking length). real_t start_length_sq = length_squared(); real_t end_length_sq = p_to.length_squared(); if (unlikely(start_length_sq == 0.0f || end_length_sq == 0.0f)) { // Zero length vectors have no angle, so the best we can do is either lerp or throw an error. return lerp(p_to, p_weight); } + Vector3 axis = cross(p_to); + real_t axis_length_sq = axis.length_squared(); + if (unlikely(axis_length_sq == 0.0f)) { + // Colinear vectors have no rotation axis or angle between them, so the best we can do is lerp. + return lerp(p_to, p_weight); + } + axis /= Math::sqrt(axis_length_sq); real_t start_length = Math::sqrt(start_length_sq); real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight); real_t angle = angle_to(p_to); - return rotated(cross(p_to).normalized(), angle * p_weight) * (result_length / start_length); + return rotated(axis, angle * p_weight) * (result_length / start_length); } Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const { |