From 8cbb1bb879ea478b21c2c90be932009503043202 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 3 Jun 2023 18:22:12 +0200 Subject: [PATCH] Started porting pull request from godot 4: Rework NavigationMeshGenerator Reworks NavigationMeshGenerator and navigation mesh parse and bake process. Adds navigation mesh baking for 2D. - smix8 https://github.com/godotengine/godot/pull/70724 https://github.com/godotengine/godot/pull/70724/commits/38699a82593ef60d680b7b46b06c92f896dd7c77 --- scene/2d/navigation_geometry_parser_2d.cpp | 66 +++++++ scene/2d/navigation_geometry_parser_2d.h | 53 +++++ scene/3d/navigation_geometry_parser_3d.cpp | 69 +++++++ scene/3d/navigation_geometry_parser_3d.h | 53 +++++ ...avigation_mesh_source_geometry_data_2d.cpp | 138 +++++++++++++ .../navigation_mesh_source_geometry_data_2d.h | 78 ++++++++ ...avigation_mesh_source_geometry_data_3d.cpp | 183 ++++++++++++++++++ .../navigation_mesh_source_geometry_data_3d.h | 79 ++++++++ .../navigation/navigation_mesh_generator.cpp | 174 +++++++++++++++++ .../navigation/navigation_mesh_generator.h | 126 ++++++++++++ 10 files changed, 1019 insertions(+) create mode 100644 scene/2d/navigation_geometry_parser_2d.cpp create mode 100644 scene/2d/navigation_geometry_parser_2d.h create mode 100644 scene/3d/navigation_geometry_parser_3d.cpp create mode 100644 scene/3d/navigation_geometry_parser_3d.h create mode 100644 scene/resources/navigation_mesh_source_geometry_data_2d.cpp create mode 100644 scene/resources/navigation_mesh_source_geometry_data_2d.h create mode 100644 scene/resources/navigation_mesh_source_geometry_data_3d.cpp create mode 100644 scene/resources/navigation_mesh_source_geometry_data_3d.h create mode 100644 servers/navigation/navigation_mesh_generator.cpp create mode 100644 servers/navigation/navigation_mesh_generator.h diff --git a/scene/2d/navigation_geometry_parser_2d.cpp b/scene/2d/navigation_geometry_parser_2d.cpp new file mode 100644 index 000000000..822d6269a --- /dev/null +++ b/scene/2d/navigation_geometry_parser_2d.cpp @@ -0,0 +1,66 @@ +/**************************************************************************/ +/* navigation_geometry_parser_2d.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "navigation_geometry_parser_2d.h" + +#include "scene/2d/node_2d.h" + +#include "scene/resources/navigation_mesh_source_geometry_data_2d.h" +#include "scene/resources/navigation_polygon.h" + +bool NavigationGeometryParser2D::parses_node(Node *p_node) { + if (Object::cast_to(p_node)) { + return false; + } + + if (has_method("_parses_node")) { + return call("_parses_node", p_node); + } + + return false; +} + +void NavigationGeometryParser2D::parse_node_geometry(Ref p_navigation_polygon, Node *p_node, Ref p_source_geometry) { + parse_geometry(p_node, p_navigation_polygon, p_source_geometry); +} + +void NavigationGeometryParser2D::parse_geometry(Node *p_node, Ref p_navigation_polygon, Ref p_source_geometry) { + if (has_method("_parse_geometry")) { + call("_parse_geometry", p_node, p_navigation_polygon, p_source_geometry); + } +} + +void NavigationGeometryParser2D::_bind_methods() { + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_parses_node", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + BIND_VMETHOD(MethodInfo("_parse_geometry", + PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"), + PropertyInfo(Variant::OBJECT, "navigation_polygon", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), + PropertyInfo(Variant::OBJECT, "source_geometry", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMeshSourceGeometryData2D"))); +} diff --git a/scene/2d/navigation_geometry_parser_2d.h b/scene/2d/navigation_geometry_parser_2d.h new file mode 100644 index 000000000..bdf952519 --- /dev/null +++ b/scene/2d/navigation_geometry_parser_2d.h @@ -0,0 +1,53 @@ +#ifndef NAVIGATION_GEOMETRY_PARSER_2D_H +#define NAVIGATION_GEOMETRY_PARSER_2D_H + +/**************************************************************************/ +/* navigation_geometry_parser_2d.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "core/object/reference.h" + +class NavigationPolygon; +class NavigationMeshSourceGeometryData2D; +class Node; + +class NavigationGeometryParser2D : public Reference { + GDCLASS(NavigationGeometryParser2D, Reference); + +protected: + static void _bind_methods(); + +public: + virtual bool parses_node(Node *p_node); + virtual void parse_geometry(Node *p_node, Ref p_navigation_polygon, Ref p_source_geometry); + + void parse_node_geometry(Ref p_navigation_polygon, Node *p_node, Ref p_source_geometry); +}; + +#endif // NAVIGATION_GEOMETRY_PARSER_2D_H diff --git a/scene/3d/navigation_geometry_parser_3d.cpp b/scene/3d/navigation_geometry_parser_3d.cpp new file mode 100644 index 000000000..622693d07 --- /dev/null +++ b/scene/3d/navigation_geometry_parser_3d.cpp @@ -0,0 +1,69 @@ +/**************************************************************************/ +/* navigation_geometry_parser_3d.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "navigation_geometry_parser_3d.h" + +#include "spatial.h" + +#include "scene/resources/navigation_mesh.h" +#include "scene/resources/navigation_mesh_source_geometry_data_3d.h" + +#ifndef _3D_DISABLED +bool NavigationGeometryParser3D::parses_node(Node *p_node) { + if (!Object::cast_to(p_node)) { + return false; + } + + if (has_method("_parses_node")) { + return call("_parses_node", p_node); + } + + return false; +} + +void NavigationGeometryParser3D::parse_node_geometry(Ref p_navigation_mesh, Node *p_node, Ref p_source_geometry) { + parse_geometry(p_node, p_navigation_mesh, p_source_geometry); +} + +void NavigationGeometryParser3D::parse_geometry(Node *p_node, Ref p_navigation_mesh, Ref p_source_geometry) { + if (has_method("_parse_geometry")) { + call("_parse_geometry", p_node, p_navigation_mesh, p_source_geometry); + } +} + +void NavigationGeometryParser3D::_bind_methods() { + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_parses_node", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + BIND_VMETHOD(MethodInfo("_parse_geometry", + PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"), + PropertyInfo(Variant::OBJECT, "navigation_mesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), + PropertyInfo(Variant::OBJECT, "source_geometry", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMeshSourceGeometryData3D"))); +} + +#endif // _3D_DISABLED diff --git a/scene/3d/navigation_geometry_parser_3d.h b/scene/3d/navigation_geometry_parser_3d.h new file mode 100644 index 000000000..2def4fdbb --- /dev/null +++ b/scene/3d/navigation_geometry_parser_3d.h @@ -0,0 +1,53 @@ +/**************************************************************************/ +/* navigation_geometry_parser_3d.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef NAVIGATION_GEOMETRY_PARSER_3D_H +#define NAVIGATION_GEOMETRY_PARSER_3D_H + +#include "core/object/reference.h" + +class NavigationMesh; +class NavigationMeshSourceGeometryData3D; +class Node; + +class NavigationGeometryParser3D : public Reference { + GDCLASS(NavigationGeometryParser3D, Reference); + +protected: + static void _bind_methods(); + +public: + virtual bool parses_node(Node *p_node); + virtual void parse_geometry(Node *p_node, Ref p_navigation_mesh, Ref p_source_geometry); + + void parse_node_geometry(Ref p_navigationmesh, Node *p_node, Ref p_source_geometry); +}; + +#endif // NAVIGATION_GEOMETRY_PARSER_3D_H diff --git a/scene/resources/navigation_mesh_source_geometry_data_2d.cpp b/scene/resources/navigation_mesh_source_geometry_data_2d.cpp new file mode 100644 index 000000000..76f4d3297 --- /dev/null +++ b/scene/resources/navigation_mesh_source_geometry_data_2d.cpp @@ -0,0 +1,138 @@ +/**************************************************************************/ +/* navigation_mesh_source_geometry_data_2d.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "navigation_mesh_source_geometry_data_2d.h" + +#include "scene/resources/mesh.h" + +void NavigationMeshSourceGeometryData2D::clear() { + traversable_outlines.clear(); + obstruction_outlines.clear(); +} + +void NavigationMeshSourceGeometryData2D::_set_traversable_outlines(const Vector> &p_traversable_outlines) { + traversable_outlines = p_traversable_outlines; +} + +void NavigationMeshSourceGeometryData2D::_set_obstruction_outlines(const Vector> &p_obstruction_outlines) { + obstruction_outlines = p_obstruction_outlines; +} + +void NavigationMeshSourceGeometryData2D::_add_traversable_outline(const Vector &p_shape_outline) { + if (p_shape_outline.size() > 1) { + traversable_outlines.push_back(p_shape_outline); + } +} + +void NavigationMeshSourceGeometryData2D::_add_obstruction_outline(const Vector &p_shape_outline) { + if (p_shape_outline.size() > 1) { + obstruction_outlines.push_back(p_shape_outline); + } +} + +void NavigationMeshSourceGeometryData2D::set_traversable_outlines(const Array &p_traversable_outlines) { + traversable_outlines.resize(p_traversable_outlines.size()); + for (int i = 0; i < p_traversable_outlines.size(); i++) { + traversable_outlines.write[i] = p_traversable_outlines[i]; + } +} + +Array NavigationMeshSourceGeometryData2D::get_traversable_outlines() const { + Array array_traversable_outlines; + array_traversable_outlines.resize(traversable_outlines.size()); + for (int i = 0; i < array_traversable_outlines.size(); i++) { + array_traversable_outlines[i] = traversable_outlines[i]; + } + + return array_traversable_outlines; +} + +void NavigationMeshSourceGeometryData2D::set_obstruction_outlines(const Array &p_obstruction_outlines) { + obstruction_outlines.resize(p_obstruction_outlines.size()); + for (int i = 0; i < p_obstruction_outlines.size(); i++) { + obstruction_outlines.write[i] = p_obstruction_outlines[i]; + } +} + +Array NavigationMeshSourceGeometryData2D::get_obstruction_outlines() const { + Array array_obstruction_outlines; + array_obstruction_outlines.resize(obstruction_outlines.size()); + for (int i = 0; i < array_obstruction_outlines.size(); i++) { + array_obstruction_outlines[i] = obstruction_outlines[i]; + } + + return array_obstruction_outlines; +} + +void NavigationMeshSourceGeometryData2D::add_traversable_outline(const PoolVector2Array &p_shape_outline) { + if (p_shape_outline.size() > 1) { + Vector traversable_outline; + traversable_outline.resize(p_shape_outline.size()); + for (int i = 0; i < p_shape_outline.size(); i++) { + traversable_outline.write[i] = p_shape_outline[i]; + } + traversable_outlines.push_back(traversable_outline); + } +} + +void NavigationMeshSourceGeometryData2D::add_obstruction_outline(const PoolVector2Array &p_shape_outline) { + if (p_shape_outline.size() > 1) { + Vector obstruction_outline; + obstruction_outline.resize(p_shape_outline.size()); + for (int i = 0; i < p_shape_outline.size(); i++) { + obstruction_outline.write[i] = p_shape_outline[i]; + } + obstruction_outlines.push_back(obstruction_outline); + } +} + +void NavigationMeshSourceGeometryData2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("clear"), &NavigationMeshSourceGeometryData2D::clear); + ClassDB::bind_method(D_METHOD("has_data"), &NavigationMeshSourceGeometryData2D::has_data); + + ClassDB::bind_method(D_METHOD("set_traversable_outlines", "traversable_outlines"), &NavigationMeshSourceGeometryData2D::set_traversable_outlines); + ClassDB::bind_method(D_METHOD("get_traversable_outlines"), &NavigationMeshSourceGeometryData2D::get_traversable_outlines); + + ClassDB::bind_method(D_METHOD("set_obstruction_outlines", "obstruction_outlines"), &NavigationMeshSourceGeometryData2D::set_obstruction_outlines); + ClassDB::bind_method(D_METHOD("get_obstruction_outlines"), &NavigationMeshSourceGeometryData2D::get_obstruction_outlines); + + ClassDB::bind_method(D_METHOD("add_traversable_outline", "shape_outline"), &NavigationMeshSourceGeometryData2D::add_traversable_outline); + ClassDB::bind_method(D_METHOD("add_obstruction_outline", "shape_outline"), &NavigationMeshSourceGeometryData2D::add_obstruction_outline); + + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "traversable_outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_traversable_outlines", "get_traversable_outlines"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "obstruction_outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_obstruction_outlines", "get_obstruction_outlines"); +} + +NavigationMeshSourceGeometryData2D::NavigationMeshSourceGeometryData2D() { +} + +NavigationMeshSourceGeometryData2D::~NavigationMeshSourceGeometryData2D() { + clear(); +} diff --git a/scene/resources/navigation_mesh_source_geometry_data_2d.h b/scene/resources/navigation_mesh_source_geometry_data_2d.h new file mode 100644 index 000000000..3400d9474 --- /dev/null +++ b/scene/resources/navigation_mesh_source_geometry_data_2d.h @@ -0,0 +1,78 @@ +#ifndef NAVIGATION_MESH_SOURCE_GEOMETRY_DATA_2D_H +#define NAVIGATION_MESH_SOURCE_GEOMETRY_DATA_2D_H + +/**************************************************************************/ +/* navigation_mesh_source_geometry_data_2d.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "scene/2d/node_2d.h" +#include "scene/resources/navigation_polygon.h" + +class NavigationMeshSourceGeometryData2D : public Resource { + GDCLASS(NavigationMeshSourceGeometryData2D, Resource); + + Vector> traversable_outlines; + Vector> obstruction_outlines; + +protected: + static void _bind_methods(); + +public: + void _set_traversable_outlines(const Vector> &p_traversable_outlines); + const Vector> &_get_traversable_outlines() const { return traversable_outlines; } + + void _set_obstruction_outlines(const Vector> &p_obstruction_outlines); + const Vector> &_get_obstruction_outlines() const { return obstruction_outlines; } + + void _add_traversable_outline(const Vector &p_shape_outline); + void _add_obstruction_outline(const Vector &p_shape_outline); + + // kept root node transform here on the geometry data + // if we add this transform to all exposed functions we need to break comp on all functions later + // when navmesh changes from global transfrom to relative to navregion + // but if it stays here we can just remove it and change the internal functions only + Transform2D root_node_transform; + + void set_traversable_outlines(const Array &p_traversable_outlines); + Array get_traversable_outlines() const; + + void set_obstruction_outlines(const Array &p_obstruction_outlines); + Array get_obstruction_outlines() const; + + void add_traversable_outline(const PoolVector2Array &p_shape_outline); + void add_obstruction_outline(const PoolVector2Array &p_shape_outline); + + bool has_data() { return traversable_outlines.size(); }; + void clear(); + + NavigationMeshSourceGeometryData2D(); + ~NavigationMeshSourceGeometryData2D(); +}; + +#endif // NAVIGATION_MESH_SOURCE_GEOMETRY_DATA_2D_H diff --git a/scene/resources/navigation_mesh_source_geometry_data_3d.cpp b/scene/resources/navigation_mesh_source_geometry_data_3d.cpp new file mode 100644 index 000000000..42f3a1920 --- /dev/null +++ b/scene/resources/navigation_mesh_source_geometry_data_3d.cpp @@ -0,0 +1,183 @@ +/**************************************************************************/ +/* navigation_mesh_source_geometry_data_3d.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "navigation_mesh_source_geometry_data_3d.h" + +void NavigationMeshSourceGeometryData3D::set_vertices(const PoolRealArray &p_vertices) { + vertices = p_vertices; +} + +void NavigationMeshSourceGeometryData3D::set_indices(const PoolIntArray &p_indices) { + indices = p_indices; +} + +void NavigationMeshSourceGeometryData3D::clear() { + vertices.clear(); + indices.clear(); +} + +void NavigationMeshSourceGeometryData3D::_add_vertex(const Vector3 &p_vec3) { + vertices.push_back(p_vec3.x); + vertices.push_back(p_vec3.y); + vertices.push_back(p_vec3.z); +} + +void NavigationMeshSourceGeometryData3D::_add_mesh(const Ref &p_mesh, const Transform &p_xform) { + int current_vertex_count; + for (int i = 0; i < p_mesh->get_surface_count(); i++) { + current_vertex_count = vertices.size() / 3; + + if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) { + continue; + } + + int index_count = 0; + if (p_mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) { + index_count = p_mesh->surface_get_array_index_len(i); + } else { + index_count = p_mesh->surface_get_array_len(i); + } + + ERR_CONTINUE((index_count == 0 || (index_count % 3) != 0)); + + int face_count = index_count / 3; + + Array a = p_mesh->surface_get_arrays(i); + + Vector mesh_vertices = a[Mesh::ARRAY_VERTEX]; + const Vector3 *vr = mesh_vertices.ptr(); + + if (p_mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) { + PoolIntArray mesh_indices = a[Mesh::ARRAY_INDEX]; + PoolIntArray::Read r = mesh_indices.read(); + const int *ir = r.ptr(); + + for (int j = 0; j < mesh_vertices.size(); j++) { + _add_vertex(p_xform.xform(vr[j])); + } + + for (int j = 0; j < face_count; j++) { + // CCW + indices.push_back(current_vertex_count + (ir[j * 3 + 0])); + indices.push_back(current_vertex_count + (ir[j * 3 + 2])); + indices.push_back(current_vertex_count + (ir[j * 3 + 1])); + } + } else { + face_count = mesh_vertices.size() / 3; + for (int j = 0; j < face_count; j++) { + _add_vertex(p_xform.xform(vr[j * 3 + 0])); + _add_vertex(p_xform.xform(vr[j * 3 + 2])); + _add_vertex(p_xform.xform(vr[j * 3 + 1])); + + indices.push_back(current_vertex_count + (j * 3 + 0)); + indices.push_back(current_vertex_count + (j * 3 + 1)); + indices.push_back(current_vertex_count + (j * 3 + 2)); + } + } + } +} + +void NavigationMeshSourceGeometryData3D::_add_mesh_array(const Array &p_mesh_array, const Transform &p_xform) { + Vector mesh_vertices = p_mesh_array[Mesh::ARRAY_VERTEX]; + const Vector3 *vr = mesh_vertices.ptr(); + + PoolIntArray mesh_indices = p_mesh_array[Mesh::ARRAY_INDEX]; + PoolIntArray::Read r = mesh_indices.read(); + const int *ir = r.ptr(); + + const int face_count = mesh_indices.size() / 3; + const int current_vertex_count = vertices.size() / 3; + + for (int j = 0; j < mesh_vertices.size(); j++) { + _add_vertex(p_xform.xform(vr[j])); + } + + for (int j = 0; j < face_count; j++) { + // CCW + indices.push_back(current_vertex_count + (ir[j * 3 + 0])); + indices.push_back(current_vertex_count + (ir[j * 3 + 2])); + indices.push_back(current_vertex_count + (ir[j * 3 + 1])); + } +} + +void NavigationMeshSourceGeometryData3D::_add_faces(const PoolVector3Array &p_faces, const Transform &p_xform) { + int face_count = p_faces.size() / 3; + int current_vertex_count = vertices.size() / 3; + + for (int j = 0; j < face_count; j++) { + _add_vertex(p_xform.xform(p_faces[j * 3 + 0])); + _add_vertex(p_xform.xform(p_faces[j * 3 + 1])); + _add_vertex(p_xform.xform(p_faces[j * 3 + 2])); + + indices.push_back(current_vertex_count + (j * 3 + 0)); + indices.push_back(current_vertex_count + (j * 3 + 2)); + indices.push_back(current_vertex_count + (j * 3 + 1)); + } +} + +void NavigationMeshSourceGeometryData3D::add_mesh(const Ref &p_mesh, const Transform &p_xform) { + ERR_FAIL_COND(!p_mesh.is_valid()); + _add_mesh(p_mesh, root_node_transform * p_xform); +} + +void NavigationMeshSourceGeometryData3D::add_mesh_array(const Array &p_mesh_array, const Transform &p_xform) { + ERR_FAIL_COND(p_mesh_array.size() != Mesh::ARRAY_MAX); + _add_mesh_array(p_mesh_array, root_node_transform * p_xform); +} + +void NavigationMeshSourceGeometryData3D::add_faces(const PoolVector3Array &p_faces, const Transform &p_xform) { + ERR_FAIL_COND(p_faces.size() % 3 != 0); + _add_faces(p_faces, root_node_transform * p_xform); +} + +void NavigationMeshSourceGeometryData3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationMeshSourceGeometryData3D::set_vertices); + ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationMeshSourceGeometryData3D::get_vertices); + + ClassDB::bind_method(D_METHOD("set_indices", "indices"), &NavigationMeshSourceGeometryData3D::set_indices); + ClassDB::bind_method(D_METHOD("get_indices"), &NavigationMeshSourceGeometryData3D::get_indices); + + ClassDB::bind_method(D_METHOD("clear"), &NavigationMeshSourceGeometryData3D::clear); + ClassDB::bind_method(D_METHOD("has_data"), &NavigationMeshSourceGeometryData3D::has_data); + + ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "xform"), &NavigationMeshSourceGeometryData3D::add_mesh); + ClassDB::bind_method(D_METHOD("add_mesh_array", "mesh_array", "xform"), &NavigationMeshSourceGeometryData3D::add_mesh_array); + ClassDB::bind_method(D_METHOD("add_faces", "faces", "xform"), &NavigationMeshSourceGeometryData3D::add_faces); + + ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices"); + ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "indices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_indices", "get_indices"); +} + +NavigationMeshSourceGeometryData3D::NavigationMeshSourceGeometryData3D() { +} + +NavigationMeshSourceGeometryData3D::~NavigationMeshSourceGeometryData3D() { + clear(); +} diff --git a/scene/resources/navigation_mesh_source_geometry_data_3d.h b/scene/resources/navigation_mesh_source_geometry_data_3d.h new file mode 100644 index 000000000..e8cb4fb8f --- /dev/null +++ b/scene/resources/navigation_mesh_source_geometry_data_3d.h @@ -0,0 +1,79 @@ +#ifndef NAVIGATION_MESH_SOURCE_GEOMETRY_DATA_3D_H +#define NAVIGATION_MESH_SOURCE_GEOMETRY_DATA_3D_H + +/**************************************************************************/ +/* navigation_mesh_source_geometry_data_3d.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "core/object/resource.h" + +#include "core/math/transform.h" + +#include "mesh.h" + +class NavigationMeshSourceGeometryData3D : public Resource { + GDCLASS(NavigationMeshSourceGeometryData3D, Resource); + + PoolRealArray vertices; + PoolIntArray indices; + +protected: + static void _bind_methods(); + +private: + void _add_vertex(const Vector3 &p_vec3); + void _add_mesh(const Ref &p_mesh, const Transform &p_xform); + void _add_mesh_array(const Array &p_array, const Transform &p_xform); + void _add_faces(const PoolVector3Array &p_faces, const Transform &p_xform); + +public: + // kept root node transform here on the geometry data + // if we add this transform to all exposed functions we need to break comp on all functions later + // when navmesh changes from global transfrom to relative to navregion + // but if it stays here we can just remove it and change the internal functions only + Transform root_node_transform; + + void set_vertices(const PoolRealArray &p_vertices); + PoolRealArray get_vertices() const { return vertices; } + + void set_indices(const PoolIntArray &p_indices); + PoolIntArray get_indices() const { return indices; } + + bool has_data() { return vertices.size() && indices.size(); }; + void clear(); + + void add_mesh(const Ref &p_mesh, const Transform &p_xform); + void add_mesh_array(const Array &p_mesh_array, const Transform &p_xform); + void add_faces(const PoolVector3Array &p_faces, const Transform &p_xform); + + NavigationMeshSourceGeometryData3D(); + ~NavigationMeshSourceGeometryData3D(); +}; + +#endif // NAVIGATION_MESH_SOURCE_GEOMETRY_DATA_3D_H diff --git a/servers/navigation/navigation_mesh_generator.cpp b/servers/navigation/navigation_mesh_generator.cpp new file mode 100644 index 000000000..ca75b124e --- /dev/null +++ b/servers/navigation/navigation_mesh_generator.cpp @@ -0,0 +1,174 @@ +/**************************************************************************/ +/* navigation_mesh_generator.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "navigation_mesh_generator.h" + +#include "core/config/project_settings.h" +#include "core/object/funcref.h" + +#include "scene/2d/navigation_geometry_parser_2d.h" +#ifndef _3D_DISABLED +#include "scene/3d/navigation_geometry_parser_3d.h" +#endif // _3D_DISABLED +#include "scene/main/node.h" +#include "scene/resources/navigation_mesh.h" +#include "scene/resources/navigation_mesh_source_geometry_data_2d.h" +#ifndef _3D_DISABLED +#include "scene/resources/navigation_mesh_source_geometry_data_3d.h" +#endif // _3D_DISABLED + +NavigationMeshGenerator *NavigationMeshGenerator::singleton = nullptr; + +void NavigationMeshGenerator::_bind_methods() { + ClassDB::bind_method(D_METHOD("register_geometry_parser_2d", "geometry_parser"), &NavigationMeshGenerator::register_geometry_parser_2d); + ClassDB::bind_method(D_METHOD("unregister_geometry_parser_2d", "geometry_parser"), &NavigationMeshGenerator::unregister_geometry_parser_2d); + + ClassDB::bind_method(D_METHOD("parse_2d_source_geometry_data", "navigation_polygon", "root_node", "callback"), &NavigationMeshGenerator::parse_2d_source_geometry_data, DEFVAL(Callable())); + ClassDB::bind_method(D_METHOD("bake_2d_from_source_geometry_data", "navigation_polygon", "source_geometry_data", "callback"), &NavigationMeshGenerator::bake_2d_from_source_geometry_data, DEFVAL(Callable())); + ClassDB::bind_method(D_METHOD("parse_and_bake_2d", "navigation_polygon", "root_node", "callback"), &NavigationMeshGenerator::parse_and_bake_2d, DEFVAL(Callable())); + + ClassDB::bind_method(D_METHOD("is_navigation_polygon_baking", "navigation_polygon"), &NavigationMeshGenerator::is_navigation_polygon_baking); + +#ifndef _3D_DISABLED + ClassDB::bind_method(D_METHOD("register_geometry_parser_3d", "geometry_parser"), &NavigationMeshGenerator::register_geometry_parser_3d); + ClassDB::bind_method(D_METHOD("unregister_geometry_parser_3d", "geometry_parser"), &NavigationMeshGenerator::unregister_geometry_parser_3d); + + ClassDB::bind_method(D_METHOD("parse_3d_source_geometry_data", "navigation_mesh", "root_node", "callback"), &NavigationMeshGenerator::parse_3d_source_geometry_data, DEFVAL(Callable())); + ClassDB::bind_method(D_METHOD("bake_3d_from_source_geometry_data", "navigation_mesh", "source_geometry_data", "callback"), &NavigationMeshGenerator::bake_3d_from_source_geometry_data, DEFVAL(Callable())); + ClassDB::bind_method(D_METHOD("parse_and_bake_3d", "navigation_mesh", "root_node", "callback"), &NavigationMeshGenerator::parse_and_bake_3d, DEFVAL(Callable())); + + ClassDB::bind_method(D_METHOD("is_navigation_mesh_baking", "navigation_mesh"), &NavigationMeshGenerator::is_navigation_mesh_baking); +#endif // _3D_DISABLED +} + +NavigationMeshGenerator *NavigationMeshGenerator::get_singleton() { + return singleton; +} + +NavigationMeshGenerator::NavigationMeshGenerator() { + ERR_FAIL_COND(singleton != nullptr); + singleton = this; +} + +NavigationMeshGenerator::~NavigationMeshGenerator() { + singleton = nullptr; +} + +/// NavigationMeshGeneratorManager //////////////////////////////////////////////////// + +NavigationMeshGeneratorManager *NavigationMeshGeneratorManager::singleton = nullptr; +const String NavigationMeshGeneratorManager::setting_property_name(PNAME("navigation/baking/generator/navigation_mesh_generator")); + +void NavigationMeshGeneratorManager::on_servers_changed() { + String nav_server_names("DEFAULT"); + for (const ClassInfo &server : navigation_mesh_generators) { + nav_server_names += "," + server.name; + } + + ProjectSettings::get_singleton()->set_custom_property_info(PropertyInfo(Variant::STRING, setting_property_name, PROPERTY_HINT_ENUM, nav_server_names)); +} + +void NavigationMeshGeneratorManager::_bind_methods() { + ClassDB::bind_method(D_METHOD("register_server", "name", "create_callback"), &NavigationMeshGeneratorManager::register_server); + ClassDB::bind_method(D_METHOD("set_default_server", "name", "priority"), &NavigationMeshGeneratorManager::set_default_server); +} + +NavigationMeshGeneratorManager *NavigationMeshGeneratorManager::get_singleton() { + return singleton; +} + +void NavigationMeshGeneratorManager::register_server(const String &p_name, const Ref &p_create_callback) { + // TODO: Enable check when is_valid() is fixed for static functions. + //ERR_FAIL_COND(!p_create_callback.is_valid()); + ERR_FAIL_COND_MSG(find_server_id(p_name) != -1, "NavigationMeshGenerator with the same name was already registered."); + + navigation_mesh_generators.push_back(ClassInfo{ p_name, p_create_callback }); + on_servers_changed(); +} + +void NavigationMeshGeneratorManager::set_default_server(const String &p_name, int p_priority) { + const int id = find_server_id(p_name); + ERR_FAIL_COND_MSG(id == -1, "NavigationMeshGenerator not found"); // Not found + + // Only change the server if it is registered with a higher priority + if (default_server_priority < p_priority) { + default_server_id = id; + default_server_priority = p_priority; + } +} + +int NavigationMeshGeneratorManager::find_server_id(const String &p_name) const { + for (int i = 0; i < navigation_mesh_generators.size(); ++i) { + if (p_name == navigation_mesh_generators[i].name) { + return i; + } + } + + return -1; +} + +NavigationMeshGenerator *NavigationMeshGeneratorManager::new_default_server() const { + ERR_FAIL_COND_V(default_server_id == -1, nullptr); + + Variant ret; + Callable::CallError ce; + navigation_mesh_generators[default_server_id].create_callback.callp(nullptr, 0, ret, ce); + + ERR_FAIL_COND_V(ce.error != Callable::CallError::CALL_OK, nullptr); + return Object::cast_to(ret.get_validated_object()); +} + +NavigationMeshGenerator *NavigationMeshGeneratorManager::new_server(const String &p_name) const { + const int id = find_server_id(p_name); + + if (id == -1) { + return nullptr; + } + + Variant ret; + Callable::CallError ce; + navigation_mesh_generators[id].create_callback.callp(nullptr, 0, ret, ce); + + ERR_FAIL_COND_V(ce.error != Callable::CallError::CALL_OK, nullptr); + return Object::cast_to(ret.get_validated_object()); +} + +NavigationMeshGeneratorManager::NavigationMeshGeneratorManager() { + singleton = this; + + GLOBAL_DEF("navigation/baking/thread_model/parsing_use_multiple_threads", true); + GLOBAL_DEF("navigation/baking/thread_model/parsing_use_high_priority_threads", true); + GLOBAL_DEF("navigation/baking/thread_model/baking_use_multiple_threads", true); + GLOBAL_DEF("navigation/baking/thread_model/baking_use_high_priority_threads", true); +} + +NavigationMeshGeneratorManager::~NavigationMeshGeneratorManager() { + singleton = nullptr; +} diff --git a/servers/navigation/navigation_mesh_generator.h b/servers/navigation/navigation_mesh_generator.h new file mode 100644 index 000000000..dd6dfd976 --- /dev/null +++ b/servers/navigation/navigation_mesh_generator.h @@ -0,0 +1,126 @@ +#ifndef NAVIGATION_MESH_GENERATOR_H +#define NAVIGATION_MESH_GENERATOR_H + +/**************************************************************************/ +/* navigation_mesh_generator.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "core/containers/rid.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" + +class Node; +class NavigationGeometryParser2D; +class NavigationGeometryParser3D; +class NavigationMeshSourceGeometryData2D; +class NavigationMeshSourceGeometryData3D; +class NavigationPolygon; +class NavigationMesh; +class FuncRef; + +class NavigationMeshGenerator : public Object { + GDCLASS(NavigationMeshGenerator, Object); + + static NavigationMeshGenerator *singleton; + +protected: + static void _bind_methods(); + +public: + static NavigationMeshGenerator *get_singleton(); + + virtual void process() = 0; + virtual void cleanup() = 0; + + // 2D ////////////////////////////// + virtual void register_geometry_parser_2d(Ref p_geometry_parser) = 0; + virtual void unregister_geometry_parser_2d(Ref p_geometry_parser) = 0; + + virtual Ref parse_2d_source_geometry_data(Ref p_navigation_polygon, Node *p_root_node, Ref p_callback = Ref()) = 0; + virtual void bake_2d_from_source_geometry_data(Ref p_navigation_polygon, Ref p_source_geometry_data, Ref p_callback = Ref()) = 0; + + virtual void parse_and_bake_2d(Ref p_navigation_polygon, Node *p_root_node, Ref p_callback = Ref()) = 0; + + virtual bool is_navigation_polygon_baking(Ref p_navigation_polygon) const = 0; + + // 3D ////////////////////////////// +#ifndef _3D_DISABLED + virtual void register_geometry_parser_3d(Ref p_geometry_parser) = 0; + virtual void unregister_geometry_parser_3d(Ref p_geometry_parser) = 0; + + virtual Ref parse_3d_source_geometry_data(Ref p_navigation_mesh, Node *p_root_node, Ref p_callback = Ref()) = 0; + virtual void bake_3d_from_source_geometry_data(Ref p_navigation_mesh, Ref p_source_geometry_data, Ref p_callback = Ref()) = 0; + + virtual void parse_and_bake_3d(Ref p_navigation_mesh, Node *p_root_node, Ref p_callback = Ref()) = 0; + + virtual bool is_navigation_mesh_baking(Ref p_navigation_mesh) const = 0; +#endif // _3D_DISABLED + + NavigationMeshGenerator(); + ~NavigationMeshGenerator() override; +}; + +/// NavigationMeshGeneratorManager //////////////////////////////////////////////////// + +class NavigationMeshGeneratorManager : public Object { + GDCLASS(NavigationMeshGeneratorManager, Object); + + static NavigationMeshGeneratorManager *singleton; + + struct ClassInfo { + String name; + Ref create_callback; + }; + + Vector navigation_mesh_generators; + int default_server_id = -1; + int default_server_priority = -1; + + void on_servers_changed(); + +protected: + static void _bind_methods(); + +public: + static const String setting_property_name; + + static NavigationMeshGeneratorManager *get_singleton(); + + void register_server(const String &p_name, const Ref &p_create_callback); + void set_default_server(const String &p_name, int p_priority = 0); + int find_server_id(const String &p_name) const; + + NavigationMeshGenerator *new_default_server() const; + NavigationMeshGenerator *new_server(const String &p_name) const; + + NavigationMeshGeneratorManager(); + ~NavigationMeshGeneratorManager() override; +}; + +#endif // NAVIGATION_MESH_GENERATOR_H