diff options
Diffstat (limited to 'core/math')
| -rw-r--r-- | core/math/a_star.h | 1 | ||||
| -rw-r--r-- | core/math/a_star_grid_2d.cpp | 80 | ||||
| -rw-r--r-- | core/math/a_star_grid_2d.h | 20 | ||||
| -rw-r--r-- | core/math/basis.cpp | 8 | ||||
| -rw-r--r-- | core/math/basis.h | 1 | ||||
| -rw-r--r-- | core/math/disjoint_set.h | 2 | ||||
| -rw-r--r-- | core/math/dynamic_bvh.h | 2 | ||||
| -rw-r--r-- | core/math/math_funcs.h | 11 | ||||
| -rw-r--r-- | core/math/projection.cpp | 1 | ||||
| -rw-r--r-- | core/math/transform_2d.cpp | 12 | ||||
| -rw-r--r-- | core/math/transform_2d.h | 1 |
11 files changed, 85 insertions, 54 deletions
diff --git a/core/math/a_star.h b/core/math/a_star.h index fc4bb09f03..0758500c8a 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -33,7 +33,6 @@ #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" -#include "core/object/script_language.h" #include "core/templates/oa_hash_map.h" /** diff --git a/core/math/a_star_grid_2d.cpp b/core/math/a_star_grid_2d.cpp index 9ba4c2ff9a..379d34aa2a 100644 --- a/core/math/a_star_grid_2d.cpp +++ b/core/math/a_star_grid_2d.cpp @@ -32,9 +32,7 @@ #include "core/variant/typed_array.h" -#define GET_POINT_UNCHECKED(m_id) points[m_id.y - region.position.y][m_id.x - region.position.x] - -static real_t heuristic_euclidian(const Vector2i &p_from, const Vector2i &p_to) { +static real_t heuristic_euclidean(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); return (real_t)Math::sqrt(dx * dx + dy * dy); @@ -59,7 +57,7 @@ static real_t heuristic_chebyshev(const Vector2i &p_from, const Vector2i &p_to) return MAX(dx, dy); } -static real_t (*heuristics[AStarGrid2D::HEURISTIC_MAX])(const Vector2i &, const Vector2i &) = { heuristic_euclidian, heuristic_manhattan, heuristic_octile, heuristic_chebyshev }; +static real_t (*heuristics[AStarGrid2D::HEURISTIC_MAX])(const Vector2i &, const Vector2i &) = { heuristic_euclidean, heuristic_manhattan, heuristic_octile, heuristic_chebyshev }; void AStarGrid2D::set_region(const Rect2i &p_region) { ERR_FAIL_COND(p_region.size.x < 0 || p_region.size.y < 0); @@ -110,19 +108,22 @@ Size2 AStarGrid2D::get_cell_size() const { void AStarGrid2D::update() { points.clear(); - const int64_t end_x = region.position.x + region.size.width; - const int64_t end_y = region.position.y + region.size.height; - for (int64_t y = region.position.y; y < end_y; y++) { + + const int32_t end_x = region.get_end().x; + const int32_t end_y = region.get_end().y; + + for (int32_t y = region.position.y; y < end_y; y++) { LocalVector<Point> line; - for (int64_t x = region.position.x; x < end_x; x++) { + for (int32_t x = region.position.x; x < end_x; x++) { line.push_back(Point(Vector2i(x, y), offset + Vector2(x, y) * cell_size)); } points.push_back(line); } + dirty = false; } -bool AStarGrid2D::is_in_bounds(int p_x, int p_y) const { +bool AStarGrid2D::is_in_bounds(int32_t p_x, int32_t p_y) const { return region.has_point(Vector2i(p_x, p_y)); } @@ -172,40 +173,38 @@ AStarGrid2D::Heuristic AStarGrid2D::get_default_estimate_heuristic() const { void AStarGrid2D::set_point_solid(const Vector2i &p_id, bool p_solid) { ERR_FAIL_COND_MSG(dirty, "Grid is not initialized. Call the update method."); ERR_FAIL_COND_MSG(!is_in_boundsv(p_id), vformat("Can't set if point is disabled. Point %s out of bounds %s.", p_id, region)); - GET_POINT_UNCHECKED(p_id).solid = p_solid; + _get_point_unchecked(p_id)->solid = p_solid; } bool AStarGrid2D::is_point_solid(const Vector2i &p_id) const { ERR_FAIL_COND_V_MSG(dirty, false, "Grid is not initialized. Call the update method."); ERR_FAIL_COND_V_MSG(!is_in_boundsv(p_id), false, vformat("Can't get if point is disabled. Point %s out of bounds %s.", p_id, region)); - return GET_POINT_UNCHECKED(p_id).solid; + return _get_point_unchecked(p_id)->solid; } void AStarGrid2D::set_point_weight_scale(const Vector2i &p_id, real_t p_weight_scale) { ERR_FAIL_COND_MSG(dirty, "Grid is not initialized. Call the update method."); ERR_FAIL_COND_MSG(!is_in_boundsv(p_id), vformat("Can't set point's weight scale. Point %s out of bounds %s.", p_id, region)); ERR_FAIL_COND_MSG(p_weight_scale < 0.0, vformat("Can't set point's weight scale less than 0.0: %f.", p_weight_scale)); - GET_POINT_UNCHECKED(p_id).weight_scale = p_weight_scale; + _get_point_unchecked(p_id)->weight_scale = p_weight_scale; } real_t AStarGrid2D::get_point_weight_scale(const Vector2i &p_id) const { ERR_FAIL_COND_V_MSG(dirty, 0, "Grid is not initialized. Call the update method."); ERR_FAIL_COND_V_MSG(!is_in_boundsv(p_id), 0, vformat("Can't get point's weight scale. Point %s out of bounds %s.", p_id, region)); - return GET_POINT_UNCHECKED(p_id).weight_scale; + return _get_point_unchecked(p_id)->weight_scale; } void AStarGrid2D::fill_solid_region(const Rect2i &p_region, bool p_solid) { ERR_FAIL_COND_MSG(dirty, "Grid is not initialized. Call the update method."); - Rect2i safe_region = p_region.intersection(region); - int from_x = safe_region.get_position().x; - int from_y = safe_region.get_position().y; - int end_x = safe_region.get_end().x; - int end_y = safe_region.get_end().y; + const Rect2i safe_region = p_region.intersection(region); + const int32_t end_x = safe_region.get_end().x; + const int32_t end_y = safe_region.get_end().y; - for (int x = from_x; x < end_x; x++) { - for (int y = from_y; y < end_y; y++) { - GET_POINT_UNCHECKED(Vector2i(x, y)).solid = p_solid; + for (int32_t y = safe_region.position.y; y < end_y; y++) { + for (int32_t x = safe_region.position.x; x < end_x; x++) { + _get_point_unchecked(x, y)->solid = p_solid; } } } @@ -214,14 +213,13 @@ void AStarGrid2D::fill_weight_scale_region(const Rect2i &p_region, real_t p_weig ERR_FAIL_COND_MSG(dirty, "Grid is not initialized. Call the update method."); ERR_FAIL_COND_MSG(p_weight_scale < 0.0, vformat("Can't set point's weight scale less than 0.0: %f.", p_weight_scale)); - Rect2i safe_region = p_region.intersection(region); - int from_x = safe_region.get_position().x; - int from_y = safe_region.get_position().y; - int end_x = safe_region.get_end().x; - int end_y = safe_region.get_end().y; - for (int x = from_x; x < end_x; x++) { - for (int y = from_y; y < end_y; y++) { - GET_POINT_UNCHECKED(Vector2i(x, y)).weight_scale = p_weight_scale; + const Rect2i safe_region = p_region.intersection(region); + const int32_t end_x = safe_region.get_end().x; + const int32_t end_y = safe_region.get_end().y; + + for (int32_t y = safe_region.position.y; y < end_y; y++) { + for (int32_t x = safe_region.position.x; x < end_x; x++) { + _get_point_unchecked(x, y)->weight_scale = p_weight_scale; } } } @@ -234,14 +232,14 @@ AStarGrid2D::Point *AStarGrid2D::_jump(Point *p_from, Point *p_to) { return p_to; } - int64_t from_x = p_from->id.x; - int64_t from_y = p_from->id.y; + int32_t from_x = p_from->id.x; + int32_t from_y = p_from->id.y; - int64_t to_x = p_to->id.x; - int64_t to_y = p_to->id.y; + int32_t to_x = p_to->id.x; + int32_t to_y = p_to->id.y; - int64_t dx = to_x - from_x; - int64_t dy = to_y - from_y; + int32_t dx = to_x - from_x; + int32_t dy = to_y - from_y; if (diagonal_mode == DIAGONAL_MODE_ALWAYS || diagonal_mode == DIAGONAL_MODE_AT_LEAST_ONE_WALKABLE) { if (dx != 0 && dy != 0) { @@ -516,7 +514,7 @@ void AStarGrid2D::clear() { Vector2 AStarGrid2D::get_point_position(const Vector2i &p_id) const { ERR_FAIL_COND_V_MSG(dirty, Vector2(), "Grid is not initialized. Call the update method."); ERR_FAIL_COND_V_MSG(!is_in_boundsv(p_id), Vector2(), vformat("Can't get point's position. Point %s out of bounds %s.", p_id, region)); - return GET_POINT_UNCHECKED(p_id).pos; + return _get_point_unchecked(p_id)->pos; } Vector<Vector2> AStarGrid2D::get_point_path(const Vector2i &p_from_id, const Vector2i &p_to_id) { @@ -542,7 +540,7 @@ Vector<Vector2> AStarGrid2D::get_point_path(const Vector2i &p_from_id, const Vec } Point *p = end_point; - int64_t pc = 1; + int32_t pc = 1; while (p != begin_point) { pc++; p = p->prev_point; @@ -555,7 +553,7 @@ Vector<Vector2> AStarGrid2D::get_point_path(const Vector2i &p_from_id, const Vec Vector2 *w = path.ptrw(); p = end_point; - int64_t idx = pc - 1; + int32_t idx = pc - 1; while (p != begin_point) { w[idx--] = p->pos; p = p->prev_point; @@ -590,7 +588,7 @@ TypedArray<Vector2i> AStarGrid2D::get_id_path(const Vector2i &p_from_id, const V } Point *p = end_point; - int64_t pc = 1; + int32_t pc = 1; while (p != begin_point) { pc++; p = p->prev_point; @@ -601,7 +599,7 @@ TypedArray<Vector2i> AStarGrid2D::get_id_path(const Vector2i &p_from_id, const V { p = end_point; - int64_t idx = pc - 1; + int32_t idx = pc - 1; while (p != begin_point) { path[idx--] = p->id; p = p->prev_point; @@ -671,5 +669,3 @@ void AStarGrid2D::_bind_methods() { BIND_ENUM_CONSTANT(DIAGONAL_MODE_ONLY_IF_NO_OBSTACLES); BIND_ENUM_CONSTANT(DIAGONAL_MODE_MAX); } - -#undef GET_POINT_UNCHECKED diff --git a/core/math/a_star_grid_2d.h b/core/math/a_star_grid_2d.h index dd5f9d0575..619551b754 100644 --- a/core/math/a_star_grid_2d.h +++ b/core/math/a_star_grid_2d.h @@ -33,7 +33,6 @@ #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" -#include "core/object/script_language.h" #include "core/templates/list.h" #include "core/templates/local_vector.h" @@ -106,24 +105,32 @@ private: uint64_t pass = 1; private: // Internal routines. - _FORCE_INLINE_ bool _is_walkable(int64_t p_x, int64_t p_y) const { + _FORCE_INLINE_ bool _is_walkable(int32_t p_x, int32_t p_y) const { if (region.has_point(Vector2i(p_x, p_y))) { return !points[p_y - region.position.y][p_x - region.position.x].solid; } return false; } - _FORCE_INLINE_ Point *_get_point(int64_t p_x, int64_t p_y) { + _FORCE_INLINE_ Point *_get_point(int32_t p_x, int32_t p_y) { if (region.has_point(Vector2i(p_x, p_y))) { return &points[p_y - region.position.y][p_x - region.position.x]; } return nullptr; } - _FORCE_INLINE_ Point *_get_point_unchecked(int64_t p_x, int64_t p_y) { + _FORCE_INLINE_ Point *_get_point_unchecked(int32_t p_x, int32_t p_y) { return &points[p_y - region.position.y][p_x - region.position.x]; } + _FORCE_INLINE_ Point *_get_point_unchecked(const Vector2i &p_id) { + return &points[p_id.y - region.position.y][p_id.x - region.position.x]; + } + + _FORCE_INLINE_ const Point *_get_point_unchecked(const Vector2i &p_id) const { + return &points[p_id.y - region.position.y][p_id.x - region.position.x]; + } + void _get_nbors(Point *p_point, LocalVector<Point *> &r_nbors); Point *_jump(Point *p_from, Point *p_to); bool _solve(Point *p_begin_point, Point *p_end_point); @@ -152,10 +159,7 @@ public: void update(); - int get_width() const; - int get_height() const; - - bool is_in_bounds(int p_x, int p_y) const; + bool is_in_bounds(int32_t p_x, int32_t p_y) const; bool is_in_boundsv(const Vector2i &p_id) const; bool is_dirty() const; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 6b0ecadc7f..9796ac59c2 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -96,6 +96,14 @@ bool Basis::is_orthogonal() const { return m.is_equal_approx(identity); } +bool Basis::is_conformal() const { + const Vector3 x = get_column(0); + const Vector3 y = get_column(1); + const Vector3 z = get_column(2); + const real_t x_len_sq = x.length_squared(); + return Math::is_equal_approx(x_len_sq, y.length_squared()) && Math::is_equal_approx(x_len_sq, z.length_squared()) && Math::is_zero_approx(x.dot(y)) && Math::is_zero_approx(x.dot(z)) && Math::is_zero_approx(y.dot(z)); +} + bool Basis::is_diagonal() const { return ( Math::is_zero_approx(rows[0][1]) && Math::is_zero_approx(rows[0][2]) && diff --git a/core/math/basis.h b/core/math/basis.h index 1a68bee686..adacd1c216 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -138,6 +138,7 @@ struct _NO_DISCARD_ Basis { _FORCE_INLINE_ Basis operator*(const real_t p_val) const; bool is_orthogonal() const; + bool is_conformal() const; bool is_diagonal() const; bool is_rotation() const; diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h index 78ae77e72c..2ece991fea 100644 --- a/core/math/disjoint_set.h +++ b/core/math/disjoint_set.h @@ -134,7 +134,7 @@ void DisjointSet<T, H, C, AL>::get_representatives(Vector<T> &out_representative template <typename T, class H, class C, class AL> void DisjointSet<T, H, C, AL>::get_members(Vector<T> &out_members, T representative) { typename MapT::Iterator rep_itr = elements.find(representative); - ERR_FAIL_COND(rep_itr == nullptr); + ERR_FAIL_NULL(rep_itr); Element *rep_element = rep_itr->value; ERR_FAIL_COND(rep_element->parent != rep_element); diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h index 21b5340aaa..dbc1cb31de 100644 --- a/core/math/dynamic_bvh.h +++ b/core/math/dynamic_bvh.h @@ -190,7 +190,7 @@ private: _FORCE_INLINE_ bool is_internal() const { return (!is_leaf()); } _FORCE_INLINE_ int get_index_in_parent() const { - ERR_FAIL_COND_V(!parent, 0); + ERR_FAIL_NULL_V(parent, 0); return (parent->children[1] == this) ? 1 : 0; } void get_max_depth(int depth, int &maxdepth) { diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index f96d3a909f..934c75b5d3 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -88,6 +88,17 @@ public: static _ALWAYS_INLINE_ double atan2(double p_y, double p_x) { return ::atan2(p_y, p_x); } static _ALWAYS_INLINE_ float atan2(float p_y, float p_x) { return ::atan2f(p_y, p_x); } + static _ALWAYS_INLINE_ double asinh(double p_x) { return ::asinh(p_x); } + static _ALWAYS_INLINE_ float asinh(float p_x) { return ::asinhf(p_x); } + + // Always does clamping so always safe to use. + static _ALWAYS_INLINE_ double acosh(double p_x) { return p_x < 1 ? 0 : ::acosh(p_x); } + static _ALWAYS_INLINE_ float acosh(float p_x) { return p_x < 1 ? 0 : ::acoshf(p_x); } + + // Always does clamping so always safe to use. + static _ALWAYS_INLINE_ double atanh(double p_x) { return p_x <= -1 ? -INFINITY : (p_x >= 1 ? INFINITY : ::atanh(p_x)); } + static _ALWAYS_INLINE_ float atanh(float p_x) { return p_x <= -1 ? -INFINITY : (p_x >= 1 ? INFINITY : ::atanhf(p_x)); } + static _ALWAYS_INLINE_ double sqrt(double p_x) { return ::sqrt(p_x); } static _ALWAYS_INLINE_ float sqrt(float p_x) { return ::sqrtf(p_x); } diff --git a/core/math/projection.cpp b/core/math/projection.cpp index a304318e2e..9d5dc8b4d6 100644 --- a/core/math/projection.cpp +++ b/core/math/projection.cpp @@ -408,7 +408,6 @@ real_t Projection::get_z_far() const { matrix[11] - matrix[10], matrix[15] - matrix[14]); - new_plane.normal = -new_plane.normal; new_plane.normalize(); return new_plane.d; diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index a0187e00b1..bc4682fd90 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -164,6 +164,18 @@ Transform2D Transform2D::orthonormalized() const { return ortho; } +bool Transform2D::is_conformal() const { + // Non-flipped case. + if (Math::is_equal_approx(columns[0][0], columns[1][1]) && Math::is_equal_approx(columns[0][1], -columns[1][0])) { + return true; + } + // Flipped case. + if (Math::is_equal_approx(columns[0][0], -columns[1][1]) && Math::is_equal_approx(columns[0][1], columns[1][0])) { + return true; + } + return false; +} + 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]); } diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index c511034669..dd1a33c5d5 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -96,6 +96,7 @@ struct _NO_DISCARD_ Transform2D { void orthonormalize(); Transform2D orthonormalized() const; + bool is_conformal() const; bool is_equal_approx(const Transform2D &p_transform) const; bool is_finite() const; |
