diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index f09b76799..3e3643c46 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -34,6 +34,8 @@ #include "core/containers/vector.h" #include "scene/2d/navigation_2d.h" #include "scene/resources/world_2d.h" +#include "servers/navigation/navigation_path_query_parameters_2d.h" +#include "servers/navigation/navigation_path_query_result_2d.h" #include "servers/navigation_2d_server.h" void NavigationAgent2D::_bind_methods() { @@ -244,17 +246,20 @@ NavigationAgent2D::NavigationAgent2D() { navigation_finished = true; agent = Navigation2DServer::get_singleton()->agent_create(); - set_neighbor_dist(0.0); - set_max_neighbors(0); - set_time_horizon(0.0); - set_radius(0.0); - set_max_speed(0.0); + set_neighbor_dist(500.0); + set_max_neighbors(10); + set_time_horizon(20.0); + set_radius(10.0); + set_max_speed(200.0); time_horizon = 0.0; nav_path_index = 0; update_frame_id = 0; + navigation_query.instance(); + navigation_result.instance(); + #ifdef DEBUG_ENABLED debug_enabled = false; debug_path_dirty = true; @@ -434,6 +439,8 @@ Vector2 NavigationAgent2D::get_target_position() const { Vector2 NavigationAgent2D::get_next_position() { update_navigation(); + + const PoolVector &navigation_path = navigation_result->get_path(); if (navigation_path.size() == 0) { ERR_FAIL_COND_V(agent_parent == nullptr, Vector2()); return agent_parent->get_global_transform().get_origin(); @@ -442,6 +449,10 @@ Vector2 NavigationAgent2D::get_next_position() { } } +const PoolVector &NavigationAgent2D::get_nav_path() const { + return navigation_result->get_path(); +} + real_t NavigationAgent2D::distance_to_target() const { ERR_FAIL_COND_V(agent_parent == nullptr, 0.0); return agent_parent->get_global_transform().get_origin().distance_to(target_position); @@ -462,6 +473,8 @@ bool NavigationAgent2D::is_navigation_finished() { Vector2 NavigationAgent2D::get_final_position() { update_navigation(); + + const PoolVector &navigation_path = navigation_result->get_path(); if (navigation_path.size() == 0) { return Vector2(); } @@ -509,22 +522,24 @@ void NavigationAgent2D::update_navigation() { update_frame_id = Engine::get_singleton()->get_physics_frames(); - Vector2 o = agent_parent->get_global_transform().get_origin(); + Vector2 origin = agent_parent->get_global_transform().get_origin(); bool reload_path = false; if (Navigation2DServer::get_singleton()->agent_is_map_changed(agent)) { reload_path = true; - } else if (navigation_path.size() == 0) { + } else if (navigation_result->get_path().size() == 0) { reload_path = true; } else { // Check if too far from the navigation path if (nav_path_index > 0) { + const PoolVector &navigation_path = navigation_result->get_path(); + Vector2 segment[2]; segment[0] = navigation_path[nav_path_index - 1]; segment[1] = navigation_path[nav_path_index]; - Vector2 p = Geometry::get_closest_point_to_segment_2d(o, segment); - if (o.distance_to(p) >= path_max_distance) { + Vector2 p = Geometry::get_closest_point_to_segment_2d(origin, segment); + if (origin.distance_to(p) >= path_max_distance) { // To faraway, reload path reload_path = true; } @@ -532,14 +547,20 @@ void NavigationAgent2D::update_navigation() { } if (reload_path) { + navigation_query->set_start_position(origin); + navigation_query->set_target_position(target_position); + navigation_query->set_navigation_layers(navigation_layers); + if (map_override.is_valid()) { - navigation_path = Navigation2DServer::get_singleton()->map_get_path(map_override, o, target_position, true, navigation_layers); + navigation_query->set_map(map_override); } else if (navigation != nullptr) { - navigation_path = Navigation2DServer::get_singleton()->map_get_path(navigation->get_rid(), o, target_position, true, navigation_layers); + navigation_query->set_map(navigation->get_rid()); } else { - navigation_path = Navigation2DServer::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_position, true, navigation_layers); + navigation_query->set_map(agent_parent->get_world_2d()->get_navigation_map()); } + Navigation2DServer::get_singleton()->query_path(navigation_query, navigation_result); + #ifdef DEBUG_ENABLED debug_path_dirty = true; #endif // DEBUG_ENABLED @@ -549,14 +570,15 @@ void NavigationAgent2D::update_navigation() { emit_signal("path_changed"); } - if (navigation_path.size() == 0) { + if (navigation_result->get_path().size() == 0) { return; } // Check if we can advance the navigation path if (navigation_finished == false) { // Advances to the next far away position. - while (o.distance_to(navigation_path[nav_path_index]) < path_desired_distance) { + const PoolVector &navigation_path = navigation_result->get_path(); + while (origin.distance_to(navigation_path[nav_path_index]) < path_desired_distance) { nav_path_index += 1; if (nav_path_index == navigation_path.size()) { _check_distance_to_target(); @@ -570,7 +592,7 @@ void NavigationAgent2D::update_navigation() { } void NavigationAgent2D::_request_repath() { - navigation_path.clear(); + navigation_result->reset(); target_reached = false; navigation_finished = false; update_frame_id = 0; @@ -660,7 +682,7 @@ void NavigationAgent2D::_update_debug_path() { RenderingServer::get_singleton()->canvas_item_set_parent(debug_path_instance, agent_parent->get_canvas()); RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, agent_parent->is_visible_in_tree()); - //const Vector &navigation_path = navigation_result->get_path(); + const PoolVector &navigation_path = navigation_result->get_path(); if (navigation_path.size() <= 1) { return; @@ -675,7 +697,8 @@ void NavigationAgent2D::_update_debug_path() { debug_path_colors.resize(navigation_path.size()); debug_path_colors.fill(debug_path_color); - RenderingServer::get_singleton()->canvas_item_add_polyline(debug_path_instance, navigation_path, debug_path_colors, debug_path_custom_line_width, false); + //TODO + //RenderingServer::get_singleton()->canvas_item_add_polyline(debug_path_instance, navigation_path, debug_path_colors, debug_path_custom_line_width, false); float point_size = Navigation2DServer::get_singleton()->get_debug_navigation_agent_path_point_size(); float half_point_size = point_size * 0.5; diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 691794f2d..e15750d26 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -34,6 +34,8 @@ class Node2D; class Navigation2D; +class NavigationPathQueryParameters2D; +class NavigationPathQueryResult2D; class NavigationAgent2D : public Node { GDCLASS(NavigationAgent2D, Node); @@ -59,7 +61,8 @@ class NavigationAgent2D : public Node { real_t path_max_distance; Vector2 target_position; - Vector navigation_path; + Ref navigation_query; + Ref navigation_result; int nav_path_index; bool velocity_submitted; Vector2 prev_safe_velocity; @@ -161,9 +164,7 @@ public: Vector2 get_next_position(); - Vector get_nav_path() const { - return navigation_path; - } + const PoolVector &get_nav_path() const; int get_nav_path_index() const { return nav_path_index; diff --git a/scene/3d/navigation_agent.cpp b/scene/3d/navigation_agent.cpp index 0c2d23f63..e99e73aa5 100644 --- a/scene/3d/navigation_agent.cpp +++ b/scene/3d/navigation_agent.cpp @@ -36,6 +36,8 @@ #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "scene/resources/world_3d.h" +#include "servers/navigation/navigation_path_query_parameters_3d.h" +#include "servers/navigation/navigation_path_query_result_3d.h" #include "servers/navigation_server.h" void NavigationAgent::_bind_methods() { @@ -261,6 +263,9 @@ NavigationAgent::NavigationAgent() { nav_path_index = 0; update_frame_id = 0; + navigation_query.instance(); + navigation_result.instance(); + #ifdef DEBUG_ENABLED debug_enabled = false; debug_path_dirty = true; @@ -451,6 +456,8 @@ Vector3 NavigationAgent::get_target_position() const { Vector3 NavigationAgent::get_next_position() { update_navigation(); + + const PoolVector &navigation_path = navigation_result->get_path(); if (navigation_path.size() == 0) { ERR_FAIL_COND_V_MSG(agent_parent == nullptr, Vector3(), "The agent has no parent."); return agent_parent->get_global_transform().origin; @@ -459,6 +466,10 @@ Vector3 NavigationAgent::get_next_position() { } } +const PoolVector &NavigationAgent::get_nav_path() const { + return navigation_result->get_path(); +} + real_t NavigationAgent::distance_to_target() const { ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent."); return agent_parent->get_global_transform().origin.distance_to(target_position); @@ -479,6 +490,9 @@ bool NavigationAgent::is_navigation_finished() { Vector3 NavigationAgent::get_final_position() { update_navigation(); + + const PoolVector &navigation_path = navigation_result->get_path(); + if (navigation_path.size() == 0) { return Vector3(); } @@ -528,25 +542,27 @@ void NavigationAgent::update_navigation() { update_frame_id = Engine::get_singleton()->get_physics_frames(); - Vector3 o = agent_parent->get_global_transform().origin; + Vector3 origin = agent_parent->get_global_transform().origin; bool reload_path = false; if (NavigationServer::get_singleton()->agent_is_map_changed(agent)) { reload_path = true; - } else if (navigation_path.size() == 0) { + } else if (navigation_result->get_path().size() == 0) { reload_path = true; } else { // Check if too far from the navigation path if (nav_path_index > 0) { + const PoolVector &navigation_path = navigation_result->get_path(); + Vector3 segment[2]; segment[0] = navigation_path[nav_path_index - 1]; segment[1] = navigation_path[nav_path_index]; segment[0].y -= navigation_height_offset; segment[1].y -= navigation_height_offset; - Vector3 p = Geometry::get_closest_point_to_segment(o, segment); + Vector3 p = Geometry::get_closest_point_to_segment(origin, segment); - if (o.distance_to(p) >= path_max_distance) { + if (origin.distance_to(p) >= path_max_distance) { // To faraway, reload path reload_path = true; } @@ -554,14 +570,21 @@ void NavigationAgent::update_navigation() { } if (reload_path) { + navigation_query->set_start_position(origin); + navigation_query->set_target_position(target_position); + navigation_query->set_navigation_layers(navigation_layers); + + if (map_override.is_valid()) { - navigation_path = NavigationServer::get_singleton()->map_get_path(map_override, o, target_position, true, navigation_layers); + navigation_query->set_map(map_override); } else if (navigation != nullptr) { - navigation_path = NavigationServer::get_singleton()->map_get_path(navigation->get_rid(), o, target_position, true, navigation_layers); + navigation_query->set_map(navigation->get_rid()); } else { - navigation_path = NavigationServer::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_position, true, navigation_layers); + navigation_query->set_map(agent_parent->get_world_3d()->get_navigation_map()); } + NavigationServer::get_singleton()->query_path(navigation_query, navigation_result); + #ifdef DEBUG_ENABLED debug_path_dirty = true; #endif // DEBUG_ENABLED @@ -571,14 +594,15 @@ void NavigationAgent::update_navigation() { emit_signal("path_changed"); } - if (navigation_path.size() == 0) { + if (navigation_result->get_path().size() == 0) { return; } // Check if we can advance the navigation path if (navigation_finished == false) { // Advances to the next far away position. - while (o.distance_to(navigation_path[nav_path_index] - Vector3(0, navigation_height_offset, 0)) < path_desired_distance) { + const PoolVector &navigation_path = navigation_result->get_path(); + while (origin.distance_to(navigation_path[nav_path_index] - Vector3(0, navigation_height_offset, 0)) < path_desired_distance) { nav_path_index += 1; if (nav_path_index == navigation_path.size()) { _check_distance_to_target(); @@ -592,7 +616,7 @@ void NavigationAgent::update_navigation() { } void NavigationAgent::_request_repath() { - navigation_path.clear(); + navigation_result->reset(); target_reached = false; navigation_finished = false; update_frame_id = 0; @@ -674,7 +698,7 @@ void NavigationAgent::_update_debug_path() { return; } - //const Vector &navigation_path = navigation_result->get_path(); + const PoolVector &navigation_path = navigation_result->get_path(); if (navigation_path.size() <= 1) { return; diff --git a/scene/3d/navigation_agent.h b/scene/3d/navigation_agent.h index 89d9032a2..92bb86b3d 100644 --- a/scene/3d/navigation_agent.h +++ b/scene/3d/navigation_agent.h @@ -36,6 +36,8 @@ class Spatial; class Navigation; class SpatialMaterial; +class NavigationPathQueryParameters3D; +class NavigationPathQueryResult3D; class NavigationAgent : public Node { GDCLASS(NavigationAgent, Node); @@ -63,7 +65,8 @@ class NavigationAgent : public Node { real_t path_max_distance; Vector3 target_position; - Vector navigation_path; + Ref navigation_query; + Ref navigation_result; int nav_path_index; bool velocity_submitted; Vector3 prev_safe_velocity; @@ -177,9 +180,7 @@ public: Vector3 get_next_position(); - Vector get_nav_path() const { - return navigation_path; - } + const PoolVector &get_nav_path() const; int get_nav_path_index() const { return nav_path_index;