|
@@ -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() {
|
|
@@ -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;
|
|
@@ -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);
|
|
@@ -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();
|
|
|
}
|
|
@@ -406,24 +421,26 @@ 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;
|
|
|
}
|
|
@@ -431,24 +448,31 @@ void NavigationAgent3D::update_navigation() {
|
|
|
}
|
|
|
|
|
|
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();
|
|
@@ -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;
|