Span - update more Geometry API to use span

This commit is contained in:
lawnjelly
2025-10-09 05:28:01 +01:00
parent 5b8789e83a
commit c59ef69184
8 changed files with 39 additions and 36 deletions

View File

@@ -1042,7 +1042,7 @@ struct _AtlasWorkRectResult {
int max_h;
};
void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size) {
void Geometry::make_atlas(const Span<Size2i> &p_rects, Vector<Point2i> &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<Size2i> &p_rects, Vector<Point2i> &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<Size2i> &p_rects, Vector<Point2i> &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<Vector<Point2>> Geometry::_polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open) {
Vector<Vector<Point2>> Geometry::_polypaths_do_operation(PolyBooleanOperation p_op, const Span<Point2> &p_polypath_a, const Span<Point2> &p_polypath_b, bool is_a_open) {
using namespace ClipperLib;
ClipType op = ctUnion;
@@ -1175,10 +1175,10 @@ Vector<Vector<Point2>> 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<Vector<Point2>> Geometry::_polypaths_do_operation(PolyBooleanOperation p_
return polypaths;
}
Vector<Vector<Point2>> Geometry::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
Vector<Vector<Point2>> Geometry::_polypath_offset(const Span<Point2> &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<Vector<Point2>> Geometry::_polypath_offset(const Vector<Point2> &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<Vector3> Geometry::compute_convex_mesh_points(const Span<Plane> &p_planes
return points;
}
Vector<Geometry::PackRectsResult> Geometry::partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size) {
Vector<Geometry::PackRectsResult> Geometry::partial_pack_rects(const Span<Vector2i> &p_sizes, const Size2i &p_atlas_size) {
Vector<stbrp_node> nodes;
nodes.resize(p_atlas_size.width);
memset(nodes.ptrw(), 0, sizeof(stbrp_node) * nodes.size());
@@ -1447,7 +1447,7 @@ Vector<Geometry::PackRectsResult> Geometry::partial_pack_rects(const Vector<Vect
Vector<stbrp_rect> 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::PackRectsResult> Geometry::partial_pack_rects(const Vector<Vect
Vector<PackRectsResult> 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<bool>(rects[i].was_packed) };
}

View File

@@ -772,35 +772,35 @@ public:
END_ROUND
};
static Vector<Vector<Point2>> merge_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
static Vector<Vector<Point2>> merge_polygons_2d(const Span<Point2> &p_polygon_a, const Span<Point2> &p_polygon_b) {
return _polypaths_do_operation(OPERATION_UNION, p_polygon_a, p_polygon_b);
}
static Vector<Vector<Point2>> clip_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
static Vector<Vector<Point2>> clip_polygons_2d(const Span<Point2> &p_polygon_a, const Span<Point2> &p_polygon_b) {
return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polygon_a, p_polygon_b);
}
static Vector<Vector<Point2>> intersect_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
static Vector<Vector<Point2>> intersect_polygons_2d(const Span<Point2> &p_polygon_a, const Span<Point2> &p_polygon_b) {
return _polypaths_do_operation(OPERATION_INTERSECTION, p_polygon_a, p_polygon_b);
}
static Vector<Vector<Point2>> exclude_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
static Vector<Vector<Point2>> exclude_polygons_2d(const Span<Point2> &p_polygon_a, const Span<Point2> &p_polygon_b) {
return _polypaths_do_operation(OPERATION_XOR, p_polygon_a, p_polygon_b);
}
static Vector<Vector<Point2>> clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
static Vector<Vector<Point2>> clip_polyline_with_polygon_2d(const Span<Vector2> &p_polyline, const Span<Vector2> &p_polygon) {
return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polyline, p_polygon, true);
}
static Vector<Vector<Point2>> intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
static Vector<Vector<Point2>> intersect_polyline_with_polygon_2d(const Span<Vector2> &p_polyline, const Span<Vector2> &p_polygon) {
return _polypaths_do_operation(OPERATION_INTERSECTION, p_polyline, p_polygon, true);
}
static Vector<Vector<Point2>> offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) {
static Vector<Vector<Point2>> offset_polygon_2d(const Span<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) {
return _polypath_offset(p_polygon, p_delta, p_join_type, END_POLYGON);
}
static Vector<Vector<Point2>> offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
static Vector<Vector<Point2>> offset_polyline_2d(const Span<Vector2> &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<Vector<Point2>>(), "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<int> triangulate_polygon(const Vector<Vector2> &p_polygon) {
static Vector<int> triangulate_polygon(const Span<Vector2> &p_polygon) {
Vector<int> triangles;
if (!Triangulate::triangulate(p_polygon, triangles)) {
return Vector<int>(); //fail
@@ -826,7 +826,7 @@ public:
return triangles;
}
static bool is_polygon_clockwise(const Vector<Vector2> &p_polygon) {
static bool is_polygon_clockwise(const Span<Vector2> &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<Vector2> &p_polygon) {
static bool is_point_in_polygon(const Vector2 &p_point, const Span<Vector2> &p_polygon) {
int c = p_polygon.size();
if (c < 3) {
return false;
@@ -1008,14 +1008,14 @@ public:
static void sort_polygon_winding(Vector<Vector2> &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<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size);
static void make_atlas(const Span<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size);
struct PackRectsResult {
int x;
int y;
bool packed;
};
static Vector<PackRectsResult> partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size);
static Vector<PackRectsResult> partial_pack_rects(const Span<Vector2i> &p_sizes, const Size2i &p_atlas_size);
static Vector<Vector3> compute_convex_mesh_points(const Span<Plane> &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<Vector<Point2>> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false);
static Vector<Vector<Point2>> _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type);
static Vector<Vector<Point2>> _polypaths_do_operation(PolyBooleanOperation p_op, const Span<Point2> &p_polypath_a, const Span<Point2> &p_polypath_b, bool is_a_open = false);
static Vector<Vector<Point2>> _polypath_offset(const Span<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type);
};
#endif // GEOMETRY_H

View File

@@ -30,7 +30,7 @@
#include "triangulate.h"
real_t Triangulate::get_area(const Vector<Vector2> &contour) {
real_t Triangulate::get_area(const Span<Vector2> &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<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V, bool relaxed) {
bool Triangulate::snip(const Span<Vector2> &p_contour, int u, int v, int w, int n, const Span<int> &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<Vector2> &p_contour, int u, int v, int w, in
return true;
}
bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &result) {
bool Triangulate::triangulate(const Span<Vector2> &contour, Vector<int> &result) {
/* allocate and initialize list of Vertices in polygon */
int n = contour.size();

View File

@@ -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<Vector2> &contour, Vector<int> &result);
static bool triangulate(const Span<Vector2> &contour, Vector<int> &result);
// compute area of a contour/polygon
static real_t get_area(const Vector<Vector2> &contour);
static real_t get_area(const Span<Vector2> &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<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V, bool relaxed);
static bool snip(const Span<Vector2> &p_contour, int u, int v, int w, int n, const Span<int> &V, bool relaxed);
};
#endif // TRIANGULATE_H

View File

@@ -424,6 +424,9 @@ public:
return find(p_val) != -1;
}
_FORCE_INLINE_ Span<T> span() const { return Span(read().ptr(), (uint32_t)size()); }
_FORCE_INLINE_ operator Span<T>() const { return span(); }
inline int size() const;
inline bool empty() const;
T get(int p_index) const;

View File

@@ -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

View File

@@ -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<Vector2>::Read points = polygon.read();

View File

@@ -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;
}
}