diff options
Diffstat (limited to 'scene/2d')
-rw-r--r-- | scene/2d/camera_2d.cpp | 18 | ||||
-rw-r--r-- | scene/2d/camera_2d.h | 6 | ||||
-rw-r--r-- | scene/2d/navigation_agent_2d.cpp | 42 | ||||
-rw-r--r-- | scene/2d/navigation_agent_2d.h | 9 | ||||
-rw-r--r-- | scene/2d/navigation_region_2d.cpp | 34 | ||||
-rw-r--r-- | scene/2d/navigation_region_2d.h | 4 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.cpp | 20 | ||||
-rw-r--r-- | scene/2d/tile_map.cpp | 4 | ||||
-rw-r--r-- | scene/2d/tile_map.h | 2 |
9 files changed, 88 insertions, 51 deletions
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index a11b2b66bf..e120aa871b 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -172,7 +172,7 @@ Transform2D Camera2D::get_camera_transform() { Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2()); real_t angle = get_global_rotation(); - if (rotating) { + if (!ignore_rotation) { screen_offset = screen_offset.rotated(angle); } @@ -204,7 +204,7 @@ Transform2D Camera2D::get_camera_transform() { Transform2D xform; xform.scale_basis(zoom_scale); - if (rotating) { + if (!ignore_rotation) { xform.set_rotation(angle); } xform.set_origin(screen_rect.position); @@ -363,15 +363,15 @@ Camera2D::AnchorMode Camera2D::get_anchor_mode() const { return anchor_mode; } -void Camera2D::set_rotating(bool p_rotating) { - rotating = p_rotating; +void Camera2D::set_ignore_rotation(bool p_ignore) { + ignore_rotation = p_ignore; Point2 old_smoothed_camera_pos = smoothed_camera_pos; _update_scroll(); smoothed_camera_pos = old_smoothed_camera_pos; } -bool Camera2D::is_rotating() const { - return rotating; +bool Camera2D::is_ignoring_rotation() const { + return ignore_rotation; } void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) { @@ -668,8 +668,8 @@ void Camera2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_anchor_mode", "anchor_mode"), &Camera2D::set_anchor_mode); ClassDB::bind_method(D_METHOD("get_anchor_mode"), &Camera2D::get_anchor_mode); - ClassDB::bind_method(D_METHOD("set_rotating", "rotating"), &Camera2D::set_rotating); - ClassDB::bind_method(D_METHOD("is_rotating"), &Camera2D::is_rotating); + ClassDB::bind_method(D_METHOD("set_ignore_rotation", "ignore"), &Camera2D::set_ignore_rotation); + ClassDB::bind_method(D_METHOD("is_ignoring_rotation"), &Camera2D::is_ignoring_rotation); ClassDB::bind_method(D_METHOD("_update_scroll"), &Camera2D::_update_scroll); @@ -733,7 +733,7 @@ void Camera2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset", PROPERTY_HINT_NONE, "suffix:px"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_mode", PROPERTY_HINT_ENUM, "Fixed TopLeft,Drag Center"), "set_anchor_mode", "get_anchor_mode"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotating"), "set_rotating", "is_rotating"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_rotation"), "set_ignore_rotation", "is_ignoring_rotation"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom", PROPERTY_HINT_LINK), "set_zoom", "get_zoom"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", PROPERTY_USAGE_NONE), "set_custom_viewport", "get_custom_viewport"); diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 78654ee606..1ce622388c 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -63,7 +63,7 @@ protected: Vector2 zoom = Vector2(1, 1); Vector2 zoom_scale = Vector2(1, 1); AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER; - bool rotating = false; + bool ignore_rotation = true; bool current = false; real_t smoothing = 5.0; bool smoothing_enabled = false; @@ -109,8 +109,8 @@ public: void set_anchor_mode(AnchorMode p_anchor_mode); AnchorMode get_anchor_mode() const; - void set_rotating(bool p_rotating); - bool is_rotating() const; + void set_ignore_rotation(bool p_ignore); + bool is_ignoring_rotation() const; void set_limit(Side p_side, int p_limit); int get_limit(Side p_side) const; 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 7a3471777d..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; } @@ -262,21 +262,16 @@ void AnimatableBody2D::_update_kinematic_motion() { #endif if (sync_to_physics) { - PhysicsServer2D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback); + PhysicsServer2D::get_singleton()->body_set_state_sync_callback(get_rid(), callable_mp(this, &AnimatableBody2D::_body_state_changed)); set_only_update_transform_changes(true); set_notify_local_transform(true); } else { - PhysicsServer2D::get_singleton()->body_set_state_sync_callback(get_rid(), nullptr, nullptr); + PhysicsServer2D::get_singleton()->body_set_state_sync_callback(get_rid(), Callable()); set_only_update_transform_changes(false); set_notify_local_transform(false); } } -void AnimatableBody2D::_body_state_changed_callback(void *p_instance, PhysicsDirectBodyState2D *p_state) { - AnimatableBody2D *body = static_cast<AnimatableBody2D *>(p_instance); - body->_body_state_changed(p_state); -} - void AnimatableBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) { if (!sync_to_physics) { return; @@ -438,11 +433,6 @@ struct _RigidBody2DInOut { int local_shape = 0; }; -void RigidBody2D::_body_state_changed_callback(void *p_instance, PhysicsDirectBodyState2D *p_state) { - RigidBody2D *body = static_cast<RigidBody2D *>(p_instance); - body->_body_state_changed(p_state); -} - void RigidBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) { set_block_transform_notify(true); // don't want notify (would feedback loop) if (!freeze || freeze_mode != FREEZE_MODE_KINEMATIC) { @@ -1079,7 +1069,7 @@ void RigidBody2D::_validate_property(PropertyInfo &p_property) const { RigidBody2D::RigidBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_RIGID) { - PhysicsServer2D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback); + PhysicsServer2D::get_singleton()->body_set_state_sync_callback(get_rid(), callable_mp(this, &RigidBody2D::_body_state_changed)); } RigidBody2D::~RigidBody2D() { @@ -1554,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 42b76d0136..bdcd1f2f28 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1861,7 +1861,6 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_ Ref<PackedScene> packed_scene = scenes_collection_source->get_scene_tile_scene(c.alternative_tile); if (packed_scene.is_valid()) { Node *scene = packed_scene->instantiate(); - add_child(scene); Control *scene_as_control = Object::cast_to<Control>(scene); Node2D *scene_as_node2d = Object::cast_to<Node2D>(scene); if (scene_as_control) { @@ -1871,6 +1870,7 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_ xform.set_origin(map_to_local(E_cell)); scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform()); } + add_child(scene); q.scenes[E_cell] = scene->get_name(); } } @@ -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; |