Make MultiMeshInstance2DNavigationGeometryParser2D use the Geometry singleton. And by proxy clipper 1.

This commit is contained in:
Relintai 2023-06-07 15:25:32 +02:00
parent d9a03e7eab
commit 2e1e153bc3
3 changed files with 18 additions and 35 deletions

View File

@ -810,6 +810,10 @@ public:
return _polypaths_do_operations(OPERATION_UNION, p_polygons, p_polypath_clip, fill_type); return _polypaths_do_operations(OPERATION_UNION, p_polygons, p_polypath_clip, fill_type);
} }
static Vector<Vector<Point2>> merge_all2_polygons_2d(const Vector<Vector<Point2>> &p_polygons, const Vector<Vector<Point2>> &p_polypath_clip, PolygonFillType fill_type = POLYGON_FILL_TYPE_EVEN_ODD) {
return _polypaths2_do_operations(OPERATION_UNION, p_polygons, p_polypath_clip, fill_type);
}
static Vector<Vector<Point2>> clip_all2_polygons_2d(const Vector<Vector<Point2>> &p_polygons, const Vector<Vector<Point2>> &p_polypath_clip, PolygonFillType fill_type = POLYGON_FILL_TYPE_EVEN_ODD) { static Vector<Vector<Point2>> clip_all2_polygons_2d(const Vector<Vector<Point2>> &p_polygons, const Vector<Vector<Point2>> &p_polypath_clip, PolygonFillType fill_type = POLYGON_FILL_TYPE_EVEN_ODD) {
return _polypaths2_do_operations(OPERATION_DIFFERENCE, p_polygons, p_polypath_clip, fill_type); return _polypaths2_do_operations(OPERATION_DIFFERENCE, p_polygons, p_polypath_clip, fill_type);
} }

View File

@ -30,24 +30,18 @@
#include "multimeshinstance2d_navigation_geometry_parser_2d.h" #include "multimeshinstance2d_navigation_geometry_parser_2d.h"
#include "core/math/geometry.h"
#include "scene/2d/multimesh_instance_2d.h" #include "scene/2d/multimesh_instance_2d.h"
#include "scene/resources/multimesh.h" #include "scene/resources/multimesh.h"
#include "scene/resources/navigation_mesh_source_geometry_data_2d.h" #include "scene/resources/navigation_mesh_source_geometry_data_2d.h"
#include "scene/resources/navigation_polygon.h" #include "scene/resources/navigation_polygon.h"
#include "modules/modules_enabled.gen.h"
#ifdef MODULE_CLIPPER2_ENABLED
#include "modules/clipper2/lib/include/clipper2/clipper.h"
#endif // MODULE_CLIPPER2_ENABLED
bool MultiMeshInstance2DNavigationGeometryParser2D::parses_node(Node *p_node) { bool MultiMeshInstance2DNavigationGeometryParser2D::parses_node(Node *p_node) {
return (Object::cast_to<MultiMeshInstance2D>(p_node) != nullptr); return (Object::cast_to<MultiMeshInstance2D>(p_node) != nullptr);
} }
void MultiMeshInstance2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) { void MultiMeshInstance2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) {
#ifdef MODULE_CLIPPER2_ENABLED
NavigationPolygon::ParsedGeometryType parsed_geometry_type = p_navigation_polygon->get_parsed_geometry_type(); NavigationPolygon::ParsedGeometryType parsed_geometry_type = p_navigation_polygon->get_parsed_geometry_type();
if (Object::cast_to<MultiMeshInstance2D>(p_node) && parsed_geometry_type != NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS) { if (Object::cast_to<MultiMeshInstance2D>(p_node) && parsed_geometry_type != NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS) {
@ -56,9 +50,7 @@ void MultiMeshInstance2DNavigationGeometryParser2D::parse_geometry(Node *p_node,
if (multimesh.is_valid() && multimesh->get_transform_format() == MultiMesh::TRANSFORM_2D) { if (multimesh.is_valid() && multimesh->get_transform_format() == MultiMesh::TRANSFORM_2D) {
Ref<Mesh> mesh = multimesh->get_mesh(); Ref<Mesh> mesh = multimesh->get_mesh();
if (mesh.is_valid()) { if (mesh.is_valid()) {
using namespace Clipper2Lib; Vector<Vector<Point2>> mesh_subject_paths, dummy_clip_paths;
Paths64 mesh_subject_paths, dummy_clip_paths;
for (int i = 0; i < mesh->get_surface_count(); i++) { for (int i = 0; i < mesh->get_surface_count(); i++) {
if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) { if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
@ -69,7 +61,7 @@ void MultiMeshInstance2DNavigationGeometryParser2D::parse_geometry(Node *p_node,
continue; continue;
} }
Path64 subject_path; Vector<Point2> subject_path;
int index_count = 0; int index_count = 0;
if (mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) { if (mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
@ -89,49 +81,42 @@ void MultiMeshInstance2DNavigationGeometryParser2D::parse_geometry(Node *p_node,
for (int j = 0; j < mesh_indices.size(); ++j) { for (int j = 0; j < mesh_indices.size(); ++j) {
int vertex_index = mesh_indices[j]; int vertex_index = mesh_indices[j];
const Vector2 &vertex = mesh_vertices[vertex_index]; const Vector2 &vertex = mesh_vertices[vertex_index];
const Point64 &point = Point64(vertex.x, vertex.y); subject_path.push_back(vertex);
subject_path.push_back(point);
} }
} else { } else {
for (int j = 0; j < mesh_vertices.size(); ++j) { for (int j = 0; j < mesh_vertices.size(); ++j) {
const Vector2 &vertex = mesh_vertices[j]; const Vector2 &vertex = mesh_vertices[j];
subject_path.push_back(vertex);
const Point64 &point = Point64(vertex.x, vertex.y);
subject_path.push_back(point);
} }
} }
mesh_subject_paths.push_back(subject_path); mesh_subject_paths.push_back(subject_path);
} }
Paths64 mesh_path_solution = Union(mesh_subject_paths, dummy_clip_paths, FillRule::NonZero); Vector<Vector<Point2>> mesh_path_solution = Geometry::merge_all2_polygons_2d(mesh_subject_paths, dummy_clip_paths, Geometry::POLYGON_FILL_TYPE_NON_ZERO);
//path_solution = RamerDouglasPeucker(path_solution, 0.025);
int multimesh_instance_count = multimesh->get_visible_instance_count(); int multimesh_instance_count = multimesh->get_visible_instance_count();
if (multimesh_instance_count == -1) { if (multimesh_instance_count == -1) {
multimesh_instance_count = multimesh->get_instance_count(); multimesh_instance_count = multimesh->get_instance_count();
} }
for (int i = 0; i < multimesh_instance_count; i++) { for (int i = 0; i < multimesh_instance_count; i++) {
const Transform2D multimesh_instance_transform = multimesh_instance->get_transform() * multimesh->get_instance_transform_2d(i); const Transform2D multimesh_instance_transform = multimesh_instance->get_transform() * multimesh->get_instance_transform_2d(i);
for (const Path64 &mesh_path : mesh_path_solution) { for (int k = 0; k < mesh_path_solution.size(); ++k) {
const Vector<Point2> &mesh_path = mesh_path_solution[k];
PoolVector<Vector2> shape_outline; PoolVector<Vector2> shape_outline;
for (const Point64 &mesh_path_point : mesh_path) { for (int j = 0; j < mesh_path.size(); j++) {
shape_outline.push_back(Point2(static_cast<real_t>(mesh_path_point.x), static_cast<real_t>(mesh_path_point.y))); const Vector2 &mesh_path_point = mesh_path[j];
shape_outline.push_back(multimesh_instance_transform.xform(mesh_path_point));
} }
for (int j = 0; j < shape_outline.size(); j++) {
shape_outline.set(j, multimesh_instance_transform.xform(shape_outline[j]));
}
p_source_geometry->add_obstruction_outline(shape_outline); p_source_geometry->add_obstruction_outline(shape_outline);
} }
} }
} }
} }
} }
#endif // MODULE_CLIPPER2_ENABLED
} }

