From 8df9fd076f3bc960657111773f52f61b4a654ec1 Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Fri, 20 May 2022 22:55:27 +0200 Subject: [PATCH] Process NavigationAgent2D/3D avoidance on demand only Changes NavigationAgent avoidance callback to a toggle that is disabled by default. Also fixes a few missing descriptions / wrong warnings. (cherry picked from commit 7f3688603cb3662e425cb7a1dce15459162c1dc6) --- doc/classes/NavigationAgent.xml | 5 ++++- doc/classes/NavigationAgent2D.xml | 5 ++++- scene/2d/navigation_agent_2d.cpp | 22 ++++++++++++++++++++-- scene/2d/navigation_agent_2d.h | 5 +++++ scene/3d/navigation_agent.cpp | 22 ++++++++++++++++++++-- scene/3d/navigation_agent.h | 5 +++++ 6 files changed, 58 insertions(+), 6 deletions(-) diff --git a/doc/classes/NavigationAgent.xml b/doc/classes/NavigationAgent.xml index fdc680b8c16..03941689ae3 100644 --- a/doc/classes/NavigationAgent.xml +++ b/doc/classes/NavigationAgent.xml @@ -48,7 +48,7 @@ - Returns the object's [RID]. + Returns the [RID] of this agent on the [NavigationServer]. @@ -101,6 +101,9 @@ The agent height offset to match the navigation mesh height. + + If [code]true[/code] the agent is registered for an RVO avoidance callback on the [NavigationServer]. When [method set_velocity] is used and the processing is completed a [code]safe_velocity[/code] Vector3 is received with a signal connection to [signal velocity_computed]. Avoidance processing with many registered agents has a significant performance cost and should only be enabled on agents that currently require it. + Ignores collisions on the Y axis. Must be [code]true[/code] to move on a horizontal plane. diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml index c2bce448801..bfbcbca7320 100644 --- a/doc/classes/NavigationAgent2D.xml +++ b/doc/classes/NavigationAgent2D.xml @@ -48,7 +48,7 @@ - Returns the object's [RID]. + Returns the [RID] of this agent on the [Navigation2DServer]. @@ -98,6 +98,9 @@ + + If [code]true[/code] the agent is registered for an RVO avoidance callback on the [Navigation2DServer]. When [method set_velocity] is used and the processing is completed a [code]safe_velocity[/code] Vector2 is received with a signal connection to [signal velocity_computed]. Avoidance processing with many registered agents has a significant performance cost and should only be enabled on agents that currently require it. + The maximum number of neighbors for the agent to consider. diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index a00b4d10a89..a126704215b 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -37,6 +37,9 @@ void NavigationAgent2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rid"), &NavigationAgent2D::get_rid); + ClassDB::bind_method(D_METHOD("set_avoidance_enabled", "enabled"), &NavigationAgent2D::set_avoidance_enabled); + ClassDB::bind_method(D_METHOD("get_avoidance_enabled"), &NavigationAgent2D::get_avoidance_enabled); + ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance); ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance); @@ -82,6 +85,7 @@ void NavigationAgent2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_time_horizon", "get_time_horizon"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_max_speed", "get_max_speed"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1"), "set_path_max_distance", "get_path_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled"); ADD_SIGNAL(MethodInfo("path_changed")); ADD_SIGNAL(MethodInfo("target_reached")); @@ -94,7 +98,7 @@ void NavigationAgent2D::_notification(int p_what) { case NOTIFICATION_READY: { agent_parent = Object::cast_to(get_parent()); - Navigation2DServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); + set_avoidance_enabled(avoidance_enabled); // Search the navigation node and set it { @@ -153,6 +157,7 @@ NavigationAgent2D::NavigationAgent2D() : agent_parent(nullptr), navigation(nullptr), agent(RID()), + avoidance_enabled(false), target_desired_distance(1.0), path_max_distance(3.0), velocity_submitted(false), @@ -171,6 +176,19 @@ NavigationAgent2D::~NavigationAgent2D() { agent = RID(); // Pointless } +void NavigationAgent2D::set_avoidance_enabled(bool p_enabled) { + avoidance_enabled = p_enabled; + if (avoidance_enabled) { + Navigation2DServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); + } else { + Navigation2DServer::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done"); + } +} + +bool NavigationAgent2D::get_avoidance_enabled() const { + return avoidance_enabled; +} + void NavigationAgent2D::set_navigation(Navigation2D *p_nav) { if (navigation == p_nav) { return; // Pointless @@ -297,7 +315,7 @@ void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) { String NavigationAgent2D::get_configuration_warning() const { if (!Object::cast_to(get_parent())) { - return TTR("The NavigationAgent2D can be used only under a Node2D node."); + return TTR("The NavigationAgent2D can be used only under a Node2D inheriting parent node."); } return String(); diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index ff508c9733a..93d12dc6cdf 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -46,6 +46,8 @@ class NavigationAgent2D : public Node { RID agent; RID map_before_pause; + bool avoidance_enabled; + real_t target_desired_distance; real_t radius; real_t neighbor_dist; @@ -87,6 +89,9 @@ public: return agent; } + void set_avoidance_enabled(bool p_enabled); + bool get_avoidance_enabled() const; + void set_target_desired_distance(real_t p_dd); real_t get_target_desired_distance() const { return target_desired_distance; diff --git a/scene/3d/navigation_agent.cpp b/scene/3d/navigation_agent.cpp index 23d2a9a5434..92f5528d595 100644 --- a/scene/3d/navigation_agent.cpp +++ b/scene/3d/navigation_agent.cpp @@ -37,6 +37,9 @@ void NavigationAgent::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rid"), &NavigationAgent::get_rid); + ClassDB::bind_method(D_METHOD("set_avoidance_enabled", "enabled"), &NavigationAgent::set_avoidance_enabled); + ClassDB::bind_method(D_METHOD("get_avoidance_enabled"), &NavigationAgent::get_avoidance_enabled); + ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent::set_target_desired_distance); ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent::get_target_desired_distance); @@ -90,6 +93,7 @@ void NavigationAgent::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_max_speed", "get_max_speed"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1"), "set_path_max_distance", "get_path_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled"); ADD_SIGNAL(MethodInfo("path_changed")); ADD_SIGNAL(MethodInfo("target_reached")); @@ -102,7 +106,7 @@ void NavigationAgent::_notification(int p_what) { case NOTIFICATION_READY: { agent_parent = Object::cast_to(get_parent()); - NavigationServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); + set_avoidance_enabled(avoidance_enabled); // Search the navigation node and set it { @@ -161,6 +165,7 @@ NavigationAgent::NavigationAgent() : agent_parent(nullptr), navigation(nullptr), agent(RID()), + avoidance_enabled(false), target_desired_distance(1.0), navigation_height_offset(0.0), path_max_distance(3.0), @@ -181,6 +186,19 @@ NavigationAgent::~NavigationAgent() { agent = RID(); // Pointless } +void NavigationAgent::set_avoidance_enabled(bool p_enabled) { + avoidance_enabled = p_enabled; + if (avoidance_enabled) { + NavigationServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); + } else { + NavigationServer::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done"); + } +} + +bool NavigationAgent::get_avoidance_enabled() const { + return avoidance_enabled; +} + void NavigationAgent::set_navigation(Navigation *p_nav) { if (navigation == p_nav) { return; // Pointless @@ -315,7 +333,7 @@ void NavigationAgent::_avoidance_done(Vector3 p_new_velocity) { String NavigationAgent::get_configuration_warning() const { if (!Object::cast_to(get_parent())) { - return TTR("The NavigationAgent can be used only under a spatial node."); + return TTR("The NavigationAgent can be used only under a Spatial inheriting parent node."); } return String(); diff --git a/scene/3d/navigation_agent.h b/scene/3d/navigation_agent.h index 5c5d67c9354..b2c57326f44 100644 --- a/scene/3d/navigation_agent.h +++ b/scene/3d/navigation_agent.h @@ -46,6 +46,8 @@ class NavigationAgent : public Node { RID agent; RID map_before_pause; + bool avoidance_enabled; + real_t target_desired_distance; real_t radius; real_t navigation_height_offset; @@ -89,6 +91,9 @@ public: return agent; } + void set_avoidance_enabled(bool p_enabled); + bool get_avoidance_enabled() const; + void set_target_desired_distance(real_t p_dd); real_t get_target_desired_distance() const { return target_desired_distance;