Browse Source

Merge pull request #104826 from smix8/navregion_iteration_id

Add function to get navigation region iteration id from NavigationServer
Thaddeus Crews 3 months ago
parent
commit
0110048d46

+ 8 - 0
doc/classes/NavigationServer2D.xml

@@ -843,6 +843,14 @@
 				Returns the enter cost of this [param region].
 			</description>
 		</method>
+		<method name="region_get_iteration_id" qualifiers="const">
+			<return type="int" />
+			<param index="0" name="region" type="RID" />
+			<description>
+				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.
+			</description>
+		</method>
 		<method name="region_get_map" qualifiers="const">
 			<return type="RID" />
 			<param index="0" name="region" type="RID" />

+ 8 - 0
doc/classes/NavigationServer3D.xml

@@ -996,6 +996,14 @@
 				Returns the enter cost of this [param region].
 			</description>
 		</method>
+		<method name="region_get_iteration_id" qualifiers="const">
+			<return type="int" />
+			<param index="0" name="region" type="RID" />
+			<description>
+				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.
+			</description>
+		</method>
 		<method name="region_get_map" qualifiers="const">
 			<return type="RID" />
 			<param index="0" name="region" type="RID" />

+ 7 - 0
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);

+ 1 - 0
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;

+ 4 - 0
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;
 }
 

+ 4 - 0
modules/navigation_2d/nav_region_2d.h

@@ -59,12 +59,16 @@ class NavRegion2D : public NavBase2D {
 	Vector<Vector2> pending_navmesh_vertices;
 	Vector<Vector<int>> pending_navmesh_polygons;
 
+	uint32_t iteration_id = 0;
+
 	SelfList<NavRegion2D> sync_dirty_request_list_element;
 
 public:
 	NavRegion2D();
 	~NavRegion2D();
 
+	uint32_t get_iteration_id() const { return iteration_id; }
+
 	void scratch_polygons() {
 		polygons_dirty = true;
 	}

+ 7 - 0
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);

+ 1 - 0
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;

+ 4 - 0
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;
 }
 

+ 4 - 0
modules/navigation_3d/nav_region_3d.h

@@ -59,12 +59,16 @@ class NavRegion3D : public NavBase3D {
 	Vector<Vector3> pending_navmesh_vertices;
 	Vector<Vector<int>> pending_navmesh_polygons;
 
+	uint32_t iteration_id = 0;
+
 	SelfList<NavRegion3D> sync_dirty_request_list_element;
 
 public:
 	NavRegion3D();
 	~NavRegion3D();
 
+	uint32_t get_iteration_id() const { return iteration_id; }
+
 	void scratch_polygons() {
 		polygons_dirty = true;
 	}

+ 1 - 0
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);

+ 1 - 0
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;

+ 1 - 0
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 {}

+ 1 - 0
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);

+ 1 - 0
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;

+ 1 - 0
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 {}