summaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
Diffstat (limited to 'core/math')
-rw-r--r--core/math/bsp_tree.cpp11
-rw-r--r--core/math/geometry.cpp4
-rw-r--r--core/math/math_2d.cpp16
-rw-r--r--core/math/math_2d.h70
-rw-r--r--core/math/matrix3.cpp86
-rw-r--r--core/math/matrix3.h9
-rw-r--r--core/math/octree.h12
-rw-r--r--core/math/plane.cpp4
-rw-r--r--core/math/plane.h21
-rw-r--r--core/math/quat.cpp55
-rw-r--r--core/math/quat.h11
-rw-r--r--core/math/rect3.h52
-rw-r--r--core/math/transform.cpp7
-rw-r--r--core/math/vector3.h22
14 files changed, 255 insertions, 125 deletions
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index 327a6017c3..e22bc2b05e 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -577,12 +577,11 @@ BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) {
error_radius = p_error_radius;
}
-BSP_Tree::BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const Rect3 &p_aabb, real_t p_error_radius) {
-
- nodes = p_nodes;
- planes = p_planes;
- aabb = p_aabb;
- error_radius = p_error_radius;
+BSP_Tree::BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const Rect3 &p_aabb, real_t p_error_radius)
+ : nodes(p_nodes),
+ planes(p_planes),
+ aabb(p_aabb),
+ error_radius(p_error_radius) {
}
BSP_Tree::~BSP_Tree() {
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index 2bea514d37..9a5811244a 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -1076,8 +1076,8 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
for (int i = 0; i < results.size(); i++) {
- real_t h = nearest_power_of_2(results[i].max_h);
- real_t w = nearest_power_of_2(results[i].max_w);
+ real_t h = next_power_of_2(results[i].max_h);
+ real_t w = next_power_of_2(results[i].max_w);
real_t aspect = h > w ? h / w : w / h;
if (aspect < best_aspect) {
best = i;
diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp
index 52e240ed47..956cfe5258 100644
--- a/core/math/math_2d.cpp
+++ b/core/math/math_2d.cpp
@@ -281,22 +281,22 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c
}
// slide returns the component of the vector along the given plane, specified by its normal vector.
-Vector2 Vector2::slide(const Vector2 &p_n) const {
+Vector2 Vector2::slide(const Vector2 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector2());
+ ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2());
#endif
- return *this - p_n * this->dot(p_n);
+ return *this - p_normal * this->dot(p_normal);
}
-Vector2 Vector2::bounce(const Vector2 &p_n) const {
- return -reflect(p_n);
+Vector2 Vector2::bounce(const Vector2 &p_normal) const {
+ return -reflect(p_normal);
}
-Vector2 Vector2::reflect(const Vector2 &p_n) const {
+Vector2 Vector2::reflect(const Vector2 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector2());
+ ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2());
#endif
- return 2.0 * p_n * this->dot(p_n) - *this;
+ return 2.0 * p_normal * this->dot(p_normal) - *this;
}
bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const {
diff --git a/core/math/math_2d.h b/core/math/math_2d.h
index 780bb532d7..6fea6c8adb 100644
--- a/core/math/math_2d.h
+++ b/core/math/math_2d.h
@@ -43,6 +43,14 @@ enum Margin {
MARGIN_BOTTOM
};
+enum Corner {
+
+ CORNER_TOP_LEFT,
+ CORNER_TOP_RIGHT,
+ CORNER_BOTTOM_RIGHT,
+ CORNER_BOTTOM_LEFT
+};
+
enum Orientation {
HORIZONTAL,
@@ -107,9 +115,9 @@ struct Vector2 {
Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const;
Vector2 cubic_interpolate_soft(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const;
- Vector2 slide(const Vector2 &p_vec) const;
- Vector2 bounce(const Vector2 &p_vec) const;
- Vector2 reflect(const Vector2 &p_vec) const;
+ Vector2 slide(const Vector2 &p_normal) const;
+ Vector2 bounce(const Vector2 &p_normal) const;
+ Vector2 reflect(const Vector2 &p_normal) const;
Vector2 operator+(const Vector2 &p_v) const;
void operator+=(const Vector2 &p_v);
@@ -378,13 +386,13 @@ struct Rect2 {
operator String() const { return String(position) + ", " + String(size); }
Rect2() {}
- Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) {
- position = Point2(p_x, p_y);
- size = Size2(p_width, p_height);
+ Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height)
+ : position(Point2(p_x, p_y)),
+ size(Size2(p_width, p_height)) {
}
- Rect2(const Point2 &p_pos, const Size2 &p_size) {
- position = p_pos;
- size = p_size;
+ Rect2(const Point2 &p_pos, const Size2 &p_size)
+ : position(p_pos),
+ size(p_size) {
}
};
@@ -571,18 +579,18 @@ struct Rect2i {
operator String() const { return String(position) + ", " + String(size); }
operator Rect2() const { return Rect2(position, size); }
- Rect2i(const Rect2 &p_r2) {
- position = p_r2.position;
- size = p_r2.size;
+ Rect2i(const Rect2 &p_r2)
+ : position(p_r2.position),
+ size(p_r2.size) {
}
Rect2i() {}
- Rect2i(int p_x, int p_y, int p_width, int p_height) {
- position = Point2(p_x, p_y);
- size = Size2(p_width, p_height);
+ Rect2i(int p_x, int p_y, int p_width, int p_height)
+ : position(Point2(p_x, p_y)),
+ size(Size2(p_width, p_height)) {
}
- Rect2i(const Point2 &p_pos, const Size2 &p_size) {
- position = p_pos;
- size = p_size;
+ Rect2i(const Point2 &p_pos, const Size2 &p_size)
+ : position(p_pos),
+ size(p_size) {
}
};
@@ -621,9 +629,9 @@ struct Transform2D {
void affine_invert();
Transform2D affine_inverse() const;
- void set_rotation(real_t p_phi);
+ void set_rotation(real_t p_rot);
real_t get_rotation() const;
- _FORCE_INLINE_ void set_rotation_and_scale(real_t p_phi, const Size2 &p_scale);
+ _FORCE_INLINE_ void set_rotation_and_scale(real_t p_rot, const Size2 &p_scale);
void rotate(real_t p_phi);
void scale(const Size2 &p_scale);
@@ -660,8 +668,8 @@ struct Transform2D {
_FORCE_INLINE_ Vector2 basis_xform_inv(const Vector2 &p_vec) const;
_FORCE_INLINE_ Vector2 xform(const Vector2 &p_vec) const;
_FORCE_INLINE_ Vector2 xform_inv(const Vector2 &p_vec) const;
- _FORCE_INLINE_ Rect2 xform(const Rect2 &p_vec) const;
- _FORCE_INLINE_ Rect2 xform_inv(const Rect2 &p_vec) const;
+ _FORCE_INLINE_ Rect2 xform(const Rect2 &p_rect) const;
+ _FORCE_INLINE_ Rect2 xform_inv(const Rect2 &p_rect) const;
operator String() const;
@@ -833,25 +841,25 @@ next4:
return true;
}
-Vector2 Transform2D::basis_xform(const Vector2 &v) const {
+Vector2 Transform2D::basis_xform(const Vector2 &p_vec) const {
return Vector2(
- tdotx(v),
- tdoty(v));
+ tdotx(p_vec),
+ tdoty(p_vec));
}
-Vector2 Transform2D::basis_xform_inv(const Vector2 &v) const {
+Vector2 Transform2D::basis_xform_inv(const Vector2 &p_vec) const {
return Vector2(
- elements[0].dot(v),
- elements[1].dot(v));
+ elements[0].dot(p_vec),
+ elements[1].dot(p_vec));
}
-Vector2 Transform2D::xform(const Vector2 &v) const {
+Vector2 Transform2D::xform(const Vector2 &p_vec) const {
return Vector2(
- tdotx(v),
- tdoty(v)) +
+ tdotx(p_vec),
+ tdoty(p_vec)) +
elements[2];
}
Vector2 Transform2D::xform_inv(const Vector2 &p_vec) const {
diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp
index b64f34d977..f2f6ff93cf 100644
--- a/core/math/matrix3.cpp
+++ b/core/math/matrix3.cpp
@@ -338,7 +338,7 @@ void Basis::set_rotation_axis_angle(const Vector3 &p_axis, real_t p_angle) {
rotate(p_axis, p_angle);
}
-// get_euler returns a vector containing the Euler angles in the format
+// get_euler_xyz returns a vector containing the Euler angles in the format
// (a1,a2,a3), where a3 is the angle of the first rotation, and a1 is the last
// (following the convention they are commonly defined in the literature).
//
@@ -348,7 +348,7 @@ void Basis::set_rotation_axis_angle(const Vector3 &p_axis, real_t p_angle) {
// And thus, assuming the matrix is a rotation matrix, this function returns
// the angles in the decomposition R = X(a1).Y(a2).Z(a3) where Z(a) rotates
// around the z-axis by a and so on.
-Vector3 Basis::get_euler() const {
+Vector3 Basis::get_euler_xyz() const {
// Euler angles in XYZ convention.
// See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
@@ -366,6 +366,9 @@ Vector3 Basis::get_euler() const {
if (euler.y > -Math_PI * 0.5) {
//if rotation is Y-only, return a proper -pi,pi range like in x or z for the same case.
if (elements[1][0] == 0.0 && elements[0][1] == 0.0 && elements[0][0] < 0.0) {
+ euler.x = 0;
+ euler.z = 0;
+
if (euler.y > 0.0)
euler.y = Math_PI - euler.y;
else
@@ -389,10 +392,11 @@ Vector3 Basis::get_euler() const {
return euler;
}
-// set_euler expects a vector containing the Euler angles in the format
-// (c,b,a), where a is the angle of the first rotation, and c is the last.
+// set_euler_xyz expects 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.
// The current implementation uses XYZ convention (Z is the first rotation).
-void Basis::set_euler(const Vector3 &p_euler) {
+void Basis::set_euler_xyz(const Vector3 &p_euler) {
real_t c, s;
@@ -412,6 +416,78 @@ void Basis::set_euler(const Vector3 &p_euler) {
*this = xmat * (ymat * zmat);
}
+// get_euler_yxz returns a vector containing the Euler angles in the YXZ convention,
+// as in first-Z, then-X, last-Y. The angles for X, Y, and Z rotations are returned
+// as the x, y, and z components of a Vector3 respectively.
+Vector3 Basis::get_euler_yxz() const {
+
+ // Euler angles in YXZ convention.
+ // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
+ //
+ // rot = cy*cz+sy*sx*sz cz*sy*sx-cy*sz cx*sy
+ // cx*sz cx*cz -sx
+ // cy*sx*sz-cz*sy cy*cz*sx+sy*sz cy*cx
+
+ Vector3 euler;
+#ifdef MATH_CHECKS
+ ERR_FAIL_COND_V(is_rotation() == false, euler);
+#endif
+ real_t m12 = elements[1][2];
+
+ if (m12 < 1) {
+ if (m12 > -1) {
+ if (elements[1][0] == 0 && elements[0][1] == 0 && elements[2][2] < 0) { // use pure x rotation
+ real_t x = asin(-m12);
+ euler.y = 0;
+ euler.z = 0;
+
+ if (x > 0.0)
+ euler.x = Math_PI - x;
+ else
+ euler.x = -(Math_PI + x);
+ } else {
+ euler.x = asin(-m12);
+ euler.y = atan2(elements[0][2], elements[2][2]);
+ euler.z = atan2(elements[1][0], elements[1][1]);
+ }
+ } else { // m12 == -1
+ euler.x = Math_PI * 0.5;
+ euler.y = -atan2(-elements[0][1], elements[0][0]);
+ euler.z = 0;
+ }
+ } else { // m12 == 1
+ euler.x = -Math_PI * 0.5;
+ euler.y = -atan2(-elements[0][1], elements[0][0]);
+ euler.z = 0;
+ }
+
+ return euler;
+}
+
+// set_euler_yxz expects 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.
+// The current implementation uses YXZ convention (Z is the first rotation).
+void Basis::set_euler_yxz(const Vector3 &p_euler) {
+
+ real_t c, s;
+
+ c = Math::cos(p_euler.x);
+ s = Math::sin(p_euler.x);
+ Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c);
+
+ c = Math::cos(p_euler.y);
+ s = Math::sin(p_euler.y);
+ Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c);
+
+ c = Math::cos(p_euler.z);
+ s = Math::sin(p_euler.z);
+ Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0);
+
+ //optimizer will optimize away all this anyway
+ *this = ymat * xmat * zmat;
+}
+
bool Basis::is_equal_approx(const Basis &a, const Basis &b) const {
for (int i = 0; i < 3; i++) {
diff --git a/core/math/matrix3.h b/core/math/matrix3.h
index 8897c692f7..74e6564578 100644
--- a/core/math/matrix3.h
+++ b/core/math/matrix3.h
@@ -84,8 +84,13 @@ public:
void set_rotation_euler(const Vector3 &p_euler);
void set_rotation_axis_angle(const Vector3 &p_axis, real_t p_angle);
- Vector3 get_euler() const;
- void set_euler(const Vector3 &p_euler);
+ Vector3 get_euler_xyz() const;
+ void set_euler_xyz(const Vector3 &p_euler);
+ Vector3 get_euler_yxz() const;
+ void set_euler_yxz(const Vector3 &p_euler);
+
+ Vector3 get_euler() const { return get_euler_yxz(); };
+ void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); };
void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const;
void set_axis_angle(const Vector3 &p_axis, real_t p_phi);
diff --git a/core/math/octree.h b/core/math/octree.h
index 010c1b18f7..2e37056030 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -351,7 +351,7 @@ private:
};
void _cull_convex(Octant *p_octant, _CullConvexData *p_cull);
- void _cull_AABB(Octant *p_octant, const Rect3 &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask);
+ void _cull_aabb(Octant *p_octant, const Rect3 &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask);
void _cull_segment(Octant *p_octant, const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask);
void _cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask);
@@ -380,7 +380,7 @@ public:
int get_subindex(OctreeElementID p_id) const;
int cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF);
- int cull_AABB(const Rect3 &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF);
+ int cull_aabb(const Rect3 &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF);
int cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF);
int cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF);
@@ -1095,7 +1095,7 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p
}
template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_cull_AABB(Octant *p_octant, const Rect3 &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
+void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const Rect3 &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
if (*p_result_idx == p_result_max)
return; //pointless
@@ -1160,7 +1160,7 @@ void Octree<T, use_pairs, AL>::_cull_AABB(Octant *p_octant, const Rect3 &p_aabb,
for (int i = 0; i < 8; i++) {
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) {
- _cull_AABB(p_octant->children[i], p_aabb, p_result_array, p_result_idx, p_result_max, p_subindex_array, p_mask);
+ _cull_aabb(p_octant->children[i], p_aabb, p_result_array, p_result_idx, p_result_max, p_subindex_array, p_mask);
}
}
}
@@ -1336,14 +1336,14 @@ int Octree<T, use_pairs, AL>::cull_convex(const Vector<Plane> &p_convex, T **p_r
}
template <class T, bool use_pairs, class AL>
-int Octree<T, use_pairs, AL>::cull_AABB(const Rect3 &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
+int Octree<T, use_pairs, AL>::cull_aabb(const Rect3 &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
if (!root)
return 0;
int result_count = 0;
pass++;
- _cull_AABB(root, p_aabb, p_result_array, &result_count, p_result_max, p_subindex_array, p_mask);
+ _cull_aabb(root, p_aabb, p_result_array, &result_count, p_result_max, p_subindex_array, p_mask);
return result_count;
}
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index f5e92866c4..17928d07c3 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -103,7 +103,7 @@ bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r
return true;
}
-bool Plane::intersects_ray(Vector3 p_from, Vector3 p_dir, Vector3 *p_intersection) const {
+bool Plane::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const {
Vector3 segment = p_dir;
real_t den = normal.dot(segment);
@@ -128,7 +128,7 @@ bool Plane::intersects_ray(Vector3 p_from, Vector3 p_dir, Vector3 *p_intersectio
return true;
}
-bool Plane::intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3 *p_intersection) const {
+bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 *p_intersection) const {
Vector3 segment = p_begin - p_end;
real_t den = normal.dot(segment);
diff --git a/core/math/plane.h b/core/math/plane.h
index 5a048674e4..73d584e553 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -56,8 +56,8 @@ public:
/* intersections */
bool intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r_result = 0) const;
- bool intersects_ray(Vector3 p_from, Vector3 p_dir, Vector3 *p_intersection) const;
- bool intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3 *p_intersection) const;
+ bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const;
+ bool intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 *p_intersection) const;
_FORCE_INLINE_ Vector3 project(const Vector3 &p_point) const {
@@ -75,7 +75,8 @@ public:
_FORCE_INLINE_ Plane() { d = 0; }
_FORCE_INLINE_ Plane(real_t p_a, real_t p_b, real_t p_c, real_t p_d)
- : normal(p_a, p_b, p_c), d(p_d){};
+ : normal(p_a, p_b, p_c),
+ d(p_d){};
_FORCE_INLINE_ Plane(const Vector3 &p_normal, real_t p_d);
_FORCE_INLINE_ Plane(const Vector3 &p_point, const Vector3 &p_normal);
@@ -99,16 +100,14 @@ bool Plane::has_point(const Vector3 &p_point, real_t _epsilon) const {
return (dist <= _epsilon);
}
-Plane::Plane(const Vector3 &p_normal, real_t p_d) {
-
- normal = p_normal;
- d = p_d;
+Plane::Plane(const Vector3 &p_normal, real_t p_d)
+ : normal(p_normal),
+ d(p_d) {
}
-Plane::Plane(const Vector3 &p_point, const Vector3 &p_normal) {
-
- normal = p_normal;
- d = p_normal.dot(p_point);
+Plane::Plane(const Vector3 &p_point, const Vector3 &p_normal)
+ : normal(p_normal),
+ d(p_normal.dot(p_point)) {
}
Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_point3, ClockDirection p_dir) {
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index 0bea97c2e8..5984cdf657 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -31,10 +31,11 @@
#include "matrix3.h"
#include "print_string.h"
-// set_euler expects a vector containing the Euler angles in the format
-// (c,b,a), where a is the angle of the first rotation, and c is the last.
-// The current implementation uses XYZ convention (Z is the first rotation).
-void Quat::set_euler(const Vector3 &p_euler) {
+// set_euler_xyz expects 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).
+void Quat::set_euler_xyz(const Vector3 &p_euler) {
real_t half_a1 = p_euler.x * 0.5;
real_t half_a2 = p_euler.y * 0.5;
real_t half_a3 = p_euler.z * 0.5;
@@ -56,12 +57,48 @@ void Quat::set_euler(const Vector3 &p_euler) {
-sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3);
}
-// get_euler returns a vector containing the Euler angles in the format
-// (a1,a2,a3), where a3 is the angle of the first rotation, and a1 is the last.
-// The current implementation uses XYZ convention (Z is the first rotation).
-Vector3 Quat::get_euler() const {
+// 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 Quat::get_euler_xyz() const {
Basis m(*this);
- return m.get_euler();
+ return m.get_euler_xyz();
+}
+
+// set_euler_yxz expects 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).
+void Quat::set_euler_yxz(const Vector3 &p_euler) {
+ real_t half_a1 = p_euler.y * 0.5;
+ real_t half_a2 = p_euler.x * 0.5;
+ real_t half_a3 = p_euler.z * 0.5;
+
+ // R = Y(a1).X(a2).Z(a3) convention for Euler angles.
+ // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
+ // a3 is the angle of the first rotation, following the notation in this reference.
+
+ real_t cos_a1 = Math::cos(half_a1);
+ real_t sin_a1 = Math::sin(half_a1);
+ real_t cos_a2 = Math::cos(half_a2);
+ real_t sin_a2 = Math::sin(half_a2);
+ real_t cos_a3 = Math::cos(half_a3);
+ real_t sin_a3 = Math::sin(half_a3);
+
+ set(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 * sin_a2 * sin_a3,
+ sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3);
+}
+
+// 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 Quat::get_euler_yxz() const {
+ Basis m(*this);
+ return m.get_euler_yxz();
}
void Quat::operator*=(const Quat &q) {
diff --git a/core/math/quat.h b/core/math/quat.h
index f22275b457..0e378eb4e4 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -51,8 +51,15 @@ public:
bool is_normalized() const;
Quat inverse() const;
_FORCE_INLINE_ real_t dot(const Quat &q) const;
- void set_euler(const Vector3 &p_euler);
- Vector3 get_euler() const;
+
+ void set_euler_xyz(const Vector3 &p_euler);
+ Vector3 get_euler_xyz() const;
+ void set_euler_yxz(const Vector3 &p_euler);
+ Vector3 get_euler_yxz() const;
+
+ void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); };
+ Vector3 get_euler() const { return get_euler_yxz(); };
+
Quat slerp(const Quat &q, const real_t &t) const;
Quat slerpni(const Quat &q, const real_t &t) const;
Quat cubic_slerp(const Quat &q, const Quat &prep, const Quat &postq, const real_t &t) const;
diff --git a/core/math/rect3.h b/core/math/rect3.h
index b7c94ad9f7..4890a19d99 100644
--- a/core/math/rect3.h
+++ b/core/math/rect3.h
@@ -47,12 +47,12 @@ public:
real_t get_area() const; /// get area
_FORCE_INLINE_ bool has_no_area() const {
- return (size.x <= CMP_EPSILON || size.y <= CMP_EPSILON || size.z <= CMP_EPSILON);
+ return (size.x <= 0 || size.y <= 0 || size.z <= 0);
}
_FORCE_INLINE_ bool has_no_surface() const {
- return (size.x <= CMP_EPSILON && size.y <= CMP_EPSILON && size.z <= CMP_EPSILON);
+ return (size.x <= 0 && size.y <= 0 && size.z <= 0);
}
const Vector3 &get_position() const { return position; }
@@ -72,9 +72,9 @@ public:
Rect3 intersection(const Rect3 &p_aabb) const; ///get box where two intersect, empty if no intersection occurs
bool intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip = NULL, Vector3 *r_normal = NULL) const;
bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip = NULL, Vector3 *r_normal = NULL) const;
- _FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &from, const Vector3 &p_dir, real_t t0, real_t t1) const;
+ _FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const;
- _FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_plane, int p_plane_count) const;
+ _FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_planes, int p_plane_count) const;
bool intersects_plane(const Plane &p_plane) const;
_FORCE_INLINE_ bool has_point(const Vector3 &p_point) const;
@@ -101,9 +101,9 @@ public:
operator String() const;
_FORCE_INLINE_ Rect3() {}
- inline Rect3(const Vector3 &p_pos, const Vector3 &p_size) {
- position = p_pos;
- size = p_size;
+ inline Rect3(const Vector3 &p_pos, const Vector3 &p_size)
+ : position(p_pos),
+ size(p_size) {
}
};
@@ -326,27 +326,27 @@ inline real_t Rect3::get_shortest_axis_size() const {
return max_size;
}
-bool Rect3::smits_intersect_ray(const Vector3 &from, const Vector3 &dir, real_t t0, real_t t1) const {
+bool Rect3::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const {
- real_t divx = 1.0 / dir.x;
- real_t divy = 1.0 / dir.y;
- real_t divz = 1.0 / dir.z;
+ real_t divx = 1.0 / p_dir.x;
+ real_t divy = 1.0 / p_dir.y;
+ real_t divz = 1.0 / p_dir.z;
Vector3 upbound = position + size;
real_t tmin, tmax, tymin, tymax, tzmin, tzmax;
- if (dir.x >= 0) {
- tmin = (position.x - from.x) * divx;
- tmax = (upbound.x - from.x) * divx;
+ if (p_dir.x >= 0) {
+ tmin = (position.x - p_from.x) * divx;
+ tmax = (upbound.x - p_from.x) * divx;
} else {
- tmin = (upbound.x - from.x) * divx;
- tmax = (position.x - from.x) * divx;
+ tmin = (upbound.x - p_from.x) * divx;
+ tmax = (position.x - p_from.x) * divx;
}
- if (dir.y >= 0) {
- tymin = (position.y - from.y) * divy;
- tymax = (upbound.y - from.y) * divy;
+ if (p_dir.y >= 0) {
+ tymin = (position.y - p_from.y) * divy;
+ tymax = (upbound.y - p_from.y) * divy;
} else {
- tymin = (upbound.y - from.y) * divy;
- tymax = (position.y - from.y) * divy;
+ tymin = (upbound.y - p_from.y) * divy;
+ tymax = (position.y - p_from.y) * divy;
}
if ((tmin > tymax) || (tymin > tmax))
return false;
@@ -354,12 +354,12 @@ bool Rect3::smits_intersect_ray(const Vector3 &from, const Vector3 &dir, real_t
tmin = tymin;
if (tymax < tmax)
tmax = tymax;
- if (dir.z >= 0) {
- tzmin = (position.z - from.z) * divz;
- tzmax = (upbound.z - from.z) * divz;
+ if (p_dir.z >= 0) {
+ tzmin = (position.z - p_from.z) * divz;
+ tzmax = (upbound.z - p_from.z) * divz;
} else {
- tzmin = (upbound.z - from.z) * divz;
- tzmax = (position.z - from.z) * divz;
+ tzmin = (upbound.z - p_from.z) * divz;
+ tzmax = (position.z - p_from.z) * divz;
}
if ((tmin > tzmax) || (tzmin > tmax))
return false;
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 7a50214596..3a86fbfc6c 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -208,8 +208,7 @@ Transform::operator String() const {
return basis.operator String() + " - " + origin.operator String();
}
-Transform::Transform(const Basis &p_basis, const Vector3 &p_origin) {
-
- basis = p_basis;
- origin = p_origin;
+Transform::Transform(const Basis &p_basis, const Vector3 &p_origin)
+ : basis(p_basis),
+ origin(p_origin) {
}
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 6a7974681e..c58a86fbdb 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -108,9 +108,9 @@ struct Vector3 {
_FORCE_INLINE_ real_t angle_to(const Vector3 &p_b) const;
- _FORCE_INLINE_ Vector3 slide(const Vector3 &p_vec) const;
- _FORCE_INLINE_ Vector3 bounce(const Vector3 &p_vec) const;
- _FORCE_INLINE_ Vector3 reflect(const Vector3 &p_vec) const;
+ _FORCE_INLINE_ Vector3 slide(const Vector3 &p_normal) const;
+ _FORCE_INLINE_ Vector3 bounce(const Vector3 &p_normal) const;
+ _FORCE_INLINE_ Vector3 reflect(const Vector3 &p_normal) const;
/* Operators */
@@ -410,22 +410,22 @@ void Vector3::zero() {
}
// slide returns the component of the vector along the given plane, specified by its normal vector.
-Vector3 Vector3::slide(const Vector3 &p_n) const {
+Vector3 Vector3::slide(const Vector3 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector3());
+ ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector3());
#endif
- return *this - p_n * this->dot(p_n);
+ return *this - p_normal * this->dot(p_normal);
}
-Vector3 Vector3::bounce(const Vector3 &p_n) const {
- return -reflect(p_n);
+Vector3 Vector3::bounce(const Vector3 &p_normal) const {
+ return -reflect(p_normal);
}
-Vector3 Vector3::reflect(const Vector3 &p_n) const {
+Vector3 Vector3::reflect(const Vector3 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_n.is_normalized() == false, Vector3());
+ ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector3());
#endif
- return 2.0 * p_n * this->dot(p_n) - *this;
+ return 2.0 * p_normal * this->dot(p_normal) - *this;
}
#endif