Bladeren bron

Add function to get navigation map iteration id from NavigationServer

Adds function to get navigation map iteration id from NavigationServer.
smix8 1 jaar geleden
bovenliggende
commit
313c1d1100

+ 8 - 0
doc/classes/NavigationServer2D.xml

@@ -504,6 +504,14 @@
 				Returns the edge connection margin of the map. The edge connection margin is a distance used to connect two regions.
 			</description>
 		</method>
+		<method name="map_get_iteration_id" qualifiers="const">
+			<return type="int" />
+			<param index="0" name="map" type="RID" />
+			<description>
+				Returns the current iteration id of the navigation map. Every time the navigation map changes and synchronizes the iteration id increases. An iteration id of 0 means the navigation map has never synchronized.
+				[b]Note:[/b] The iteration id will wrap back to 1 after reaching its range limit.
+			</description>
+		</method>
 		<method name="map_get_link_connection_radius" qualifiers="const">
 			<return type="float" />
 			<param index="0" name="map" type="RID" />

+ 8 - 0
doc/classes/NavigationServer3D.xml

@@ -568,6 +568,14 @@
 				Returns the edge connection margin of the map. This distance is the minimum vertex distance needed to connect two edges from different regions.
 			</description>
 		</method>
+		<method name="map_get_iteration_id" qualifiers="const">
+			<return type="int" />
+			<param index="0" name="map" type="RID" />
+			<description>
+				Returns the current iteration id of the navigation map. Every time the navigation map changes and synchronizes the iteration id increases. An iteration id of 0 means the navigation map has never synchronized.
+				[b]Note:[/b] The iteration id will wrap back to 1 after reaching its range limit.
+			</description>
+		</method>
 		<method name="map_get_link_connection_radius" qualifiers="const">
 			<return type="float" />
 			<param index="0" name="map" type="RID" />

+ 13 - 6
modules/navigation/godot_navigation_server.cpp

@@ -121,13 +121,13 @@ COMMAND_2(map_set_active, RID, p_map, bool, p_active) {
 	if (p_active) {
 		if (!map_is_active(p_map)) {
 			active_maps.push_back(map);
-			active_maps_update_id.push_back(map->get_map_update_id());
+			active_maps_iteration_id.push_back(map->get_iteration_id());
 		}
 	} else {
 		int map_index = active_maps.find(map);
 		ERR_FAIL_COND(map_index < 0);
 		active_maps.remove_at(map_index);
-		active_maps_update_id.remove_at(map_index);
+		active_maps_iteration_id.remove_at(map_index);
 	}
 }
 