View File

@ -39,16 +39,11 @@
#include "modules/modules_enabled.gen.h" #include "modules/modules_enabled.gen.h"
#ifdef MODULE_CLIPPER2_ENABLED
#include "modules/clipper2/lib/include/clipper2/clipper.h"
#endif // MODULE_CLIPPER2_ENABLED
bool TileMap2DNavigationGeometryParser2D::parses_node(Node *p_node) { bool TileMap2DNavigationGeometryParser2D::parses_node(Node *p_node) {
return (Object::cast_to<TileMap>(p_node) != nullptr); return (Object::cast_to<TileMap>(p_node) != nullptr);
} }
void TileMap2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) { void TileMap2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) {
#ifdef MODULE_CLIPPER2_ENABLED
TileMap *tilemap = Object::cast_to<TileMap>(p_node); TileMap *tilemap = Object::cast_to<TileMap>(p_node);
//NavigationPolygon::ParsedGeometryType parsed_geometry_type = p_navigation_polygon->get_parsed_geometry_type(); //NavigationPolygon::ParsedGeometryType parsed_geometry_type = p_navigation_polygon->get_parsed_geometry_type();
//uint32_t navigation_polygon_collision_mask = p_navigation_polygon->get_collision_mask(); //uint32_t navigation_polygon_collision_mask = p_navigation_polygon->get_collision_mask();
@ -87,7 +82,7 @@ void TileMap2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<Navig
p_source_geometry->_add_traversable_outline(traversable_outline_new); p_source_geometry->_add_traversable_outline(traversable_outline_new);
} }
} }
/* /*
TODO TODO
if (parsed_geometry_type != NavigationPolygon::PARSED_GEOMETRY_MESH_INSTANCES && (tilemap->get_collision_layer() & navigation_polygon_collision_mask)) { if (parsed_geometry_type != NavigationPolygon::PARSED_GEOMETRY_MESH_INSTANCES && (tilemap->get_collision_layer() & navigation_polygon_collision_mask)) {
@ -105,4 +100,3 @@ void TileMap2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<Navig
} }
} }
} }
#endif // MODULE_CLIPPER2_ENABLED