From 1c0898763c40d4eaf46b17b10b85282799041ec6 Mon Sep 17 00:00:00 2001
From: smix8 <52464204+smix8@users.noreply.github.com>
Date: Mon, 3 Oct 2022 11:51:17 +0200
Subject: [PATCH] Fix avoidance calculation on NO_THREADS build
---
doc/classes/NavigationAgent.xml | 1 +
doc/classes/NavigationAgent2D.xml | 1 +
doc/classes/NavigationServer.xml | 1 +
modules/navigation/nav_map.cpp | 9 +++++++++
modules/navigation/nav_map.h | 2 ++
5 files changed, 14 insertions(+)
diff --git a/doc/classes/NavigationAgent.xml b/doc/classes/NavigationAgent.xml
index c98c8eeed..bef7a58f4 100644
--- a/doc/classes/NavigationAgent.xml
+++ b/doc/classes/NavigationAgent.xml
@@ -6,6 +6,7 @@
3D agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO (Reciprocal Velocity Obstacles) collision avoidance. The agent needs navigation data to work correctly. By default this node will register to the default [World3D] navigation map. If this node is a child of a [Navigation] node it will register to the navigation map of the navigation node or the function [method set_navigation] can be used to set the navigation node directly. [NavigationAgent] is physics safe.
[b]Note:[/b] After [method set_target_location] is used it is required to use the [method get_next_location] function once every physics frame to update the internal path logic of the NavigationAgent. The returned vector position from this function should be used as the next movement position for the agent's parent Node.
+ [b]Note:[/b] By default, the expensive calculations for avoidance are done in a thread. In HTML5 exports without thread support, they will be done on the main thread, which can lead to performance issues.
diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml
index 5d060d4ea..b31c6383e 100644
--- a/doc/classes/NavigationAgent2D.xml
+++ b/doc/classes/NavigationAgent2D.xml
@@ -6,6 +6,7 @@
2D agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO (Reciprocal Velocity Obstacles) collision avoidance. The agent needs navigation data to work correctly. By default this node will register to the default [World2D] navigation map. If this node is a child of a [Navigation2D] node it will register to the navigation map of the navigation node or the function [method set_navigation] can be used to set the navigation node directly. [NavigationAgent2D] is physics safe.
[b]Note:[/b] After [method set_target_location] is used it is required to use the [method get_next_location] function once every physics frame to update the internal path logic of the NavigationAgent. The returned vector position from this function should be used as the next movement position for the agent's parent Node.
+ [b]Note:[/b] By default, the expensive calculations for avoidance are done in a thread. In HTML5 exports without thread support, they will be done on the main thread, which can lead to performance issues.
diff --git a/doc/classes/NavigationServer.xml b/doc/classes/NavigationServer.xml
index d780f594a..c120c6de4 100644
--- a/doc/classes/NavigationServer.xml
+++ b/doc/classes/NavigationServer.xml
@@ -10,6 +10,7 @@
For two regions to be connected to each other, they must share a similar edge. An edge is considered connected to another if both of its two vertices are at a distance less than [member Navigation.edge_connection_margin] to the respective other edge's vertex.
To use the collision avoidance system, you may use agents. You can set an agent's target velocity, then the servers will emit a callback with a modified velocity.
[b]Note:[/b] The collision avoidance system ignores regions. Using the modified velocity as-is might lead to pushing and agent outside of a navigable area. This is a limitation of the collision avoidance system, any more complex situation may require the use of the physics engine.
+ [b]Note:[/b] By default, the expensive calculations for avoidance are done in a thread. In HTML5 exports without thread support, they will be done on the main thread, which can lead to performance issues.
This server keeps tracks of any call and executes them during the sync phase. This means that you can request any change to the map, using any thread, without worrying.
diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp
index f01746132..cfca657f1 100644
--- a/modules/navigation/nav_map.cpp
+++ b/modules/navigation/nav_map.cpp
@@ -702,6 +702,7 @@ void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) {
void NavMap::step(real_t p_deltatime) {
deltatime = p_deltatime;
if (controlled_agents.size() > 0) {
+#ifndef NO_THREADS
if (step_work_pool.get_thread_count() == 0) {
step_work_pool.init();
}
@@ -710,6 +711,12 @@ void NavMap::step(real_t p_deltatime) {
this,
&NavMap::compute_single_step,
controlled_agents.ptr());
+#else
+ for (int i(0); i < static_cast(controlled_agents.size()); i++) {
+ controlled_agents[i]->get_agent()->computeNeighbors(&rvo);
+ controlled_agents[i]->get_agent()->computeNewVelocity(deltatime);
+ }
+#endif // NO_THREADS
}
}
@@ -767,5 +774,7 @@ NavMap::NavMap() {
}
NavMap::~NavMap() {
+#ifndef NO_THREADS
step_work_pool.finish();
+#endif // !NO_THREADS
}
diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h
index 519db5114..8c14da647 100644
--- a/modules/navigation/nav_map.h
+++ b/modules/navigation/nav_map.h
@@ -82,8 +82,10 @@ class NavMap : public NavRid {
/// Change the id each time the map is updated.
uint32_t map_update_id;
+#ifndef NO_THREADS
/// Pooled threads for computing steps
ThreadWorkPool step_work_pool;
+#endif // NO_THREADS
public:
NavMap();