summaryrefslogtreecommitdiff
path: root/modules/navigation
diff options
context:
space:
mode:
Diffstat (limited to 'modules/navigation')
-rw-r--r--modules/navigation/godot_navigation_server.cpp32
-rw-r--r--modules/navigation/godot_navigation_server.h5
-rw-r--r--modules/navigation/nav_map.cpp4
-rw-r--r--modules/navigation/nav_map.h2
-rw-r--r--modules/navigation/nav_utils.h12
-rw-r--r--modules/navigation/navigation_mesh_generator.cpp26
-rw-r--r--modules/navigation/register_types.cpp22
-rw-r--r--modules/navigation/register_types.h6
8 files changed, 85 insertions, 24 deletions
diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp
index d16d41b438..42aad77979 100644
--- a/modules/navigation/godot_navigation_server.cpp
+++ b/modules/navigation/godot_navigation_server.cpp
@@ -233,6 +233,38 @@ RID GodotNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3
return map->get_closest_point_owner(p_point);
}
+Array GodotNavigationServer::map_get_regions(RID p_map) const {
+ Array regions_rids;
+ const NavMap *map = map_owner.get_or_null(p_map);
+ ERR_FAIL_COND_V(map == nullptr, regions_rids);
+ for (NavRegion *region : map->get_regions()) {
+ regions_rids.push_back(region->get_self());
+ }
+ return regions_rids;
+}
+
+Array GodotNavigationServer::map_get_agents(RID p_map) const {
+ Array agents_rids;
+ const NavMap *map = map_owner.get_or_null(p_map);
+ ERR_FAIL_COND_V(map == nullptr, agents_rids);
+ for (RvoAgent *agent : map->get_agents()) {
+ agents_rids.push_back(agent->get_self());
+ }
+ return agents_rids;
+}
+
+RID GodotNavigationServer::region_get_map(RID p_region) const {
+ NavRegion *region = region_owner.get_or_null(p_region);
+ ERR_FAIL_COND_V(region == nullptr, RID());
+ return region->get_map()->get_self();
+}
+
+RID GodotNavigationServer::agent_get_map(RID p_agent) const {
+ RvoAgent *agent = agent_owner.get_or_null(p_agent);
+ ERR_FAIL_COND_V(agent == nullptr, RID());
+ return agent->get_map()->get_self();
+}
+
RID GodotNavigationServer::region_create() const {
GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this);
MutexLock lock(mut_this->operations_mutex);
diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h
index 7ad5e2d501..89e7311e51 100644
--- a/modules/navigation/godot_navigation_server.h
+++ b/modules/navigation/godot_navigation_server.h
@@ -105,8 +105,12 @@ public:
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const override;
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const override;
+ virtual Array map_get_regions(RID p_map) const override;
+ virtual Array map_get_agents(RID p_map) const override;
+
virtual RID region_create() const override;
COMMAND_2(region_set_map, RID, p_region, RID, p_map);
+ virtual RID region_get_map(RID p_region) const override;
COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers);
virtual uint32_t region_get_layers(RID p_region) const override;
COMMAND_2(region_set_transform, RID, p_region, Transform3D, p_transform);
@@ -118,6 +122,7 @@ public:
virtual RID agent_create() const override;
COMMAND_2(agent_set_map, RID, p_agent, RID, p_map);
+ virtual RID agent_get_map(RID p_agent) const override;
COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist);
COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count);
COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time);
diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp
index cbc0adc574..344475fb37 100644
--- a/modules/navigation/nav_map.cpp
+++ b/modules/navigation/nav_map.cpp
@@ -541,7 +541,7 @@ void NavMap::sync() {
}
// Group all edges per key.
- Map<gd::EdgeKey, Vector<gd::Edge::Connection>> connections;
+ HashMap<gd::EdgeKey, Vector<gd::Edge::Connection>, gd::EdgeKey> connections;
for (size_t poly_id(0); poly_id < polygons.size(); poly_id++) {
gd::Polygon &poly(polygons[poly_id]);
@@ -549,7 +549,7 @@ void NavMap::sync() {
int next_point = (p + 1) % poly.points.size();
gd::EdgeKey ek(poly.points[p].key, poly.points[next_point].key);
- Map<gd::EdgeKey, Vector<gd::Edge::Connection>>::Element *connection = connections.find(ek);
+ HashMap<gd::EdgeKey, Vector<gd::Edge::Connection>, gd::EdgeKey>::Iterator connection = connections.find(ek);
if (!connection) {
connections[ek] = Vector<gd::Edge::Connection>();
}
diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h
index 5232e42bed..0ebdea30e1 100644
--- a/modules/navigation/nav_map.h
+++ b/modules/navigation/nav_map.h
@@ -34,7 +34,7 @@
#include "nav_rid.h"
#include "core/math/math_defs.h"
-#include "core/templates/map.h"
+#include "core/templates/rb_map.h"
#include "core/templates/thread_work_pool.h"
#include "nav_utils.h"
diff --git a/modules/navigation/nav_utils.h b/modules/navigation/nav_utils.h
index 5b6c695ca4..a9f4e0e2fc 100644
--- a/modules/navigation/nav_utils.h
+++ b/modules/navigation/nav_utils.h
@@ -32,8 +32,9 @@
#define NAV_UTILS_H
#include "core/math/vector3.h"
+#include "core/templates/hash_map.h"
+#include "core/templates/hashfuncs.h"
#include "core/templates/vector.h"
-
#include <vector>
class NavRegion;
@@ -49,15 +50,18 @@ union PointKey {
};
uint64_t key = 0;
- bool operator<(const PointKey &p_key) const { return key < p_key.key; }
};
struct EdgeKey {
PointKey a;
PointKey b;
- bool operator<(const EdgeKey &p_key) const {
- return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key);
+ static uint32_t hash(const EdgeKey &p_val) {
+ return hash_one_uint64(p_val.a.key) ^ hash_one_uint64(p_val.b.key);
+ }
+
+ bool operator==(const EdgeKey &p_key) const {
+ return (a.key == p_key.a.key) && (b.key == p_key.b.key);
}
EdgeKey(const PointKey &p_a = PointKey(), const PointKey &p_b = PointKey()) :
diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp
index 9e2daf3a99..110a4f5138 100644
--- a/modules/navigation/navigation_mesh_generator.cpp
+++ b/modules/navigation/navigation_mesh_generator.cpp
@@ -34,7 +34,6 @@
#include "core/math/convex_hull.h"
#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"
@@ -202,14 +201,17 @@ void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_trans
StaticBody3D *static_body = Object::cast_to<StaticBody3D>(p_node);
if (static_body->get_collision_layer() & p_collision_mask) {
- for (int i = 0; i < p_node->get_child_count(); ++i) {
- Node *child = p_node->get_child(i);
- if (Object::cast_to<CollisionShape3D>(child)) {
- CollisionShape3D *col_shape = Object::cast_to<CollisionShape3D>(child);
-
- Transform3D transform = p_navmesh_transform * static_body->get_global_transform() * col_shape->get_transform();
+ List<uint32_t> shape_owners;
+ static_body->get_shape_owners(&shape_owners);
+ for (uint32_t shape_owner : shape_owners) {
+ const int shape_count = static_body->shape_owner_get_shape_count(shape_owner);
+ for (int i = 0; i < shape_count; i++) {
+ Ref<Shape3D> s = static_body->shape_owner_get_shape(shape_owner, i);
+ if (s.is_null()) {
+ continue;
+ }
- Ref<Shape3D> s = col_shape->get_shape();
+ const Transform3D transform = p_navmesh_transform * static_body->get_global_transform() * static_body->shape_owner_get_transform(shape_owner);
BoxShape3D *box = Object::cast_to<BoxShape3D>(*s);
if (box) {
@@ -460,6 +462,14 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
#endif
rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height);
+ // ~30000000 seems to be around sweetspot where Editor baking breaks
+ if ((cfg.width * cfg.height) > 30000000) {
+ WARN_PRINT("NavigationMesh baking process will likely fail."
+ "\nSource geometry is suspiciously big for the current Cell Size and Cell Height in the NavMesh Resource bake settings."
+ "\nIf baking does not fail, the resulting NavigationMesh will create serious pathfinding performance issues."
+ "\nIt is advised to increase Cell Size and/or Cell Height in the NavMesh Resource bake settings or reduce the size / scale of the source geometry.");
+ }
+
#ifdef TOOLS_ENABLED
if (ep) {
ep->step(TTR("Creating heightfield..."), 3);
diff --git a/modules/navigation/register_types.cpp b/modules/navigation/register_types.cpp
index 218f2c2937..62ae2c7f02 100644
--- a/modules/navigation/register_types.cpp
+++ b/modules/navigation/register_types.cpp
@@ -51,21 +51,29 @@ NavigationServer3D *new_server() {
return memnew(GodotNavigationServer);
}
-void register_navigation_types() {
- NavigationServer3DManager::set_default_server(new_server);
+void initialize_navigation_module(ModuleInitializationLevel p_level) {
+ if (p_level == MODULE_INITIALIZATION_LEVEL_SERVERS) {
+ NavigationServer3DManager::set_default_server(new_server);
#ifndef _3D_DISABLED
- _nav_mesh_generator = memnew(NavigationMeshGenerator);
- GDREGISTER_CLASS(NavigationMeshGenerator);
- Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", NavigationMeshGenerator::get_singleton()));
+ _nav_mesh_generator = memnew(NavigationMeshGenerator);
+ GDREGISTER_CLASS(NavigationMeshGenerator);
+ Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", NavigationMeshGenerator::get_singleton()));
#endif
+ }
#ifdef TOOLS_ENABLED
- EditorPlugins::add_by_type<NavigationMeshEditorPlugin>();
+ if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
+ EditorPlugins::add_by_type<NavigationMeshEditorPlugin>();
+ }
#endif
}
-void unregister_navigation_types() {
+void uninitialize_navigation_module(ModuleInitializationLevel p_level) {
+ if (p_level != MODULE_INITIALIZATION_LEVEL_SERVERS) {
+ return;
+ }
+
#ifndef _3D_DISABLED
if (_nav_mesh_generator) {
memdelete(_nav_mesh_generator);
diff --git a/modules/navigation/register_types.h b/modules/navigation/register_types.h
index 11fa5769d7..c4dbd19ed3 100644
--- a/modules/navigation/register_types.h
+++ b/modules/navigation/register_types.h
@@ -31,7 +31,9 @@
#ifndef NAVIGATION_REGISTER_TYPES_H
#define NAVIGATION_REGISTER_TYPES_H
-void register_navigation_types();
-void unregister_navigation_types();
+#include "modules/register_module_types.h"
+
+void initialize_navigation_module(ModuleInitializationLevel p_level);
+void uninitialize_navigation_module(ModuleInitializationLevel p_level);
#endif // NAVIGATION_REGISTER_TYPES_H