diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml index f7aba7e4d6a..f486c79823a 100644 --- a/doc/classes/NavigationServer2D.xml +++ b/doc/classes/NavigationServer2D.xml @@ -843,6 +843,14 @@ Returns the enter cost of this [param region]. + + + + + Returns the current iteration ID of the navigation region. Every time the navigation region changes and synchronizes, the iteration ID increases. An iteration ID of [code]0[/code] means the navigation region has never synchronized. + [b]Note:[/b] The iteration ID will wrap around to [code]1[/code] after reaching its range limit. + + diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index 3a37bd4535b..8349fe19905 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -996,6 +996,14 @@ Returns the enter cost of this [param region]. + + + + + Returns the current iteration ID of the navigation region. Every time the navigation region changes and synchronizes, the iteration ID increases. An iteration ID of [code]0[/code] means the navigation region has never synchronized. + [b]Note:[/b] The iteration ID will wrap around to [code]1[/code] after reaching its range limit. + + diff --git a/modules/navigation_2d/2d/godot_navigation_server_2d.cpp b/modules/navigation_2d/2d/godot_navigation_server_2d.cpp index e733a71e4b4..2b4f898dafd 100644 --- a/modules/navigation_2d/2d/godot_navigation_server_2d.cpp +++ b/modules/navigation_2d/2d/godot_navigation_server_2d.cpp @@ -448,6 +448,13 @@ RID GodotNavigationServer2D::region_create() { return rid; } +uint32_t GodotNavigationServer2D::region_get_iteration_id(RID p_region) const { + NavRegion2D *region = region_owner.get_or_null(p_region); + ERR_FAIL_NULL_V(region, 0); + + return region->get_iteration_id(); +} + COMMAND_2(region_set_enabled, RID, p_region, bool, p_enabled) { NavRegion2D *region = region_owner.get_or_null(p_region); ERR_FAIL_NULL(region); diff --git a/modules/navigation_2d/2d/godot_navigation_server_2d.h b/modules/navigation_2d/2d/godot_navigation_server_2d.h index 249b758107d..13f07d044ff 100644 --- a/modules/navigation_2d/2d/godot_navigation_server_2d.h +++ b/modules/navigation_2d/2d/godot_navigation_server_2d.h @@ -144,6 +144,7 @@ public: virtual Vector2 map_get_random_point(RID p_map, uint32_t p_navigation_layers, bool p_uniformly) const override; virtual RID region_create() override; + virtual uint32_t region_get_iteration_id(RID p_region) const override; COMMAND_2(region_set_enabled, RID, p_region, bool, p_enabled); virtual bool region_get_enabled(RID p_region) const override; diff --git a/modules/navigation_2d/nav_region_2d.cpp b/modules/navigation_2d/nav_region_2d.cpp index 09f5799970b..2d2db8ad8be 100644 --- a/modules/navigation_2d/nav_region_2d.cpp +++ b/modules/navigation_2d/nav_region_2d.cpp @@ -178,6 +178,10 @@ bool NavRegion2D::sync() { update_polygons(); + if (something_changed) { + iteration_id = iteration_id % UINT32_MAX + 1; + } + return something_changed; } diff --git a/modules/navigation_2d/nav_region_2d.h b/modules/navigation_2d/nav_region_2d.h index 411a76e39bf..8c4dc642f7f 100644 --- a/modules/navigation_2d/nav_region_2d.h +++ b/modules/navigation_2d/nav_region_2d.h @@ -59,12 +59,16 @@ class NavRegion2D : public NavBase2D { Vector pending_navmesh_vertices; Vector> pending_navmesh_polygons; + uint32_t iteration_id = 0; + SelfList sync_dirty_request_list_element; public: NavRegion2D(); ~NavRegion2D(); + uint32_t get_iteration_id() const { return iteration_id; } + void scratch_polygons() { polygons_dirty = true; } diff --git a/modules/navigation_3d/3d/godot_navigation_server_3d.cpp b/modules/navigation_3d/3d/godot_navigation_server_3d.cpp index ff50b4a4827..498566a04e7 100644 --- a/modules/navigation_3d/3d/godot_navigation_server_3d.cpp +++ b/modules/navigation_3d/3d/godot_navigation_server_3d.cpp @@ -389,6 +389,13 @@ RID GodotNavigationServer3D::region_create() { return rid; } +uint32_t GodotNavigationServer3D::region_get_iteration_id(RID p_region) const { + NavRegion3D *region = region_owner.get_or_null(p_region); + ERR_FAIL_NULL_V(region, 0); + + return region->get_iteration_id(); +} + COMMAND_2(region_set_enabled, RID, p_region, bool, p_enabled) { NavRegion3D *region = region_owner.get_or_null(p_region); ERR_FAIL_NULL(region); diff --git a/modules/navigation_3d/3d/godot_navigation_server_3d.h b/modules/navigation_3d/3d/godot_navigation_server_3d.h index b1f9a746462..0e08f85cf90 100644 --- a/modules/navigation_3d/3d/godot_navigation_server_3d.h +++ b/modules/navigation_3d/3d/godot_navigation_server_3d.h @@ -147,6 +147,7 @@ public: virtual Vector3 map_get_random_point(RID p_map, uint32_t p_navigation_layers, bool p_uniformly) const override; virtual RID region_create() override; + virtual uint32_t region_get_iteration_id(RID p_region) const override; COMMAND_2(region_set_enabled, RID, p_region, bool, p_enabled); virtual bool region_get_enabled(RID p_region) const override; diff --git a/modules/navigation_3d/nav_region_3d.cpp b/modules/navigation_3d/nav_region_3d.cpp index 2d18f4ae44f..7bba108e253 100644 --- a/modules/navigation_3d/nav_region_3d.cpp +++ b/modules/navigation_3d/nav_region_3d.cpp @@ -194,6 +194,10 @@ bool NavRegion3D::sync() { update_polygons(); + if (something_changed) { + iteration_id = iteration_id % UINT32_MAX + 1; + } + return something_changed; } diff --git a/modules/navigation_3d/nav_region_3d.h b/modules/navigation_3d/nav_region_3d.h index 3a947f041d2..4abeb92d95b 100644 --- a/modules/navigation_3d/nav_region_3d.h +++ b/modules/navigation_3d/nav_region_3d.h @@ -59,12 +59,16 @@ class NavRegion3D : public NavBase3D { Vector pending_navmesh_vertices; Vector> pending_navmesh_polygons; + uint32_t iteration_id = 0; + SelfList sync_dirty_request_list_element; public: NavRegion3D(); ~NavRegion3D(); + uint32_t get_iteration_id() const { return iteration_id; } + void scratch_polygons() { polygons_dirty = true; } diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index 0541509f45c..2b7c95ff375 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -75,6 +75,7 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("query_path", "parameters", "result", "callback"), &NavigationServer2D::query_path, DEFVAL(Callable())); ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer2D::region_create); + ClassDB::bind_method(D_METHOD("region_get_iteration_id", "region"), &NavigationServer2D::region_get_iteration_id); 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); diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index 25796249be9..85c095472f4 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -113,6 +113,7 @@ public: /// Creates a new region. virtual RID region_create() = 0; + virtual uint32_t region_get_iteration_id(RID p_region) const = 0; virtual void region_set_enabled(RID p_region, bool p_enabled) = 0; virtual bool region_get_enabled(RID p_region) const = 0; diff --git a/servers/navigation_server_2d_dummy.h b/servers/navigation_server_2d_dummy.h index f5401008ad2..427101300a3 100644 --- a/servers/navigation_server_2d_dummy.h +++ b/servers/navigation_server_2d_dummy.h @@ -63,6 +63,7 @@ public: bool map_get_use_async_iterations(RID p_map) const override { return false; } RID region_create() override { return RID(); } + uint32_t region_get_iteration_id(RID p_region) const override { return 0; } 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 {} diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index f635121ad1a..4459253d937 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -83,6 +83,7 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("query_path", "parameters", "result", "callback"), &NavigationServer3D::query_path, DEFVAL(Callable())); ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer3D::region_create); + ClassDB::bind_method(D_METHOD("region_get_iteration_id", "region"), &NavigationServer3D::region_get_iteration_id); 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); diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 07fc9c0fe7d..4014df213b7 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -129,6 +129,7 @@ public: /// Creates a new region. virtual RID region_create() = 0; + virtual uint32_t region_get_iteration_id(RID p_region) const = 0; virtual void region_set_enabled(RID p_region, bool p_enabled) = 0; virtual bool region_get_enabled(RID p_region) const = 0; diff --git a/servers/navigation_server_3d_dummy.h b/servers/navigation_server_3d_dummy.h index 43097f0105b..a89c3eaa0ee 100644 --- a/servers/navigation_server_3d_dummy.h +++ b/servers/navigation_server_3d_dummy.h @@ -70,6 +70,7 @@ public: bool map_get_use_async_iterations(RID p_map) const override { return false; } RID region_create() override { return RID(); } + uint32_t region_get_iteration_id(RID p_region) const override { return 0; } 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 {}