From 69fad39cf5437b45bac2039d864605b2b63b9950 Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Thu, 6 Jul 2023 23:01:19 +0200 Subject: [PATCH] Add NavigationServer API to enable regions and links Adds NavigationServer API to enable regions and links. --- doc/classes/NavigationServer2D.xml | 30 +++++++++++++++++++ doc/classes/NavigationServer3D.xml | 30 +++++++++++++++++++ .../navigation/godot_navigation_server.cpp | 28 +++++++++++++++++ modules/navigation/godot_navigation_server.h | 5 ++++ modules/navigation/nav_link.cpp | 10 +++++++ modules/navigation/nav_link.h | 4 +++ modules/navigation/nav_map.cpp | 6 ++++ modules/navigation/nav_region.cpp | 10 +++++++ modules/navigation/nav_region.h | 4 +++ scene/2d/navigation_link_2d.cpp | 10 +------ scene/2d/navigation_region_2d.cpp | 10 +------ scene/3d/navigation_link_3d.cpp | 10 +------ scene/3d/navigation_region_3d.cpp | 10 +------ servers/navigation_server_2d.cpp | 8 +++++ servers/navigation_server_2d.h | 6 ++++ servers/navigation_server_3d.cpp | 4 +++ servers/navigation_server_3d.h | 6 ++++ servers/navigation_server_3d_dummy.h | 4 +++ 18 files changed, 159 insertions(+), 36 deletions(-) diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml index 7f0e29676b7..32215316d13 100644 --- a/doc/classes/NavigationServer2D.xml +++ b/doc/classes/NavigationServer2D.xml @@ -207,6 +207,13 @@ Create a new link between two positions on a map. + + + + + Returns [code]true[/code] if the specified [param link] is enabled. + + @@ -271,6 +278,14 @@ Sets whether this [param link] can be travelled in both directions. + + + + + + If [param enabled] is [code]true[/code] the specified [param link] will contribute to its current navigation map. + + @@ -601,6 +616,13 @@ Returns how many connections this [param region] has with other regions in the map. + + + + + Returns [code]true[/code] if the specified [param region] is enabled. + + @@ -653,6 +675,14 @@ [b]Note:[/b] If navigation meshes from different navigation regions overlap (which should be avoided in general) the result might not be what is expected. + + + + + + If [param enabled] is [code]true[/code] the specified [param region] will contribute to its current navigation map. + + diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index e4f9a1627fc..ebde6fdf7b4 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -248,6 +248,13 @@ Create a new link between two positions on a map. + + + + + Returns [code]true[/code] if the specified [param link] is enabled. + + @@ -312,6 +319,14 @@ Sets whether this [param link] can be travelled in both directions. + + + + + + If [param enabled] is [code]true[/code] the specified [param link] will contribute to its current navigation map. + + @@ -734,6 +749,13 @@ Returns how many connections this [param region] has with other regions in the map. + + + + + Returns [code]true[/code] if the specified [param region] is enabled. + + @@ -786,6 +808,14 @@ [b]Note:[/b] If navigation meshes from different navigation regions overlap (which should be avoided in general) the result might not be what is expected. + + + + + + If [param enabled] is [code]true[/code] the specified [param region] will contribute to its current navigation map. + + diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index b73c5ca3e20..29fa73aa85f 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -340,6 +340,20 @@ RID GodotNavigationServer::region_create() { return rid; } +COMMAND_2(region_set_enabled, RID, p_region, bool, p_enabled) { + NavRegion *region = region_owner.get_or_null(p_region); + ERR_FAIL_COND(region == nullptr); + + region->set_enabled(p_enabled); +} + +bool GodotNavigationServer::region_get_enabled(RID p_region) const { + const NavRegion *region = region_owner.get_or_null(p_region); + ERR_FAIL_COND_V(region == nullptr, false); + + return region->get_enabled(); +} + COMMAND_2(region_set_use_edge_connections, RID, p_region, bool, p_enabled) { NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND(region == nullptr); @@ -512,6 +526,20 @@ RID GodotNavigationServer::link_get_map(const RID p_link) const { return RID(); } +COMMAND_2(link_set_enabled, RID, p_link, bool, p_enabled) { + NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND(link == nullptr); + + link->set_enabled(p_enabled); +} + +bool GodotNavigationServer::link_get_enabled(RID p_link) const { + const NavLink *link = link_owner.get_or_null(p_link); + ERR_FAIL_COND_V(link == nullptr, false); + + return link->get_enabled(); +} + COMMAND_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional) { NavLink *link = link_owner.get_or_null(p_link); ERR_FAIL_COND(link == nullptr); diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index 95aa88194ea..0b3789102cf 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -135,6 +135,9 @@ public: virtual RID region_create() override; + COMMAND_2(region_set_enabled, RID, p_region, bool, p_enabled); + virtual bool region_get_enabled(RID p_region) const override; + COMMAND_2(region_set_use_edge_connections, RID, p_region, bool, p_enabled); virtual bool region_get_use_edge_connections(RID p_region) const override; @@ -164,6 +167,8 @@ public: virtual RID link_create() override; COMMAND_2(link_set_map, RID, p_link, RID, p_map); virtual RID link_get_map(RID p_link) const override; + COMMAND_2(link_set_enabled, RID, p_link, bool, p_enabled); + virtual bool link_get_enabled(RID p_link) const override; COMMAND_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional); virtual bool link_is_bidirectional(RID p_link) const override; COMMAND_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers); diff --git a/modules/navigation/nav_link.cpp b/modules/navigation/nav_link.cpp index d712987a467..c693cc91c8e 100644 --- a/modules/navigation/nav_link.cpp +++ b/modules/navigation/nav_link.cpp @@ -49,6 +49,16 @@ void NavLink::set_map(NavMap *p_map) { } } +void NavLink::set_enabled(bool p_enabled) { + if (enabled == p_enabled) { + return; + } + enabled = p_enabled; + + // TODO: This should not require a full rebuild as the link has not really changed. + link_dirty = true; +}; + void NavLink::set_bidirectional(bool p_bidirectional) { if (bidirectional == p_bidirectional) { return; diff --git a/modules/navigation/nav_link.h b/modules/navigation/nav_link.h index 0b8ad4db693..a7609831db2 100644 --- a/modules/navigation/nav_link.h +++ b/modules/navigation/nav_link.h @@ -39,6 +39,7 @@ class NavLink : public NavBase { bool bidirectional = true; Vector3 start_position; Vector3 end_position; + bool enabled = true; bool link_dirty = true; @@ -52,6 +53,9 @@ public: return map; } + void set_enabled(bool p_enabled); + bool get_enabled() const { return enabled; } + void set_bidirectional(bool p_bidirectional); bool is_bidirectional() const { return bidirectional; diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 3a1d4126187..745c227fe54 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -804,6 +804,9 @@ void NavMap::sync() { // Resize the polygon count. int count = 0; for (const NavRegion *region : regions) { + if (!region->get_enabled()) { + continue; + } count += region->get_polygons().size(); } polygons.resize(count); @@ -811,6 +814,9 @@ void NavMap::sync() { // Copy all region polygons in the map. count = 0; for (const NavRegion *region : regions) { + if (!region->get_enabled()) { + continue; + } const LocalVector &polygons_source = region->get_polygons(); for (uint32_t n = 0; n < polygons_source.size(); n++) { polygons[count + n] = polygons_source[n]; diff --git a/modules/navigation/nav_region.cpp b/modules/navigation/nav_region.cpp index 9c0ce3e71ea..4e7964ed76c 100644 --- a/modules/navigation/nav_region.cpp +++ b/modules/navigation/nav_region.cpp @@ -51,6 +51,16 @@ void NavRegion::set_map(NavMap *p_map) { } } +void NavRegion::set_enabled(bool p_enabled) { + if (enabled == p_enabled) { + return; + } + enabled = p_enabled; + + // TODO: This should not require a full rebuild as the region has not really changed. + polygons_dirty = true; +}; + void NavRegion::set_use_edge_connections(bool p_enabled) { if (use_edge_connections != p_enabled) { use_edge_connections = p_enabled; diff --git a/modules/navigation/nav_region.h b/modules/navigation/nav_region.h index 0c3c1b56b6c..6a8ebe53362 100644 --- a/modules/navigation/nav_region.h +++ b/modules/navigation/nav_region.h @@ -41,6 +41,7 @@ class NavRegion : public NavBase { Transform3D transform; Ref mesh; Vector connections; + bool enabled = true; bool use_edge_connections = true; @@ -58,6 +59,9 @@ public: polygons_dirty = true; } + void set_enabled(bool p_enabled); + bool get_enabled() const { return enabled; } + void set_map(NavMap *p_map); NavMap *get_map() const { return map; diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp index 3664040e7be..95798b68564 100644 --- a/scene/2d/navigation_link_2d.cpp +++ b/scene/2d/navigation_link_2d.cpp @@ -182,15 +182,7 @@ void NavigationLink2D::set_enabled(bool p_enabled) { enabled = p_enabled; - if (!is_inside_tree()) { - return; - } - - if (!enabled) { - NavigationServer2D::get_singleton()->link_set_map(link, RID()); - } else { - NavigationServer2D::get_singleton()->link_set_map(link, get_world_2d()->get_navigation_map()); - } + NavigationServer3D::get_singleton()->link_set_enabled(link, enabled); #ifdef DEBUG_ENABLED if (Engine::get_singleton()->is_editor_hint() || NavigationServer2D::get_singleton()->get_debug_enabled()) { diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index fa037135924..670a2c641c5 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -42,15 +42,7 @@ void NavigationRegion2D::set_enabled(bool p_enabled) { enabled = p_enabled; - if (!is_inside_tree()) { - return; - } - - if (!enabled) { - _region_enter_navigation_map(); - } else { - _region_exit_navigation_map(); - } + NavigationServer2D::get_singleton()->region_set_enabled(region, enabled); #ifdef DEBUG_ENABLED if (Engine::get_singleton()->is_editor_hint() || NavigationServer2D::get_singleton()->get_debug_navigation_enabled()) { diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation_link_3d.cpp index 2263d38d6ce..70416ca93b6 100644 --- a/scene/3d/navigation_link_3d.cpp +++ b/scene/3d/navigation_link_3d.cpp @@ -291,15 +291,7 @@ void NavigationLink3D::set_enabled(bool p_enabled) { enabled = p_enabled; - if (!is_inside_tree()) { - return; - } - - if (enabled) { - NavigationServer3D::get_singleton()->link_set_map(link, get_world_3d()->get_navigation_map()); - } else { - NavigationServer3D::get_singleton()->link_set_map(link, RID()); - } + NavigationServer3D::get_singleton()->link_set_enabled(link, enabled); #ifdef DEBUG_ENABLED if (debug_instance.is_valid() && debug_mesh.is_valid()) { diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 3f1cfae99d6..8d66f7ebebb 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -40,15 +40,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) { enabled = p_enabled; - if (!is_inside_tree()) { - return; - } - - if (!enabled) { - _region_enter_navigation_map(); - } else { - _region_exit_navigation_map(); - } + NavigationServer3D::get_singleton()->region_set_enabled(region, enabled); #ifdef DEBUG_ENABLED if (debug_instance.is_valid()) { diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index e906db2acff..cd92d9dd2f3 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -391,6 +391,8 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("query_path", "parameters", "result"), &NavigationServer2D::query_path); ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer2D::region_create); + ClassDB::bind_method(D_METHOD("region_set_enabled", "region", "enabled"), &NavigationServer2D::region_set_enabled); + ClassDB::bind_method(D_METHOD("region_get_enabled", "region"), &NavigationServer2D::region_get_enabled); ClassDB::bind_method(D_METHOD("region_set_use_edge_connections", "region", "enabled"), &NavigationServer2D::region_set_use_edge_connections); ClassDB::bind_method(D_METHOD("region_get_use_edge_connections", "region"), &NavigationServer2D::region_get_use_edge_connections); ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer2D::region_set_enter_cost); @@ -413,6 +415,8 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("link_create"), &NavigationServer2D::link_create); ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &NavigationServer2D::link_set_map); ClassDB::bind_method(D_METHOD("link_get_map", "link"), &NavigationServer2D::link_get_map); + ClassDB::bind_method(D_METHOD("link_set_enabled", "link", "enabled"), &NavigationServer2D::link_set_enabled); + ClassDB::bind_method(D_METHOD("link_get_enabled", "link"), &NavigationServer2D::link_get_enabled); ClassDB::bind_method(D_METHOD("link_set_bidirectional", "link", "bidirectional"), &NavigationServer2D::link_set_bidirectional); ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &NavigationServer2D::link_is_bidirectional); ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &NavigationServer2D::link_set_navigation_layers); @@ -536,6 +540,8 @@ RID FORWARD_2_C(map_get_closest_point_owner, RID, p_map, const Vector2 &, p_poin RID FORWARD_0(region_create); +void FORWARD_2(region_set_enabled, RID, p_region, bool, p_enabled, rid_to_rid, bool_to_bool); +bool FORWARD_1_C(region_get_enabled, RID, p_region, rid_to_rid); void FORWARD_2(region_set_use_edge_connections, RID, p_region, bool, p_enabled, rid_to_rid, bool_to_bool); bool FORWARD_1_C(region_get_use_edge_connections, RID, p_region, rid_to_rid); @@ -564,6 +570,8 @@ RID FORWARD_0(link_create); void FORWARD_2(link_set_map, RID, p_link, RID, p_map, rid_to_rid, rid_to_rid); RID FORWARD_1_C(link_get_map, RID, p_link, rid_to_rid); +void FORWARD_2(link_set_enabled, RID, p_link, bool, p_enabled, rid_to_rid, bool_to_bool); +bool FORWARD_1_C(link_get_enabled, RID, p_link, rid_to_rid); void FORWARD_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional, rid_to_rid, bool_to_bool); bool FORWARD_1_C(link_is_bidirectional, RID, p_link, rid_to_rid); void FORWARD_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers, rid_to_rid, uint32_to_uint32); diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index b9b1e2a75e9..c78edaf8788 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -101,6 +101,9 @@ public: /// Creates a new region. virtual RID region_create(); + virtual void region_set_enabled(RID p_region, bool p_enabled); + virtual bool region_get_enabled(RID p_region) const; + virtual void region_set_use_edge_connections(RID p_region, bool p_enabled); virtual bool region_get_use_edge_connections(RID p_region) const; @@ -144,6 +147,9 @@ public: virtual void link_set_map(RID p_link, RID p_map); virtual RID link_get_map(RID p_link) const; + virtual void link_set_enabled(RID p_link, bool p_enabled); + virtual bool link_get_enabled(RID p_link) const; + /// Set whether this link travels in both directions. virtual void link_set_bidirectional(RID p_link, bool p_bidirectional); virtual bool link_is_bidirectional(RID p_link) const; diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 89d45b19299..04facdb8d95 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -67,6 +67,8 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("query_path", "parameters", "result"), &NavigationServer3D::query_path); ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer3D::region_create); + ClassDB::bind_method(D_METHOD("region_set_enabled", "region", "enabled"), &NavigationServer3D::region_set_enabled); + ClassDB::bind_method(D_METHOD("region_get_enabled", "region"), &NavigationServer3D::region_get_enabled); ClassDB::bind_method(D_METHOD("region_set_use_edge_connections", "region", "enabled"), &NavigationServer3D::region_set_use_edge_connections); ClassDB::bind_method(D_METHOD("region_get_use_edge_connections", "region"), &NavigationServer3D::region_get_use_edge_connections); ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer3D::region_set_enter_cost); @@ -92,6 +94,8 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("link_create"), &NavigationServer3D::link_create); ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &NavigationServer3D::link_set_map); ClassDB::bind_method(D_METHOD("link_get_map", "link"), &NavigationServer3D::link_get_map); + ClassDB::bind_method(D_METHOD("link_set_enabled", "link", "enabled"), &NavigationServer3D::link_set_enabled); + ClassDB::bind_method(D_METHOD("link_get_enabled", "link"), &NavigationServer3D::link_get_enabled); ClassDB::bind_method(D_METHOD("link_set_bidirectional", "link", "bidirectional"), &NavigationServer3D::link_set_bidirectional); ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &NavigationServer3D::link_is_bidirectional); ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &NavigationServer3D::link_set_navigation_layers); diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 0764690b813..391730e18f5 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -117,6 +117,9 @@ public: /// Creates a new region. virtual RID region_create() = 0; + virtual void region_set_enabled(RID p_region, bool p_enabled) = 0; + virtual bool region_get_enabled(RID p_region) const = 0; + virtual void region_set_use_edge_connections(RID p_region, bool p_enabled) = 0; virtual bool region_get_use_edge_connections(RID p_region) const = 0; @@ -165,6 +168,9 @@ public: virtual void link_set_map(RID p_link, RID p_map) = 0; virtual RID link_get_map(RID p_link) const = 0; + virtual void link_set_enabled(RID p_link, bool p_enabled) = 0; + virtual bool link_get_enabled(RID p_link) const = 0; + /// Set whether this link travels in both directions. virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) = 0; virtual bool link_is_bidirectional(RID p_link) const = 0; diff --git a/servers/navigation_server_3d_dummy.h b/servers/navigation_server_3d_dummy.h index 4a2e9f74393..b2d452f67a0 100644 --- a/servers/navigation_server_3d_dummy.h +++ b/servers/navigation_server_3d_dummy.h @@ -64,6 +64,8 @@ public: TypedArray map_get_obstacles(RID p_map) const override { return TypedArray(); } void map_force_update(RID p_map) override {} RID region_create() override { return RID(); } + void region_set_enabled(RID p_region, bool p_enabled) override {} + bool region_get_enabled(RID p_region) const override { return false; } void region_set_use_edge_connections(RID p_region, bool p_enabled) override {} bool region_get_use_edge_connections(RID p_region) const override { return false; } void region_set_enter_cost(RID p_region, real_t p_enter_cost) override {} @@ -88,6 +90,8 @@ public: RID link_create() override { return RID(); } void link_set_map(RID p_link, RID p_map) override {} RID link_get_map(RID p_link) const override { return RID(); } + void link_set_enabled(RID p_link, bool p_enabled) override {} + bool link_get_enabled(RID p_link) const override { return false; } void link_set_bidirectional(RID p_link, bool p_bidirectional) override {} bool link_is_bidirectional(RID p_link) const override { return false; } void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) override {}