summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/navigation_agent_2d.cpp42
-rw-r--r--scene/2d/navigation_agent_2d.h9
-rw-r--r--scene/2d/navigation_region_2d.cpp34
-rw-r--r--scene/2d/navigation_region_2d.h4
-rw-r--r--scene/2d/physics_body_2d.cpp4
-rw-r--r--scene/2d/tile_map.cpp2
-rw-r--r--scene/2d/tile_map.h2
7 files changed, 72 insertions, 25 deletions
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 55cebdaadc..f077f7f5e6 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -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() {
@@ -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();
@@ -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);
@@ -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();
}
@@ -391,22 +406,24 @@ 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;
}
@@ -414,24 +431,31 @@ void NavigationAgent2D::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 = 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();
@@ -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;
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 2fbacc4c76..5abd3c0317 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -34,6 +34,8 @@
#include "scene/main/node.h"
class Node2D;
+class NavigationPathQueryParameters2D;
+class NavigationPathQueryResult2D;
class NavigationAgent2D : public Node {
GDCLASS(NavigationAgent2D, Node);
@@ -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;
@@ -138,9 +141,7 @@ public:
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;
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index b1e2875a8b..6e8ecb13b1 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -354,10 +354,13 @@ void NavigationPolygon::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_outlines", "_get_outlines");
}
+/////////////////////////////
+
void NavigationRegion2D::set_enabled(bool p_enabled) {
if (enabled == p_enabled) {
return;
}
+
enabled = p_enabled;
if (!is_inside_tree()) {
@@ -384,35 +387,50 @@ bool NavigationRegion2D::is_enabled() const {
}
void NavigationRegion2D::set_navigation_layers(uint32_t p_navigation_layers) {
- NavigationServer2D::get_singleton()->region_set_navigation_layers(region, p_navigation_layers);
+ if (navigation_layers == p_navigation_layers) {
+ return;
+ }
+
+ navigation_layers = p_navigation_layers;
+
+ NavigationServer2D::get_singleton()->region_set_navigation_layers(region, navigation_layers);
}
uint32_t NavigationRegion2D::get_navigation_layers() const {
- return NavigationServer2D::get_singleton()->region_get_navigation_layers(region);
+ return navigation_layers;
}
void NavigationRegion2D::set_navigation_layer_value(int p_layer_number, bool p_value) {
ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
+
uint32_t _navigation_layers = get_navigation_layers();
+
if (p_value) {
_navigation_layers |= 1 << (p_layer_number - 1);
} else {
_navigation_layers &= ~(1 << (p_layer_number - 1));
}
+
set_navigation_layers(_navigation_layers);
}
bool NavigationRegion2D::get_navigation_layer_value(int p_layer_number) const {
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
+
return get_navigation_layers() & (1 << (p_layer_number - 1));
}
void NavigationRegion2D::set_enter_cost(real_t p_enter_cost) {
ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive.");
- enter_cost = MAX(p_enter_cost, 0.0);
- NavigationServer2D::get_singleton()->region_set_enter_cost(region, p_enter_cost);
+ if (Math::is_equal_approx(enter_cost, p_enter_cost)) {
+ return;
+ }
+
+ enter_cost = p_enter_cost;
+
+ NavigationServer2D::get_singleton()->region_set_enter_cost(region, enter_cost);
}
real_t NavigationRegion2D::get_enter_cost() const {
@@ -421,7 +439,12 @@ real_t NavigationRegion2D::get_enter_cost() const {
void NavigationRegion2D::set_travel_cost(real_t p_travel_cost) {
ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive.");
- travel_cost = MAX(p_travel_cost, 0.0);
+ if (Math::is_equal_approx(travel_cost, p_travel_cost)) {
+ return;
+ }
+
+ travel_cost = p_travel_cost;
+
NavigationServer2D::get_singleton()->region_set_travel_cost(region, travel_cost);
}
@@ -433,7 +456,6 @@ RID NavigationRegion2D::get_region_rid() const {
return region;
}
-/////////////////////////////
#ifdef TOOLS_ENABLED
Rect2 NavigationRegion2D::_edit_get_rect() const {
return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2();
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index 893de41a94..c630e20780 100644
--- a/scene/2d/navigation_region_2d.h
+++ b/scene/2d/navigation_region_2d.h
@@ -96,10 +96,10 @@ class NavigationRegion2D : public Node2D {
bool enabled = true;
RID region;
- Ref<NavigationPolygon> navpoly;
-
+ uint32_t navigation_layers = 1;
real_t enter_cost = 0.0;
real_t travel_cost = 1.0;
+ Ref<NavigationPolygon> navpoly;
void _navpoly_changed();
void _map_changed(RID p_RID);
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 16686f4fe6..4e6b37a860 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -62,7 +62,7 @@ Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_distance, bool p
if (move_and_collide(parameters, result, p_test_only)) {
// Create a new instance when the cached reference is invalid or still in use in script.
- if (motion_cache.is_null() || motion_cache->reference_get_count() > 1) {
+ if (motion_cache.is_null() || motion_cache->get_reference_count() > 1) {
motion_cache.instantiate();
motion_cache->owner = this;
}
@@ -1544,7 +1544,7 @@ Ref<KinematicCollision2D> CharacterBody2D::_get_slide_collision(int p_bounce) {
}
// Create a new instance when the cached reference is invalid or still in use in script.
- if (slide_colliders[p_bounce].is_null() || slide_colliders[p_bounce]->reference_get_count() > 1) {
+ if (slide_colliders[p_bounce].is_null() || slide_colliders[p_bounce]->get_reference_count() > 1) {
slide_colliders.write[p_bounce].instantiate();
slide_colliders.write[p_bounce]->owner = this;
}
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 577284a752..bdcd1f2f28 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -3615,7 +3615,7 @@ TypedArray<Vector2i> TileMap::get_used_cells(int p_layer) const {
return a;
}
-Rect2 TileMap::get_used_rect() { // Not const because of cache
+Rect2i TileMap::get_used_rect() { // Not const because of cache
// Return the rect of the currently used area
if (used_rect_cache_dirty) {
bool first = true;
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index b1a2118c6b..902926291d 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -375,7 +375,7 @@ public:
Vector2i get_neighbor_cell(const Vector2i &p_coords, TileSet::CellNeighbor p_cell_neighbor) const;
TypedArray<Vector2i> get_used_cells(int p_layer) const;
- Rect2 get_used_rect(); // Not const because of cache
+ Rect2i get_used_rect(); // Not const because of cache
// Override some methods of the CanvasItem class to pass the changes to the quadrants CanvasItems
virtual void set_light_mask(int p_light_mask) override;