diff options
Diffstat (limited to 'core/math')
45 files changed, 476 insertions, 384 deletions
diff --git a/core/math/a_star_grid_2d.cpp b/core/math/a_star_grid_2d.cpp index ad67cfa852..c30acf32bb 100644 --- a/core/math/a_star_grid_2d.cpp +++ b/core/math/a_star_grid_2d.cpp @@ -30,6 +30,8 @@ #include "a_star_grid_2d.h" +#include "core/variant/typed_array.h" + static real_t heuristic_euclidian(const Vector2i &p_from, const Vector2i &p_to) { real_t dx = (real_t)ABS(p_to.x - p_from.x); real_t dy = (real_t)ABS(p_to.y - p_from.y); @@ -492,17 +494,17 @@ Vector<Vector2> AStarGrid2D::get_point_path(const Vector2i &p_from_id, const Vec return path; } -Vector<Vector2> AStarGrid2D::get_id_path(const Vector2i &p_from_id, const Vector2i &p_to_id) { - ERR_FAIL_COND_V_MSG(dirty, Vector<Vector2>(), "Grid is not initialized. Call the update method."); - ERR_FAIL_COND_V_MSG(!is_in_boundsv(p_from_id), Vector<Vector2>(), vformat("Can't get id path. Point out of bounds (%s/%s, %s/%s)", p_from_id.x, size.width, p_from_id.y, size.height)); - ERR_FAIL_COND_V_MSG(!is_in_boundsv(p_to_id), Vector<Vector2>(), vformat("Can't get id path. Point out of bounds (%s/%s, %s/%s)", p_to_id.x, size.width, p_to_id.y, size.height)); +TypedArray<Vector2i> AStarGrid2D::get_id_path(const Vector2i &p_from_id, const Vector2i &p_to_id) { + ERR_FAIL_COND_V_MSG(dirty, TypedArray<Vector2i>(), "Grid is not initialized. Call the update method."); + ERR_FAIL_COND_V_MSG(!is_in_boundsv(p_from_id), TypedArray<Vector2i>(), vformat("Can't get id path. Point out of bounds (%s/%s, %s/%s)", p_from_id.x, size.width, p_from_id.y, size.height)); + ERR_FAIL_COND_V_MSG(!is_in_boundsv(p_to_id), TypedArray<Vector2i>(), vformat("Can't get id path. Point out of bounds (%s/%s, %s/%s)", p_to_id.x, size.width, p_to_id.y, size.height)); Point *a = _get_point(p_from_id.x, p_from_id.y); Point *b = _get_point(p_to_id.x, p_to_id.y); if (a == b) { - Vector<Vector2> ret; - ret.push_back(Vector2((float)a->id.x, (float)a->id.y)); + TypedArray<Vector2i> ret; + ret.push_back(a); return ret; } @@ -511,7 +513,7 @@ Vector<Vector2> AStarGrid2D::get_id_path(const Vector2i &p_from_id, const Vector bool found_route = _solve(begin_point, end_point); if (!found_route) { - return Vector<Vector2>(); + return TypedArray<Vector2i>(); } Point *p = end_point; @@ -521,20 +523,18 @@ Vector<Vector2> AStarGrid2D::get_id_path(const Vector2i &p_from_id, const Vector p = p->prev_point; } - Vector<Vector2> path; + TypedArray<Vector2i> path; path.resize(pc); { - Vector2 *w = path.ptrw(); - p = end_point; int64_t idx = pc - 1; while (p != begin_point) { - w[idx--] = Vector2((float)p->id.x, (float)p->id.y); + path[idx--] = p->id; p = p->prev_point; } - w[0] = p->id; + path[0] = p->id; } return path; diff --git a/core/math/a_star_grid_2d.h b/core/math/a_star_grid_2d.h index bf6363aa01..1002f18738 100644 --- a/core/math/a_star_grid_2d.h +++ b/core/math/a_star_grid_2d.h @@ -169,7 +169,7 @@ public: void clear(); Vector<Vector2> get_point_path(const Vector2i &p_from, const Vector2i &p_to); - Vector<Vector2> get_id_path(const Vector2i &p_from, const Vector2i &p_to); + TypedArray<Vector2i> get_id_path(const Vector2i &p_from, const Vector2i &p_to); }; VARIANT_ENUM_CAST(AStarGrid2D::DiagonalMode); diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp index 4c89be7f4d..fcf245d2ad 100644 --- a/core/math/aabb.cpp +++ b/core/math/aabb.cpp @@ -30,7 +30,7 @@ #include "aabb.h" -#include "core/string/print_string.h" +#include "core/string/ustring.h" #include "core/variant/variant.h" real_t AABB::get_volume() const { @@ -76,6 +76,10 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const { return position.is_equal_approx(p_aabb.position) && size.is_equal_approx(p_aabb.size); } +bool AABB::is_finite() const { + return position.is_finite() && size.is_finite(); +} + AABB AABB::intersection(const AABB &p_aabb) const { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) { @@ -403,6 +407,7 @@ Variant AABB::intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to } return Variant(); } + Variant AABB::intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const { Vector3 inters; if (intersects_ray(p_from, p_dir, &inters)) { diff --git a/core/math/aabb.h b/core/math/aabb.h index acf903eeba..9d5837ad37 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -31,7 +31,6 @@ #ifndef AABB_H #define AABB_H -#include "core/math/math_defs.h" #include "core/math/plane.h" #include "core/math/vector3.h" @@ -64,6 +63,7 @@ struct _NO_DISCARD_ AABB { bool operator!=(const AABB &p_rval) const; bool is_equal_approx(const AABB &p_aabb) const; + bool is_finite() const; _FORCE_INLINE_ bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap _FORCE_INLINE_ bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap _FORCE_INLINE_ bool encloses(const AABB &p_aabb) const; /// p_aabb is completely inside this @@ -101,7 +101,7 @@ struct _NO_DISCARD_ AABB { _FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */ _FORCE_INLINE_ AABB abs() const { - return AABB(Vector3(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0), position.z + MIN(size.z, 0)), size.abs()); + return AABB(Vector3(position.x + MIN(size.x, (real_t)0), position.y + MIN(size.y, (real_t)0), position.z + MIN(size.z, (real_t)0)), size.abs()); } Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 4b163409ce..9b8188eed8 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -31,7 +31,7 @@ #include "basis.h" #include "core/math/math_funcs.h" -#include "core/string/print_string.h" +#include "core/string/ustring.h" #define cofac(row1, col1, row2, col2) \ (rows[row1][col1] * rows[row2][col2] - rows[row1][col2] * rows[row2][col1]) @@ -142,8 +142,8 @@ bool Basis::is_symmetric() const { #endif Basis Basis::diagonalize() { -//NOTE: only implemented for symmetric matrices -//with the Jacobi iterative method +// NOTE: only implemented for symmetric matrices +// with the Jacobi iterative method #ifdef MATH_CHECKS ERR_FAIL_COND_V(!is_symmetric(), Basis()); #endif @@ -691,6 +691,10 @@ bool Basis::is_equal_approx(const Basis &p_basis) const { return rows[0].is_equal_approx(p_basis.rows[0]) && rows[1].is_equal_approx(p_basis.rows[1]) && rows[2].is_equal_approx(p_basis.rows[2]); } +bool Basis::is_finite() const { + return rows[0].is_finite() && rows[1].is_finite() && rows[2].is_finite(); +} + bool Basis::operator==(const Basis &p_matrix) const { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { diff --git a/core/math/basis.h b/core/math/basis.h index cc2924f5ff..69bef5a7be 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -134,6 +134,7 @@ struct _NO_DISCARD_ Basis { } bool is_equal_approx(const Basis &p_basis) const; + bool is_finite() const; bool operator==(const Basis &p_matrix) const; bool operator!=(const Basis &p_matrix) const; diff --git a/core/math/bvh_abb.h b/core/math/bvh_abb.h index 8a44f1c4da..699f7de604 100644 --- a/core/math/bvh_abb.h +++ b/core/math/bvh_abb.h @@ -251,7 +251,9 @@ struct BVH_ABB { void expand(real_t p_change) { POINT change; - change.set_all(p_change); + for (int axis = 0; axis < POINT::AXIS_COUNT; ++axis) { + change[axis] = p_change; + } grow(change); } @@ -262,7 +264,9 @@ struct BVH_ABB { } void set_to_max_opposite_extents() { - neg_max.set_all(FLT_MAX); + for (int axis = 0; axis < POINT::AXIS_COUNT; ++axis) { + neg_max[axis] = FLT_MAX; + } min = neg_max; } diff --git a/core/math/bvh_split.inc b/core/math/bvh_split.inc index ff07166d4a..180bbfb511 100644 --- a/core/math/bvh_split.inc +++ b/core/math/bvh_split.inc @@ -13,7 +13,7 @@ void _split_inform_references(uint32_t p_node_id) { void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, uint16_t *group_b, const BVHABB_CLASS *temp_bounds, const BVHABB_CLASS full_bound) { // special case for low leaf sizes .. should static compile out - if (MAX_ITEMS < 4) { + if constexpr (MAX_ITEMS < 4) { uint32_t ind = group_a[0]; // add to b @@ -34,7 +34,7 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u order[POINT::AXIS_COUNT - 1] = size.max_axis_index(); static_assert(POINT::AXIS_COUNT <= 3, "BVH POINT::AXIS_COUNT has unexpected size"); - if (POINT::AXIS_COUNT == 3) { + if constexpr (POINT::AXIS_COUNT == 3) { order[1] = 3 - (order[0] + order[2]); } diff --git a/core/math/bvh_tree.h b/core/math/bvh_tree.h index cdb2bb4413..3836e92a83 100644 --- a/core/math/bvh_tree.h +++ b/core/math/bvh_tree.h @@ -43,7 +43,6 @@ #include "core/math/bvh_abb.h" #include "core/math/geometry_3d.h" #include "core/math/vector3.h" -#include "core/string/print_string.h" #include "core/templates/local_vector.h" #include "core/templates/pooled_list.h" #include <limits.h> @@ -235,7 +234,7 @@ private: // no need to keep back references for children at the moment - uint32_t sibling_id; // always a node id, as tnode is never a leaf + uint32_t sibling_id = 0; // always a node id, as tnode is never a leaf bool sibling_present = false; // if there are more children, or this is the root node, don't try and delete diff --git a/core/math/color.cpp b/core/math/color.cpp index 4bdeafd2f2..f223853f6b 100644 --- a/core/math/color.cpp +++ b/core/math/color.cpp @@ -32,85 +32,85 @@ #include "color_names.inc" #include "core/math/math_funcs.h" -#include "core/string/print_string.h" +#include "core/string/ustring.h" #include "core/templates/rb_map.h" #include "thirdparty/misc/ok_color.h" uint32_t Color::to_argb32() const { - uint32_t c = (uint8_t)Math::round(a * 255); + uint32_t c = (uint8_t)Math::round(a * 255.0f); c <<= 8; - c |= (uint8_t)Math::round(r * 255); + c |= (uint8_t)Math::round(r * 255.0f); c <<= 8; - c |= (uint8_t)Math::round(g * 255); + c |= (uint8_t)Math::round(g * 255.0f); c <<= 8; - c |= (uint8_t)Math::round(b * 255); + c |= (uint8_t)Math::round(b * 255.0f); return c; } uint32_t Color::to_abgr32() const { - uint32_t c = (uint8_t)Math::round(a * 255); + uint32_t c = (uint8_t)Math::round(a * 255.0f); c <<= 8; - c |= (uint8_t)Math::round(b * 255); + c |= (uint8_t)Math::round(b * 255.0f); c <<= 8; - c |= (uint8_t)Math::round(g * 255); + c |= (uint8_t)Math::round(g * 255.0f); c <<= 8; - c |= (uint8_t)Math::round(r * 255); + c |= (uint8_t)Math::round(r * 255.0f); return c; } uint32_t Color::to_rgba32() const { - uint32_t c = (uint8_t)Math::round(r * 255); + uint32_t c = (uint8_t)Math::round(r * 255.0f); c <<= 8; - c |= (uint8_t)Math::round(g * 255); + c |= (uint8_t)Math::round(g * 255.0f); c <<= 8; - c |= (uint8_t)Math::round(b * 255); + c |= (uint8_t)Math::round(b * 255.0f); c <<= 8; - c |= (uint8_t)Math::round(a * 255); + c |= (uint8_t)Math::round(a * 255.0f); return c; } uint64_t Color::to_abgr64() const { - uint64_t c = (uint16_t)Math::round(a * 65535); + uint64_t c = (uint16_t)Math::round(a * 65535.0f); c <<= 16; - c |= (uint16_t)Math::round(b * 65535); + c |= (uint16_t)Math::round(b * 65535.0f); c <<= 16; - c |= (uint16_t)Math::round(g * 65535); + c |= (uint16_t)Math::round(g * 65535.0f); c <<= 16; - c |= (uint16_t)Math::round(r * 65535); + c |= (uint16_t)Math::round(r * 65535.0f); return c; } uint64_t Color::to_argb64() const { - uint64_t c = (uint16_t)Math::round(a * 65535); + uint64_t c = (uint16_t)Math::round(a * 65535.0f); c <<= 16; - c |= (uint16_t)Math::round(r * 65535); + c |= (uint16_t)Math::round(r * 65535.0f); c <<= 16; - c |= (uint16_t)Math::round(g * 65535); + c |= (uint16_t)Math::round(g * 65535.0f); c <<= 16; - c |= (uint16_t)Math::round(b * 65535); + c |= (uint16_t)Math::round(b * 65535.0f); return c; } uint64_t Color::to_rgba64() const { - uint64_t c = (uint16_t)Math::round(r * 65535); + uint64_t c = (uint16_t)Math::round(r * 65535.0f); c <<= 16; - c |= (uint16_t)Math::round(g * 65535); + c |= (uint16_t)Math::round(g * 65535.0f); c <<= 16; - c |= (uint16_t)Math::round(b * 65535); + c |= (uint16_t)Math::round(b * 65535.0f); c <<= 16; - c |= (uint16_t)Math::round(a * 65535); + c |= (uint16_t)Math::round(a * 65535.0f); return c; } String _to_hex(float p_val) { - int v = Math::round(p_val * 255); + int v = Math::round(p_val * 255.0f); v = CLAMP(v, 0, 255); String ret; @@ -150,8 +150,8 @@ float Color::get_h() const { float delta = max - min; - if (delta == 0) { - return 0; + if (delta == 0.0f) { + return 0.0f; } float h; @@ -164,7 +164,7 @@ float Color::get_h() const { } h /= 6.0f; - if (h < 0) { + if (h < 0.0f) { h += 1.0f; } @@ -179,7 +179,7 @@ float Color::get_s() const { float delta = max - min; - return (max != 0) ? (delta / max) : 0; + return (max != 0.0f) ? (delta / max) : 0.0f; } float Color::get_v() const { @@ -193,7 +193,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) { float f, p, q, t; a = p_alpha; - if (p_s == 0) { + if (p_s == 0.0f) { // Achromatic (grey) r = g = b = p_v; return; @@ -204,9 +204,9 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) { i = Math::floor(p_h); f = p_h - i; - p = p_v * (1 - p_s); - q = p_v * (1 - p_s * f); - t = p_v * (1 - p_s * (1 - f)); + p = p_v * (1.0f - p_s); + q = p_v * (1.0f - p_s * f); + t = p_v * (1.0f - p_s * (1.0f - f)); switch (i) { case 0: // Red is the dominant color @@ -347,7 +347,7 @@ Color Color::html(const String &p_rgba) { ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_rgba + "."); } - float r, g, b, a = 1.0; + float r, g, b, a = 1.0f; if (is_shorthand) { r = _parse_col4(color, 0) / 15.0f; g = _parse_col4(color, 1) / 15.0f; @@ -363,10 +363,10 @@ Color Color::html(const String &p_rgba) { a = _parse_col8(color, 6) / 255.0f; } } - ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_rgba + "."); - ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_rgba + "."); - ERR_FAIL_COND_V_MSG(b < 0, Color(), "Invalid color code: " + p_rgba + "."); - ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_rgba + "."); + ERR_FAIL_COND_V_MSG(r < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); + ERR_FAIL_COND_V_MSG(g < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); + ERR_FAIL_COND_V_MSG(b < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); + ERR_FAIL_COND_V_MSG(a < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); return Color(r, g, b, a); } @@ -474,7 +474,7 @@ Color Color::from_rgbe9995(uint32_t p_rgbe) { float g = (p_rgbe >> 9) & 0x1ff; float b = (p_rgbe >> 18) & 0x1ff; float e = (p_rgbe >> 27); - float m = Math::pow(2, e - 15.0f - 9.0f); + float m = Math::pow(2.0f, e - 15.0f - 9.0f); float rd = r * m; float gd = g * m; diff --git a/core/math/color.h b/core/math/color.h index 65036f74cc..a23a4953ce 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -32,7 +32,8 @@ #define COLOR_H #include "core/math/math_funcs.h" -#include "core/string/ustring.h" + +class String; struct _NO_DISCARD_ Color { union { @@ -55,11 +56,11 @@ struct _NO_DISCARD_ Color { float get_h() const; float get_s() const; float get_v() const; - void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0); + void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0f); float get_ok_hsl_h() const; float get_ok_hsl_s() const; float get_ok_hsl_l() const; - void set_ok_hsl(float p_h, float p_s, float p_l, float p_alpha = 1.0); + void set_ok_hsl(float p_h, float p_s, float p_l, float p_alpha = 1.0f); _FORCE_INLINE_ float &operator[](int p_idx) { return components[p_idx]; @@ -175,9 +176,9 @@ struct _NO_DISCARD_ Color { _FORCE_INLINE_ Color srgb_to_linear() const { return Color( - r < 0.04045f ? r * (1.0 / 12.92) : Math::pow((r + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f), - g < 0.04045f ? g * (1.0 / 12.92) : Math::pow((g + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f), - b < 0.04045f ? b * (1.0 / 12.92) : Math::pow((b + 0.055f) * (float)(1.0 / (1 + 0.055)), 2.4f), + r < 0.04045f ? r * (1.0f / 12.92f) : Math::pow((r + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f), + g < 0.04045f ? g * (1.0f / 12.92f) : Math::pow((g + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f), + b < 0.04045f ? b * (1.0f / 12.92f) : Math::pow((b + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f), a); } _FORCE_INLINE_ Color linear_to_srgb() const { @@ -198,11 +199,11 @@ struct _NO_DISCARD_ Color { static String get_named_color_name(int p_idx); static Color get_named_color(int p_idx); static Color from_string(const String &p_string, const Color &p_default); - static Color from_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0); - static Color from_ok_hsl(float p_h, float p_s, float p_l, float p_alpha = 1.0); + static Color from_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0f); + static Color from_ok_hsl(float p_h, float p_s, float p_l, float p_alpha = 1.0f); static Color from_rgbe9995(uint32_t p_rgbe); - _FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys + _FORCE_INLINE_ bool operator<(const Color &p_color) const; // Used in set keys. operator String() const; // For the binder. diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp index 996f4f4d67..561970d2ee 100644 --- a/core/math/convex_hull.cpp +++ b/core/math/convex_hull.cpp @@ -62,6 +62,7 @@ subject to the following restrictions: #include "core/math/aabb.h" #include "core/math/math_defs.h" #include "core/os/memory.h" +#include "core/templates/oa_hash_map.h" #include "core/templates/paged_allocator.h" #include <string.h> @@ -2252,19 +2253,62 @@ Error ConvexHullComputer::convex_hull(const Vector<Vector3> &p_points, Geometry3 r_mesh.vertices = ch.vertices; + // Tag which face each edge belongs to + LocalVector<int32_t> edge_faces; + edge_faces.resize(ch.edges.size()); + + for (uint32_t i = 0; i < ch.edges.size(); i++) { + edge_faces[i] = -1; + } + + for (uint32_t i = 0; i < ch.faces.size(); i++) { + const Edge *e_start = &ch.edges[ch.faces[i]]; + const Edge *e = e_start; + do { + int64_t ofs = e - ch.edges.ptr(); + edge_faces[ofs] = i; + + e = e->get_next_edge_of_face(); + } while (e != e_start); + } + // Copy the edges over. There's two "half-edges" for every edge, so we pick only one of them. r_mesh.edges.resize(ch.edges.size() / 2); + OAHashMap<uint64_t, int32_t> edge_map; + edge_map.reserve(ch.edges.size() * 4); // The higher the capacity, the faster the insert + uint32_t edges_copied = 0; for (uint32_t i = 0; i < ch.edges.size(); i++) { + ERR_CONTINUE(edge_faces[i] == -1); // Sanity check + uint32_t a = (&ch.edges[i])->get_source_vertex(); uint32_t b = (&ch.edges[i])->get_target_vertex(); if (a < b) { // Copy only the "canonical" edge. For the reverse edge, this will be false. ERR_BREAK(edges_copied >= (uint32_t)r_mesh.edges.size()); - r_mesh.edges.write[edges_copied].a = a; - r_mesh.edges.write[edges_copied].b = b; + r_mesh.edges[edges_copied].vertex_a = a; + r_mesh.edges[edges_copied].vertex_b = b; + r_mesh.edges[edges_copied].face_a = edge_faces[i]; + r_mesh.edges[edges_copied].face_b = -1; + + uint64_t key = a; + key <<= 32; + key |= b; + edge_map.insert(key, edges_copied); + edges_copied++; + } else { + uint64_t key = b; + key <<= 32; + key |= a; + int32_t index; + if (!edge_map.lookup(key, index)) { + ERR_PRINT("Invalid edge"); + } else { + r_mesh.edges[index].face_b = edge_faces[i]; + } } } + if (edges_copied != (uint32_t)r_mesh.edges.size()) { ERR_PRINT("Invalid edge count."); } @@ -2273,7 +2317,7 @@ Error ConvexHullComputer::convex_hull(const Vector<Vector3> &p_points, Geometry3 for (uint32_t i = 0; i < ch.faces.size(); i++) { const Edge *e_start = &ch.edges[ch.faces[i]]; const Edge *e = e_start; - Geometry3D::MeshData::Face &face = r_mesh.faces.write[i]; + Geometry3D::MeshData::Face &face = r_mesh.faces[i]; do { face.indices.push_back(e->get_target_vertex()); @@ -2284,8 +2328,8 @@ Error ConvexHullComputer::convex_hull(const Vector<Vector3> &p_points, Geometry3 // reverse indices: Godot wants clockwise, but this is counter-clockwise if (face.indices.size() > 2) { // reverse all but the first index. - int *indices = face.indices.ptrw(); - for (int c = 0; c < (face.indices.size() - 1) / 2; c++) { + int *indices = face.indices.ptr(); + for (uint32_t c = 0; c < (face.indices.size() - 1) / 2; c++) { SWAP(indices[c + 1], indices[face.indices.size() - 1 - c]); } } diff --git a/core/math/convex_hull.h b/core/math/convex_hull.h index bd86fe0eba..ab6671a7d0 100644 --- a/core/math/convex_hull.h +++ b/core/math/convex_hull.h @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef CONVEX_HULL_H +#define CONVEX_HULL_H + /* Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net This software is provided 'as-is', without any express or implied warranty. @@ -40,9 +43,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#ifndef CONVEX_HULL_H -#define CONVEX_HULL_H - #include "core/math/geometry_3d.h" #include "core/math/vector3.h" #include "core/templates/local_vector.h" @@ -62,6 +62,10 @@ public: friend class ConvexHullComputer; public: + int32_t get_next_relative() const { + return next; + } + int32_t get_source_vertex() const { return (this + reverse)->target_vertex; } @@ -86,7 +90,7 @@ public: }; // Vertices of the output hull - Vector<Vector3> vertices; + LocalVector<Vector3> vertices; // Edges of the output hull LocalVector<Edge> edges; diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 898c3c2d91..3f8fe09445 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -35,7 +35,6 @@ #include "core/math/aabb.h" #include "core/math/projection.h" #include "core/math/vector3.h" -#include "core/string/print_string.h" #include "core/templates/local_vector.h" #include "core/templates/oa_hash_map.h" #include "core/templates/vector.h" @@ -186,25 +185,25 @@ class Delaunay3D { Projection cm; - cm.matrix[0][0] = p_points[p_simplex.points[0]].x; - cm.matrix[0][1] = p_points[p_simplex.points[1]].x; - cm.matrix[0][2] = p_points[p_simplex.points[2]].x; - cm.matrix[0][3] = p_points[p_simplex.points[3]].x; - - cm.matrix[1][0] = p_points[p_simplex.points[0]].y; - cm.matrix[1][1] = p_points[p_simplex.points[1]].y; - cm.matrix[1][2] = p_points[p_simplex.points[2]].y; - cm.matrix[1][3] = p_points[p_simplex.points[3]].y; - - cm.matrix[2][0] = p_points[p_simplex.points[0]].z; - cm.matrix[2][1] = p_points[p_simplex.points[1]].z; - cm.matrix[2][2] = p_points[p_simplex.points[2]].z; - cm.matrix[2][3] = p_points[p_simplex.points[3]].z; - - cm.matrix[3][0] = 1.0; - cm.matrix[3][1] = 1.0; - cm.matrix[3][2] = 1.0; - cm.matrix[3][3] = 1.0; + cm.columns[0][0] = p_points[p_simplex.points[0]].x; + cm.columns[0][1] = p_points[p_simplex.points[1]].x; + cm.columns[0][2] = p_points[p_simplex.points[2]].x; + cm.columns[0][3] = p_points[p_simplex.points[3]].x; + + cm.columns[1][0] = p_points[p_simplex.points[0]].y; + cm.columns[1][1] = p_points[p_simplex.points[1]].y; + cm.columns[1][2] = p_points[p_simplex.points[2]].y; + cm.columns[1][3] = p_points[p_simplex.points[3]].y; + + cm.columns[2][0] = p_points[p_simplex.points[0]].z; + cm.columns[2][1] = p_points[p_simplex.points[1]].z; + cm.columns[2][2] = p_points[p_simplex.points[2]].z; + cm.columns[2][3] = p_points[p_simplex.points[3]].z; + + cm.columns[3][0] = 1.0; + cm.columns[3][1] = 1.0; + cm.columns[3][2] = 1.0; + cm.columns[3][3] = 1.0; return ABS(cm.determinant()) <= CMP_EPSILON; } diff --git a/core/math/expression.cpp b/core/math/expression.cpp index e230b69dc9..dcec3929fe 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -560,7 +560,7 @@ const char *Expression::token_name[TK_MAX] = { }; Expression::ENode *Expression::_parse_expression() { - Vector<ExpressionNode> expression; + Vector<ExpressionNode> expression_nodes; while (true) { //keep appending stuff to expression @@ -838,14 +838,14 @@ Expression::ENode *Expression::_parse_expression() { ExpressionNode e; e.is_op = true; e.op = Variant::OP_NEGATE; - expression.push_back(e); + expression_nodes.push_back(e); continue; } break; case TK_OP_NOT: { ExpressionNode e; e.is_op = true; e.op = Variant::OP_NOT; - expression.push_back(e); + expression_nodes.push_back(e); continue; } break; @@ -960,7 +960,7 @@ Expression::ENode *Expression::_parse_expression() { ExpressionNode e; e.is_op = false; e.node = expr; - expression.push_back(e); + expression_nodes.push_back(e); } //ok finally look for an operator @@ -1054,19 +1054,19 @@ Expression::ENode *Expression::_parse_expression() { ExpressionNode e; e.is_op = true; e.op = op; - expression.push_back(e); + expression_nodes.push_back(e); } } /* Reduce the set of expressions and place them in an operator tree, respecting precedence */ - while (expression.size() > 1) { + while (expression_nodes.size() > 1) { int next_op = -1; int min_priority = 0xFFFFF; bool is_unary = false; - for (int i = 0; i < expression.size(); i++) { - if (!expression[i].is_op) { + for (int i = 0; i < expression_nodes.size(); i++) { + if (!expression_nodes[i].is_op) { continue; } @@ -1074,7 +1074,7 @@ Expression::ENode *Expression::_parse_expression() { bool unary = false; - switch (expression[i].op) { + switch (expression_nodes[i].op) { case Variant::OP_POWER: priority = 0; break; @@ -1130,7 +1130,7 @@ Expression::ENode *Expression::_parse_expression() { priority = 14; break; default: { - _set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op)); + _set_error("Parser bug, invalid operator in expression: " + itos(expression_nodes[i].op)); return nullptr; } } @@ -1153,9 +1153,9 @@ Expression::ENode *Expression::_parse_expression() { // OK! create operator.. if (is_unary) { int expr_pos = next_op; - while (expression[expr_pos].is_op) { + while (expression_nodes[expr_pos].is_op) { expr_pos++; - if (expr_pos == expression.size()) { + if (expr_pos == expression_nodes.size()) { //can happen.. _set_error("Unexpected end of expression..."); return nullptr; @@ -1165,29 +1165,29 @@ Expression::ENode *Expression::_parse_expression() { //consecutively do unary operators for (int i = expr_pos - 1; i >= next_op; i--) { OperatorNode *op = alloc_node<OperatorNode>(); - op->op = expression[i].op; - op->nodes[0] = expression[i + 1].node; + op->op = expression_nodes[i].op; + op->nodes[0] = expression_nodes[i + 1].node; op->nodes[1] = nullptr; - expression.write[i].is_op = false; - expression.write[i].node = op; - expression.remove_at(i + 1); + expression_nodes.write[i].is_op = false; + expression_nodes.write[i].node = op; + expression_nodes.remove_at(i + 1); } } else { - if (next_op < 1 || next_op >= (expression.size() - 1)) { + if (next_op < 1 || next_op >= (expression_nodes.size() - 1)) { _set_error("Parser bug..."); ERR_FAIL_V(nullptr); } OperatorNode *op = alloc_node<OperatorNode>(); - op->op = expression[next_op].op; + op->op = expression_nodes[next_op].op; - if (expression[next_op - 1].is_op) { + if (expression_nodes[next_op - 1].is_op) { _set_error("Parser bug..."); ERR_FAIL_V(nullptr); } - if (expression[next_op + 1].is_op) { + if (expression_nodes[next_op + 1].is_op) { // this is not invalid and can really appear // but it becomes invalid anyway because no binary op // can be followed by a unary op in a valid combination, @@ -1197,17 +1197,17 @@ Expression::ENode *Expression::_parse_expression() { return nullptr; } - op->nodes[0] = expression[next_op - 1].node; //expression goes as left - op->nodes[1] = expression[next_op + 1].node; //next expression goes as right + op->nodes[0] = expression_nodes[next_op - 1].node; //expression goes as left + op->nodes[1] = expression_nodes[next_op + 1].node; //next expression goes as right //replace all 3 nodes by this operator and make it an expression - expression.write[next_op - 1].node = op; - expression.remove_at(next_op); - expression.remove_at(next_op); + expression_nodes.write[next_op - 1].node = op; + expression_nodes.remove_at(next_op); + expression_nodes.remove_at(next_op); } } - return expression[0].node; + return expression_nodes[0].node; } bool Expression::_compile_expression() { diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index 9238293b48..548b9e4620 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -30,8 +30,6 @@ #include "geometry_3d.h" -#include "core/string/print_string.h" - #include "thirdparty/misc/clipper.hpp" #include "thirdparty/misc/polypartition.h" @@ -143,21 +141,21 @@ real_t Geometry3D::get_closest_distance_between_segments(const Vector3 &p_p0, co void Geometry3D::MeshData::optimize_vertices() { HashMap<int, int> vtx_remap; - for (int i = 0; i < faces.size(); i++) { - for (int j = 0; j < faces[i].indices.size(); j++) { + for (uint32_t i = 0; i < faces.size(); i++) { + for (uint32_t j = 0; j < faces[i].indices.size(); j++) { int idx = faces[i].indices[j]; if (!vtx_remap.has(idx)) { int ni = vtx_remap.size(); vtx_remap[idx] = ni; } - faces.write[i].indices.write[j] = vtx_remap[idx]; + faces[i].indices[j] = vtx_remap[idx]; } } - for (int i = 0; i < edges.size(); i++) { - int a = edges[i].a; - int b = edges[i].b; + for (uint32_t i = 0; i < edges.size(); i++) { + int a = edges[i].vertex_a; + int b = edges[i].vertex_b; if (!vtx_remap.has(a)) { int ni = vtx_remap.size(); @@ -168,16 +166,16 @@ void Geometry3D::MeshData::optimize_vertices() { vtx_remap[b] = ni; } - edges.write[i].a = vtx_remap[a]; - edges.write[i].b = vtx_remap[b]; + edges[i].vertex_a = vtx_remap[a]; + edges[i].vertex_b = vtx_remap[b]; } - Vector<Vector3> new_vertices; + LocalVector<Vector3> new_vertices; new_vertices.resize(vtx_remap.size()); - for (int i = 0; i < vertices.size(); i++) { + for (uint32_t i = 0; i < vertices.size(); i++) { if (vtx_remap.has(i)) { - new_vertices.write[vtx_remap[i]] = vertices[i]; + new_vertices[vtx_remap[i]] = vertices[i]; } } vertices = new_vertices; @@ -753,7 +751,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes Vector3 center = p.center(); // make a quad clockwise - Vector<Vector3> vertices = { + LocalVector<Vector3> vertices = { center - up * subplane_size + right * subplane_size, center - up * subplane_size - right * subplane_size, center + up * subplane_size - right * subplane_size, @@ -765,7 +763,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes continue; } - Vector<Vector3> new_vertices; + LocalVector<Vector3> new_vertices; Plane clip = p_planes[j]; if (clip.normal.dot(p.normal) > 0.95f) { @@ -776,7 +774,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes break; } - for (int k = 0; k < vertices.size(); k++) { + for (uint32_t k = 0; k < vertices.size(); k++) { int k_n = (k + 1) % vertices.size(); Vector3 edge0_A = vertices[k]; @@ -818,9 +816,9 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes MeshData::Face face; // Add face indices. - for (int j = 0; j < vertices.size(); j++) { + for (uint32_t j = 0; j < vertices.size(); j++) { int idx = -1; - for (int k = 0; k < mesh.vertices.size(); k++) { + for (uint32_t k = 0; k < mesh.vertices.size(); k++) { if (mesh.vertices[k].distance_to(vertices[j]) < 0.001f) { idx = k; break; @@ -839,28 +837,34 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes // Add edge. - for (int j = 0; j < face.indices.size(); j++) { + for (uint32_t j = 0; j < face.indices.size(); j++) { int a = face.indices[j]; int b = face.indices[(j + 1) % face.indices.size()]; bool found = false; - for (int k = 0; k < mesh.edges.size(); k++) { - if (mesh.edges[k].a == a && mesh.edges[k].b == b) { + int found_idx = -1; + for (uint32_t k = 0; k < mesh.edges.size(); k++) { + if (mesh.edges[k].vertex_a == a && mesh.edges[k].vertex_b == b) { found = true; + found_idx = k; break; } - if (mesh.edges[k].b == a && mesh.edges[k].a == b) { + if (mesh.edges[k].vertex_b == a && mesh.edges[k].vertex_a == b) { found = true; + found_idx = k; break; } } if (found) { + mesh.edges[found_idx].face_b = j; continue; } MeshData::Edge edge; - edge.a = a; - edge.b = b; + edge.vertex_a = a; + edge.vertex_b = b; + edge.face_a = j; + edge.face_b = -1; mesh.edges.push_back(edge); } } diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index e5ace9db72..4b4c173a1e 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -33,6 +33,7 @@ #include "core/math/face3.h" #include "core/object/object.h" +#include "core/templates/local_vector.h" #include "core/templates/vector.h" class Geometry3D { @@ -539,18 +540,19 @@ public: struct MeshData { struct Face { Plane plane; - Vector<int> indices; + LocalVector<int> indices; }; - Vector<Face> faces; + LocalVector<Face> faces; struct Edge { - int a, b; + int vertex_a, vertex_b; + int face_a, face_b; }; - Vector<Edge> edges; + LocalVector<Edge> edges; - Vector<Vector3> vertices; + LocalVector<Vector3> vertices; void optimize_vertices(); }; diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp index f36b228543..7b30b9a98c 100644 --- a/core/math/math_fieldwise.cpp +++ b/core/math/math_fieldwise.cpp @@ -56,6 +56,15 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } + case Variant::VECTOR2I: { + SETUP_TYPE(Vector2i) + + /**/ TRY_TRANSFER_FIELD("x", x) + else TRY_TRANSFER_FIELD("y", y) + + return target; + } + case Variant::RECT2: { SETUP_TYPE(Rect2) @@ -67,6 +76,17 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } + case Variant::RECT2I: { + SETUP_TYPE(Rect2i) + + /**/ TRY_TRANSFER_FIELD("x", position.x) + else TRY_TRANSFER_FIELD("y", position.y) + else TRY_TRANSFER_FIELD("w", size.x) + else TRY_TRANSFER_FIELD("h", size.y) + + return target; + } + case Variant::VECTOR3: { SETUP_TYPE(Vector3) @@ -192,6 +212,29 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } + case Variant::PROJECTION: { + SETUP_TYPE(Projection) + + /**/ TRY_TRANSFER_FIELD("xx", columns[0].x) + else TRY_TRANSFER_FIELD("xy", columns[0].y) + else TRY_TRANSFER_FIELD("xz", columns[0].z) + else TRY_TRANSFER_FIELD("xw", columns[0].w) + else TRY_TRANSFER_FIELD("yx", columns[1].x) + else TRY_TRANSFER_FIELD("yy", columns[1].y) + else TRY_TRANSFER_FIELD("yz", columns[1].z) + else TRY_TRANSFER_FIELD("yw", columns[1].w) + else TRY_TRANSFER_FIELD("zx", columns[2].x) + else TRY_TRANSFER_FIELD("zy", columns[2].y) + else TRY_TRANSFER_FIELD("zz", columns[2].z) + else TRY_TRANSFER_FIELD("zw", columns[2].w) + else TRY_TRANSFER_FIELD("xo", columns[3].x) + else TRY_TRANSFER_FIELD("yo", columns[3].y) + else TRY_TRANSFER_FIELD("zo", columns[3].z) + else TRY_TRANSFER_FIELD("wo", columns[3].w) + + return target; + } + default: { ERR_FAIL_V(p_target); } diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 7fa674a23d..0af529ad98 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -184,6 +184,9 @@ public: #endif } + static _ALWAYS_INLINE_ bool is_finite(double p_val) { return isfinite(p_val); } + static _ALWAYS_INLINE_ bool is_finite(float p_val) { return isfinite(p_val); } + static _ALWAYS_INLINE_ double abs(double g) { return absd(g); } static _ALWAYS_INLINE_ float abs(float g) { return absf(g); } static _ALWAYS_INLINE_ int abs(int g) { return g > 0 ? g : -g; } diff --git a/core/math/plane.cpp b/core/math/plane.cpp index 6881ad4014..a5d2fe5628 100644 --- a/core/math/plane.cpp +++ b/core/math/plane.cpp @@ -147,6 +147,7 @@ Variant Plane::intersect_3_bind(const Plane &p_plane1, const Plane &p_plane2) co return Variant(); } } + Variant Plane::intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const { Vector3 inters; if (intersects_ray(p_from, p_dir, &inters)) { @@ -155,6 +156,7 @@ Variant Plane::intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) return Variant(); } } + Variant Plane::intersects_segment_bind(const Vector3 &p_begin, const Vector3 &p_end) const { Vector3 inters; if (intersects_segment(p_begin, p_end, &inters)) { @@ -174,6 +176,10 @@ bool Plane::is_equal_approx(const Plane &p_plane) const { return normal.is_equal_approx(p_plane.normal) && Math::is_equal_approx(d, p_plane.d); } +bool Plane::is_finite() const { + return normal.is_finite() && Math::is_finite(d); +} + Plane::operator String() const { return "[N: " + normal.operator String() + ", D: " + String::num_real(d, false) + "]"; } diff --git a/core/math/plane.h b/core/math/plane.h index 73babfa496..77da59fb27 100644 --- a/core/math/plane.h +++ b/core/math/plane.h @@ -74,6 +74,7 @@ struct _NO_DISCARD_ Plane { Plane operator-() const { return Plane(-normal, -d); } bool is_equal_approx(const Plane &p_plane) const; bool is_equal_approx_any_side(const Plane &p_plane) const; + bool is_finite() const; _FORCE_INLINE_ bool operator==(const Plane &p_plane) const; _FORCE_INLINE_ bool operator!=(const Plane &p_plane) const; diff --git a/core/math/projection.cpp b/core/math/projection.cpp index 863fe6ee79..70cc9b5f7c 100644 --- a/core/math/projection.cpp +++ b/core/math/projection.cpp @@ -35,27 +35,27 @@ #include "core/math/plane.h" #include "core/math/rect2.h" #include "core/math/transform_3d.h" -#include "core/string/print_string.h" +#include "core/string/ustring.h" float Projection::determinant() const { - return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0] - matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0] - - matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0] + matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0] + - matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0] - matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0] - - matrix[0][3] * matrix[1][2] * matrix[2][0] * matrix[3][1] + matrix[0][2] * matrix[1][3] * matrix[2][0] * matrix[3][1] + - matrix[0][3] * matrix[1][0] * matrix[2][2] * matrix[3][1] - matrix[0][0] * matrix[1][3] * matrix[2][2] * matrix[3][1] - - matrix[0][2] * matrix[1][0] * matrix[2][3] * matrix[3][1] + matrix[0][0] * matrix[1][2] * matrix[2][3] * matrix[3][1] + - matrix[0][3] * matrix[1][1] * matrix[2][0] * matrix[3][2] - matrix[0][1] * matrix[1][3] * matrix[2][0] * matrix[3][2] - - matrix[0][3] * matrix[1][0] * matrix[2][1] * matrix[3][2] + matrix[0][0] * matrix[1][3] * matrix[2][1] * matrix[3][2] + - matrix[0][1] * matrix[1][0] * matrix[2][3] * matrix[3][2] - matrix[0][0] * matrix[1][1] * matrix[2][3] * matrix[3][2] - - matrix[0][2] * matrix[1][1] * matrix[2][0] * matrix[3][3] + matrix[0][1] * matrix[1][2] * matrix[2][0] * matrix[3][3] + - matrix[0][2] * matrix[1][0] * matrix[2][1] * matrix[3][3] - matrix[0][0] * matrix[1][2] * matrix[2][1] * matrix[3][3] - - matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3] + matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3]; + return columns[0][3] * columns[1][2] * columns[2][1] * columns[3][0] - columns[0][2] * columns[1][3] * columns[2][1] * columns[3][0] - + columns[0][3] * columns[1][1] * columns[2][2] * columns[3][0] + columns[0][1] * columns[1][3] * columns[2][2] * columns[3][0] + + columns[0][2] * columns[1][1] * columns[2][3] * columns[3][0] - columns[0][1] * columns[1][2] * columns[2][3] * columns[3][0] - + columns[0][3] * columns[1][2] * columns[2][0] * columns[3][1] + columns[0][2] * columns[1][3] * columns[2][0] * columns[3][1] + + columns[0][3] * columns[1][0] * columns[2][2] * columns[3][1] - columns[0][0] * columns[1][3] * columns[2][2] * columns[3][1] - + columns[0][2] * columns[1][0] * columns[2][3] * columns[3][1] + columns[0][0] * columns[1][2] * columns[2][3] * columns[3][1] + + columns[0][3] * columns[1][1] * columns[2][0] * columns[3][2] - columns[0][1] * columns[1][3] * columns[2][0] * columns[3][2] - + columns[0][3] * columns[1][0] * columns[2][1] * columns[3][2] + columns[0][0] * columns[1][3] * columns[2][1] * columns[3][2] + + columns[0][1] * columns[1][0] * columns[2][3] * columns[3][2] - columns[0][0] * columns[1][1] * columns[2][3] * columns[3][2] - + columns[0][2] * columns[1][1] * columns[2][0] * columns[3][3] + columns[0][1] * columns[1][2] * columns[2][0] * columns[3][3] + + columns[0][2] * columns[1][0] * columns[2][1] * columns[3][3] - columns[0][0] * columns[1][2] * columns[2][1] * columns[3][3] - + columns[0][1] * columns[1][0] * columns[2][2] * columns[3][3] + columns[0][0] * columns[1][1] * columns[2][2] * columns[3][3]; } void Projection::set_identity() { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - matrix[i][j] = (i == j) ? 1 : 0; + columns[i][j] = (i == j) ? 1 : 0; } } } @@ -63,7 +63,7 @@ void Projection::set_identity() { void Projection::set_zero() { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - matrix[i][j] = 0; + columns[i][j] = 0; } } } @@ -71,26 +71,26 @@ void Projection::set_zero() { Plane Projection::xform4(const Plane &p_vec4) const { Plane ret; - ret.normal.x = matrix[0][0] * p_vec4.normal.x + matrix[1][0] * p_vec4.normal.y + matrix[2][0] * p_vec4.normal.z + matrix[3][0] * p_vec4.d; - ret.normal.y = matrix[0][1] * p_vec4.normal.x + matrix[1][1] * p_vec4.normal.y + matrix[2][1] * p_vec4.normal.z + matrix[3][1] * p_vec4.d; - ret.normal.z = matrix[0][2] * p_vec4.normal.x + matrix[1][2] * p_vec4.normal.y + matrix[2][2] * p_vec4.normal.z + matrix[3][2] * p_vec4.d; - ret.d = matrix[0][3] * p_vec4.normal.x + matrix[1][3] * p_vec4.normal.y + matrix[2][3] * p_vec4.normal.z + matrix[3][3] * p_vec4.d; + ret.normal.x = columns[0][0] * p_vec4.normal.x + columns[1][0] * p_vec4.normal.y + columns[2][0] * p_vec4.normal.z + columns[3][0] * p_vec4.d; + ret.normal.y = columns[0][1] * p_vec4.normal.x + columns[1][1] * p_vec4.normal.y + columns[2][1] * p_vec4.normal.z + columns[3][1] * p_vec4.d; + ret.normal.z = columns[0][2] * p_vec4.normal.x + columns[1][2] * p_vec4.normal.y + columns[2][2] * p_vec4.normal.z + columns[3][2] * p_vec4.d; + ret.d = columns[0][3] * p_vec4.normal.x + columns[1][3] * p_vec4.normal.y + columns[2][3] * p_vec4.normal.z + columns[3][3] * p_vec4.d; return ret; } Vector4 Projection::xform(const Vector4 &p_vec4) const { return Vector4( - matrix[0][0] * p_vec4.x + matrix[1][0] * p_vec4.y + matrix[2][0] * p_vec4.z + matrix[3][0] * p_vec4.w, - matrix[0][1] * p_vec4.x + matrix[1][1] * p_vec4.y + matrix[2][1] * p_vec4.z + matrix[3][1] * p_vec4.w, - matrix[0][2] * p_vec4.x + matrix[1][2] * p_vec4.y + matrix[2][2] * p_vec4.z + matrix[3][2] * p_vec4.w, - matrix[0][3] * p_vec4.x + matrix[1][3] * p_vec4.y + matrix[2][3] * p_vec4.z + matrix[3][3] * p_vec4.w); + columns[0][0] * p_vec4.x + columns[1][0] * p_vec4.y + columns[2][0] * p_vec4.z + columns[3][0] * p_vec4.w, + columns[0][1] * p_vec4.x + columns[1][1] * p_vec4.y + columns[2][1] * p_vec4.z + columns[3][1] * p_vec4.w, + columns[0][2] * p_vec4.x + columns[1][2] * p_vec4.y + columns[2][2] * p_vec4.z + columns[3][2] * p_vec4.w, + columns[0][3] * p_vec4.x + columns[1][3] * p_vec4.y + columns[2][3] * p_vec4.z + columns[3][3] * p_vec4.w); } Vector4 Projection::xform_inv(const Vector4 &p_vec4) const { return Vector4( - matrix[0][0] * p_vec4.x + matrix[0][1] * p_vec4.y + matrix[0][2] * p_vec4.z + matrix[0][3] * p_vec4.w, - matrix[1][0] * p_vec4.x + matrix[1][1] * p_vec4.y + matrix[1][2] * p_vec4.z + matrix[1][3] * p_vec4.w, - matrix[2][0] * p_vec4.x + matrix[2][1] * p_vec4.y + matrix[2][2] * p_vec4.z + matrix[2][3] * p_vec4.w, - matrix[3][0] * p_vec4.x + matrix[3][1] * p_vec4.y + matrix[3][2] * p_vec4.z + matrix[3][3] * p_vec4.w); + columns[0][0] * p_vec4.x + columns[0][1] * p_vec4.y + columns[0][2] * p_vec4.z + columns[0][3] * p_vec4.w, + columns[1][0] * p_vec4.x + columns[1][1] * p_vec4.y + columns[1][2] * p_vec4.z + columns[1][3] * p_vec4.w, + columns[2][0] * p_vec4.x + columns[2][1] * p_vec4.y + columns[2][2] * p_vec4.z + columns[2][3] * p_vec4.w, + columns[3][0] * p_vec4.x + columns[3][1] * p_vec4.y + columns[3][2] * p_vec4.z + columns[3][3] * p_vec4.w); } void Projection::adjust_perspective_znear(real_t p_new_znear) { @@ -98,8 +98,8 @@ void Projection::adjust_perspective_znear(real_t p_new_znear) { real_t znear = p_new_znear; real_t deltaZ = zfar - znear; - matrix[2][2] = -(zfar + znear) / deltaZ; - matrix[3][2] = -2 * znear * zfar / deltaZ; + columns[2][2] = -(zfar + znear) / deltaZ; + columns[3][2] = -2 * znear * zfar / deltaZ; } Projection Projection::create_depth_correction(bool p_flip_y) { @@ -169,7 +169,7 @@ Projection Projection::perspective_znear_adjusted(real_t p_new_znear) const { } Plane Projection::get_projection_plane(Planes p_plane) const { - const real_t *matrix = (const real_t *)this->matrix; + const real_t *matrix = (const real_t *)columns; switch (p_plane) { case PLANE_NEAR: { @@ -267,12 +267,12 @@ void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t set_identity(); - matrix[0][0] = cotangent / p_aspect; - matrix[1][1] = cotangent; - matrix[2][2] = -(p_z_far + p_z_near) / deltaZ; - matrix[2][3] = -1; - matrix[3][2] = -2 * p_z_near * p_z_far / deltaZ; - matrix[3][3] = 0; + columns[0][0] = cotangent / p_aspect; + columns[1][1] = cotangent; + columns[2][2] = -(p_z_far + p_z_near) / deltaZ; + columns[2][3] = -1; + columns[3][2] = -2 * p_z_near * p_z_far / deltaZ; + columns[3][3] = 0; } void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) { @@ -309,7 +309,7 @@ void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t // translate matrix by (modeltranslation, 0.0, 0.0) Projection cm; cm.set_identity(); - cm.matrix[3][0] = modeltranslation; + cm.columns[3][0] = modeltranslation; *this = *this * cm; } @@ -344,13 +344,13 @@ void Projection::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_di void Projection::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) { set_identity(); - matrix[0][0] = 2.0 / (p_right - p_left); - matrix[3][0] = -((p_right + p_left) / (p_right - p_left)); - matrix[1][1] = 2.0 / (p_top - p_bottom); - matrix[3][1] = -((p_top + p_bottom) / (p_top - p_bottom)); - matrix[2][2] = -2.0 / (p_zfar - p_znear); - matrix[3][2] = -((p_zfar + p_znear) / (p_zfar - p_znear)); - matrix[3][3] = 1.0; + columns[0][0] = 2.0 / (p_right - p_left); + columns[3][0] = -((p_right + p_left) / (p_right - p_left)); + columns[1][1] = 2.0 / (p_top - p_bottom); + columns[3][1] = -((p_top + p_bottom) / (p_top - p_bottom)); + columns[2][2] = -2.0 / (p_zfar - p_znear); + columns[3][2] = -((p_zfar + p_znear) / (p_zfar - p_znear)); + columns[3][3] = 1.0; } void Projection::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) { @@ -366,7 +366,7 @@ void Projection::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, rea ERR_FAIL_COND(p_top <= p_bottom); ERR_FAIL_COND(p_far <= p_near); - real_t *te = &matrix[0][0]; + real_t *te = &columns[0][0]; real_t x = 2 * p_near / (p_right - p_left); real_t y = 2 * p_near / (p_top - p_bottom); @@ -402,7 +402,7 @@ void Projection::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, r } real_t Projection::get_z_far() const { - const real_t *matrix = (const real_t *)this->matrix; + const real_t *matrix = (const real_t *)columns; Plane new_plane = Plane(matrix[3] - matrix[2], matrix[7] - matrix[6], matrix[11] - matrix[10], @@ -415,7 +415,7 @@ real_t Projection::get_z_far() const { } real_t Projection::get_z_near() const { - const real_t *matrix = (const real_t *)this->matrix; + const real_t *matrix = (const real_t *)columns; Plane new_plane = Plane(matrix[3] + matrix[2], matrix[7] + matrix[6], matrix[11] + matrix[10], @@ -426,7 +426,7 @@ real_t Projection::get_z_near() const { } Vector2 Projection::get_viewport_half_extents() const { - const real_t *matrix = (const real_t *)this->matrix; + const real_t *matrix = (const real_t *)columns; ///////--- Near Plane ---/////// Plane near_plane = Plane(matrix[3] + matrix[2], matrix[7] + matrix[6], @@ -454,7 +454,7 @@ Vector2 Projection::get_viewport_half_extents() const { } Vector2 Projection::get_far_plane_half_extents() const { - const real_t *matrix = (const real_t *)this->matrix; + const real_t *matrix = (const real_t *)columns; ///////--- Far Plane ---/////// Plane far_plane = Plane(matrix[3] - matrix[2], matrix[7] - matrix[6], @@ -496,7 +496,10 @@ bool Projection::get_endpoints(const Transform3D &p_transform, Vector3 *p_8point for (int i = 0; i < 8; i++) { Vector3 point; - bool res = planes[intersections[i][0]].intersect_3(planes[intersections[i][1]], planes[intersections[i][2]], &point); + Plane a = planes[intersections[i][0]]; + Plane b = planes[intersections[i][1]]; + Plane c = planes[intersections[i][2]]; + bool res = a.intersect_3(b, c, &point); ERR_FAIL_COND_V(!res, false); p_8points[i] = p_transform.xform(point); } @@ -514,7 +517,7 @@ Vector<Plane> Projection::get_projection_planes(const Transform3D &p_transform) Vector<Plane> planes; planes.resize(6); - const real_t *matrix = (const real_t *)this->matrix; + const real_t *matrix = (const real_t *)columns; Plane new_plane; @@ -601,15 +604,15 @@ void Projection::invert() { real_t determinant = 1.0f; for (k = 0; k < 4; k++) { /** Locate k'th pivot element **/ - pvt_val = matrix[k][k]; /** Initialize for search **/ + pvt_val = columns[k][k]; /** Initialize for search **/ pvt_i[k] = k; pvt_j[k] = k; for (i = k; i < 4; i++) { for (j = k; j < 4; j++) { - if (Math::abs(matrix[i][j]) > Math::abs(pvt_val)) { + if (Math::abs(columns[i][j]) > Math::abs(pvt_val)) { pvt_i[k] = i; pvt_j[k] = j; - pvt_val = matrix[i][j]; + pvt_val = columns[i][j]; } } } @@ -624,9 +627,9 @@ void Projection::invert() { i = pvt_i[k]; if (i != k) { /** If rows are different **/ for (j = 0; j < 4; j++) { - hold = -matrix[k][j]; - matrix[k][j] = matrix[i][j]; - matrix[i][j] = hold; + hold = -columns[k][j]; + columns[k][j] = columns[i][j]; + columns[i][j] = hold; } } @@ -634,25 +637,25 @@ void Projection::invert() { j = pvt_j[k]; if (j != k) { /** If columns are different **/ for (i = 0; i < 4; i++) { - hold = -matrix[i][k]; - matrix[i][k] = matrix[i][j]; - matrix[i][j] = hold; + hold = -columns[i][k]; + columns[i][k] = columns[i][j]; + columns[i][j] = hold; } } /** Divide column by minus pivot value **/ for (i = 0; i < 4; i++) { if (i != k) { - matrix[i][k] /= (-pvt_val); + columns[i][k] /= (-pvt_val); } } /** Reduce the matrix **/ for (i = 0; i < 4; i++) { - hold = matrix[i][k]; + hold = columns[i][k]; for (j = 0; j < 4; j++) { if (i != k && j != k) { - matrix[i][j] += hold * matrix[k][j]; + columns[i][j] += hold * columns[k][j]; } } } @@ -660,12 +663,12 @@ void Projection::invert() { /** Divide row by pivot **/ for (j = 0; j < 4; j++) { if (j != k) { - matrix[k][j] /= pvt_val; + columns[k][j] /= pvt_val; } } /** Replace pivot by reciprocal (at last we can touch it). **/ - matrix[k][k] = 1.0 / pvt_val; + columns[k][k] = 1.0 / pvt_val; } /* That was most of the work, one final pass of row/column interchange */ @@ -674,18 +677,18 @@ void Projection::invert() { i = pvt_j[k]; /* Rows to swap correspond to pivot COLUMN */ if (i != k) { /* If rows are different */ for (j = 0; j < 4; j++) { - hold = matrix[k][j]; - matrix[k][j] = -matrix[i][j]; - matrix[i][j] = hold; + hold = columns[k][j]; + columns[k][j] = -columns[i][j]; + columns[i][j] = hold; } } j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */ if (j != k) { /* If columns are different */ for (i = 0; i < 4; i++) { - hold = matrix[i][k]; - matrix[i][k] = -matrix[i][j]; - matrix[i][j] = hold; + hold = columns[i][k]; + columns[i][k] = -columns[i][j]; + columns[i][j] = hold; } } } @@ -693,7 +696,7 @@ void Projection::invert() { void Projection::flip_y() { for (int i = 0; i < 4; i++) { - matrix[1][i] = -matrix[1][i]; + columns[1][i] = -columns[1][i]; } } @@ -708,9 +711,9 @@ Projection Projection::operator*(const Projection &p_matrix) const { for (int i = 0; i < 4; i++) { real_t ab = 0; for (int k = 0; k < 4; k++) { - ab += matrix[k][i] * p_matrix.matrix[j][k]; + ab += columns[k][i] * p_matrix.columns[j][k]; } - new_matrix.matrix[j][i] = ab; + new_matrix.columns[j][i] = ab; } } @@ -718,7 +721,7 @@ Projection Projection::operator*(const Projection &p_matrix) const { } void Projection::set_depth_correction(bool p_flip_y) { - real_t *m = &matrix[0][0]; + real_t *m = &columns[0][0]; m[0] = 1; m[1] = 0.0; @@ -739,7 +742,7 @@ void Projection::set_depth_correction(bool p_flip_y) { } void Projection::set_light_bias() { - real_t *m = &matrix[0][0]; + real_t *m = &columns[0][0]; m[0] = 0.5; m[1] = 0.0; @@ -760,7 +763,7 @@ void Projection::set_light_bias() { } void Projection::set_light_atlas_rect(const Rect2 &p_rect) { - real_t *m = &matrix[0][0]; + real_t *m = &columns[0][0]; m[0] = p_rect.size.width; m[1] = 0.0; @@ -784,7 +787,7 @@ Projection::operator String() const { String str; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - str += String((j > 0) ? ", " : "\n") + rtos(matrix[i][j]); + str += String((j > 0) ? ", " : "\n") + rtos(columns[i][j]); } } @@ -803,11 +806,11 @@ int Projection::get_pixels_per_meter(int p_for_pixel_width) const { } bool Projection::is_orthogonal() const { - return matrix[3][3] == 1.0; + return columns[3][3] == 1.0; } real_t Projection::get_fov() const { - const real_t *matrix = (const real_t *)this->matrix; + const real_t *matrix = (const real_t *)columns; Plane right_plane = Plane(matrix[3] - matrix[0], matrix[7] - matrix[4], @@ -838,48 +841,49 @@ float Projection::get_lod_multiplier() const { return 1.0 / (zn / width); } - //usage is lod_size / (lod_distance * multiplier) < threshold + // Usage is lod_size / (lod_distance * multiplier) < threshold } + void Projection::make_scale(const Vector3 &p_scale) { set_identity(); - matrix[0][0] = p_scale.x; - matrix[1][1] = p_scale.y; - matrix[2][2] = p_scale.z; + columns[0][0] = p_scale.x; + columns[1][1] = p_scale.y; + columns[2][2] = p_scale.z; } void Projection::scale_translate_to_fit(const AABB &p_aabb) { Vector3 min = p_aabb.position; Vector3 max = p_aabb.position + p_aabb.size; - matrix[0][0] = 2 / (max.x - min.x); - matrix[1][0] = 0; - matrix[2][0] = 0; - matrix[3][0] = -(max.x + min.x) / (max.x - min.x); + columns[0][0] = 2 / (max.x - min.x); + columns[1][0] = 0; + columns[2][0] = 0; + columns[3][0] = -(max.x + min.x) / (max.x - min.x); - matrix[0][1] = 0; - matrix[1][1] = 2 / (max.y - min.y); - matrix[2][1] = 0; - matrix[3][1] = -(max.y + min.y) / (max.y - min.y); + columns[0][1] = 0; + columns[1][1] = 2 / (max.y - min.y); + columns[2][1] = 0; + columns[3][1] = -(max.y + min.y) / (max.y - min.y); - matrix[0][2] = 0; - matrix[1][2] = 0; - matrix[2][2] = 2 / (max.z - min.z); - matrix[3][2] = -(max.z + min.z) / (max.z - min.z); + columns[0][2] = 0; + columns[1][2] = 0; + columns[2][2] = 2 / (max.z - min.z); + columns[3][2] = -(max.z + min.z) / (max.z - min.z); - matrix[0][3] = 0; - matrix[1][3] = 0; - matrix[2][3] = 0; - matrix[3][3] = 1; + columns[0][3] = 0; + columns[1][3] = 0; + columns[2][3] = 0; + columns[3][3] = 1; } void Projection::add_jitter_offset(const Vector2 &p_offset) { - matrix[3][0] += p_offset.x; - matrix[3][1] += p_offset.y; + columns[3][0] += p_offset.x; + columns[3][1] += p_offset.y; } Projection::operator Transform3D() const { Transform3D tr; - const real_t *m = &matrix[0][0]; + const real_t *m = &columns[0][0]; tr.basis.rows[0][0] = m[0]; tr.basis.rows[1][0] = m[1]; @@ -899,15 +903,17 @@ Projection::operator Transform3D() const { return tr; } + Projection::Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) { - matrix[0] = p_x; - matrix[1] = p_y; - matrix[2] = p_z; - matrix[3] = p_w; + columns[0] = p_x; + columns[1] = p_y; + columns[2] = p_z; + columns[3] = p_w; } + Projection::Projection(const Transform3D &p_transform) { const Transform3D &tr = p_transform; - real_t *m = &matrix[0][0]; + real_t *m = &columns[0][0]; m[0] = tr.basis.rows[0][0]; m[1] = tr.basis.rows[1][0]; diff --git a/core/math/projection.h b/core/math/projection.h index f149d307b3..38fb9781ae 100644 --- a/core/math/projection.h +++ b/core/math/projection.h @@ -31,10 +31,11 @@ #ifndef PROJECTION_H #define PROJECTION_H -#include "core/math/math_defs.h" #include "core/math/vector3.h" #include "core/math/vector4.h" -#include "core/templates/vector.h" + +template <class T> +class Vector; struct AABB; struct Plane; @@ -42,7 +43,7 @@ struct Rect2; struct Transform3D; struct Vector2; -struct Projection { +struct _NO_DISCARD_ Projection { enum Planes { PLANE_NEAR, PLANE_FAR, @@ -52,16 +53,16 @@ struct Projection { PLANE_BOTTOM }; - Vector4 matrix[4]; + Vector4 columns[4]; _FORCE_INLINE_ const Vector4 &operator[](const int p_axis) const { DEV_ASSERT((unsigned int)p_axis < 4); - return matrix[p_axis]; + return columns[p_axis]; } _FORCE_INLINE_ Vector4 &operator[](const int p_axis) { DEV_ASSERT((unsigned int)p_axis < 4); - return matrix[p_axis]; + return columns[p_axis]; } float determinant() const; @@ -135,7 +136,7 @@ struct Projection { bool operator==(const Projection &p_cam) const { for (uint32_t i = 0; i < 4; i++) { for (uint32_t j = 0; j < 4; j++) { - if (matrix[i][j] != p_cam.matrix[i][j]) { + if (columns[i][j] != p_cam.columns[i][j]) { return false; } } @@ -157,10 +158,10 @@ struct Projection { Vector3 Projection::xform(const Vector3 &p_vec3) const { Vector3 ret; - ret.x = matrix[0][0] * p_vec3.x + matrix[1][0] * p_vec3.y + matrix[2][0] * p_vec3.z + matrix[3][0]; - ret.y = matrix[0][1] * p_vec3.x + matrix[1][1] * p_vec3.y + matrix[2][1] * p_vec3.z + matrix[3][1]; - ret.z = matrix[0][2] * p_vec3.x + matrix[1][2] * p_vec3.y + matrix[2][2] * p_vec3.z + matrix[3][2]; - real_t w = matrix[0][3] * p_vec3.x + matrix[1][3] * p_vec3.y + matrix[2][3] * p_vec3.z + matrix[3][3]; + ret.x = columns[0][0] * p_vec3.x + columns[1][0] * p_vec3.y + columns[2][0] * p_vec3.z + columns[3][0]; + ret.y = columns[0][1] * p_vec3.x + columns[1][1] * p_vec3.y + columns[2][1] * p_vec3.z + columns[3][1]; + ret.z = columns[0][2] * p_vec3.x + columns[1][2] * p_vec3.y + columns[2][2] * p_vec3.z + columns[3][2]; + real_t w = columns[0][3] * p_vec3.x + columns[1][3] * p_vec3.y + columns[2][3] * p_vec3.z + columns[3][3]; return ret / w; } diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index c836a82e37..6a5f29f3d8 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -31,7 +31,7 @@ #include "quaternion.h" #include "core/math/basis.h" -#include "core/string/print_string.h" +#include "core/string/ustring.h" real_t Quaternion::angle_to(const Quaternion &p_to) const { real_t d = dot(p_to); @@ -79,6 +79,10 @@ bool Quaternion::is_equal_approx(const Quaternion &p_quaternion) const { return Math::is_equal_approx(x, p_quaternion.x) && Math::is_equal_approx(y, p_quaternion.y) && Math::is_equal_approx(z, p_quaternion.z) && Math::is_equal_approx(w, p_quaternion.w); } +bool Quaternion::is_finite() const { + return Math::is_finite(x) && Math::is_finite(y) && Math::is_finite(z) && Math::is_finite(w); +} + real_t Quaternion::length() const { return Math::sqrt(length_squared()); } diff --git a/core/math/quaternion.h b/core/math/quaternion.h index 43d7bffcfc..7aa400aa8c 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -31,10 +31,10 @@ #ifndef QUATERNION_H #define QUATERNION_H -#include "core/math/math_defs.h" #include "core/math/math_funcs.h" #include "core/math/vector3.h" -#include "core/string/ustring.h" + +class String; struct _NO_DISCARD_ Quaternion { union { @@ -55,6 +55,7 @@ struct _NO_DISCARD_ Quaternion { } _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Quaternion &p_quaternion) const; + bool is_finite() const; real_t length() const; void normalize(); Quaternion normalized() const; @@ -143,8 +144,7 @@ struct _NO_DISCARD_ Quaternion { w = p_q.w; } - Quaternion(const Vector3 &v0, const Vector3 &v1) // shortest arc - { + Quaternion(const Vector3 &v0, const Vector3 &v1) { // Shortest arc. Vector3 c = v0.cross(v1); real_t d = v0.dot(v1); diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index c7727a44a1..c194e1cc21 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -369,7 +369,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ for (List<Geometry3D::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) { Geometry3D::MeshData::Face &f = E->get(); - for (int i = 0; i < f.indices.size(); i++) { + for (uint32_t i = 0; i < f.indices.size(); i++) { int a = E->get().indices[i]; int b = E->get().indices[(i + 1) % f.indices.size()]; Edge e(a, b); @@ -436,17 +436,24 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ r_mesh.faces.clear(); r_mesh.faces.resize(ret_faces.size()); + HashMap<List<Geometry3D::MeshData::Face>::Element *, int> face_indices; + int idx = 0; - for (const Geometry3D::MeshData::Face &E : ret_faces) { - r_mesh.faces.write[idx++] = E; + for (List<Geometry3D::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) { + face_indices[E] = idx; + r_mesh.faces[idx++] = E->get(); } r_mesh.edges.resize(ret_edges.size()); idx = 0; for (const KeyValue<Edge, RetFaceConnect> &E : ret_edges) { Geometry3D::MeshData::Edge e; - e.a = E.key.vertices[0]; - e.b = E.key.vertices[1]; - r_mesh.edges.write[idx++] = e; + e.vertex_a = E.key.vertices[0]; + e.vertex_b = E.key.vertices[1]; + ERR_CONTINUE(!face_indices.has(E.value.left)); + ERR_CONTINUE(!face_indices.has(E.value.right)); + e.face_a = face_indices[E.value.left]; + e.face_b = face_indices[E.value.right]; + r_mesh.edges[idx++] = e; } r_mesh.vertices = p_points; diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h index 9352bae0a6..bf67154cd6 100644 --- a/core/math/random_number_generator.h +++ b/core/math/random_number_generator.h @@ -57,7 +57,7 @@ public: _FORCE_INLINE_ real_t randfn(real_t p_mean = 0.0, real_t p_deviation = 1.0) { return randbase.randfn(p_mean, p_deviation); } _FORCE_INLINE_ int randi_range(int p_from, int p_to) { return randbase.random(p_from, p_to); } - RandomNumberGenerator() {} + RandomNumberGenerator() { randbase.randomize(); } }; #endif // RANDOM_NUMBER_GENERATOR_H diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp index 9e78ead816..facf4eb3c4 100644 --- a/core/math/rect2.cpp +++ b/core/math/rect2.cpp @@ -38,6 +38,10 @@ bool Rect2::is_equal_approx(const Rect2 &p_rect) const { return position.is_equal_approx(p_rect.position) && size.is_equal_approx(p_rect.size); } +bool Rect2::is_finite() const { + return position.is_finite() && size.is_finite(); +} + bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0)) { diff --git a/core/math/rect2.h b/core/math/rect2.h index 2d1be3d4f3..9863405d8e 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -178,7 +178,7 @@ struct _NO_DISCARD_ Rect2 { new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); - new_rect.size = new_rect.size - new_rect.position; //make relative again + new_rect.size = new_rect.size - new_rect.position; // Make relative again. return new_rect; } @@ -207,6 +207,7 @@ struct _NO_DISCARD_ Rect2 { } bool is_equal_approx(const Rect2 &p_rect) const; + bool is_finite() const; bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } @@ -253,7 +254,7 @@ struct _NO_DISCARD_ Rect2 { return r; } - inline void expand_to(const Vector2 &p_vector) { //in place function for speed + inline void expand_to(const Vector2 &p_vector) { // In place function for speed. #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0)) { ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size."); @@ -281,7 +282,7 @@ struct _NO_DISCARD_ Rect2 { } _FORCE_INLINE_ Rect2 abs() const { - return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); + return Rect2(Point2(position.x + MIN(size.x, (real_t)0), position.y + MIN(size.y, (real_t)0)), size.abs()); } Vector2 get_support(const Vector2 &p_normal) const { @@ -311,7 +312,7 @@ struct _NO_DISCARD_ Rect2 { continue; } - //check inside + // Check inside. Vector2 tg = r.orthogonal(); float s = tg.dot(center) - tg.dot(a); if (s < 0.0f) { @@ -320,7 +321,7 @@ struct _NO_DISCARD_ Rect2 { side_minus++; } - //check ray box + // Check ray box. r /= l; Vector2 ir(1.0f / r.x, 1.0f / r.y); @@ -341,7 +342,7 @@ struct _NO_DISCARD_ Rect2 { } if (side_plus * side_minus == 0) { - return true; //all inside + return true; // All inside. } else { return false; } diff --git a/core/math/rect2i.h b/core/math/rect2i.h index 2b58dcdd98..c92f2cae02 100644 --- a/core/math/rect2i.h +++ b/core/math/rect2i.h @@ -121,7 +121,7 @@ struct _NO_DISCARD_ Rect2i { new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); - new_rect.size = new_rect.size - new_rect.position; //make relative again + new_rect.size = new_rect.size - new_rect.position; // Make relative again. return new_rect; } diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 226076029b..548a82d254 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -168,6 +168,10 @@ bool Transform2D::is_equal_approx(const Transform2D &p_transform) const { return columns[0].is_equal_approx(p_transform.columns[0]) && columns[1].is_equal_approx(p_transform.columns[1]) && columns[2].is_equal_approx(p_transform.columns[2]); } +bool Transform2D::is_finite() const { + return columns[0].is_finite() && columns[1].is_finite() && columns[2].is_finite(); +} + Transform2D Transform2D::looking_at(const Vector2 &p_target) const { Transform2D return_trans = Transform2D(get_rotation(), get_origin()); Vector2 target_position = affine_inverse().xform(p_target); @@ -282,7 +286,7 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, const real_t dot = v1.dot(v2); - dot = CLAMP(dot, -1.0f, 1.0f); + dot = CLAMP(dot, (real_t)-1.0, (real_t)1.0); Vector2 v; diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index f23f32867a..2b11f36535 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -98,6 +98,7 @@ struct _NO_DISCARD_ Transform2D { void orthonormalize(); Transform2D orthonormalized() const; bool is_equal_approx(const Transform2D &p_transform) const; + bool is_finite() const; Transform2D looking_at(const Vector2 &p_target) const; diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp index 2de9e81b38..3285cbd664 100644 --- a/core/math/transform_3d.cpp +++ b/core/math/transform_3d.cpp @@ -31,7 +31,7 @@ #include "transform_3d.h" #include "core/math/math_funcs.h" -#include "core/string/print_string.h" +#include "core/string/ustring.h" void Transform3D::affine_invert() { basis.invert(); @@ -174,6 +174,10 @@ bool Transform3D::is_equal_approx(const Transform3D &p_transform) const { return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin); } +bool Transform3D::is_finite() const { + return basis.is_finite() && origin.is_finite(); +} + bool Transform3D::operator==(const Transform3D &p_transform) const { return (basis == p_transform.basis && origin == p_transform.origin); } diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index c62e4a7b0e..cb347aa1c1 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -34,6 +34,7 @@ #include "core/math/aabb.h" #include "core/math/basis.h" #include "core/math/plane.h" +#include "core/templates/vector.h" struct _NO_DISCARD_ Transform3D { Basis basis; @@ -74,6 +75,7 @@ struct _NO_DISCARD_ Transform3D { void orthogonalize(); Transform3D orthogonalized() const; bool is_equal_approx(const Transform3D &p_transform) const; + bool is_finite() const; bool operator==(const Transform3D &p_transform) const; bool operator!=(const Transform3D &p_transform) const; diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 4433559e6d..6515c55a85 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -215,10 +215,8 @@ Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const { switch (stack[level] >> VISITED_BIT_SHIFT) { case TEST_AABB_BIT: { - bool valid = b.aabb.intersects(p_aabb); - if (!valid) { + if (!b.aabb.intersects(p_aabb)) { stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - } else { if (b.face_index >= 0) { const Triangle &s = triangleptr[b.face_index]; @@ -302,12 +300,8 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en switch (stack[level] >> VISITED_BIT_SHIFT) { case TEST_AABB_BIT: { - bool valid = b.aabb.intersects_segment(p_begin, p_end); - //bool valid = b.aabb.intersects(ray_aabb); - - if (!valid) { + if (!b.aabb.intersects_segment(p_begin, p_end)) { stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - } else { if (b.face_index >= 0) { const Triangle &s = triangleptr[b.face_index]; @@ -407,10 +401,8 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V switch (stack[level] >> VISITED_BIT_SHIFT) { case TEST_AABB_BIT: { - bool valid = b.aabb.intersects_ray(p_begin, p_dir); - if (!valid) { + if (!b.aabb.intersects_ray(p_begin, p_dir)) { stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - } else { if (b.face_index >= 0) { const Triangle &s = triangleptr[b.face_index]; @@ -508,10 +500,8 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou switch (stack[level] >> VISITED_BIT_SHIFT) { case TEST_AABB_BIT: { - bool valid = b.aabb.intersects_convex_shape(p_planes, p_plane_count, p_points, p_point_count); - if (!valid) { + if (!b.aabb.intersects_convex_shape(p_planes, p_plane_count, p_points, p_point_count)) { stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - } else { if (b.face_index >= 0) { const Triangle &s = triangleptr[b.face_index]; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 56dbba393a..5366587126 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -186,6 +186,10 @@ bool Vector2::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y); } +bool Vector2::is_finite() const { + return Math::is_finite(x) && Math::is_finite(y); +} + Vector2::operator String() const { return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ")"; } diff --git a/core/math/vector2.h b/core/math/vector2.h index 9441f84087..5775d8e735 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -69,10 +69,6 @@ struct _NO_DISCARD_ Vector2 { return coord[p_idx]; } - _FORCE_INLINE_ void set_all(const real_t p_value) { - x = y = p_value; - } - _FORCE_INLINE_ Vector2::Axis min_axis_index() const { return x < y ? Vector2::AXIS_X : Vector2::AXIS_Y; } @@ -125,6 +121,7 @@ struct _NO_DISCARD_ Vector2 { bool is_equal_approx(const Vector2 &p_v) const; bool is_zero_approx() const; + bool is_finite() const; Vector2 operator+(const Vector2 &p_v) const; void operator+=(const Vector2 &p_v); diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 4db45fe798..b106200c4a 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -45,16 +45,6 @@ Vector3 Vector3::rotated(const Vector3 &p_axis, const real_t p_angle) const { return r; } -void Vector3::set_axis(const int p_axis, const real_t p_value) { - ERR_FAIL_INDEX(p_axis, 3); - coord[p_axis] = p_value; -} - -real_t Vector3::get_axis(const int p_axis) const { - ERR_FAIL_INDEX_V(p_axis, 3, 0); - return operator[](p_axis); -} - Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const { return Vector3( CLAMP(x, p_min.x, p_max.x), @@ -149,6 +139,10 @@ bool Vector3::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z); } +bool Vector3::is_finite() const { + return Math::is_finite(x) && Math::is_finite(y) && Math::is_finite(z); +} + Vector3::operator String() const { return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ")"; } diff --git a/core/math/vector3.h b/core/math/vector3.h index 3944afa92e..19771eb312 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -68,13 +68,6 @@ struct _NO_DISCARD_ Vector3 { return coord[p_axis]; } - void set_axis(const int p_axis, const real_t p_value); - real_t get_axis(const int p_axis) const; - - _FORCE_INLINE_ void set_all(const real_t p_value) { - x = y = z = p_value; - } - _FORCE_INLINE_ Vector3::Axis min_axis_index() const { return x < y ? (x < z ? Vector3::AXIS_X : Vector3::AXIS_Z) : (y < z ? Vector3::AXIS_Y : Vector3::AXIS_Z); } @@ -143,6 +136,7 @@ struct _NO_DISCARD_ Vector3 { bool is_equal_approx(const Vector3 &p_v) const; bool is_zero_approx() const; + bool is_finite() const; /* Operators */ diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp index b8e74ea6d2..b248f35035 100644 --- a/core/math/vector3i.cpp +++ b/core/math/vector3i.cpp @@ -33,16 +33,6 @@ #include "core/math/vector3.h" #include "core/string/ustring.h" -void Vector3i::set_axis(const int p_axis, const int32_t p_value) { - ERR_FAIL_INDEX(p_axis, 3); - coord[p_axis] = p_value; -} - -int32_t Vector3i::get_axis(const int p_axis) const { - ERR_FAIL_INDEX_V(p_axis, 3, 0); - return operator[](p_axis); -} - Vector3i::Axis Vector3i::min_axis_index() const { return x < y ? (x < z ? Vector3i::AXIS_X : Vector3i::AXIS_Z) : (y < z ? Vector3i::AXIS_Y : Vector3i::AXIS_Z); } diff --git a/core/math/vector3i.h b/core/math/vector3i.h index c6d03cd031..710fd96376 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -66,9 +66,6 @@ struct _NO_DISCARD_ Vector3i { return coord[p_axis]; } - void set_axis(const int p_axis, const int32_t p_value); - int32_t get_axis(const int p_axis) const; - Vector3i::Axis min_axis_index() const; Vector3i::Axis max_axis_index() const; diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp index 3c25f454a3..3b189f7ed4 100644 --- a/core/math/vector4.cpp +++ b/core/math/vector4.cpp @@ -30,18 +30,7 @@ #include "vector4.h" -#include "core/math/basis.h" -#include "core/string/print_string.h" - -void Vector4::set_axis(const int p_axis, const real_t p_value) { - ERR_FAIL_INDEX(p_axis, 4); - components[p_axis] = p_value; -} - -real_t Vector4::get_axis(const int p_axis) const { - ERR_FAIL_INDEX_V(p_axis, 4, 0); - return operator[](p_axis); -} +#include "core/string/ustring.h" Vector4::Axis Vector4::min_axis_index() const { uint32_t min_index = 0; @@ -75,6 +64,10 @@ bool Vector4::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z) && Math::is_zero_approx(w); } +bool Vector4::is_finite() const { + return Math::is_finite(x) && Math::is_finite(y) && Math::is_finite(z) && Math::is_finite(w); +} + real_t Vector4::length() const { return Math::sqrt(length_squared()); } diff --git a/core/math/vector4.h b/core/math/vector4.h index d89f3ddb05..7c4bdc1788 100644 --- a/core/math/vector4.h +++ b/core/math/vector4.h @@ -31,10 +31,10 @@ #ifndef VECTOR4_H #define VECTOR4_H -#include "core/math/math_defs.h" +#include "core/error/error_macros.h" #include "core/math/math_funcs.h" -#include "core/math/vector3.h" -#include "core/string/ustring.h" + +class String; struct _NO_DISCARD_ Vector4 { static const int AXIS_COUNT = 4; @@ -65,17 +65,13 @@ struct _NO_DISCARD_ Vector4 { return components[p_axis]; } - _FORCE_INLINE_ void set_all(const real_t p_value); - - void set_axis(const int p_axis, const real_t p_value); - real_t get_axis(const int p_axis) const; - Vector4::Axis min_axis_index() const; Vector4::Axis max_axis_index() const; _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Vector4 &p_vec4) const; bool is_zero_approx() const; + bool is_finite() const; real_t length() const; void normalize(); Vector4 normalized() const; @@ -150,10 +146,6 @@ struct _NO_DISCARD_ Vector4 { } }; -void Vector4::set_all(const real_t p_value) { - x = y = z = p_value; -} - real_t Vector4::dot(const Vector4 &p_vec4) const { return x * p_vec4.x + y * p_vec4.y + z * p_vec4.z + w * p_vec4.w; } diff --git a/core/math/vector4i.cpp b/core/math/vector4i.cpp index a89b802675..77f6fbd5b7 100644 --- a/core/math/vector4i.cpp +++ b/core/math/vector4i.cpp @@ -33,16 +33,6 @@ #include "core/math/vector4.h" #include "core/string/ustring.h" -void Vector4i::set_axis(const int p_axis, const int32_t p_value) { - ERR_FAIL_INDEX(p_axis, 4); - coord[p_axis] = p_value; -} - -int32_t Vector4i::get_axis(const int p_axis) const { - ERR_FAIL_INDEX_V(p_axis, 4, 0); - return operator[](p_axis); -} - Vector4i::Axis Vector4i::min_axis_index() const { uint32_t min_index = 0; int32_t min_value = x; diff --git a/core/math/vector4i.h b/core/math/vector4i.h index fdf33b9569..a32414bb18 100644 --- a/core/math/vector4i.h +++ b/core/math/vector4i.h @@ -68,9 +68,6 @@ struct _NO_DISCARD_ Vector4i { return coord[p_axis]; } - void set_axis(const int p_axis, const int32_t p_value); - int32_t get_axis(const int p_axis) const; - Vector4i::Axis min_axis_index() const; Vector4i::Axis max_axis_index() const; |