Merge pull request #63912 from aaronfranke/vec3-slerp-colinear
This commit is contained in:
commit
453fbcf2f9
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue