diff options
Diffstat (limited to 'core/math')
-rw-r--r-- | core/math/bsp_tree.cpp | 11 | ||||
-rw-r--r-- | core/math/geometry.cpp | 4 | ||||
-rw-r--r-- | core/math/math_2d.cpp | 16 | ||||
-rw-r--r-- | core/math/math_2d.h | 70 | ||||
-rw-r--r-- | core/math/matrix3.cpp | 86 | ||||
-rw-r--r-- | core/math/matrix3.h | 9 | ||||
-rw-r--r-- | core/math/octree.h | 12 | ||||
-rw-r--r-- | core/math/plane.cpp | 4 | ||||
-rw-r--r-- | core/math/plane.h | 21 | ||||
-rw-r--r-- | core/math/quat.cpp | 55 | ||||
-rw-r--r-- | core/math/quat.h | 11 | ||||
-rw-r--r-- | core/math/rect3.h | 52 | ||||
-rw-r--r-- | core/math/transform.cpp | 7 | ||||
-rw-r--r-- | core/math/vector3.h | 22 |
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 |