summaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
Diffstat (limited to 'core/math')
-rw-r--r--core/math/basis.cpp12
-rw-r--r--core/math/basis.h24
-rw-r--r--core/math/math_funcs.h21
-rw-r--r--core/math/vector2.cpp7
-rw-r--r--core/math/vector2.h24
-rw-r--r--core/math/vector3.cpp8
-rw-r--r--core/math/vector3.h25
7 files changed, 86 insertions, 35 deletions
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 65353d8118..ce5e9aa9b3 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -365,12 +365,12 @@ Basis Basis::rotated_local(const Vector3 &p_axis, real_t p_angle) const {
return (*this) * Basis(p_axis, p_angle);
}
-Basis Basis::rotated(const Vector3 &p_euler) const {
- return Basis(p_euler) * (*this);
+Basis Basis::rotated(const Vector3 &p_euler, EulerOrder p_order) const {
+ return Basis::from_euler(p_euler, p_order) * (*this);
}
-void Basis::rotate(const Vector3 &p_euler) {
- *this = rotated(p_euler);
+void Basis::rotate(const Vector3 &p_euler, EulerOrder p_order) {
+ *this = rotated(p_euler, p_order);
}
Basis Basis::rotated(const Quaternion &p_quaternion) const {
@@ -935,9 +935,9 @@ void Basis::set_axis_angle_scale(const Vector3 &p_axis, real_t p_angle, const Ve
rotate(p_axis, p_angle);
}
-void Basis::set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale) {
+void Basis::set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale, EulerOrder p_order) {
_set_diagonal(p_scale);
- rotate(p_euler);
+ rotate(p_euler, p_order);
}
void Basis::set_quaternion_scale(const Quaternion &p_quaternion, const Vector3 &p_scale) {
diff --git a/core/math/basis.h b/core/math/basis.h
index 9cce22510b..4be325cdd2 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -56,6 +56,15 @@ 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);
@@ -64,21 +73,12 @@ 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);
- Basis rotated(const Vector3 &p_euler) 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 Quaternion &p_quaternion);
Basis rotated(const Quaternion &p_quaternion) const;
- enum EulerOrder {
- EULER_ORDER_XYZ,
- EULER_ORDER_XZY,
- EULER_ORDER_YXZ,
- EULER_ORDER_YZX,
- EULER_ORDER_ZXY,
- EULER_ORDER_ZYX
- };
-
Vector3 get_euler_normalized(EulerOrder p_order = EULER_ORDER_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;
@@ -119,7 +119,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);
+ void set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale, EulerOrder p_order = EULER_ORDER_YXZ);
void set_quaternion_scale(const Quaternion &p_quaternion, const Vector3 &p_scale);
// transposed dot products
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index c8a55341aa..53deb9bd42 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -253,6 +253,27 @@ public:
(-p_pre + 3.0f * p_from - 3.0f * p_to + p_post) * (p_weight * p_weight * p_weight));
}
+ static _ALWAYS_INLINE_ double bezier_interpolate(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 omt3 = omt2 * omt;
+ double t2 = p_t * p_t;
+ double t3 = t2 * p_t;
+
+ return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3;
+ }
+ static _ALWAYS_INLINE_ float bezier_interpolate(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 omt3 = omt2 * omt;
+ float t2 = p_t * p_t;
+ float t3 = t2 * p_t;
+
+ 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 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/vector2.cpp b/core/math/vector2.cpp
index a27227905c..d9b5d55454 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -152,13 +152,6 @@ Vector2 Vector2::limit_length(const real_t p_len) const {
return v;
}
-Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight) const {
- Vector2 res = *this;
- res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight);
- res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight);
- return res;
-}
-
Vector2 Vector2::move_toward(const Vector2 &p_to, const real_t p_delta) const {
Vector2 v = *this;
Vector2 vd = p_to - v;
diff --git a/core/math/vector2.h b/core/math/vector2.h
index bd67299f33..91d3d3a56b 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -113,7 +113,9 @@ struct _NO_DISCARD_ Vector2 {
_FORCE_INLINE_ Vector2 lerp(const Vector2 &p_to, const real_t p_weight) const;
_FORCE_INLINE_ Vector2 slerp(const Vector2 &p_to, const real_t p_weight) const;
- 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(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight) 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;
+
Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const;
Vector2 slide(const Vector2 &p_normal) const;
@@ -261,6 +263,26 @@ Vector2 Vector2::slerp(const Vector2 &p_to, const real_t p_weight) const {
return rotated(angle * p_weight) * (result_length / start_length);
}
+Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight) const {
+ Vector2 res = *this;
+ res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight);
+ res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight);
+ return res;
+}
+
+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;
+
+ /* 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::direction_to(const Vector2 &p_to) const {
Vector2 ret(p_to.x - x, p_to.y - y);
ret.normalize();
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index f94f39b7f2..d71d365053 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -85,14 +85,6 @@ Vector3 Vector3::limit_length(const real_t p_len) const {
return v;
}
-Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const {
- Vector3 res = *this;
- res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight);
- res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight);
- res.z = Math::cubic_interpolate(res.z, p_b.z, p_pre_a.z, p_post_b.z, p_weight);
- return res;
-}
-
Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const {
Vector3 v = *this;
Vector3 vd = p_to - v;
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 8891532f42..970416234d 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -104,7 +104,9 @@ struct _NO_DISCARD_ Vector3 {
_FORCE_INLINE_ Vector3 lerp(const Vector3 &p_to, const real_t p_weight) const;
_FORCE_INLINE_ Vector3 slerp(const Vector3 &p_to, const real_t p_weight) const;
- 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(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) 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;
+
Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const;
Vector2 octahedron_encode() const;
@@ -227,6 +229,27 @@ Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const {
return rotated(cross(p_to).normalized(), 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 {
+ Vector3 res = *this;
+ res.x = Math::cubic_interpolate(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight);
+ res.y = Math::cubic_interpolate(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight);
+ res.z = Math::cubic_interpolate(res.z, p_b.z, p_pre_a.z, p_post_b.z, p_weight);
+ return res;
+}
+
+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;
+
+ /* 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;
+}
+
real_t Vector3::distance_to(const Vector3 &p_to) const {
return (p_to - *this).length();
}