Skip to content

Commit

Permalink
Update NavigationAgent to use query_path
Browse files Browse the repository at this point in the history
This paves the way for having agents respond to link traversal.
  • Loading branch information
DarkKilauea committed Sep 29, 2022
1 parent c2f6664 commit a2c53b8
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 26 deletions.
8 changes: 8 additions & 0 deletions doc/classes/NavigationPathQueryResult2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
</description>
<tutorials>
</tutorials>
<methods>
<method name="reset">
<return type="void" />
<description>
Reset the result object to its initial state. This is useful to reuse the object across multiple queries.
</description>
</method>
</methods>
<members>
<member name="path" type="PackedVector2Array" setter="set_path" getter="get_path" default="PackedVector2Array()">
The resulting path array from the navigation query. All path array positions are in global coordinates. Without customized query parameters this is the same path as returned by [method NavigationServer2D.map_get_path].
Expand Down
8 changes: 8 additions & 0 deletions doc/classes/NavigationPathQueryResult3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
</description>
<tutorials>
</tutorials>
<methods>
<method name="reset">
<return type="void" />
<description>
Reset the result object to its initial state. This is useful to reuse the object across multiple queries.
</description>
</method>
</methods>
<members>
<member name="path" type="PackedVector3Array" setter="set_path" getter="get_path" default="PackedVector3Array()">
The resulting path array from the navigation query. All path array positions are in global coordinates. Without customized query parameters this is the same path as returned by [method NavigationServer3D.map_get_path].
Expand Down
42 changes: 33 additions & 9 deletions scene/2d/navigation_agent_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@ NavigationAgent2D::NavigationAgent2D() {
set_time_horizon(20.0);
set_radius(10.0);
set_max_speed(200.0);

// Preallocate query and result objects to improve performance.
navigation_query = Ref<NavigationPathQueryParameters2D>();
navigation_query.instantiate();

navigation_result = Ref<NavigationPathQueryResult2D>();
navigation_result.instantiate();
}

