Allow Vector2/3 slerp values to have any length
This commit is contained in:
parent
f5d281d55f
commit
064036d786
4 changed files with 22 additions and 9 deletions
|
@ -261,11 +261,16 @@ Vector2 Vector2::lerp(const Vector2 &p_to, const real_t p_weight) const {
|
|||
}
|
||||
|
||||
Vector2 Vector2::slerp(const Vector2 &p_to, const real_t p_weight) const {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Vector2(), "The start Vector2 must be normalized.");
|
||||
#endif
|
||||
real_t theta = angle_to(p_to);
|
||||
return rotated(theta * p_weight);
|
||||
real_t start_length_sq = length_squared();
|
||||
real_t end_length_sq = p_to.length_squared();
|
||||
if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) {
|
||||
// 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);
|
||||
}
|
||||
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(angle * p_weight) * (result_length / start_length);
|
||||
}
|
||||
|
||||
Vector2 Vector2::direction_to(const Vector2 &p_to) const {
|
||||
|
|
|
@ -240,8 +240,16 @@ 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 {
|
||||
real_t theta = angle_to(p_to);
|
||||
return rotated(cross(p_to).normalized(), theta * p_weight);
|
||||
real_t start_length_sq = length_squared();
|
||||
real_t end_length_sq = p_to.length_squared();
|
||||
if (unlikely(start_length_sq == 0.0 || end_length_sq == 0.0)) {
|
||||
// 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
real_t Vector3::distance_to(const Vector3 &p_to) const {
|
||||
|
|
|
@ -299,7 +299,7 @@
|
|||
<argument index="1" name="weight" type="float" />
|
||||
<description>
|
||||
Returns the result of spherical linear interpolation between this vector and [code]to[/code], by amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation.
|
||||
[b]Note:[/b] 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].
|
||||
</description>
|
||||
</method>
|
||||
<method name="slide" qualifiers="const">
|
||||
|
|
|
@ -290,7 +290,7 @@
|
|||
<argument index="1" name="weight" type="float" />
|
||||
<description>
|
||||
Returns the result of spherical linear interpolation between this vector and [code]to[/code], by amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation.
|
||||
[b]Note:[/b] 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].
|
||||
</description>
|
||||
</method>
|
||||
<method name="slide" qualifiers="const">
|
||||
|
|
Loading…
Reference in a new issue