Merge pull request #66806 from smix8/navigation_avoidance_nothread_3.x

Fix avoidance calculation on NO_THREADS build
This commit is contained in:
Rémi Verschelde 2022-10-03 13:58:35 +02:00
commit ecaf2b0322
5 changed files with 14 additions and 0 deletions

View file

@ -6,6 +6,7 @@
<description> <description>
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 [World] 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. 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 [World] 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] 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.
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>

View file

@ -6,6 +6,7 @@
<description> <description>
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. 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] 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.
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>

View file

@ -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. 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. 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] 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. 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.
</description> </description>
<tutorials> <tutorials>

View file

@ -690,6 +690,7 @@ void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) {
void NavMap::step(real_t p_deltatime) { void NavMap::step(real_t p_deltatime) {
deltatime = p_deltatime; deltatime = p_deltatime;
if (controlled_agents.size() > 0) { if (controlled_agents.size() > 0) {
#ifndef NO_THREADS
if (step_work_pool.get_thread_count() == 0) { if (step_work_pool.get_thread_count() == 0) {
step_work_pool.init(); step_work_pool.init();
} }
@ -698,6 +699,12 @@ void NavMap::step(real_t p_deltatime) {
this, this,
&NavMap::compute_single_step, &NavMap::compute_single_step,
controlled_agents.ptr()); controlled_agents.ptr());
#else
for (int i(0); i < static_cast<int>(controlled_agents.size()); i++) {
controlled_agents[i]->get_agent()->computeNeighbors(&rvo);
controlled_agents[i]->get_agent()->computeNewVelocity(deltatime);
}
#endif // NO_THREADS
} }
} }
@ -743,5 +750,7 @@ NavMap::NavMap() {
} }
NavMap::~NavMap() { NavMap::~NavMap() {
#ifndef NO_THREADS
step_work_pool.finish(); step_work_pool.finish();
#endif // !NO_THREADS
} }

View file

@ -82,8 +82,10 @@ class NavMap : public NavRid {
/// Change the id each time the map is updated. /// Change the id each time the map is updated.
uint32_t map_update_id = 0; uint32_t map_update_id = 0;
#ifndef NO_THREADS
/// Pooled threads for computing steps /// Pooled threads for computing steps
ThreadWorkPool step_work_pool; ThreadWorkPool step_work_pool;
#endif // NO_THREADS
public: public:
NavMap(); NavMap();