Skip to content

Commit

Permalink
Add rotate_toward method to Vector2, Vector3, Quaternion, and Basis
Browse files Browse the repository at this point in the history
  • Loading branch information
fire committed Oct 3, 2023
1 parent 57a6813 commit 96e497d
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 0 deletions.
4 changes: 4 additions & 0 deletions core/math/basis.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ struct _NO_DISCARD_ Basis {
rows[2].zero();
}

_FORCE_INLINE_ Basis rotate_toward(Basis p_to_basis, real_t p_delta) const {
return Basis(get_rotation_quaternion().rotate_toward(p_to_basis.get_rotation_quaternion(), p_delta));
}

_FORCE_INLINE_ Basis transpose_xform(const Basis &m) const {
return Basis(
rows[0].x * m[0].x + rows[1].x * m[1].x + rows[2].x * m[2].x,
Expand Down
16 changes: 16 additions & 0 deletions core/math/quaternion.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@ struct _NO_DISCARD_ Quaternion {
r_axis.z = z * r;
}

_FORCE_INLINE_ Quaternion rotate_toward(const Quaternion &p_to, real_t p_delta) const {
Quaternion to = p_to;
if (Math::is_zero_approx(p_delta)) {
return *this;
}
if (p_delta < 0.0) {
p_delta = -p_delta;
to = p_to.inverse();
}
real_t angle = this->angle_to(p_to);
if (angle < p_delta) {
return to;
}
return this->slerp(to, p_delta / angle);
}

void operator*=(const Quaternion &p_q);
Quaternion operator*(const Quaternion &p_q) const;

Expand Down
19 changes: 19 additions & 0 deletions core/math/vector2.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,25 @@ struct _NO_DISCARD_ Vector2 {
_FORCE_INLINE_ Vector2 bezier_interpolate(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const;
_FORCE_INLINE_ Vector2 bezier_derivative(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const;

_FORCE_INLINE_ Vector2 rotate_toward(Vector2 p_to, real_t p_delta) const {
if (Math::is_zero_approx(p_delta)) {
return *this;
}

if (p_delta < 0.0f) {
p_delta = -p_delta;
p_to = -p_to;
}

real_t angle = angle_to(p_to);

if (angle < p_delta) {
return p_to;
}

return slerp(p_to, p_delta / angle);
}

Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const;

Vector2 slide(const Vector2 &p_normal) const;
Expand Down
19 changes: 19 additions & 0 deletions core/math/vector3.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,25 @@ struct _NO_DISCARD_ Vector3 {
return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z));
}

_FORCE_INLINE_ Vector3 rotate_toward(Vector3 p_to, real_t p_delta) const {
if (Math::is_zero_approx(p_delta)) {
return *this;
}

if (p_delta < 0.0f) {
p_delta = -p_delta;
p_to = -p_to;
}

real_t angle = angle_to(p_to);

if (angle < p_delta) {
return p_to;
}

return slerp(p_to, p_delta / angle);
}

_FORCE_INLINE_ real_t length() const;
_FORCE_INLINE_ real_t length_squared() const;

Expand Down
4 changes: 4 additions & 0 deletions core/variant/variant_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1770,6 +1770,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, cubic_interpolate_in_time, sarray("b", "pre_a", "post_b", "weight", "b_t", "pre_a_t", "post_b_t"), varray());
bind_method(Vector2, bezier_interpolate, sarray("control_1", "control_2", "end", "t"), varray());
bind_method(Vector2, bezier_derivative, sarray("control_1", "control_2", "end", "t"), varray());
bind_method(Vector2, rotate_toward, sarray("to", "delta"), varray());
bind_method(Vector2, max_axis_index, sarray(), varray());
bind_method(Vector2, min_axis_index, sarray(), varray());
bind_method(Vector2, move_toward, sarray("to", "delta"), varray());
Expand Down Expand Up @@ -1865,6 +1866,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3, bezier_interpolate, sarray("control_1", "control_2", "end", "t"), varray());
bind_method(Vector3, bezier_derivative, sarray("control_1", "control_2", "end", "t"), varray());
bind_method(Vector3, move_toward, sarray("to", "delta"), varray());
bind_method(Vector3, rotate_toward, sarray("to", "delta"), varray());
bind_method(Vector3, dot, sarray("with"), varray());
bind_method(Vector3, cross, sarray("with"), varray());
bind_method(Vector3, outer, sarray("with"), varray());
Expand Down Expand Up @@ -1959,6 +1961,7 @@ static void _register_variant_builtin_methods() {
bind_method(Quaternion, log, sarray(), varray());
bind_method(Quaternion, exp, sarray(), varray());
bind_method(Quaternion, angle_to, sarray("to"), varray());
bind_method(Quaternion, rotate_toward, sarray("to", "delta"), varray());
bind_method(Quaternion, dot, sarray("with"), varray());
bind_method(Quaternion, slerp, sarray("to", "weight"), varray());
bind_method(Quaternion, slerpni, sarray("to", "weight"), varray());
Expand Down Expand Up @@ -2087,6 +2090,7 @@ static void _register_variant_builtin_methods() {
bind_method(Basis, orthonormalized, sarray(), varray());
bind_method(Basis, determinant, sarray(), varray());
bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, real_t) const>(&Basis::rotated), sarray("axis", "angle"), varray());
bind_method(Basis, rotate_toward, sarray("to", "delta"), varray());
bind_method(Basis, scaled, sarray("scale"), varray());
bind_method(Basis, get_scale, sarray(), varray());
bind_method(Basis, get_euler, sarray("order"), varray((int64_t)EulerOrder::YXZ));
Expand Down
9 changes: 9 additions & 0 deletions doc/classes/Basis.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@
Returns the orthonormalized version of the matrix (useful to call from time to time to avoid rounding error for orthogonal matrices). This performs a Gram-Schmidt orthonormalization on the basis of the matrix.
</description>
</method>
<method name="rotate_toward" qualifiers="const">
<return type="Basis" />
<param index="0" name="to" type="Basis" />
<param index="1" name="delta" type="float" />
<description>
Assuming that the matrix is a proper rotation matrix, rotates toward [param to] by [param delta].
Passing a negative [param delta] will rotate toward the inverse of [param to].
</description>
</method>
<method name="rotated" qualifiers="const">
<return type="Basis" />
<param index="0" name="axis" type="Vector3" />
Expand Down
10 changes: 10 additions & 0 deletions doc/classes/Quaternion.xml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,16 @@
Returns a copy of the quaternion, normalized to unit length.
</description>
</method>
<method name="rotate_toward" qualifiers="const">
<return type="Quaternion" />
<param index="0" name="to" type="Quaternion" />
<param index="1" name="delta" type="float" />
<description>
Returns the result of rotating toward [param to] by [param delta].
Passing a negative [param delta] will rotate toward the inverse of [param to].
[b]Note:[/b] Both quaternions must be normalized.
</description>
</method>
<method name="slerp" qualifiers="const">
<return type="Quaternion" />
<param index="0" name="to" type="Quaternion" />
Expand Down
9 changes: 9 additions & 0 deletions doc/classes/Vector2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,15 @@
Returns the result of reflecting the vector from a line defined by the given direction vector [param n].
</description>
</method>
<method name="rotate_toward" qualifiers="const">
<return type="Vector2" />
<param index="0" name="to" type="Vector2" />
<param index="1" name="delta" type="float" />
<description>
Returns the result of rotating this vector towards [param to], by increment [param delta] (in radians).
Passing a negative [param delta] will rotate toward the opposite of [param to].
</description>
</method>
<method name="rotated" qualifiers="const">
<return type="Vector2" />
<param index="0" name="angle" type="float" />
Expand Down
9 changes: 9 additions & 0 deletions doc/classes/Vector3.xml
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,15 @@
Returns the result of reflecting the vector from a plane defined by the given normal [param n].
</description>
</method>
<method name="rotate_toward" qualifiers="const">
<return type="Vector3" />
<param index="0" name="to" type="Vector3" />
<param index="1" name="delta" type="float" />
<description>
Returns the result of rotating this vector towards [param to], by increment [param delta] (in radians).
Passing a negative [param delta] will rotate toward the opposite of [param to].
</description>
</method>
<method name="rotated" qualifiers="const">
<return type="Vector3" />
<param index="0" name="axis" type="Vector3" />
Expand Down

0 comments on commit 96e497d

Please sign in to comment.