Merge pull request #63912 from aaronfranke/vec3-slerp-colinear

This commit is contained in:
Rémi Verschelde 2022-08-05 00:26:53 +02:00 committed by GitHub
commit 453fbcf2f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 1 deletions

View File

@ -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 {