From c59ef6918497583a7f57044998d735203c496563 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Thu, 9 Oct 2025 05:28:01 +0100 Subject: [PATCH] `Span` - update more `Geometry` API to use span --- core/math/geometry.cpp | 24 ++++++++++++------------ core/math/geometry.h | 30 +++++++++++++++--------------- core/math/triangulate.cpp | 6 +++--- core/math/triangulate.h | 6 +++--- core/pool_vector.h | 3 +++ scene/2d/collision_polygon_2d.cpp | 2 +- scene/2d/light_occluder_2d.cpp | 2 +- scene/2d/navigation_polygon.cpp | 2 +- 8 files changed, 39 insertions(+), 36 deletions(-) diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp index 6784e317f3f..d937c81f406 100644 --- a/core/math/geometry.cpp +++ b/core/math/geometry.cpp @@ -1042,7 +1042,7 @@ struct _AtlasWorkRectResult { int max_h; }; -void Geometry::make_atlas(const Vector &p_rects, Vector &r_result, Size2i &r_size) { +void Geometry::make_atlas(const Span &p_rects, Vector &r_result, Size2i &r_size) { // Super simple, almost brute force scanline stacking fitter. // It's pretty basic for now, but it tries to make sure that the aspect ratio of the // resulting atlas is somehow square. This is necessary because video cards have limits. @@ -1052,14 +1052,14 @@ void Geometry::make_atlas(const Vector &p_rects, Vector &r_resu // 256x8192 atlas (won't work anywhere). ERR_FAIL_COND(p_rects.size() == 0); - for (int i = 0; i < p_rects.size(); i++) { + for (uint32_t i = 0; i < p_rects.size(); i++) { ERR_FAIL_COND(p_rects[i].width <= 0); ERR_FAIL_COND(p_rects[i].height <= 0); } Vector<_AtlasWorkRect> wrects; wrects.resize(p_rects.size()); - for (int i = 0; i < p_rects.size(); i++) { + for (uint32_t i = 0; i < p_rects.size(); i++) { wrects.write[i].s = p_rects[i]; wrects.write[i].idx = i; } @@ -1146,14 +1146,14 @@ void Geometry::make_atlas(const Vector &p_rects, Vector &r_resu r_result.resize(p_rects.size()); - for (int i = 0; i < p_rects.size(); i++) { + for (uint32_t i = 0; i < p_rects.size(); i++) { r_result.write[results[best].result[i].idx] = results[best].result[i].p; } r_size = Size2(results[best].max_w, results[best].max_h); } -Vector> Geometry::_polypaths_do_operation(PolyBooleanOperation p_op, const Vector &p_polypath_a, const Vector &p_polypath_b, bool is_a_open) { +Vector> Geometry::_polypaths_do_operation(PolyBooleanOperation p_op, const Span &p_polypath_a, const Span &p_polypath_b, bool is_a_open) { using namespace ClipperLib; ClipType op = ctUnion; @@ -1175,10 +1175,10 @@ Vector> Geometry::_polypaths_do_operation(PolyBooleanOperation p_ Path path_a, path_b; // Need to scale points (Clipper's requirement for robust computation). - for (int i = 0; i != p_polypath_a.size(); ++i) { + for (uint32_t i = 0; i != p_polypath_a.size(); ++i) { path_a << IntPoint(p_polypath_a[i].x * (real_t)SCALE_FACTOR, p_polypath_a[i].y * (real_t)SCALE_FACTOR); } - for (int i = 0; i != p_polypath_b.size(); ++i) { + for (uint32_t i = 0; i != p_polypath_b.size(); ++i) { path_b << IntPoint(p_polypath_b[i].x * (real_t)SCALE_FACTOR, p_polypath_b[i].y * (real_t)SCALE_FACTOR); } Clipper clp; @@ -1212,7 +1212,7 @@ Vector> Geometry::_polypaths_do_operation(PolyBooleanOperation p_ return polypaths; } -Vector> Geometry::_polypath_offset(const Vector &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { +Vector> Geometry::_polypath_offset(const Span &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { using namespace ClipperLib; JoinType jt = jtSquare; @@ -1252,7 +1252,7 @@ Vector> Geometry::_polypath_offset(const Vector &p_polypa Path path; // Need to scale points (Clipper's requirement for robust computation). - for (int i = 0; i != p_polypath.size(); ++i) { + for (uint32_t i = 0; i != p_polypath.size(); ++i) { path << IntPoint(p_polypath[i].x * (real_t)SCALE_FACTOR, p_polypath[i].y * (real_t)SCALE_FACTOR); } co.AddPath(path, jt, et); @@ -1436,7 +1436,7 @@ Vector Geometry::compute_convex_mesh_points(const Span &p_planes return points; } -Vector Geometry::partial_pack_rects(const Vector &p_sizes, const Size2i &p_atlas_size) { +Vector Geometry::partial_pack_rects(const Span &p_sizes, const Size2i &p_atlas_size) { Vector nodes; nodes.resize(p_atlas_size.width); memset(nodes.ptrw(), 0, sizeof(stbrp_node) * nodes.size()); @@ -1447,7 +1447,7 @@ Vector Geometry::partial_pack_rects(const Vector rects; rects.resize(p_sizes.size()); - for (int i = 0; i < p_sizes.size(); i++) { + for (uint32_t i = 0; i < p_sizes.size(); i++) { rects.write[i].id = i; rects.write[i].w = p_sizes[i].width; rects.write[i].h = p_sizes[i].height; @@ -1461,7 +1461,7 @@ Vector Geometry::partial_pack_rects(const Vector ret; ret.resize(p_sizes.size()); - for (int i = 0; i < p_sizes.size(); i++) { + for (uint32_t i = 0; i < p_sizes.size(); i++) { ret.write[rects[i].id] = { rects[i].x, rects[i].y, static_cast(rects[i].was_packed) }; } diff --git a/core/math/geometry.h b/core/math/geometry.h index 4ef9624dac6..56fb29e5e68 100644 --- a/core/math/geometry.h +++ b/core/math/geometry.h @@ -772,35 +772,35 @@ public: END_ROUND }; - static Vector> merge_polygons_2d(const Vector &p_polygon_a, const Vector &p_polygon_b) { + static Vector> merge_polygons_2d(const Span &p_polygon_a, const Span &p_polygon_b) { return _polypaths_do_operation(OPERATION_UNION, p_polygon_a, p_polygon_b); } - static Vector> clip_polygons_2d(const Vector &p_polygon_a, const Vector &p_polygon_b) { + static Vector> clip_polygons_2d(const Span &p_polygon_a, const Span &p_polygon_b) { return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polygon_a, p_polygon_b); } - static Vector> intersect_polygons_2d(const Vector &p_polygon_a, const Vector &p_polygon_b) { + static Vector> intersect_polygons_2d(const Span &p_polygon_a, const Span &p_polygon_b) { return _polypaths_do_operation(OPERATION_INTERSECTION, p_polygon_a, p_polygon_b); } - static Vector> exclude_polygons_2d(const Vector &p_polygon_a, const Vector &p_polygon_b) { + static Vector> exclude_polygons_2d(const Span &p_polygon_a, const Span &p_polygon_b) { return _polypaths_do_operation(OPERATION_XOR, p_polygon_a, p_polygon_b); } - static Vector> clip_polyline_with_polygon_2d(const Vector &p_polyline, const Vector &p_polygon) { + static Vector> clip_polyline_with_polygon_2d(const Span &p_polyline, const Span &p_polygon) { return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polyline, p_polygon, true); } - static Vector> intersect_polyline_with_polygon_2d(const Vector &p_polyline, const Vector &p_polygon) { + static Vector> intersect_polyline_with_polygon_2d(const Span &p_polyline, const Span &p_polygon) { return _polypaths_do_operation(OPERATION_INTERSECTION, p_polyline, p_polygon, true); } - static Vector> offset_polygon_2d(const Vector &p_polygon, real_t p_delta, PolyJoinType p_join_type) { + static Vector> offset_polygon_2d(const Span &p_polygon, real_t p_delta, PolyJoinType p_join_type) { return _polypath_offset(p_polygon, p_delta, p_join_type, END_POLYGON); } - static Vector> offset_polyline_2d(const Vector &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { + static Vector> offset_polyline_2d(const Span &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) { ERR_FAIL_COND_V_MSG(p_end_type == END_POLYGON, Vector>(), "Attempt to offset a polyline like a polygon (use offset_polygon_2d instead)."); return _polypath_offset(p_polygon, p_delta, p_join_type, p_end_type); @@ -818,7 +818,7 @@ public: return triangles; } - static Vector triangulate_polygon(const Vector &p_polygon) { + static Vector triangulate_polygon(const Span &p_polygon) { Vector triangles; if (!Triangulate::triangulate(p_polygon, triangles)) { return Vector(); //fail @@ -826,7 +826,7 @@ public: return triangles; } - static bool is_polygon_clockwise(const Vector &p_polygon) { + static bool is_polygon_clockwise(const Span &p_polygon) { int c = p_polygon.size(); if (c < 3) { return false; @@ -843,7 +843,7 @@ public: } // Alternate implementation that should be faster. - static bool is_point_in_polygon(const Vector2 &p_point, const Vector &p_polygon) { + static bool is_point_in_polygon(const Vector2 &p_point, const Span &p_polygon) { int c = p_polygon.size(); if (c < 3) { return false; @@ -1008,14 +1008,14 @@ public: static void sort_polygon_winding(Vector &r_verts, bool p_clockwise = true); static real_t find_polygon_area(const Vector3 *p_verts, int p_num_verts); - static void make_atlas(const Vector &p_rects, Vector &r_result, Size2i &r_size); + static void make_atlas(const Span &p_rects, Vector &r_result, Size2i &r_size); struct PackRectsResult { int x; int y; bool packed; }; - static Vector partial_pack_rects(const Vector &p_sizes, const Size2i &p_atlas_size); + static Vector partial_pack_rects(const Span &p_sizes, const Size2i &p_atlas_size); static Vector compute_convex_mesh_points(const Span &p_planes, real_t p_epsilon = CMP_EPSILON); static bool convex_hull_intersects_convex_hull(const Plane *p_planes_a, int p_plane_count_a, const Plane *p_planes_b, int p_plane_count_b); @@ -1023,8 +1023,8 @@ public: static bool verify_indices(const int *p_indices, int p_num_indices, int p_num_vertices); private: - static Vector> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector &p_polypath_a, const Vector &p_polypath_b, bool is_a_open = false); - static Vector> _polypath_offset(const Vector &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type); + static Vector> _polypaths_do_operation(PolyBooleanOperation p_op, const Span &p_polypath_a, const Span &p_polypath_b, bool is_a_open = false); + static Vector> _polypath_offset(const Span &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type); }; #endif // GEOMETRY_H diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp index a0d60ffecde..cdf3f628a8f 100644 --- a/core/math/triangulate.cpp +++ b/core/math/triangulate.cpp @@ -30,7 +30,7 @@ #include "triangulate.h" -real_t Triangulate::get_area(const Vector &contour) { +real_t Triangulate::get_area(const Span &contour) { int n = contour.size(); const Vector2 *c = &contour[0]; @@ -78,7 +78,7 @@ bool Triangulate::is_inside_triangle(real_t Ax, real_t Ay, } } -bool Triangulate::snip(const Vector &p_contour, int u, int v, int w, int n, const Vector &V, bool relaxed) { +bool Triangulate::snip(const Span &p_contour, int u, int v, int w, int n, const Span &V, bool relaxed) { int p; real_t Ax, Ay, Bx, By, Cx, Cy, Px, Py; const Vector2 *contour = &p_contour[0]; @@ -117,7 +117,7 @@ bool Triangulate::snip(const Vector &p_contour, int u, int v, int w, in return true; } -bool Triangulate::triangulate(const Vector &contour, Vector &result) { +bool Triangulate::triangulate(const Span &contour, Vector &result) { /* allocate and initialize list of Vertices in polygon */ int n = contour.size(); diff --git a/core/math/triangulate.h b/core/math/triangulate.h index 6911124ee53..88f23f1e891 100644 --- a/core/math/triangulate.h +++ b/core/math/triangulate.h @@ -41,10 +41,10 @@ class Triangulate { public: // triangulate a contour/polygon, places results in STL vector // as series of triangles. - static bool triangulate(const Vector &contour, Vector &result); + static bool triangulate(const Span &contour, Vector &result); // compute area of a contour/polygon - static real_t get_area(const Vector &contour); + static real_t get_area(const Span &contour); // decide if point Px/Py is inside triangle defined by // (Ax,Ay) (Bx,By) (Cx,Cy) @@ -55,7 +55,7 @@ public: bool include_edges); private: - static bool snip(const Vector &p_contour, int u, int v, int w, int n, const Vector &V, bool relaxed); + static bool snip(const Span &p_contour, int u, int v, int w, int n, const Span &V, bool relaxed); }; #endif // TRIANGULATE_H diff --git a/core/pool_vector.h b/core/pool_vector.h index 36872f7dc74..b4cce5c09f8 100644 --- a/core/pool_vector.h +++ b/core/pool_vector.h @@ -424,6 +424,9 @@ public: return find(p_val) != -1; } + _FORCE_INLINE_ Span span() const { return Span(read().ptr(), (uint32_t)size()); } + _FORCE_INLINE_ operator Span() const { return span(); } + inline int size() const; inline bool empty() const; T get(int p_index) const; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 41355c98f36..e3cbdf9b527 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -239,7 +239,7 @@ bool CollisionPolygon2D::_edit_use_rect() const { } bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - return Geometry::is_point_in_polygon(p_point, Variant(polygon)); + return Geometry::is_point_in_polygon(p_point, polygon); } #endif diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 96f8ca7f841..cc7124d9489 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -68,7 +68,7 @@ Rect2 OccluderPolygon2D::_edit_get_rect() const { bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { if (closed) { - return Geometry::is_point_in_polygon(p_point, Variant(polygon)); + return Geometry::is_point_in_polygon(p_point, polygon); } else { const real_t d = LINE_GRAB_WIDTH / 2 + p_tolerance; PoolVector::Read points = polygon.read(); diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index 46d1026d276..2172d0d9d2d 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -73,7 +73,7 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double if (outline_size < 3) { continue; } - if (Geometry::is_point_in_polygon(p_point, Variant(outline))) { + if (Geometry::is_point_in_polygon(p_point, outline)) { return true; } }