@@ -1165,7 +1165,7 @@ COMMAND_1(free, RID, p_object) {
 		int map_index = active_maps.find(map);
 		if (map_index >= 0) {
 			active_maps.remove_at(map_index);
-			active_maps_update_id.remove_at(map_index);
+			active_maps_iteration_id.remove_at(map_index);
 		}
 		map_owner.free(p_object);
 
@@ -1258,6 +1258,13 @@ void GodotNavigationServer::map_force_update(RID p_map) {
 	map->sync();
 }
 
+uint32_t GodotNavigationServer::map_get_iteration_id(RID p_map) const {
+	NavMap *map = map_owner.get_or_null(p_map);
+	ERR_FAIL_NULL_V(map, 0);
+
+	return map->get_iteration_id();
+}
+
 void GodotNavigationServer::sync() {
 #ifndef _3D_DISABLED
 	if (navmesh_generator_3d) {
@@ -1300,10 +1307,10 @@ void GodotNavigationServer::process(real_t p_delta_time) {
 		_new_pm_edge_free_count += active_maps[i]->get_pm_edge_free_count();
 
 		// Emit a signal if a map changed.
-		const uint32_t new_map_update_id = active_maps[i]->get_map_update_id();
-		if (new_map_update_id != active_maps_update_id[i]) {
+		const uint32_t new_map_iteration_id = active_maps[i]->get_iteration_id();
+		if (new_map_iteration_id != active_maps_iteration_id[i]) {
 			emit_signal(SNAME("map_changed"), active_maps[i]->get_self());
-			active_maps_update_id[i] = new_map_update_id;
+			active_maps_iteration_id[i] = new_map_iteration_id;
 		}
 	}
 

+ 2 - 1
modules/navigation/godot_navigation_server.h

@@ -80,7 +80,7 @@ class GodotNavigationServer : public NavigationServer3D {
 
 	bool active = true;
 	LocalVector<NavMap *> active_maps;
-	LocalVector<uint32_t> active_maps_update_id;
+	LocalVector<uint32_t> active_maps_iteration_id;
 
 #ifndef _3D_DISABLED
 	NavMeshGenerator3D *navmesh_generator_3d = nullptr;
@@ -142,6 +142,7 @@ public:
 	virtual TypedArray<RID> map_get_obstacles(RID p_map) const override;
 
 	virtual void map_force_update(RID p_map) override;
+	virtual uint32_t map_get_iteration_id(RID p_map) const override;
 
 	virtual Vector3 map_get_random_point(RID p_map, uint32_t p_navigation_layers, bool p_uniformly) const override;
 

+ 4 - 0
modules/navigation/godot_navigation_server_2d.cpp

@@ -253,6 +253,10 @@ void GodotNavigationServer2D::map_force_update(RID p_map) {
 	NavigationServer3D::get_singleton()->map_force_update(p_map);
 }
 
+uint32_t GodotNavigationServer2D::map_get_iteration_id(RID p_map) const {
+	return NavigationServer3D::get_singleton()->map_get_iteration_id(p_map);
+}
+
 void FORWARD_2(map_set_cell_size, RID, p_map, real_t, p_cell_size, rid_to_rid, real_to_real);
 real_t FORWARD_1_C(map_get_cell_size, RID, p_map, rid_to_rid);
 

+ 1 - 0
modules/navigation/godot_navigation_server_2d.h

@@ -77,6 +77,7 @@ public:
 	virtual TypedArray<RID> map_get_obstacles(RID p_map) const override;
 	virtual void map_force_update(RID p_map) override;
 	virtual Vector2 map_get_random_point(RID p_map, uint32_t p_navigation_layers, bool p_uniformly) const override;
+	virtual uint32_t map_get_iteration_id(RID p_map) const override;
 
 	virtual RID region_create() override;
 	virtual void region_set_enabled(RID p_region, bool p_enabled) override;

+ 2 - 2
modules/navigation/nav_agent.cpp

@@ -111,8 +111,8 @@ void NavAgent::set_map(NavMap *p_map) {
 
 bool NavAgent::is_map_changed() {
 	if (map) {
-		bool is_changed = map->get_map_update_id() != map_update_id;
-		map_update_id = map->get_map_update_id();
+		bool is_changed = map->get_iteration_id() != last_map_iteration_id;
+		last_map_iteration_id = map->get_iteration_id();
 		return is_changed;
 	} else {
 		return false;

+ 1 - 1
modules/navigation/nav_agent.h

@@ -72,7 +72,7 @@ class NavAgent : public NavRid {
 
 	bool agent_dirty = true;
 
-	uint32_t map_update_id = 0;
+	uint32_t last_map_iteration_id = 0;
 	bool paused = false;
 
 public:

+ 7 - 8
modules/navigation/nav_map.cpp

@@ -128,7 +128,7 @@ gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const {
 
 Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers, Vector<int32_t> *r_path_types, TypedArray<RID> *r_path_rids, Vector<int64_t> *r_path_owners) const {
 	RWLockRead read_lock(map_rwlock);
-	if (map_update_id == 0) {
+	if (iteration_id == 0) {
 		ERR_FAIL_V_MSG(Vector<Vector3>(), "NavigationServer map query failed because it was made before first map synchronization.");
 	}
 
@@ -592,7 +592,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
 
 Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
 	RWLockRead read_lock(map_rwlock);
-	if (map_update_id == 0) {
+	if (iteration_id == 0) {
 		ERR_FAIL_V_MSG(Vector3(), "NavigationServer map query failed because it was made before first map synchronization.");
 	}
 
@@ -644,7 +644,7 @@ Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector
 
 Vector3 NavMap::get_closest_point(const Vector3 &p_point) const {
 	RWLockRead read_lock(map_rwlock);
-	if (map_update_id == 0) {
+	if (iteration_id == 0) {
 		ERR_FAIL_V_MSG(Vector3(), "NavigationServer map query failed because it was made before first map synchronization.");
 	}
 	gd::ClosestPointQueryResult cp = get_closest_point_info(p_point);
@@ -653,7 +653,7 @@ Vector3 NavMap::get_closest_point(const Vector3 &p_point) const {
 
 Vector3 NavMap::get_closest_point_normal(const Vector3 &p_point) const {
 	RWLockRead read_lock(map_rwlock);
-	if (map_update_id == 0) {
+	if (iteration_id == 0) {
 		ERR_FAIL_V_MSG(Vector3(), "NavigationServer map query failed because it was made before first map synchronization.");
 	}
 	gd::ClosestPointQueryResult cp = get_closest_point_info(p_point);
@@ -662,7 +662,7 @@ Vector3 NavMap::get_closest_point_normal(const Vector3 &p_point) const {
 
 RID NavMap::get_closest_point_owner(const Vector3 &p_point) const {
 	RWLockRead read_lock(map_rwlock);
-	if (map_update_id == 0) {
+	if (iteration_id == 0) {
 		ERR_FAIL_V_MSG(RID(), "NavigationServer map query failed because it was made before first map synchronization.");
 	}
 	gd::ClosestPointQueryResult cp = get_closest_point_info(p_point);
@@ -1160,9 +1160,8 @@ void NavMap::sync() {
 			}
 		}
 
-		// Update the update ID.
-		// Some code treats 0 as a failure case, so we avoid returning 0.
-		map_update_id = map_update_id % 9999999 + 1;
+		// Some code treats 0 as a failure case, so we avoid returning 0 and modulo wrap UINT32_MAX manually.
+		iteration_id = iteration_id % UINT32_MAX + 1;
 	}
 
 	// Do we have modified obstacle positions?

+ 3 - 5
modules/navigation/nav_map.h

@@ -108,7 +108,7 @@ class NavMap : public NavRid {
 	real_t deltatime = 0.0;
 
 	/// Change the id each time the map is updated.
-	uint32_t map_update_id = 0;
+	uint32_t iteration_id = 0;
 
 	bool use_threads = true;
 	bool avoidance_use_multiple_threads = true;
@@ -128,6 +128,8 @@ public:
 	NavMap();
 	~NavMap();
 
+	uint32_t get_iteration_id() const { return iteration_id; }
+
 	void set_up(Vector3 p_up);
 	Vector3 get_up() const {
 		return up;
@@ -199,10 +201,6 @@ public:
 		return obstacles;
 	}
 
-	uint32_t get_map_update_id() const {
-		return map_update_id;
-	}
-
 	Vector3 get_random_point(uint32_t p_navigation_layers, bool p_uniformly) const;
 
 	void sync();

+ 2 - 2
modules/navigation/nav_obstacle.cpp

@@ -149,8 +149,8 @@ void NavObstacle::set_vertices(const Vector<Vector3> &p_vertices) {
 
 bool NavObstacle::is_map_changed() {
 	if (map) {
-		bool is_changed = map->get_map_update_id() != map_update_id;
-		map_update_id = map->get_map_update_id();
+		bool is_changed = map->get_iteration_id() != last_map_iteration_id;
+		last_map_iteration_id = map->get_iteration_id();
 		return is_changed;
 	} else {
 		return false;

+ 1 - 1
modules/navigation/nav_obstacle.h

@@ -55,7 +55,7 @@ class NavObstacle : public NavRid {
 
 	bool obstacle_dirty = true;
 
-	uint32_t map_update_id = 0;
+	uint32_t last_map_iteration_id = 0;
 	bool paused = false;
 
 public:

+ 1 - 0
servers/navigation_server_2d.cpp

@@ -58,6 +58,7 @@ void NavigationServer2D::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("map_get_obstacles", "map"), &NavigationServer2D::map_get_obstacles);
 
 	ClassDB::bind_method(D_METHOD("map_force_update", "map"), &NavigationServer2D::map_force_update);
+	ClassDB::bind_method(D_METHOD("map_get_iteration_id", "map"), &NavigationServer2D::map_get_iteration_id);
 
 	ClassDB::bind_method(D_METHOD("map_get_random_point", "map", "navigation_layers", "uniformly"), &NavigationServer2D::map_get_random_point);
 

+ 1 - 0
servers/navigation_server_2d.h

@@ -102,6 +102,7 @@ public:
 	virtual TypedArray<RID> map_get_obstacles(RID p_map) const = 0;
 
 	virtual void map_force_update(RID p_map) = 0;
+	virtual uint32_t map_get_iteration_id(RID p_map) const = 0;
 
 	virtual Vector2 map_get_random_point(RID p_map, uint32_t p_navigation_layers, bool p_uniformly) const = 0;
 

+ 1 - 0
servers/navigation_server_2d_dummy.h

@@ -59,6 +59,7 @@ public:
 	TypedArray<RID> map_get_obstacles(RID p_map) const override { return TypedArray<RID>(); }
 	void map_force_update(RID p_map) override {}
 	Vector2 map_get_random_point(RID p_map, uint32_t p_naviation_layers, bool p_uniformly) const override { return Vector2(); };
+	uint32_t map_get_iteration_id(RID p_map) const override { return 0; }
 
 	RID region_create() override { return RID(); }
 	void region_set_enabled(RID p_region, bool p_enabled) override {}

+ 1 - 0
servers/navigation_server_3d.cpp

@@ -65,6 +65,7 @@ void NavigationServer3D::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("map_get_obstacles", "map"), &NavigationServer3D::map_get_obstacles);
 
 	ClassDB::bind_method(D_METHOD("map_force_update", "map"), &NavigationServer3D::map_force_update);
+	ClassDB::bind_method(D_METHOD("map_get_iteration_id", "map"), &NavigationServer3D::map_get_iteration_id);
 
 	ClassDB::bind_method(D_METHOD("map_get_random_point", "map", "navigation_layers", "uniformly"), &NavigationServer3D::map_get_random_point);
 

+ 1 - 0
servers/navigation_server_3d.h

@@ -116,6 +116,7 @@ public:
 	virtual TypedArray<RID> map_get_obstacles(RID p_map) const = 0;
 
 	virtual void map_force_update(RID p_map) = 0;
+	virtual uint32_t map_get_iteration_id(RID p_map) const = 0;
 
 	virtual Vector3 map_get_random_point(RID p_map, uint32_t p_navigation_layers, bool p_uniformly) const = 0;
 

+ 8 - 0
servers/navigation_server_3d_dummy.h

@@ -66,6 +66,8 @@ public:
 	TypedArray<RID> map_get_agents(RID p_map) const override { return TypedArray<RID>(); }
 	TypedArray<RID> map_get_obstacles(RID p_map) const override { return TypedArray<RID>(); }
 	void map_force_update(RID p_map) override {}
+	uint32_t map_get_iteration_id(RID p_map) const override { return 0; }
+
 	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; }
@@ -92,6 +94,7 @@ public:
 	Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const override { return Vector3(); }
 	Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const override { return Vector3(); }
 	Vector3 region_get_random_point(RID p_region, uint32_t p_navigation_layers, bool p_uniformly) const override { return Vector3(); }
+
 	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(); }
@@ -111,6 +114,7 @@ public:
 	real_t link_get_travel_cost(RID p_link) const override { return 0; }
 	void link_set_owner_id(RID p_link, ObjectID p_owner_id) override {}
 	ObjectID link_get_owner_id(RID p_link) const override { return ObjectID(); }
+
 	RID agent_create() override { return RID(); }
 	void agent_set_map(RID p_agent, RID p_map) override {}
 	RID agent_get_map(RID p_agent) const override { return RID(); }
@@ -148,6 +152,7 @@ public:
 	uint32_t agent_get_avoidance_mask(RID p_agent) const override { return 0; }
 	void agent_set_avoidance_priority(RID p_agent, real_t p_priority) override {}
 	real_t agent_get_avoidance_priority(RID p_agent) const override { return 0; }
+
 	RID obstacle_create() override { return RID(); }
 	void obstacle_set_map(RID p_obstacle, RID p_map) override {}
 	RID obstacle_get_map(RID p_obstacle) const override { return RID(); }
@@ -169,6 +174,7 @@ public:
 	Vector<Vector3> obstacle_get_vertices(RID p_obstacle) const override { return Vector<Vector3>(); }
 	void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) override {}
 	uint32_t obstacle_get_avoidance_layers(RID p_obstacle) const override { return 0; }
+
 	void parse_source_geometry_data(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, Node *p_root_node, const Callable &p_callback = Callable()) override {}
 	void bake_from_source_geometry_data(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, const Callable &p_callback = Callable()) override {}
 	void bake_from_source_geometry_data_async(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, const Callable &p_callback = Callable()) override {}
@@ -180,8 +186,10 @@ public:
 	void init() override {}
 	void sync() override {}
 	void finish() override {}
+
 	NavigationUtilities::PathQueryResult _query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const override { return NavigationUtilities::PathQueryResult(); }
 	int get_process_info(ProcessInfo p_info) const override { return 0; }
+
 	void set_debug_enabled(bool p_enabled) {}
 	bool get_debug_enabled() const { return false; }
 };