NavigationAgent2D::~NavigationAgent2D() {
Expand Down Expand Up @@ -314,6 +321,8 @@ Vector2 NavigationAgent2D::get_target_location() const {

Vector2 NavigationAgent2D::get_next_location() {
update_navigation();

const Vector<Vector2> &navigation_path = navigation_result->get_path();
if (navigation_path.size() == 0) {
ERR_FAIL_COND_V_MSG(agent_parent == nullptr, Vector2(), "The agent has no parent.");
return agent_parent->get_global_position();
Expand All @@ -322,6 +331,10 @@ Vector2 NavigationAgent2D::get_next_location() {
}
}

const Vector<Vector2> &NavigationAgent2D::get_nav_path() const {
return navigation_result->get_path();
}

real_t NavigationAgent2D::distance_to_target() const {
ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent.");
return agent_parent->get_global_position().distance_to(target_location);
Expand All @@ -342,6 +355,8 @@ bool NavigationAgent2D::is_navigation_finished() {

Vector2 NavigationAgent2D::get_final_location() {
update_navigation();

const Vector<Vector2> &navigation_path = navigation_result->get_path();
if (navigation_path.size() == 0) {
return Vector2();
}
Expand Down Expand Up @@ -391,47 +406,56 @@ void NavigationAgent2D::update_navigation() {

update_frame_id = Engine::get_singleton()->get_physics_frames();

Vector2 o = agent_parent->get_global_position();
Vector2 origin = agent_parent->get_global_position();

bool reload_path = false;

if (NavigationServer2D::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 Vector<Vector2> &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 = Geometry2D::get_closest_point_to_segment(o, segment);
if (o.distance_to(p) >= path_max_distance) {
Vector2 p = Geometry2D::get_closest_point_to_segment(origin, segment);
if (origin.distance_to(p) >= path_max_distance) {
// To faraway, reload path
reload_path = true;
}
}
}

if (reload_path) {
navigation_query->set_start_position(origin);
navigation_query->set_target_position(target_location);
navigation_query->set_navigation_layers(navigation_layers);

if (map_override.is_valid()) {
navigation_path = NavigationServer2D::get_singleton()->map_get_path(map_override, o, target_location, true, navigation_layers);
navigation_query->set_map(map_override);
} else {
navigation_path = NavigationServer2D::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_location, true, navigation_layers);
navigation_query->set_map(agent_parent->get_world_2d()->get_navigation_map());
}

NavigationServer2D::get_singleton()->query_path(navigation_query, navigation_result);
navigation_finished = false;
nav_path_index = 0;
emit_signal(SNAME("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 location.
while (o.distance_to(navigation_path[nav_path_index]) < path_desired_distance) {
const Vector<Vector2> &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();
Expand All @@ -445,7 +469,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;
Expand Down
9 changes: 5 additions & 4 deletions scene/2d/navigation_agent_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include "scene/main/node.h"

class Node2D;
class NavigationPathQueryParameters2D;
class NavigationPathQueryResult2D;

class NavigationAgent2D : public Node {
GDCLASS(NavigationAgent2D, Node);
Expand All @@ -58,7 +60,8 @@ class NavigationAgent2D : public Node {
real_t path_max_distance = 3.0;

Vector2 target_location;
Vector<Vector2> navigation_path;
Ref<NavigationPathQueryParameters2D> navigation_query;
Ref<NavigationPathQueryResult2D> navigation_result;
int nav_path_index = 0;
bool velocity_submitted = false;
Vector2 prev_safe_velocity;
Expand Down Expand Up @@ -138,9 +141,7 @@ class NavigationAgent2D : public Node {

Vector2 get_next_location();

Vector<Vector2> get_nav_path() const {
return navigation_path;
}
const Vector<Vector2> &get_nav_path() const;

int get_nav_path_index() const {
return nav_path_index;
Expand Down
42 changes: 33 additions & 9 deletions scene/3d/navigation_agent_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ NavigationAgent3D::NavigationAgent3D() {
set_radius(1.0);
set_max_speed(10.0);
set_ignore_y(true);

// Preallocate query and result objects to improve performance.
navigation_query = Ref<NavigationPathQueryParameters3D>();
navigation_query.instantiate();

navigation_result = Ref<NavigationPathQueryResult3D>();
navigation_result.instantiate();
}

NavigationAgent3D::~NavigationAgent3D() {
Expand Down Expand Up @@ -330,6 +337,8 @@ Vector3 NavigationAgent3D::get_target_location() const {

Vector3 NavigationAgent3D::get_next_location() {
update_navigation();

const Vector<Vector3> &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;
Expand All @@ -338,6 +347,10 @@ Vector3 NavigationAgent3D::get_next_location() {
}
}

const Vector<Vector3> &NavigationAgent3D::get_nav_path() const {
return navigation_result->get_path();
}

real_t NavigationAgent3D::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_location);
Expand All @@ -358,6 +371,8 @@ bool NavigationAgent3D::is_navigation_finished() {

Vector3 NavigationAgent3D::get_final_location() {
update_navigation();

const Vector<Vector3> &navigation_path = navigation_result->get_path();
if (navigation_path.size() == 0) {
return Vector3();
}
Expand Down Expand Up @@ -406,49 +421,58 @@ void NavigationAgent3D::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 (NavigationServer3D::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 Vector<Vector3> &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 = Geometry3D::get_closest_point_to_segment(o, segment);
if (o.distance_to(p) >= path_max_distance) {
Vector3 p = Geometry3D::get_closest_point_to_segment(origin, segment);
if (origin.distance_to(p) >= path_max_distance) {
// To faraway, reload path
reload_path = true;
}
}
}

if (reload_path) {
navigation_query->set_start_position(origin);
navigation_query->set_target_position(target_location);
navigation_query->set_navigation_layers(navigation_layers);

if (map_override.is_valid()) {
navigation_path = NavigationServer3D::get_singleton()->map_get_path(map_override, o, target_location, true, navigation_layers);
navigation_query->set_map(map_override);
} else {
navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true, navigation_layers);
navigation_query->set_map(agent_parent->get_world_3d()->get_navigation_map());
}

NavigationServer3D::get_singleton()->query_path(navigation_query, navigation_result);
navigation_finished = false;
nav_path_index = 0;
emit_signal(SNAME("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 location.
while (o.distance_to(navigation_path[nav_path_index] - Vector3(0, navigation_height_offset, 0)) < path_desired_distance) {
const Vector<Vector3> &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();
Expand All @@ -462,7 +486,7 @@ void NavigationAgent3D::update_navigation() {
}

void NavigationAgent3D::_request_repath() {
navigation_path.clear();
navigation_result->reset();
target_reached = false;
navigation_finished = false;
update_frame_id = 0;
Expand Down
9 changes: 5 additions & 4 deletions scene/3d/navigation_agent_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include "scene/main/node.h"

class Node3D;
class NavigationPathQueryParameters3D;
class NavigationPathQueryResult3D;

class NavigationAgent3D : public Node {
GDCLASS(NavigationAgent3D, Node);
Expand All @@ -60,7 +62,8 @@ class NavigationAgent3D : public Node {
real_t path_max_distance = 3.0;

Vector3 target_location;
Vector<Vector3> navigation_path;
Ref<NavigationPathQueryParameters3D> navigation_query;
Ref<NavigationPathQueryResult3D> navigation_result;
int nav_path_index = 0;
bool velocity_submitted = false;
Vector3 prev_safe_velocity;
Expand Down Expand Up @@ -150,9 +153,7 @@ class NavigationAgent3D : public Node {

Vector3 get_next_location();

Vector<Vector3> get_nav_path() const {
return navigation_path;
}
const Vector<Vector3> &get_nav_path() const;

int get_nav_path_index() const {
return nav_path_index;
Expand Down
6 changes: 6 additions & 0 deletions servers/navigation/navigation_path_query_result_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,15 @@ const Vector<Vector2> &NavigationPathQueryResult2D::get_path() const {
return path;
}

void NavigationPathQueryResult2D::reset() {
path.clear();
}

void NavigationPathQueryResult2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult2D::set_path);
ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult2D::get_path);

ClassDB::bind_method(D_METHOD("reset"), &NavigationPathQueryResult2D::reset);

ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "path"), "set_path", "get_path");
}
2 changes: 2 additions & 0 deletions servers/navigation/navigation_path_query_result_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class NavigationPathQueryResult2D : public RefCounted {
public:
void set_path(const Vector<Vector2> &p_path);
const Vector<Vector2> &get_path() const;

void reset();
};

#endif // NAVIGATION_PATH_QUERY_RESULT_2D_H
6 changes: 6 additions & 0 deletions servers/navigation/navigation_path_query_result_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,15 @@ const Vector<Vector3> &NavigationPathQueryResult3D::get_path() const {
return path;
}

void NavigationPathQueryResult3D::reset() {
path.clear();
}

void NavigationPathQueryResult3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult3D::set_path);
ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult3D::get_path);

ClassDB::bind_method(D_METHOD("reset"), &NavigationPathQueryResult3D::reset);

ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "path"), "set_path", "get_path");
}
2 changes: 2 additions & 0 deletions servers/navigation/navigation_path_query_result_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class NavigationPathQueryResult3D : public RefCounted {
public:
void set_path(const Vector<Vector3> &p_path);
const Vector<Vector3> &get_path() const;

void reset();
};

#endif // NAVIGATION_PATH_QUERY_RESULT_3D_H

0 comments on commit a2c53b8

Please sign in to comment.