diff options
Diffstat (limited to 'core/math')
-rw-r--r-- | core/math/audio_frame.h | 8 | ||||
-rw-r--r-- | core/math/basis.cpp | 34 | ||||
-rw-r--r-- | core/math/basis.h | 23 | ||||
-rw-r--r-- | core/math/color.h | 10 | ||||
-rw-r--r-- | core/math/expression.cpp | 2 | ||||
-rw-r--r-- | core/math/math_defs.h | 9 | ||||
-rw-r--r-- | core/math/math_funcs.h | 20 | ||||
-rw-r--r-- | core/math/projection.cpp | 12 | ||||
-rw-r--r-- | core/math/quaternion.cpp | 29 | ||||
-rw-r--r-- | core/math/quaternion.h | 7 | ||||
-rw-r--r-- | core/math/vector2.h | 24 | ||||
-rw-r--r-- | core/math/vector2i.cpp | 6 | ||||
-rw-r--r-- | core/math/vector2i.h | 1 | ||||
-rw-r--r-- | core/math/vector3.h | 29 | ||||
-rw-r--r-- | core/math/vector3i.cpp | 7 | ||||
-rw-r--r-- | core/math/vector3i.h | 1 | ||||
-rw-r--r-- | core/math/vector4.cpp | 11 | ||||
-rw-r--r-- | core/math/vector4i.cpp | 8 | ||||
-rw-r--r-- | core/math/vector4i.h | 1 |
19 files changed, 137 insertions, 105 deletions
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h index 1a80faaa12..d06f9bef1e 100644 --- a/core/math/audio_frame.h +++ b/core/math/audio_frame.h @@ -34,7 +34,7 @@ #include "core/math/vector2.h" #include "core/typedefs.h" -static inline float undenormalise(volatile float f) { +static inline float undenormalize(volatile float f) { union { uint32_t i; float f; @@ -101,9 +101,9 @@ struct AudioFrame { r /= p_sample; } - _ALWAYS_INLINE_ void undenormalise() { - l = ::undenormalise(l); - r = ::undenormalise(r); + _ALWAYS_INLINE_ void undenormalize() { + l = ::undenormalize(l); + r = ::undenormalize(r); } _FORCE_INLINE_ AudioFrame lerp(const AudioFrame &p_b, float p_t) const { diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 9b8188eed8..d7bb025b69 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -453,7 +453,7 @@ void Basis::get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) cons Vector3 Basis::get_euler(EulerOrder p_order) const { switch (p_order) { - case EULER_ORDER_XYZ: { + case EulerOrder::XYZ: { // Euler angles in XYZ convention. // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix // @@ -487,8 +487,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { euler.z = 0.0f; } return euler; - } break; - case EULER_ORDER_XZY: { + } + case EulerOrder::XZY: { // Euler angles in XZY convention. // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix // @@ -516,8 +516,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { euler.z = -Math_PI / 2.0f; } return euler; - } break; - case EULER_ORDER_YXZ: { + } + case EulerOrder::YXZ: { // Euler angles in YXZ convention. // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix // @@ -554,8 +554,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { } return euler; - } break; - case EULER_ORDER_YZX: { + } + case EulerOrder::YZX: { // Euler angles in YZX convention. // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix // @@ -584,7 +584,7 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { } return euler; } break; - case EULER_ORDER_ZXY: { + case EulerOrder::ZXY: { // Euler angles in ZXY convention. // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix // @@ -612,7 +612,7 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { } return euler; } break; - case EULER_ORDER_ZYX: { + case EulerOrder::ZYX: { // Euler angles in ZYX convention. // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix // @@ -639,7 +639,7 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { euler.z = -Math::atan2(rows[0][1], rows[1][1]); } return euler; - } break; + } default: { ERR_FAIL_V_MSG(Vector3(), "Invalid parameter for get_euler(order)"); } @@ -663,22 +663,22 @@ void Basis::set_euler(const Vector3 &p_euler, EulerOrder p_order) { Basis zmat(c, -s, 0, s, c, 0, 0, 0, 1); switch (p_order) { - case EULER_ORDER_XYZ: { + case EulerOrder::XYZ: { *this = xmat * (ymat * zmat); } break; - case EULER_ORDER_XZY: { + case EulerOrder::XZY: { *this = xmat * zmat * ymat; } break; - case EULER_ORDER_YXZ: { + case EulerOrder::YXZ: { *this = ymat * xmat * zmat; } break; - case EULER_ORDER_YZX: { + case EulerOrder::YZX: { *this = ymat * zmat * xmat; } break; - case EULER_ORDER_ZXY: { + case EulerOrder::ZXY: { *this = zmat * xmat * ymat; } break; - case EULER_ORDER_ZYX: { + case EulerOrder::ZYX: { *this = zmat * ymat * xmat; } break; default: { @@ -815,7 +815,7 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { return; } // As we have reached here there are no singularities so we can handle normally. - double s = Math::sqrt((rows[2][1] - rows[1][2]) * (rows[2][1] - rows[1][2]) + (rows[0][2] - rows[2][0]) * (rows[0][2] - rows[2][0]) + (rows[1][0] - rows[0][1]) * (rows[1][0] - rows[0][1])); // Used to normalise. + double s = Math::sqrt((rows[2][1] - rows[1][2]) * (rows[2][1] - rows[1][2]) + (rows[0][2] - rows[2][0]) * (rows[0][2] - rows[2][0]) + (rows[1][0] - rows[0][1]) * (rows[1][0] - rows[0][1])); // Used to normalize. if (Math::abs(s) < CMP_EPSILON) { // Prevent divide by zero, should not happen if matrix is orthogonal and should be caught by singularity test above. diff --git a/core/math/basis.h b/core/math/basis.h index 69bef5a7be..a1d9fccef1 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -56,15 +56,6 @@ struct _NO_DISCARD_ Basis { _FORCE_INLINE_ real_t determinant() const; - enum EulerOrder { - EULER_ORDER_XYZ, - EULER_ORDER_XZY, - EULER_ORDER_YXZ, - EULER_ORDER_YZX, - EULER_ORDER_ZXY, - EULER_ORDER_ZYX - }; - void from_z(const Vector3 &p_z); void rotate(const Vector3 &p_axis, real_t p_angle); @@ -73,13 +64,13 @@ struct _NO_DISCARD_ Basis { void rotate_local(const Vector3 &p_axis, real_t p_angle); Basis rotated_local(const Vector3 &p_axis, real_t p_angle) const; - void rotate(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ); - Basis rotated(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ) const; + void rotate(const Vector3 &p_euler, EulerOrder p_order = EulerOrder::YXZ); + Basis rotated(const Vector3 &p_euler, EulerOrder p_order = EulerOrder::YXZ) const; void rotate(const Quaternion &p_quaternion); Basis rotated(const Quaternion &p_quaternion) const; - Vector3 get_euler_normalized(EulerOrder p_order = EULER_ORDER_YXZ) const; + Vector3 get_euler_normalized(EulerOrder p_order = EulerOrder::YXZ) const; void get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const; void get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) const; Quaternion get_rotation_quaternion() const; @@ -88,9 +79,9 @@ struct _NO_DISCARD_ Basis { Vector3 rotref_posscale_decomposition(Basis &rotref) const; - Vector3 get_euler(EulerOrder p_order = EULER_ORDER_YXZ) const; - void set_euler(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ); - static Basis from_euler(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ) { + Vector3 get_euler(EulerOrder p_order = EulerOrder::YXZ) const; + void set_euler(const Vector3 &p_euler, EulerOrder p_order = EulerOrder::YXZ); + static Basis from_euler(const Vector3 &p_euler, EulerOrder p_order = EulerOrder::YXZ) { Basis b; b.set_euler(p_euler, p_order); return b; @@ -119,7 +110,7 @@ struct _NO_DISCARD_ Basis { Vector3 get_scale_local() const; void set_axis_angle_scale(const Vector3 &p_axis, real_t p_angle, const Vector3 &p_scale); - void set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale, EulerOrder p_order = EULER_ORDER_YXZ); + void set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale, EulerOrder p_order = EulerOrder::YXZ); void set_quaternion_scale(const Quaternion &p_quaternion, const Vector3 &p_scale); // transposed dot products diff --git a/core/math/color.h b/core/math/color.h index a23a4953ce..5630539aa7 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -105,12 +105,10 @@ struct _NO_DISCARD_ Color { _FORCE_INLINE_ Color lerp(const Color &p_to, float p_weight) const { Color res = *this; - - res.r += (p_weight * (p_to.r - r)); - res.g += (p_weight * (p_to.g - g)); - res.b += (p_weight * (p_to.b - b)); - res.a += (p_weight * (p_to.a - a)); - + res.r = Math::lerp(res.r, p_to.r, p_weight); + res.g = Math::lerp(res.g, p_to.g, p_weight); + res.b = Math::lerp(res.b, p_to.b, p_weight); + res.a = Math::lerp(res.a, p_to.a, p_weight); return res; } diff --git a/core/math/expression.cpp b/core/math/expression.cpp index dcec3929fe..26b809e7f2 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -1420,7 +1420,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression: Callable::CallError ce; Variant::call_utility_function(bifunc->func, &r_ret, (const Variant **)argp.ptr(), argp.size(), ce); if (ce.error != Callable::CallError::CALL_OK) { - r_error_str = "Builtin Call Failed. " + Variant::get_call_error_text(bifunc->func, (const Variant **)argp.ptr(), argp.size(), ce); + r_error_str = "Builtin call failed: " + Variant::get_call_error_text(bifunc->func, (const Variant **)argp.ptr(), argp.size(), ce); return true; } diff --git a/core/math/math_defs.h b/core/math/math_defs.h index b8b82f2ff4..759667e2d5 100644 --- a/core/math/math_defs.h +++ b/core/math/math_defs.h @@ -116,6 +116,15 @@ enum Corner { CORNER_BOTTOM_LEFT }; +enum class EulerOrder { + XYZ, + XZY, + YXZ, + YZX, + ZXY, + ZYX +}; + /** * The "Real" type is an abstract type used for real numbers, such as 1.5, * in contrast to integer numbers. Precision can be controlled with the diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 0af529ad98..8dff8e6e7e 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -364,6 +364,26 @@ public: return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0f + p_control_2 * omt * t2 * 3.0f + p_end * t3; } + static _ALWAYS_INLINE_ double bezier_derivative(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + double omt = (1.0 - p_t); + double omt2 = omt * omt; + double t2 = p_t * p_t; + + double d = (p_control_1 - p_start) * 3.0 * omt2 + (p_control_2 - p_control_1) * 6.0 * omt * p_t + (p_end - p_control_2) * 3.0 * t2; + return d; + } + + static _ALWAYS_INLINE_ float bezier_derivative(float p_start, float p_control_1, float p_control_2, float p_end, float p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + float omt = (1.0f - p_t); + float omt2 = omt * omt; + float t2 = p_t * p_t; + + float d = (p_control_1 - p_start) * 3.0f * omt2 + (p_control_2 - p_control_1) * 6.0f * omt * p_t + (p_end - p_control_2) * 3.0f * t2; + return d; + } + static _ALWAYS_INLINE_ double lerp_angle(double p_from, double p_to, double p_weight) { double difference = fmod(p_to - p_from, Math_TAU); double distance = fmod(2.0 * difference, Math_TAU) - difference; diff --git a/core/math/projection.cpp b/core/math/projection.cpp index 70cc9b5f7c..9af388b081 100644 --- a/core/math/projection.cpp +++ b/core/math/projection.cpp @@ -181,7 +181,7 @@ Plane Projection::get_projection_plane(Planes p_plane) const { new_plane.normal = -new_plane.normal; new_plane.normalize(); return new_plane; - } break; + } case PLANE_FAR: { Plane new_plane = Plane(matrix[3] - matrix[2], matrix[7] - matrix[6], @@ -191,7 +191,7 @@ Plane Projection::get_projection_plane(Planes p_plane) const { new_plane.normal = -new_plane.normal; new_plane.normalize(); return new_plane; - } break; + } case PLANE_LEFT: { Plane new_plane = Plane(matrix[3] + matrix[0], matrix[7] + matrix[4], @@ -201,7 +201,7 @@ Plane Projection::get_projection_plane(Planes p_plane) const { new_plane.normal = -new_plane.normal; new_plane.normalize(); return new_plane; - } break; + } case PLANE_TOP: { Plane new_plane = Plane(matrix[3] - matrix[1], matrix[7] - matrix[5], @@ -211,7 +211,7 @@ Plane Projection::get_projection_plane(Planes p_plane) const { new_plane.normal = -new_plane.normal; new_plane.normalize(); return new_plane; - } break; + } case PLANE_RIGHT: { Plane new_plane = Plane(matrix[3] - matrix[0], matrix[7] - matrix[4], @@ -221,7 +221,7 @@ Plane Projection::get_projection_plane(Planes p_plane) const { new_plane.normal = -new_plane.normal; new_plane.normalize(); return new_plane; - } break; + } case PLANE_BOTTOM: { Plane new_plane = Plane(matrix[3] + matrix[1], matrix[7] + matrix[5], @@ -231,7 +231,7 @@ Plane Projection::get_projection_plane(Planes p_plane) const { new_plane.normal = -new_plane.normal; new_plane.normalize(); return new_plane; - } break; + } } return Plane(); diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 6a5f29f3d8..942a0b766e 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -38,25 +38,11 @@ real_t Quaternion::angle_to(const Quaternion &p_to) const { return Math::acos(CLAMP(d * d * 2 - 1, -1, 1)); } -// get_euler_xyz returns a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// This implementation uses XYZ convention (Z is the first rotation). -Vector3 Quaternion::get_euler_xyz() const { - Basis m(*this); - return m.get_euler(Basis::EULER_ORDER_XYZ); -} - -// get_euler_yxz returns a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// This implementation uses YXZ convention (Z is the first rotation). -Vector3 Quaternion::get_euler_yxz() const { +Vector3 Quaternion::get_euler(EulerOrder p_order) const { #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(!is_normalized(), Vector3(0, 0, 0), "The quaternion must be normalized."); #endif - Basis m(*this); - return m.get_euler(Basis::EULER_ORDER_YXZ); + return Basis(*this).get_euler(p_order); } void Quaternion::operator*=(const Quaternion &p_q) { @@ -330,7 +316,7 @@ Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) { // (ax, ay, az), where ax is the angle of rotation around x axis, // and similar for other axes. // This implementation uses YXZ convention (Z is the first rotation). -Quaternion::Quaternion(const Vector3 &p_euler) { +Quaternion Quaternion::from_euler(const Vector3 &p_euler) { real_t half_a1 = p_euler.y * 0.5f; real_t half_a2 = p_euler.x * 0.5f; real_t half_a3 = p_euler.z * 0.5f; @@ -346,8 +332,9 @@ Quaternion::Quaternion(const Vector3 &p_euler) { real_t cos_a3 = Math::cos(half_a3); real_t sin_a3 = Math::sin(half_a3); - x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3; - y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3; - z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3; - w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3; + return Quaternion( + sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3, + sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3, + -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3, + sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3); } diff --git a/core/math/quaternion.h b/core/math/quaternion.h index 7aa400aa8c..c5af2121d9 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -66,9 +66,8 @@ struct _NO_DISCARD_ Quaternion { _FORCE_INLINE_ real_t dot(const Quaternion &p_q) const; real_t angle_to(const Quaternion &p_to) const; - Vector3 get_euler_xyz() const; - Vector3 get_euler_yxz() const; - Vector3 get_euler() const { return get_euler_yxz(); }; + Vector3 get_euler(EulerOrder p_order = EulerOrder::YXZ) const; + static Quaternion from_euler(const Vector3 &p_euler); Quaternion slerp(const Quaternion &p_to, const real_t &p_weight) const; Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const; @@ -128,8 +127,6 @@ struct _NO_DISCARD_ Quaternion { Quaternion(const Vector3 &p_axis, real_t p_angle); - Quaternion(const Vector3 &p_euler); - Quaternion(const Quaternion &p_q) : x(p_q.x), y(p_q.y), diff --git a/core/math/vector2.h b/core/math/vector2.h index 5775d8e735..835c3d1ba6 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -112,6 +112,7 @@ struct _NO_DISCARD_ Vector2 { _FORCE_INLINE_ Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight) const; _FORCE_INLINE_ Vector2 cubic_interpolate_in_time(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const; _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; Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const; @@ -242,10 +243,8 @@ _FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const { Vector2 Vector2::lerp(const Vector2 &p_to, const real_t p_weight) const { Vector2 res = *this; - - res.x += (p_weight * (p_to.x - x)); - res.y += (p_weight * (p_to.y - y)); - + res.x = Math::lerp(res.x, p_to.x, p_weight); + res.y = Math::lerp(res.y, p_to.y, p_weight); return res; } @@ -278,15 +277,16 @@ Vector2 Vector2::cubic_interpolate_in_time(const Vector2 &p_b, const Vector2 &p_ Vector2 Vector2::bezier_interpolate(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const { Vector2 res = *this; + res.x = Math::bezier_interpolate(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t); + res.y = Math::bezier_interpolate(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t); + return res; +} - /* Formula from Wikipedia article on Bezier curves. */ - real_t omt = (1.0 - p_t); - real_t omt2 = omt * omt; - real_t omt3 = omt2 * omt; - real_t t2 = p_t * p_t; - real_t t3 = t2 * p_t; - - return res * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3; +Vector2 Vector2::bezier_derivative(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const { + Vector2 res = *this; + res.x = Math::bezier_derivative(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t); + res.y = Math::bezier_derivative(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t); + return res; } Vector2 Vector2::direction_to(const Vector2 &p_to) const { diff --git a/core/math/vector2i.cpp b/core/math/vector2i.cpp index dfed42e4d6..ff8693ee5b 100644 --- a/core/math/vector2i.cpp +++ b/core/math/vector2i.cpp @@ -39,6 +39,12 @@ Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const { CLAMP(y, p_min.y, p_max.y)); } +Vector2i Vector2i::snapped(const Vector2i &p_step) const { + return Vector2i( + Math::snapped(x, p_step.x), + Math::snapped(y, p_step.y)); +} + int64_t Vector2i::length_squared() const { return x * (int64_t)x + y * (int64_t)y; } diff --git a/core/math/vector2i.h b/core/math/vector2i.h index e131bdea94..927be11030 100644 --- a/core/math/vector2i.h +++ b/core/math/vector2i.h @@ -119,6 +119,7 @@ struct _NO_DISCARD_ Vector2i { Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); } Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); } Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const; + Vector2i snapped(const Vector2i &p_step) const; operator String() const; operator Vector2() const; diff --git a/core/math/vector3.h b/core/math/vector3.h index 19771eb312..dc74096690 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -100,6 +100,7 @@ struct _NO_DISCARD_ Vector3 { _FORCE_INLINE_ Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const; _FORCE_INLINE_ Vector3 cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const; _FORCE_INLINE_ Vector3 bezier_interpolate(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const; + _FORCE_INLINE_ Vector3 bezier_derivative(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const; Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const; @@ -208,10 +209,11 @@ Vector3 Vector3::round() const { } Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const { - return Vector3( - x + (p_weight * (p_to.x - x)), - y + (p_weight * (p_to.y - y)), - z + (p_weight * (p_to.z - z))); + Vector3 res = *this; + res.x = Math::lerp(res.x, p_to.x, p_weight); + res.y = Math::lerp(res.y, p_to.y, p_weight); + res.z = Math::lerp(res.z, p_to.z, p_weight); + return res; } Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const { @@ -254,15 +256,18 @@ Vector3 Vector3::cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_ Vector3 Vector3::bezier_interpolate(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const { Vector3 res = *this; + res.x = Math::bezier_interpolate(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t); + res.y = Math::bezier_interpolate(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t); + res.z = Math::bezier_interpolate(res.z, p_control_1.z, p_control_2.z, p_end.z, p_t); + return res; +} - /* Formula from Wikipedia article on Bezier curves. */ - real_t omt = (1.0 - p_t); - real_t omt2 = omt * omt; - real_t omt3 = omt2 * omt; - real_t t2 = p_t * p_t; - real_t t3 = t2 * p_t; - - return res * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3; +Vector3 Vector3::bezier_derivative(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const { + Vector3 res = *this; + res.x = Math::bezier_derivative(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t); + res.y = Math::bezier_derivative(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t); + res.z = Math::bezier_derivative(res.z, p_control_1.z, p_control_2.z, p_end.z, p_t); + return res; } real_t Vector3::distance_to(const Vector3 &p_to) const { diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp index b248f35035..901f2b5a64 100644 --- a/core/math/vector3i.cpp +++ b/core/math/vector3i.cpp @@ -48,6 +48,13 @@ Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const { CLAMP(z, p_min.z, p_max.z)); } +Vector3i Vector3i::snapped(const Vector3i &p_step) const { + return Vector3i( + Math::snapped(x, p_step.x), + Math::snapped(y, p_step.y), + Math::snapped(z, p_step.z)); +} + Vector3i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")"; } diff --git a/core/math/vector3i.h b/core/math/vector3i.h index 710fd96376..36bac3d8ae 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -77,6 +77,7 @@ struct _NO_DISCARD_ Vector3i { _FORCE_INLINE_ Vector3i abs() const; _FORCE_INLINE_ Vector3i sign() const; Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const; + Vector3i snapped(const Vector3i &p_step) const; /* Operators */ diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp index 3b189f7ed4..5ddf2bb6f6 100644 --- a/core/math/vector4.cpp +++ b/core/math/vector4.cpp @@ -130,11 +130,12 @@ Vector4 Vector4::round() const { } Vector4 Vector4::lerp(const Vector4 &p_to, const real_t p_weight) const { - return Vector4( - x + (p_weight * (p_to.x - x)), - y + (p_weight * (p_to.y - y)), - z + (p_weight * (p_to.z - z)), - w + (p_weight * (p_to.w - w))); + Vector4 res = *this; + res.x = Math::lerp(res.x, p_to.x, p_weight); + res.y = Math::lerp(res.y, p_to.y, p_weight); + res.z = Math::lerp(res.z, p_to.z, p_weight); + res.w = Math::lerp(res.w, p_to.w, p_weight); + return res; } Vector4 Vector4::cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight) const { diff --git a/core/math/vector4i.cpp b/core/math/vector4i.cpp index 77f6fbd5b7..e906ab45ad 100644 --- a/core/math/vector4i.cpp +++ b/core/math/vector4i.cpp @@ -65,6 +65,14 @@ Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const { CLAMP(w, p_min.w, p_max.w)); } +Vector4i Vector4i::snapped(const Vector4i &p_step) const { + return Vector4i( + Math::snapped(x, p_step.x), + Math::snapped(y, p_step.y), + Math::snapped(z, p_step.z), + Math::snapped(w, p_step.w)); +} + Vector4i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")"; } diff --git a/core/math/vector4i.h b/core/math/vector4i.h index a32414bb18..cb5a48daf9 100644 --- a/core/math/vector4i.h +++ b/core/math/vector4i.h @@ -79,6 +79,7 @@ struct _NO_DISCARD_ Vector4i { _FORCE_INLINE_ Vector4i abs() const; _FORCE_INLINE_ Vector4i sign() const; Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const; + Vector4i snapped(const Vector4i &p_step) const; /* Operators */ |