summaryrefslogtreecommitdiff
path: root/modules/navigation
diff options
context:
space:
mode:
Diffstat (limited to 'modules/navigation')
-rw-r--r--modules/navigation/godot_navigation_server.cpp90
-rw-r--r--modules/navigation/nav_map.cpp16
-rw-r--r--modules/navigation/navigation_mesh_generator.cpp69
-rw-r--r--modules/navigation/navigation_mesh_generator.h8
4 files changed, 100 insertions, 83 deletions
diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp
index fd965674d6..ac3422187f 100644
--- a/modules/navigation/godot_navigation_server.cpp
+++ b/modules/navigation/godot_navigation_server.cpp
@@ -133,13 +133,13 @@ RID GodotNavigationServer::map_create() const {
GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this);
MutexLock lock(mut_this->operations_mutex);
RID rid = map_owner.make_rid();
- NavMap *space = map_owner.getornull(rid);
+ NavMap *space = map_owner.get_or_null(rid);
space->set_self(rid);
return rid;
}
COMMAND_2(map_set_active, RID, p_map, bool, p_active) {
- NavMap *map = map_owner.getornull(p_map);
+ NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND(map == nullptr);
if (p_active) {
@@ -150,90 +150,90 @@ COMMAND_2(map_set_active, RID, p_map, bool, p_active) {
} else {
int map_index = active_maps.find(map);
ERR_FAIL_COND(map_index < 0);
- active_maps.remove(map_index);
- active_maps_update_id.remove(map_index);
+ active_maps.remove_at(map_index);
+ active_maps_update_id.remove_at(map_index);
}
}
bool GodotNavigationServer::map_is_active(RID p_map) const {
- NavMap *map = map_owner.getornull(p_map);
+ NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, false);
return active_maps.find(map) >= 0;
}
COMMAND_2(map_set_up, RID, p_map, Vector3, p_up) {
- NavMap *map = map_owner.getornull(p_map);
+ NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND(map == nullptr);
map->set_up(p_up);
}
Vector3 GodotNavigationServer::map_get_up(RID p_map) const {
- const NavMap *map = map_owner.getornull(p_map);
+ const NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector3());
return map->get_up();
}
COMMAND_2(map_set_cell_size, RID, p_map, real_t, p_cell_size) {
- NavMap *map = map_owner.getornull(p_map);
+ NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND(map == nullptr);
map->set_cell_size(p_cell_size);
}
real_t GodotNavigationServer::map_get_cell_size(RID p_map) const {
- const NavMap *map = map_owner.getornull(p_map);
+ const NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, 0);
return map->get_cell_size();
}
COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin) {
- NavMap *map = map_owner.getornull(p_map);
+ NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND(map == nullptr);
map->set_edge_connection_margin(p_connection_margin);
}
real_t GodotNavigationServer::map_get_edge_connection_margin(RID p_map) const {
- const NavMap *map = map_owner.getornull(p_map);
+ const NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, 0);
return map->get_edge_connection_margin();
}
Vector<Vector3> GodotNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const {
- const NavMap *map = map_owner.getornull(p_map);
+ const NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>());
return map->get_path(p_origin, p_destination, p_optimize, p_layers);
}
Vector3 GodotNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
- const NavMap *map = map_owner.getornull(p_map);
+ const NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector3());
return map->get_closest_point_to_segment(p_from, p_to, p_use_collision);
}
Vector3 GodotNavigationServer::map_get_closest_point(RID p_map, const Vector3 &p_point) const {
- const NavMap *map = map_owner.getornull(p_map);
+ const NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector3());
return map->get_closest_point(p_point);
}
Vector3 GodotNavigationServer::map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const {
- const NavMap *map = map_owner.getornull(p_map);
+ const NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector3());
return map->get_closest_point_normal(p_point);
}
RID GodotNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const {
- const NavMap *map = map_owner.getornull(p_map);
+ const NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, RID());
return map->get_closest_point_owner(p_point);
@@ -243,13 +243,13 @@ RID GodotNavigationServer::region_create() const {
GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this);
MutexLock lock(mut_this->operations_mutex);
RID rid = region_owner.make_rid();
- NavRegion *reg = region_owner.getornull(rid);
+ NavRegion *reg = region_owner.get_or_null(rid);
reg->set_self(rid);
return rid;
}
COMMAND_2(region_set_map, RID, p_region, RID, p_map) {
- NavRegion *region = region_owner.getornull(p_region);
+ NavRegion *region = region_owner.get_or_null(p_region);
ERR_FAIL_COND(region == nullptr);
if (region->get_map() != nullptr) {
@@ -262,7 +262,7 @@ COMMAND_2(region_set_map, RID, p_region, RID, p_map) {
}
if (p_map.is_valid()) {
- NavMap *map = map_owner.getornull(p_map);
+ NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND(map == nullptr);
map->add_region(region);
@@ -271,28 +271,28 @@ COMMAND_2(region_set_map, RID, p_region, RID, p_map) {
}
COMMAND_2(region_set_transform, RID, p_region, Transform3D, p_transform) {
- NavRegion *region = region_owner.getornull(p_region);
+ NavRegion *region = region_owner.get_or_null(p_region);
ERR_FAIL_COND(region == nullptr);
region->set_transform(p_transform);
}
COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers) {
- NavRegion *region = region_owner.getornull(p_region);
+ NavRegion *region = region_owner.get_or_null(p_region);
ERR_FAIL_COND(region == nullptr);
region->set_layers(p_layers);
}
uint32_t GodotNavigationServer::region_get_layers(RID p_region) const {
- NavRegion *region = region_owner.getornull(p_region);
+ NavRegion *region = region_owner.get_or_null(p_region);
ERR_FAIL_COND_V(region == nullptr, 0);
return region->get_layers();
}
COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh) {
- NavRegion *region = region_owner.getornull(p_region);
+ NavRegion *region = region_owner.get_or_null(p_region);
ERR_FAIL_COND(region == nullptr);
region->set_mesh(p_nav_mesh);
@@ -309,21 +309,21 @@ void GodotNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node
}
int GodotNavigationServer::region_get_connections_count(RID p_region) const {
- NavRegion *region = region_owner.getornull(p_region);
+ NavRegion *region = region_owner.get_or_null(p_region);
ERR_FAIL_COND_V(!region, 0);
return region->get_connections_count();
}
Vector3 GodotNavigationServer::region_get_connection_pathway_start(RID p_region, int p_connection_id) const {
- NavRegion *region = region_owner.getornull(p_region);
+ NavRegion *region = region_owner.get_or_null(p_region);
ERR_FAIL_COND_V(!region, Vector3());
return region->get_connection_pathway_start(p_connection_id);
}
Vector3 GodotNavigationServer::region_get_connection_pathway_end(RID p_region, int p_connection_id) const {
- NavRegion *region = region_owner.getornull(p_region);
+ NavRegion *region = region_owner.get_or_null(p_region);
ERR_FAIL_COND_V(!region, Vector3());
return region->get_connection_pathway_end(p_connection_id);
@@ -333,13 +333,13 @@ RID GodotNavigationServer::agent_create() const {
GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this);
MutexLock lock(mut_this->operations_mutex);
RID rid = agent_owner.make_rid();
- RvoAgent *agent = agent_owner.getornull(rid);
+ RvoAgent *agent = agent_owner.get_or_null(rid);
agent->set_self(rid);
return rid;
}
COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
if (agent->get_map()) {
@@ -353,7 +353,7 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) {
agent->set_map(nullptr);
if (p_map.is_valid()) {
- NavMap *map = map_owner.getornull(p_map);
+ NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND(map == nullptr);
agent->set_map(map);
@@ -366,77 +366,77 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) {
}
COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->get_agent()->neighborDist_ = p_dist;
}
COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->get_agent()->maxNeighbors_ = p_count;
}
COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->get_agent()->timeHorizon_ = p_time;
}
COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->get_agent()->radius_ = p_radius;
}
COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->get_agent()->maxSpeed_ = p_max_speed;
}
COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->get_agent()->velocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z);
}
COMMAND_2(agent_set_target_velocity, RID, p_agent, Vector3, p_velocity) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->get_agent()->prefVelocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z);
}
COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->get_agent()->position_ = RVO::Vector3(p_position.x, p_position.y, p_position.z);
}
COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->get_agent()->ignore_y_ = p_ignore;
}
bool GodotNavigationServer::agent_is_map_changed(RID p_agent) const {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND_V(agent == nullptr, false);
return agent->is_map_changed();
}
COMMAND_4(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_method, Variant, p_udata) {
- RvoAgent *agent = agent_owner.getornull(p_agent);
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->set_callback(p_receiver == nullptr ? ObjectID() : p_receiver->get_instance_id(), p_method, p_udata);
@@ -452,7 +452,7 @@ COMMAND_4(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_
COMMAND_1(free, RID, p_object) {
if (map_owner.owns(p_object)) {
- NavMap *map = map_owner.getornull(p_object);
+ NavMap *map = map_owner.get_or_null(p_object);
// Removes any assigned region
std::vector<NavRegion *> regions = map->get_regions();
@@ -469,12 +469,12 @@ COMMAND_1(free, RID, p_object) {
}
int map_index = active_maps.find(map);
- active_maps.remove(map_index);
- active_maps_update_id.remove(map_index);
+ active_maps.remove_at(map_index);
+ active_maps_update_id.remove_at(map_index);
map_owner.free(p_object);
} else if (region_owner.owns(p_object)) {
- NavRegion *region = region_owner.getornull(p_object);
+ NavRegion *region = region_owner.get_or_null(p_object);
// Removes this region from the map if assigned
if (region->get_map() != nullptr) {
@@ -485,7 +485,7 @@ COMMAND_1(free, RID, p_object) {
region_owner.free(p_object);
} else if (agent_owner.owns(p_object)) {
- RvoAgent *agent = agent_owner.getornull(p_object);
+ RvoAgent *agent = agent_owner.get_or_null(p_object);
// Removes this agent from the map if assigned
if (agent->get_map() != nullptr) {
diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp
index 3150ca0bc8..0c8f0ed8c9 100644
--- a/modules/navigation/nav_map.cpp
+++ b/modules/navigation/nav_map.cpp
@@ -613,17 +613,17 @@ void NavMap::sync() {
}
Vector<gd::Edge::Connection> free_edges;
- for (Map<gd::EdgeKey, Vector<gd::Edge::Connection>>::Element *E = connections.front(); E; E = E->next()) {
- if (E->get().size() == 2) {
+ for (KeyValue<gd::EdgeKey, Vector<gd::Edge::Connection>> &E : connections) {
+ if (E.value.size() == 2) {
// Connect edge that are shared in different polygons.
- gd::Edge::Connection &c1 = E->get().write[0];
- gd::Edge::Connection &c2 = E->get().write[1];
+ gd::Edge::Connection &c1 = E.value.write[0];
+ gd::Edge::Connection &c2 = E.value.write[1];
c1.polygon->edges[c1.edge].connections.push_back(c2);
c2.polygon->edges[c2.edge].connections.push_back(c1);
// Note: The pathway_start/end are full for those connection and do not need to be modified.
} else {
- CRASH_COND_MSG(E->get().size() != 1, vformat("Number of connection != 1. Found: %d", E->get().size()));
- free_edges.push_back(E->get()[0]);
+ CRASH_COND_MSG(E.value.size() != 1, vformat("Number of connection != 1. Found: %d", E.value.size()));
+ free_edges.push_back(E.value[0]);
}
}
@@ -664,7 +664,7 @@ void NavMap::sync() {
} else {
other1 = other_edge_p1.lerp(other_edge_p2, (1.0 - projected_p1_ratio) / (projected_p2_ratio - projected_p1_ratio));
}
- if ((self1 - other1).length() > edge_connection_margin) {
+ if (other1.distance_to(self1) > edge_connection_margin) {
continue;
}
@@ -675,7 +675,7 @@ void NavMap::sync() {
} else {
other2 = other_edge_p1.lerp(other_edge_p2, (0.0 - projected_p1_ratio) / (projected_p2_ratio - projected_p1_ratio));
}
- if ((self2 - other2).length() > edge_connection_margin) {
+ if (other2.distance_to(self2) > edge_connection_margin) {
continue;
}
diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp
index 905d10c9d4..0bce0fc9f0 100644
--- a/modules/navigation/navigation_mesh_generator.cpp
+++ b/modules/navigation/navigation_mesh_generator.cpp
@@ -36,6 +36,7 @@
#include "core/os/thread.h"
#include "scene/3d/collision_shape_3d.h"
#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/multimesh_instance_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/resources/box_shape_3d.h"
#include "scene/resources/capsule_shape_3d.h"
@@ -45,14 +46,15 @@
#include "scene/resources/primitive_meshes.h"
#include "scene/resources/shape_3d.h"
#include "scene/resources/sphere_shape_3d.h"
-#include "scene/resources/world_margin_shape_3d.h"
+#include "scene/resources/world_boundary_shape_3d.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#endif
-#include "modules/modules_enabled.gen.h"
+#include "modules/modules_enabled.gen.h" // For csg, gridmap.
+
#ifdef MODULE_CSG_ENABLED
#include "modules/csg/csg_shape.h"
#endif
@@ -62,17 +64,17 @@
NavigationMeshGenerator *NavigationMeshGenerator::singleton = nullptr;
-void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) {
- p_verticies.push_back(p_vec3.x);
- p_verticies.push_back(p_vec3.y);
- p_verticies.push_back(p_vec3.z);
+void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_vertices) {
+ p_vertices.push_back(p_vec3.x);
+ p_vertices.push_back(p_vec3.y);
+ p_vertices.push_back(p_vec3.z);
}
-void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices) {
int current_vertex_count;
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
- current_vertex_count = p_verticies.size() / 3;
+ current_vertex_count = p_vertices.size() / 3;
if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
continue;
@@ -99,7 +101,7 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
const int *ir = mesh_indices.ptr();
for (int j = 0; j < mesh_vertices.size(); j++) {
- _add_vertex(p_xform.xform(vr[j]), p_verticies);
+ _add_vertex(p_xform.xform(vr[j]), p_vertices);
}
for (int j = 0; j < face_count; j++) {
@@ -111,9 +113,9 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
} else {
face_count = mesh_vertices.size() / 3;
for (int j = 0; j < face_count; j++) {
- _add_vertex(p_xform.xform(vr[j * 3 + 0]), p_verticies);
- _add_vertex(p_xform.xform(vr[j * 3 + 2]), p_verticies);
- _add_vertex(p_xform.xform(vr[j * 3 + 1]), p_verticies);
+ _add_vertex(p_xform.xform(vr[j * 3 + 0]), p_vertices);
+ _add_vertex(p_xform.xform(vr[j * 3 + 2]), p_vertices);
+ _add_vertex(p_xform.xform(vr[j * 3 + 1]), p_vertices);
p_indices.push_back(current_vertex_count + (j * 3 + 0));
p_indices.push_back(current_vertex_count + (j * 3 + 1));
@@ -123,14 +125,14 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
}
}
-void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices) {
int face_count = p_faces.size() / 3;
- int current_vertex_count = p_verticies.size() / 3;
+ int current_vertex_count = p_vertices.size() / 3;
for (int j = 0; j < face_count; j++) {
- _add_vertex(p_xform.xform(p_faces[j * 3 + 0]), p_verticies);
- _add_vertex(p_xform.xform(p_faces[j * 3 + 1]), p_verticies);
- _add_vertex(p_xform.xform(p_faces[j * 3 + 2]), p_verticies);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 0]), p_vertices);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 1]), p_vertices);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 2]), p_vertices);
p_indices.push_back(current_vertex_count + (j * 3 + 0));
p_indices.push_back(current_vertex_count + (j * 3 + 2));
@@ -138,12 +140,27 @@ void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, cons
}
}
-void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
+void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
if (Object::cast_to<MeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mesh_instance->get_mesh();
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_vertices, p_indices);
+ }
+ }
+
+ if (Object::cast_to<MultiMeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
+ MultiMeshInstance3D *multimesh_instance = Object::cast_to<MultiMeshInstance3D>(p_node);
+ Ref<MultiMesh> multimesh = multimesh_instance->get_multimesh();
+ Ref<Mesh> mesh = multimesh->get_mesh();
+ if (mesh.is_valid()) {
+ int n = multimesh->get_visible_instance_count();
+ if (n == -1) {
+ n = multimesh->get_instance_count();
+ }
+ for (int i = 0; i < n; i++) {
+ _add_mesh(mesh, p_accumulated_transform * multimesh->get_instance_transform(i), p_vertices, p_indices);
+ }
}
}
@@ -154,7 +171,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
if (!meshes.is_empty()) {
Ref<Mesh> mesh = meshes[1];
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_vertices, p_indices);
}
}
}
@@ -212,7 +229,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
ConcavePolygonShape3D *concave_polygon = Object::cast_to<ConcavePolygonShape3D>(*s);
if (concave_polygon) {
- _add_faces(concave_polygon->get_faces(), transform, p_verticies, p_indices);
+ _add_faces(concave_polygon->get_faces(), transform, p_vertices, p_indices);
}
ConvexPolygonShape3D *convex_polygon = Object::cast_to<ConvexPolygonShape3D>(*s);
@@ -235,12 +252,12 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
}
}
- _add_faces(faces, transform, p_verticies, p_indices);
+ _add_faces(faces, transform, p_vertices, p_indices);
}
}
if (mesh.is_valid()) {
- _add_mesh(mesh, transform, p_verticies, p_indices);
+ _add_mesh(mesh, transform, p_vertices, p_indices);
}
}
}
@@ -255,7 +272,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
for (int i = 0; i < meshes.size(); i += 2) {
Ref<Mesh> mesh = meshes[i + 1];
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_vertices, p_indices);
}
}
}
@@ -268,7 +285,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
if (p_recurse_children) {
for (int i = 0; i < p_node->get_child_count(); i++) {
- _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_verticies, p_indices, p_generate_from, p_collision_mask, p_recurse_children);
+ _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_vertices, p_indices, p_generate_from, p_collision_mask, p_recurse_children);
}
}
}
@@ -489,7 +506,7 @@ NavigationMeshGenerator::~NavigationMeshGenerator() {
}
void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) {
- ERR_FAIL_COND(!p_nav_mesh.is_valid());
+ ERR_FAIL_COND_MSG(!p_nav_mesh.is_valid(), "Invalid navigation mesh.");
#ifdef TOOLS_ENABLED
EditorProgress *ep(nullptr);
diff --git a/modules/navigation/navigation_mesh_generator.h b/modules/navigation/navigation_mesh_generator.h
index 78f1329e3f..dac844c68e 100644
--- a/modules/navigation/navigation_mesh_generator.h
+++ b/modules/navigation/navigation_mesh_generator.h
@@ -49,10 +49,10 @@ class NavigationMeshGenerator : public Object {
protected:
static void _bind_methods();
- static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies);
- static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
- static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
- static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
+ static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_vertices);
+ static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices);
+ static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices);
+ static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh);
static void _build_recast_navigation_mesh(