summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/animated_sprite_2d.cpp4
-rw-r--r--scene/2d/animated_sprite_2d.h2
-rw-r--r--scene/2d/camera_2d.cpp18
-rw-r--r--scene/2d/camera_2d.h6
-rw-r--r--scene/2d/canvas_modulate.cpp4
-rw-r--r--scene/2d/canvas_modulate.h2
-rw-r--r--scene/2d/collision_object_2d.cpp4
-rw-r--r--scene/2d/collision_object_2d.h2
-rw-r--r--scene/2d/collision_polygon_2d.cpp4
-rw-r--r--scene/2d/collision_polygon_2d.h2
-rw-r--r--scene/2d/collision_shape_2d.cpp4
-rw-r--r--scene/2d/collision_shape_2d.h2
-rw-r--r--scene/2d/cpu_particles_2d.cpp4
-rw-r--r--scene/2d/cpu_particles_2d.h2
-rw-r--r--scene/2d/gpu_particles_2d.cpp4
-rw-r--r--scene/2d/gpu_particles_2d.h2
-rw-r--r--scene/2d/joint_2d.cpp4
-rw-r--r--scene/2d/joint_2d.h2
-rw-r--r--scene/2d/light_2d.cpp4
-rw-r--r--scene/2d/light_2d.h2
-rw-r--r--scene/2d/light_occluder_2d.cpp4
-rw-r--r--scene/2d/light_occluder_2d.h2
-rw-r--r--scene/2d/navigation_agent_2d.cpp4
-rw-r--r--scene/2d/navigation_agent_2d.h2
-rw-r--r--scene/2d/navigation_link_2d.cpp4
-rw-r--r--scene/2d/navigation_link_2d.h2
-rw-r--r--scene/2d/navigation_obstacle_2d.cpp4
-rw-r--r--scene/2d/navigation_obstacle_2d.h2
-rw-r--r--scene/2d/navigation_region_2d.cpp38
-rw-r--r--scene/2d/navigation_region_2d.h6
-rw-r--r--scene/2d/parallax_layer.cpp4
-rw-r--r--scene/2d/parallax_layer.h2
-rw-r--r--scene/2d/path_2d.cpp4
-rw-r--r--scene/2d/path_2d.h2
-rw-r--r--scene/2d/physical_bone_2d.cpp4
-rw-r--r--scene/2d/physical_bone_2d.h2
-rw-r--r--scene/2d/physics_body_2d.cpp31
-rw-r--r--scene/2d/physics_body_2d.h2
-rw-r--r--scene/2d/remote_transform_2d.cpp4
-rw-r--r--scene/2d/remote_transform_2d.h2
-rw-r--r--scene/2d/shape_cast_2d.cpp4
-rw-r--r--scene/2d/shape_cast_2d.h2
-rw-r--r--scene/2d/skeleton_2d.cpp4
-rw-r--r--scene/2d/skeleton_2d.h2
-rw-r--r--scene/2d/tile_map.cpp8
-rw-r--r--scene/2d/tile_map.h4
-rw-r--r--scene/3d/bone_attachment_3d.cpp4
-rw-r--r--scene/3d/bone_attachment_3d.h2
-rw-r--r--scene/3d/collision_object_3d.cpp4
-rw-r--r--scene/3d/collision_object_3d.h2
-rw-r--r--scene/3d/collision_polygon_3d.cpp4
-rw-r--r--scene/3d/collision_polygon_3d.h2
-rw-r--r--scene/3d/collision_shape_3d.cpp4
-rw-r--r--scene/3d/collision_shape_3d.h2
-rw-r--r--scene/3d/cpu_particles_3d.cpp4
-rw-r--r--scene/3d/cpu_particles_3d.h2
-rw-r--r--scene/3d/decal.cpp4
-rw-r--r--scene/3d/decal.h2
-rw-r--r--scene/3d/fog_volume.cpp4
-rw-r--r--scene/3d/fog_volume.h2
-rw-r--r--scene/3d/gpu_particles_3d.cpp4
-rw-r--r--scene/3d/gpu_particles_3d.h2
-rw-r--r--scene/3d/gpu_particles_collision_3d.cpp4
-rw-r--r--scene/3d/gpu_particles_collision_3d.h2
-rw-r--r--scene/3d/joint_3d.cpp4
-rw-r--r--scene/3d/joint_3d.h2
-rw-r--r--scene/3d/light_3d.cpp8
-rw-r--r--scene/3d/light_3d.h4
-rw-r--r--scene/3d/navigation_agent_3d.cpp4
-rw-r--r--scene/3d/navigation_agent_3d.h2
-rw-r--r--scene/3d/navigation_link_3d.cpp4
-rw-r--r--scene/3d/navigation_link_3d.h2
-rw-r--r--scene/3d/navigation_obstacle_3d.cpp4
-rw-r--r--scene/3d/navigation_obstacle_3d.h2
-rw-r--r--scene/3d/navigation_region_3d.cpp37
-rw-r--r--scene/3d/navigation_region_3d.h6
-rw-r--r--scene/3d/node_3d.cpp1
-rw-r--r--scene/3d/occluder_instance_3d.cpp4
-rw-r--r--scene/3d/occluder_instance_3d.h2
-rw-r--r--scene/3d/path_3d.cpp4
-rw-r--r--scene/3d/path_3d.h2
-rw-r--r--scene/3d/physics_body_3d.cpp40
-rw-r--r--scene/3d/physics_body_3d.h2
-rw-r--r--scene/3d/remote_transform_3d.cpp4
-rw-r--r--scene/3d/remote_transform_3d.h2
-rw-r--r--scene/3d/shape_cast_3d.cpp4
-rw-r--r--scene/3d/shape_cast_3d.h2
-rw-r--r--scene/3d/soft_body_3d.cpp4
-rw-r--r--scene/3d/soft_body_3d.h2
-rw-r--r--scene/3d/sprite_3d.cpp497
-rw-r--r--scene/3d/sprite_3d.h12
-rw-r--r--scene/3d/vehicle_body_3d.cpp4
-rw-r--r--scene/3d/vehicle_body_3d.h2
-rw-r--r--scene/3d/visual_instance_3d.cpp4
-rw-r--r--scene/3d/visual_instance_3d.h2
-rw-r--r--scene/3d/voxel_gi.cpp4
-rw-r--r--scene/3d/voxel_gi.h2
-rw-r--r--scene/3d/world_environment.cpp4
-rw-r--r--scene/3d/world_environment.h2
-rw-r--r--scene/3d/xr_nodes.cpp12
-rw-r--r--scene/3d/xr_nodes.h6
-rw-r--r--scene/animation/animation_blend_tree.cpp26
-rw-r--r--scene/animation/animation_blend_tree.h38
-rw-r--r--scene/animation/animation_node_state_machine.cpp11
-rw-r--r--scene/animation/animation_player.cpp30
-rw-r--r--scene/animation/animation_player.h28
-rw-r--r--scene/animation/animation_tree.cpp6
-rw-r--r--scene/animation/animation_tree.h4
-rw-r--r--scene/animation/easing_equations.h6
-rw-r--r--scene/animation/tween.cpp50
-rw-r--r--scene/animation/tween.h52
-rw-r--r--scene/gui/base_button.cpp9
-rw-r--r--scene/gui/code_edit.cpp35
-rw-r--r--scene/gui/color_picker.cpp7
-rw-r--r--scene/gui/container.cpp4
-rw-r--r--scene/gui/container.h2
-rw-r--r--scene/gui/control.cpp16
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/gui/file_dialog.cpp10
-rw-r--r--scene/gui/graph_edit.cpp4
-rw-r--r--scene/gui/graph_edit.h2
-rw-r--r--scene/gui/item_list.cpp16
-rw-r--r--scene/gui/menu_bar.cpp2
-rw-r--r--scene/gui/popup_menu.cpp11
-rw-r--r--scene/gui/popup_menu.h2
-rw-r--r--scene/gui/range.cpp4
-rw-r--r--scene/gui/range.h2
-rw-r--r--scene/gui/rich_text_label.cpp224
-rw-r--r--scene/gui/rich_text_label.h12
-rw-r--r--scene/gui/scroll_container.cpp4
-rw-r--r--scene/gui/scroll_container.h2
-rw-r--r--scene/gui/subviewport_container.cpp4
-rw-r--r--scene/gui/subviewport_container.h2
-rw-r--r--scene/gui/tab_container.cpp4
-rw-r--r--scene/gui/text_edit.cpp19
-rw-r--r--scene/gui/tree.cpp78
-rw-r--r--scene/gui/tree.h10
-rw-r--r--scene/gui/video_stream_player.cpp4
-rw-r--r--scene/gui/video_stream_player.h4
-rw-r--r--scene/main/http_request.cpp125
-rw-r--r--scene/main/http_request.h4
-rw-r--r--scene/main/missing_node.cpp4
-rw-r--r--scene/main/missing_node.h2
-rw-r--r--scene/main/node.cpp12
-rw-r--r--scene/main/node.h2
-rw-r--r--scene/main/scene_tree.cpp5
-rw-r--r--scene/main/scene_tree.h4
-rw-r--r--scene/main/shader_globals_override.cpp4
-rw-r--r--scene/main/shader_globals_override.h2
-rw-r--r--scene/main/timer.cpp4
-rw-r--r--scene/main/timer.h2
-rw-r--r--scene/main/viewport.cpp8
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/main/window.cpp25
-rw-r--r--scene/main/window.h2
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/animation.cpp4
-rw-r--r--scene/resources/audio_stream_wav.cpp12
-rw-r--r--scene/resources/audio_stream_wav.h8
-rw-r--r--scene/resources/default_theme/default_theme.cpp2
-rw-r--r--scene/resources/default_theme/default_theme.h2
-rw-r--r--scene/resources/fog_material.cpp2
-rw-r--r--scene/resources/font.cpp25
-rw-r--r--scene/resources/material.cpp2
-rw-r--r--scene/resources/particle_process_material.h6
-rw-r--r--scene/resources/primitive_meshes.h13
-rw-r--r--scene/resources/sky_material.h6
-rw-r--r--scene/resources/texture.cpp3
-rw-r--r--scene/resources/texture.h9
-rw-r--r--scene/resources/tile_set.cpp1
-rw-r--r--scene/resources/video_stream.h8
-rw-r--r--scene/resources/visual_shader.h7
-rw-r--r--scene/resources/visual_shader_particle_nodes.cpp47
173 files changed, 1125 insertions, 971 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index f84e82a6bb..7ee9861d3f 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -454,8 +454,8 @@ StringName AnimatedSprite2D::get_animation() const {
return animation;
}
-TypedArray<String> AnimatedSprite2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray AnimatedSprite2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (frames.is_null()) {
warnings.push_back(RTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite2D to display frames."));
diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h
index be1cc5353e..11c4adb816 100644
--- a/scene/2d/animated_sprite_2d.h
+++ b/scene/2d/animated_sprite_2d.h
@@ -109,7 +109,7 @@ public:
void set_flip_v(bool p_flip);
bool is_flipped_v() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
AnimatedSprite2D();
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/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp
index 61a17a4845..330afe4a1b 100644
--- a/scene/2d/canvas_modulate.cpp
+++ b/scene/2d/canvas_modulate.cpp
@@ -78,8 +78,8 @@ Color CanvasModulate::get_color() const {
return color;
}
-TypedArray<String> CanvasModulate::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray CanvasModulate::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (is_visible_in_tree() && is_inside_tree()) {
List<Node *> nodes;
diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h
index 1fd54898f8..4f522ca1c7 100644
--- a/scene/2d/canvas_modulate.h
+++ b/scene/2d/canvas_modulate.h
@@ -46,7 +46,7 @@ public:
void set_color(const Color &p_color);
Color get_color() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
CanvasModulate();
~CanvasModulate();
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index a79c81e8bd..23948c2fd3 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -565,8 +565,8 @@ void CollisionObject2D::_update_pickable() {
}
}
-TypedArray<String> CollisionObject2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray CollisionObject2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (shapes.is_empty()) {
warnings.push_back(RTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape2D or CollisionPolygon2D as a child to define its shape."));
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index 48ea59e040..6b778d1b60 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -157,7 +157,7 @@ public:
void set_pickable(bool p_enabled);
bool is_pickable() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
_FORCE_INLINE_ RID get_rid() const { return rid; }
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index b69b19d30d..d06461b566 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -235,8 +235,8 @@ bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
}
#endif
-TypedArray<String> CollisionPolygon2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray CollisionPolygon2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<CollisionObject2D>(get_parent())) {
warnings.push_back(RTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, CharacterBody2D, etc. to give them a shape."));
diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h
index e18022ab7e..066f7271c6 100644
--- a/scene/2d/collision_polygon_2d.h
+++ b/scene/2d/collision_polygon_2d.h
@@ -77,7 +77,7 @@ public:
void set_polygon(const Vector<Point2> &p_polygon);
Vector<Point2> get_polygon() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
void set_disabled(bool p_disabled);
bool is_disabled() const;
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index 039bfee451..7e167a3807 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -168,8 +168,8 @@ bool CollisionShape2D::_edit_is_selected_on_click(const Point2 &p_point, double
return shape->_edit_is_selected_on_click(p_point, p_tolerance);
}
-TypedArray<String> CollisionShape2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray CollisionShape2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<CollisionObject2D>(get_parent())) {
warnings.push_back(RTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, CharacterBody2D, etc. to give them a shape."));
diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h
index dbc81e8424..5e50420e00 100644
--- a/scene/2d/collision_shape_2d.h
+++ b/scene/2d/collision_shape_2d.h
@@ -72,7 +72,7 @@ public:
void set_one_way_collision_margin(real_t p_margin);
real_t get_one_way_collision_margin() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
CollisionShape2D();
};
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 4523e5dfe9..eece90190b 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -242,8 +242,8 @@ bool CPUParticles2D::get_fractional_delta() const {
return fractional_delta;
}
-TypedArray<String> CPUParticles2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node2D::get_configuration_warnings();
+PackedStringArray CPUParticles2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node2D::get_configuration_warnings();
CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr());
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 3fd1c7fd0f..ea735411a8 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -282,7 +282,7 @@ public:
void set_gravity(const Vector2 &p_gravity);
Vector2 get_gravity() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
void restart();
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index bed68b4ee0..18f709f241 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -296,8 +296,8 @@ bool GPUParticles2D::get_interpolate() const {
return interpolate;
}
-TypedArray<String> GPUParticles2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node2D::get_configuration_warnings();
+PackedStringArray GPUParticles2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node2D::get_configuration_warnings();
if (RenderingServer::get_singleton()->is_low_end()) {
warnings.push_back(RTR("GPU-based particles are not supported by the OpenGL video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles2D\" option for this purpose."));
diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h
index 10ae91775f..d613b4ef51 100644
--- a/scene/2d/gpu_particles_2d.h
+++ b/scene/2d/gpu_particles_2d.h
@@ -145,7 +145,7 @@ public:
void set_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_texture() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
void set_sub_emitter(const NodePath &p_path);
NodePath get_sub_emitter() const;
diff --git a/scene/2d/joint_2d.cpp b/scene/2d/joint_2d.cpp
index 89b6f3f9da..6000508f36 100644
--- a/scene/2d/joint_2d.cpp
+++ b/scene/2d/joint_2d.cpp
@@ -202,8 +202,8 @@ bool Joint2D::get_exclude_nodes_from_collision() const {
return exclude_from_collision;
}
-TypedArray<String> Joint2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node2D::get_configuration_warnings();
+PackedStringArray Joint2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node2D::get_configuration_warnings();
if (!warning.is_empty()) {
warnings.push_back(warning);
diff --git a/scene/2d/joint_2d.h b/scene/2d/joint_2d.h
index e3cd600cbd..8b145be6ae 100644
--- a/scene/2d/joint_2d.h
+++ b/scene/2d/joint_2d.h
@@ -62,7 +62,7 @@ protected:
_FORCE_INLINE_ bool is_configured() const { return configured; }
public:
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
void set_node_a(const NodePath &p_node_a);
NodePath get_node_a() const;
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 7eb6b43af7..90402260ed 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -395,8 +395,8 @@ Vector2 PointLight2D::get_texture_offset() const {
return texture_offset;
}
-TypedArray<String> PointLight2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray PointLight2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!texture.is_valid()) {
warnings.push_back(RTR("A texture with the shape of the light must be supplied to the \"Texture\" property."));
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index 373cfe59fd..29870923aa 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -171,7 +171,7 @@ public:
void set_texture_scale(real_t p_scale);
real_t get_texture_scale() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
PointLight2D();
};
diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp
index 6c171383ca..67e82140e4 100644
--- a/scene/2d/light_occluder_2d.cpp
+++ b/scene/2d/light_occluder_2d.cpp
@@ -246,8 +246,8 @@ int LightOccluder2D::get_occluder_light_mask() const {
return mask;
}
-TypedArray<String> LightOccluder2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray LightOccluder2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!occluder_polygon.is_valid()) {
warnings.push_back(RTR("An occluder polygon must be set (or drawn) for this occluder to take effect."));
diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h
index b61e23464a..ee4d87e54b 100644
--- a/scene/2d/light_occluder_2d.h
+++ b/scene/2d/light_occluder_2d.h
@@ -105,7 +105,7 @@ public:
void set_as_sdf_collision(bool p_enable);
bool is_set_as_sdf_collision() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
LightOccluder2D();
~LightOccluder2D();
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index d7f75c63a4..55cebdaadc 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -368,8 +368,8 @@ void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) {
emit_signal(SNAME("velocity_computed"), velocity);
}
-TypedArray<String> NavigationAgent2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray NavigationAgent2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<Node2D>(get_parent())) {
warnings.push_back(RTR("The NavigationAgent2D can be used only under a Node2D inheriting parent node."));
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 11b845665d..2fbacc4c76 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -155,7 +155,7 @@ public:
void set_velocity(Vector2 p_velocity);
void _avoidance_done(Vector3 p_new_velocity);
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
private:
void update_navigation();
diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp
index 8ba51482ee..3f7e10eaea 100644
--- a/scene/2d/navigation_link_2d.cpp
+++ b/scene/2d/navigation_link_2d.cpp
@@ -267,8 +267,8 @@ void NavigationLink2D::set_travel_cost(real_t p_travel_cost) {
NavigationServer2D::get_singleton()->link_set_travel_cost(link, travel_cost);
}
-TypedArray<String> NavigationLink2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray NavigationLink2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (start_location.is_equal_approx(end_location)) {
warnings.push_back(RTR("NavigationLink2D start location should be different than the end location to be useful."));
diff --git a/scene/2d/navigation_link_2d.h b/scene/2d/navigation_link_2d.h
index 5990ea082c..2a5092216d 100644
--- a/scene/2d/navigation_link_2d.h
+++ b/scene/2d/navigation_link_2d.h
@@ -79,7 +79,7 @@ public:
void set_travel_cost(real_t p_travel_cost);
real_t get_travel_cost() const { return travel_cost; }
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
NavigationLink2D();
~NavigationLink2D();
diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp
index 1850e00ecd..e46bb79551 100644
--- a/scene/2d/navigation_obstacle_2d.cpp
+++ b/scene/2d/navigation_obstacle_2d.cpp
@@ -120,8 +120,8 @@ NavigationObstacle2D::~NavigationObstacle2D() {
agent = RID(); // Pointless
}
-TypedArray<String> NavigationObstacle2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray NavigationObstacle2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<Node2D>(get_parent())) {
warnings.push_back(RTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object."));
diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h
index 6eff95adec..d4c1df343f 100644
--- a/scene/2d/navigation_obstacle_2d.h
+++ b/scene/2d/navigation_obstacle_2d.h
@@ -73,7 +73,7 @@ public:
return radius;
}
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
private:
void initialize_agent();
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index ffccb95a22..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();
@@ -566,8 +588,8 @@ void NavigationRegion2D::_map_changed(RID p_map) {
#endif // DEBUG_ENABLED
}
-TypedArray<String> NavigationRegion2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node2D::get_configuration_warnings();
+PackedStringArray NavigationRegion2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node2D::get_configuration_warnings();
if (is_visible_in_tree() && is_inside_tree()) {
if (!navpoly.is_valid()) {
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index 3c9df91fe3..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);
@@ -134,7 +134,7 @@ public:
void set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly);
Ref<NavigationPolygon> get_navigation_polygon() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
NavigationRegion2D();
~NavigationRegion2D();
diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index d4138dc516..01e4bf19f3 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -137,8 +137,8 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, real_t p_s
_update_mirroring();
}
-TypedArray<String> ParallaxLayer::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray ParallaxLayer::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<ParallaxBackground>(get_parent())) {
warnings.push_back(RTR("ParallaxLayer node only works when set as child of a ParallaxBackground node."));
diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h
index c03f4cc293..6471f56c5c 100644
--- a/scene/2d/parallax_layer.h
+++ b/scene/2d/parallax_layer.h
@@ -59,7 +59,7 @@ public:
void set_base_offset_and_scale(const Point2 &p_offset, real_t p_scale);
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
ParallaxLayer();
};
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index 90b2e3d460..c1044fdf5b 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -256,8 +256,8 @@ void PathFollow2D::_validate_property(PropertyInfo &p_property) const {
}
}
-TypedArray<String> PathFollow2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray PathFollow2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (is_visible_in_tree() && is_inside_tree()) {
if (!Object::cast_to<Path2D>(get_parent())) {
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 3d66ca1fab..5e436fb9f6 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -106,7 +106,7 @@ public:
void set_cubic_interpolation(bool p_enable);
bool get_cubic_interpolation() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
PathFollow2D() {}
};
diff --git a/scene/2d/physical_bone_2d.cpp b/scene/2d/physical_bone_2d.cpp
index e6933b8a40..5ff706ebb7 100644
--- a/scene/2d/physical_bone_2d.cpp
+++ b/scene/2d/physical_bone_2d.cpp
@@ -106,8 +106,8 @@ void PhysicalBone2D::_find_joint_child() {
}
}
-TypedArray<String> PhysicalBone2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray PhysicalBone2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!parent_skeleton) {
warnings.push_back(RTR("A PhysicalBone2D only works with a Skeleton2D or another PhysicalBone2D as a parent node!"));
diff --git a/scene/2d/physical_bone_2d.h b/scene/2d/physical_bone_2d.h
index 9fbfa04100..33ac0d9935 100644
--- a/scene/2d/physical_bone_2d.h
+++ b/scene/2d/physical_bone_2d.h
@@ -79,7 +79,7 @@ public:
void set_follow_bone_when_simulating(bool p_follow);
bool get_follow_bone_when_simulating() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
PhysicalBone2D();
~PhysicalBone2D();
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 2aa14aa11a..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) {
@@ -921,10 +911,10 @@ void RigidBody2D::_notification(int p_what) {
#endif
}
-TypedArray<String> RigidBody2D::get_configuration_warnings() const {
+PackedStringArray RigidBody2D::get_configuration_warnings() const {
Transform2D t = get_transform();
- TypedArray<String> warnings = CollisionObject2D::get_configuration_warnings();
+ PackedStringArray warnings = CollisionObject2D::get_configuration_warnings();
if (ABS(t.columns[0].length() - 1.0) > 0.05 || ABS(t.columns[1].length() - 1.0) > 0.05) {
warnings.push_back(RTR("Size changes to RigidBody2D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead."));
@@ -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() {
@@ -1144,7 +1134,6 @@ bool CharacterBody2D::move_and_slide() {
if (!current_platform_velocity.is_zero_approx()) {
PhysicsServer2D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin);
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
parameters.exclude_bodies.insert(platform_rid);
if (platform_object_id.is_valid()) {
parameters.exclude_objects.insert(platform_object_id);
@@ -1203,7 +1192,6 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer2D::MotionParameters parameters(get_global_transform(), motion, margin);
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
Vector2 prev_position = parameters.from.columns[2];
@@ -1360,7 +1348,6 @@ void CharacterBody2D::_move_and_slide_floating(double p_delta) {
bool first_slide = true;
for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer2D::MotionParameters parameters(get_global_transform(), motion, margin);
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
PhysicsServer2D::MotionResult result;
bool collided = move_and_collide(parameters, result, false, false);
@@ -1407,7 +1394,7 @@ void CharacterBody2D::_snap_on_floor(bool p_was_on_floor, bool p_vel_dir_facing_
real_t length = MAX(floor_snap_length, margin);
PhysicsServer2D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
+ parameters.recovery_as_collision = true; // Report margin recovery as collision to improve floor detection.
parameters.collide_separation_ray = true;
PhysicsServer2D::MotionResult result;
@@ -1443,7 +1430,7 @@ bool CharacterBody2D::_on_floor_if_snapped(bool p_was_on_floor, bool p_vel_dir_f
real_t length = MAX(floor_snap_length, margin);
PhysicsServer2D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
+ parameters.recovery_as_collision = true; // Report margin recovery as collision to improve floor detection.
parameters.collide_separation_ray = true;
PhysicsServer2D::MotionResult result;
@@ -1557,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/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 1bc24f3264..932ec1de16 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -309,7 +309,7 @@ public:
TypedArray<Node2D> get_colliding_bodies() const; //function for script
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
RigidBody2D();
~RigidBody2D();
diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp
index 6c4bfd58ce..f4343e4c03 100644
--- a/scene/2d/remote_transform_2d.cpp
+++ b/scene/2d/remote_transform_2d.cpp
@@ -183,8 +183,8 @@ void RemoteTransform2D::force_update_cache() {
_update_cache();
}
-TypedArray<String> RemoteTransform2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray RemoteTransform2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!has_node(remote_node) || !Object::cast_to<Node2D>(get_node(remote_node))) {
warnings.push_back(RTR("Path property must point to a valid Node2D node to work."));
diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h
index bd352e1054..f98eec75c6 100644
--- a/scene/2d/remote_transform_2d.h
+++ b/scene/2d/remote_transform_2d.h
@@ -70,7 +70,7 @@ public:
void force_update_cache();
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
RemoteTransform2D();
};
diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp
index a25d5934ee..6222b0db14 100644
--- a/scene/2d/shape_cast_2d.cpp
+++ b/scene/2d/shape_cast_2d.cpp
@@ -391,8 +391,8 @@ Array ShapeCast2D::_get_collision_result() const {
return ret;
}
-TypedArray<String> ShapeCast2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node2D::get_configuration_warnings();
+PackedStringArray ShapeCast2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node2D::get_configuration_warnings();
if (shape.is_null()) {
warnings.push_back(RTR("This node cannot interact with other objects unless a Shape2D is assigned."));
diff --git a/scene/2d/shape_cast_2d.h b/scene/2d/shape_cast_2d.h
index 660e52f189..7b55566b01 100644
--- a/scene/2d/shape_cast_2d.h
+++ b/scene/2d/shape_cast_2d.h
@@ -117,7 +117,7 @@ public:
void remove_exception(const CollisionObject2D *p_node);
void clear_exceptions();
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
};
#endif // SHAPE_CAST_2D_H
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index 8f0bf22617..b5759c54f7 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -434,8 +434,8 @@ int Bone2D::get_index_in_skeleton() const {
return skeleton_index;
}
-TypedArray<String> Bone2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray Bone2D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!skeleton) {
if (parent_bone) {
warnings.push_back(RTR("This Bone2D chain should end at a Skeleton2D node."));
diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h
index 98fb867d99..580aed97ce 100644
--- a/scene/2d/skeleton_2d.h
+++ b/scene/2d/skeleton_2d.h
@@ -78,7 +78,7 @@ public:
void apply_rest();
Transform2D get_skeleton_rest() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
void set_default_length(real_t p_length);
real_t get_default_length() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 5de6d547d7..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;
@@ -3819,8 +3819,8 @@ void TileMap::draw_cells_outline(Control *p_control, RBSet<Vector2i> p_cells, Co
#undef DRAW_SIDE_IF_NEEDED
}
-TypedArray<String> TileMap::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray TileMap::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
// Retrieve the set of Z index values with a Y-sorted layer.
RBSet<int> y_sorted_z_index;
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index a819eeab71..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;
@@ -406,7 +406,7 @@ public:
GDVIRTUAL3(_tile_data_runtime_update, int, Vector2i, TileData *);
// Configuration warnings.
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
TileMap();
~TileMap();
diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp
index b3ff6497a7..7b0a6c7e3e 100644
--- a/scene/3d/bone_attachment_3d.cpp
+++ b/scene/3d/bone_attachment_3d.cpp
@@ -100,8 +100,8 @@ void BoneAttachment3D::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
-TypedArray<String> BoneAttachment3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node3D::get_configuration_warnings();
+PackedStringArray BoneAttachment3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node3D::get_configuration_warnings();
if (use_external_skeleton) {
if (external_skeleton_node_cache.is_null()) {
diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h
index f85053e614..2db6ba6268 100644
--- a/scene/3d/bone_attachment_3d.h
+++ b/scene/3d/bone_attachment_3d.h
@@ -76,7 +76,7 @@ protected:
#endif // TOOLS_ENABLED
public:
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
void set_bone_name(const String &p_name);
String get_bone_name() const;
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index f5e3e8b015..c3c1c8ba36 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -703,8 +703,8 @@ bool CollisionObject3D::get_capture_input_on_drag() const {
return capture_input_on_drag;
}
-TypedArray<String> CollisionObject3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray CollisionObject3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (shapes.is_empty()) {
warnings.push_back(RTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape3D or CollisionPolygon3D as a child to define its shape."));
diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h
index c638be9d90..1406e6c698 100644
--- a/scene/3d/collision_object_3d.h
+++ b/scene/3d/collision_object_3d.h
@@ -164,7 +164,7 @@ public:
_FORCE_INLINE_ RID get_rid() const { return rid; }
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
CollisionObject3D();
~CollisionObject3D();
diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp
index 90099d787b..81b2c85de4 100644
--- a/scene/3d/collision_polygon_3d.cpp
+++ b/scene/3d/collision_polygon_3d.cpp
@@ -167,8 +167,8 @@ void CollisionPolygon3D::set_margin(real_t p_margin) {
}
}
-TypedArray<String> CollisionPolygon3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray CollisionPolygon3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
warnings.push_back(RTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, CharacterBody3D, etc. to give them a shape."));
diff --git a/scene/3d/collision_polygon_3d.h b/scene/3d/collision_polygon_3d.h
index 74e5867a2f..bbcea539b2 100644
--- a/scene/3d/collision_polygon_3d.h
+++ b/scene/3d/collision_polygon_3d.h
@@ -74,7 +74,7 @@ public:
real_t get_margin() const;
void set_margin(real_t p_margin);
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
CollisionPolygon3D();
};
diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp
index a9bc28b464..7a0001bc6f 100644
--- a/scene/3d/collision_shape_3d.cpp
+++ b/scene/3d/collision_shape_3d.cpp
@@ -114,8 +114,8 @@ void CollisionShape3D::resource_changed(Ref<Resource> res) {
update_gizmos();
}
-TypedArray<String> CollisionShape3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray CollisionShape3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
warnings.push_back(RTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, CharacterBody3D, etc. to give them a shape."));
diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h
index 124c0d166d..70653daa19 100644
--- a/scene/3d/collision_shape_3d.h
+++ b/scene/3d/collision_shape_3d.h
@@ -62,7 +62,7 @@ public:
void set_disabled(bool p_disabled);
bool is_disabled() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
CollisionShape3D();
~CollisionShape3D();
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index d7bf76a6f6..ef373cf9ca 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -188,8 +188,8 @@ bool CPUParticles3D::get_fractional_delta() const {
return fractional_delta;
}
-TypedArray<String> CPUParticles3D::get_configuration_warnings() const {
- TypedArray<String> warnings = GeometryInstance3D::get_configuration_warnings();
+PackedStringArray CPUParticles3D::get_configuration_warnings() const {
+ PackedStringArray warnings = GeometryInstance3D::get_configuration_warnings();
bool mesh_found = false;
bool anim_material_found = false;
diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h
index d84b0aedd2..26c702172b 100644
--- a/scene/3d/cpu_particles_3d.h
+++ b/scene/3d/cpu_particles_3d.h
@@ -302,7 +302,7 @@ public:
void set_gravity(const Vector3 &p_gravity);
Vector3 get_gravity() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
void restart();
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index 460402ad1d..fc442986a8 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -158,8 +158,8 @@ void Decal::_validate_property(PropertyInfo &p_property) const {
}
}
-TypedArray<String> Decal::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray Decal::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (textures[TEXTURE_ALBEDO].is_null() && textures[TEXTURE_NORMAL].is_null() && textures[TEXTURE_ORM].is_null() && textures[TEXTURE_EMISSION].is_null()) {
warnings.push_back(RTR("The decal has no textures loaded into any of its texture properties, and will therefore not be visible."));
diff --git a/scene/3d/decal.h b/scene/3d/decal.h
index 1a7d55b108..ab39350b75 100644
--- a/scene/3d/decal.h
+++ b/scene/3d/decal.h
@@ -65,7 +65,7 @@ protected:
void _validate_property(PropertyInfo &p_property) const;
public:
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
void set_extents(const Vector3 &p_extents);
Vector3 get_extents() const;
diff --git a/scene/3d/fog_volume.cpp b/scene/3d/fog_volume.cpp
index cfee7028d4..4606e70310 100644
--- a/scene/3d/fog_volume.cpp
+++ b/scene/3d/fog_volume.cpp
@@ -99,8 +99,8 @@ AABB FogVolume::get_aabb() const {
return AABB();
}
-TypedArray<String> FogVolume::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray FogVolume::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
Ref<Environment> environment = get_viewport()->find_world_3d()->get_environment();
diff --git a/scene/3d/fog_volume.h b/scene/3d/fog_volume.h
index fcdc1e2807..d79836be0e 100644
--- a/scene/3d/fog_volume.h
+++ b/scene/3d/fog_volume.h
@@ -62,7 +62,7 @@ public:
Ref<Material> get_material() const;
virtual AABB get_aabb() const override;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
FogVolume();
~FogVolume();
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index bd63939d74..dbbf196f7a 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -269,8 +269,8 @@ bool GPUParticles3D::get_interpolate() const {
return interpolate;
}
-TypedArray<String> GPUParticles3D::get_configuration_warnings() const {
- TypedArray<String> warnings = GeometryInstance3D::get_configuration_warnings();
+PackedStringArray GPUParticles3D::get_configuration_warnings() const {
+ PackedStringArray warnings = GeometryInstance3D::get_configuration_warnings();
if (RenderingServer::get_singleton()->is_low_end()) {
warnings.push_back(RTR("GPU-based particles are not supported by the OpenGL video driver.\nUse the CPUParticles3D node instead. You can use the \"Convert to CPUParticles3D\" option for this purpose."));
diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h
index 2ad9672474..ef92218e4d 100644
--- a/scene/3d/gpu_particles_3d.h
+++ b/scene/3d/gpu_particles_3d.h
@@ -147,7 +147,7 @@ public:
void set_draw_pass_mesh(int p_pass, const Ref<Mesh> &p_mesh);
Ref<Mesh> get_draw_pass_mesh(int p_pass) const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
void set_sub_emitter(const NodePath &p_path);
NodePath get_sub_emitter() const;
diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp
index 24bfa7b6de..d3f53d9c0d 100644
--- a/scene/3d/gpu_particles_collision_3d.cpp
+++ b/scene/3d/gpu_particles_collision_3d.cpp
@@ -503,8 +503,8 @@ Ref<Image> GPUParticlesCollisionSDF3D::bake() {
return ret;
}
-TypedArray<String> GPUParticlesCollisionSDF3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray GPUParticlesCollisionSDF3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (bake_mask == 0) {
warnings.push_back(RTR("The Bake Mask has no bits enabled, which means baking will not produce any collision for this GPUParticlesCollisionSDF3D.\nTo resolve this, enable at least one bit in the Bake Mask property."));
diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h
index 712bd015ff..548552bb70 100644
--- a/scene/3d/gpu_particles_collision_3d.h
+++ b/scene/3d/gpu_particles_collision_3d.h
@@ -162,7 +162,7 @@ protected:
static void _bind_methods();
public:
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
void set_thickness(float p_thickness);
float get_thickness() const;
diff --git a/scene/3d/joint_3d.cpp b/scene/3d/joint_3d.cpp
index 7dc094062b..1a18f43e7b 100644
--- a/scene/3d/joint_3d.cpp
+++ b/scene/3d/joint_3d.cpp
@@ -198,8 +198,8 @@ bool Joint3D::get_exclude_nodes_from_collision() const {
return exclude_from_collision;
}
-TypedArray<String> Joint3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node3D::get_configuration_warnings();
+PackedStringArray Joint3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node3D::get_configuration_warnings();
if (!warning.is_empty()) {
warnings.push_back(warning);
diff --git a/scene/3d/joint_3d.h b/scene/3d/joint_3d.h
index cb967023e8..5af427446f 100644
--- a/scene/3d/joint_3d.h
+++ b/scene/3d/joint_3d.h
@@ -63,7 +63,7 @@ protected:
_FORCE_INLINE_ bool is_configured() const { return configured; }
public:
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
void set_node_a(const NodePath &p_node_a);
NodePath get_node_a() const;
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index e51f06e083..23fd091be6 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -578,8 +578,8 @@ OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const {
return shadow_mode;
}
-TypedArray<String> OmniLight3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray OmniLight3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!has_shadow() && get_projector().is_valid()) {
warnings.push_back(RTR("Projector texture only works with shadows active."));
@@ -608,8 +608,8 @@ OmniLight3D::OmniLight3D() :
set_param(PARAM_SHADOW_BIAS, 0.2);
}
-TypedArray<String> SpotLight3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray SpotLight3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (has_shadow() && get_param(PARAM_SPOT_ANGLE) >= 90.0) {
warnings.push_back(RTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows."));
diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h
index e43d6f0419..8da45bee79 100644
--- a/scene/3d/light_3d.h
+++ b/scene/3d/light_3d.h
@@ -216,7 +216,7 @@ public:
void set_shadow_mode(ShadowMode p_mode);
ShadowMode get_shadow_mode() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
OmniLight3D();
};
@@ -230,7 +230,7 @@ protected:
static void _bind_methods();
public:
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
SpotLight3D() :
Light3D(RenderingServer::LIGHT_SPOT) {}
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 34e84861a2..3476ced6ee 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -383,8 +383,8 @@ void NavigationAgent3D::_avoidance_done(Vector3 p_new_velocity) {
emit_signal(SNAME("velocity_computed"), p_new_velocity);
}
-TypedArray<String> NavigationAgent3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray NavigationAgent3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<Node3D>(get_parent())) {
warnings.push_back(RTR("The NavigationAgent3D can be used only under a Node3D inheriting parent node."));
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index 35c1b1175a..eed6457f4a 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -167,7 +167,7 @@ public:
void set_velocity(Vector3 p_velocity);
void _avoidance_done(Vector3 p_new_velocity);
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
private:
void update_navigation();
diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation_link_3d.cpp
index 47b602c966..78fe4754ea 100644
--- a/scene/3d/navigation_link_3d.cpp
+++ b/scene/3d/navigation_link_3d.cpp
@@ -378,8 +378,8 @@ void NavigationLink3D::set_travel_cost(real_t p_travel_cost) {
NavigationServer3D::get_singleton()->link_set_travel_cost(link, travel_cost);
}
-TypedArray<String> NavigationLink3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray NavigationLink3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (start_location.is_equal_approx(end_location)) {
warnings.push_back(RTR("NavigationLink3D start location should be different than the end location to be useful."));
diff --git a/scene/3d/navigation_link_3d.h b/scene/3d/navigation_link_3d.h
index 1f88075527..1fc03546fa 100644
--- a/scene/3d/navigation_link_3d.h
+++ b/scene/3d/navigation_link_3d.h
@@ -84,7 +84,7 @@ public:
void set_travel_cost(real_t p_travel_cost);
real_t get_travel_cost() const { return travel_cost; }
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
};
#endif // NAVIGATION_LINK_3D_H
diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp
index 9b49238333..07d8cd9289 100644
--- a/scene/3d/navigation_obstacle_3d.cpp
+++ b/scene/3d/navigation_obstacle_3d.cpp
@@ -126,8 +126,8 @@ NavigationObstacle3D::~NavigationObstacle3D() {
agent = RID(); // Pointless
}
-TypedArray<String> NavigationObstacle3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray NavigationObstacle3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<Node3D>(get_parent())) {
warnings.push_back(RTR("The NavigationObstacle3D only serves to provide collision avoidance to a Node3D inheriting parent object."));
diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h
index 24caf50680..f242d2f99e 100644
--- a/scene/3d/navigation_obstacle_3d.h
+++ b/scene/3d/navigation_obstacle_3d.h
@@ -72,7 +72,7 @@ public:
return radius;
}
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
private:
void initialize_agent();
diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp
index 049ca4c8a0..b060d314ba 100644
--- a/scene/3d/navigation_region_3d.cpp
+++ b/scene/3d/navigation_region_3d.cpp
@@ -37,6 +37,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) {
if (enabled == p_enabled) {
return;
}
+
enabled = p_enabled;
if (!is_inside_tree()) {
@@ -81,35 +82,50 @@ bool NavigationRegion3D::is_enabled() const {
}
void NavigationRegion3D::set_navigation_layers(uint32_t p_navigation_layers) {
- NavigationServer3D::get_singleton()->region_set_navigation_layers(region, p_navigation_layers);
+ if (navigation_layers == p_navigation_layers) {
+ return;
+ }
+
+ navigation_layers = p_navigation_layers;
+
+ NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers);
}
uint32_t NavigationRegion3D::get_navigation_layers() const {
- return NavigationServer3D::get_singleton()->region_get_navigation_layers(region);
+ return navigation_layers;
}
void NavigationRegion3D::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 NavigationRegion3D::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 NavigationRegion3D::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);
- NavigationServer3D::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;
+
+ NavigationServer3D::get_singleton()->region_set_enter_cost(region, enter_cost);
}
real_t NavigationRegion3D::get_enter_cost() const {
@@ -118,7 +134,12 @@ real_t NavigationRegion3D::get_enter_cost() const {
void NavigationRegion3D::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;
+
NavigationServer3D::get_singleton()->region_set_travel_cost(region, travel_cost);
}
@@ -130,8 +151,6 @@ RID NavigationRegion3D::get_region_rid() const {
return region;
}
-/////////////////////////////
-
void NavigationRegion3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
@@ -260,8 +279,8 @@ void NavigationRegion3D::_bake_finished(Ref<NavigationMesh> p_nav_mesh) {
emit_signal(SNAME("bake_finished"));
}
-TypedArray<String> NavigationRegion3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray NavigationRegion3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (is_visible_in_tree() && is_inside_tree()) {
if (!navmesh.is_valid()) {
diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h
index ba326abb46..660538d314 100644
--- a/scene/3d/navigation_region_3d.h
+++ b/scene/3d/navigation_region_3d.h
@@ -39,10 +39,10 @@ class NavigationRegion3D : public Node3D {
bool enabled = true;
RID region;
- Ref<NavigationMesh> navmesh;
-
+ uint32_t navigation_layers = 1;
real_t enter_cost = 0.0;
real_t travel_cost = 1.0;
+ Ref<NavigationMesh> navmesh;
Thread bake_thread;
@@ -90,7 +90,7 @@ public:
void bake_navigation_mesh(bool p_on_thread);
void _bake_finished(Ref<NavigationMesh> p_nav_mesh);
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
NavigationRegion3D();
~NavigationRegion3D();
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 59ec036558..ebf26996dd 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -1037,6 +1037,7 @@ void Node3D::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_ENTER_WORLD);
BIND_CONSTANT(NOTIFICATION_EXIT_WORLD);
BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED);
+ BIND_CONSTANT(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
BIND_ENUM_CONSTANT(ROTATION_EDIT_MODE_EULER);
BIND_ENUM_CONSTANT(ROTATION_EDIT_MODE_QUATERNION);
diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp
index 015cb9a21d..4e1ed5654a 100644
--- a/scene/3d/occluder_instance_3d.cpp
+++ b/scene/3d/occluder_instance_3d.cpp
@@ -682,8 +682,8 @@ OccluderInstance3D::BakeError OccluderInstance3D::bake_scene(Node *p_from_node,
return BAKE_ERROR_OK;
}
-TypedArray<String> OccluderInstance3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray OccluderInstance3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!bool(GLOBAL_GET("rendering/occlusion_culling/use_occlusion_culling"))) {
warnings.push_back(RTR("Occlusion culling is disabled in the Project Settings, which means occlusion culling won't be performed in the root viewport.\nTo resolve this, open the Project Settings and enable Rendering > Occlusion Culling > Use Occlusion Culling."));
diff --git a/scene/3d/occluder_instance_3d.h b/scene/3d/occluder_instance_3d.h
index 69a80e63fc..f507fee024 100644
--- a/scene/3d/occluder_instance_3d.h
+++ b/scene/3d/occluder_instance_3d.h
@@ -181,7 +181,7 @@ protected:
static void _bind_methods();
public:
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
enum BakeError {
BAKE_ERROR_OK,
diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp
index 2d1f4a579b..123a044b84 100644
--- a/scene/3d/path_3d.cpp
+++ b/scene/3d/path_3d.cpp
@@ -341,8 +341,8 @@ void PathFollow3D::_validate_property(PropertyInfo &p_property) const {
}
}
-TypedArray<String> PathFollow3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray PathFollow3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (is_visible_in_tree() && is_inside_tree()) {
if (!Object::cast_to<Path3D>(get_parent())) {
diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h
index 45fa2c8917..b161b12185 100644
--- a/scene/3d/path_3d.h
+++ b/scene/3d/path_3d.h
@@ -112,7 +112,7 @@ public:
void set_cubic_interpolation(bool p_enable);
bool get_cubic_interpolation() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
PathFollow3D() {}
};
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index c6c59a5c64..594e94644c 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -100,7 +100,7 @@ Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &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;
}
@@ -317,11 +317,6 @@ void AnimatableBody3D::_update_kinematic_motion() {
}
}
-void AnimatableBody3D::_body_state_changed_callback(void *p_instance, PhysicsDirectBodyState3D *p_state) {
- AnimatableBody3D *body = (AnimatableBody3D *)p_instance;
- body->_body_state_changed(p_state);
-}
-
void AnimatableBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) {
linear_velocity = p_state->get_linear_velocity();
angular_velocity = p_state->get_angular_velocity();
@@ -373,7 +368,7 @@ void AnimatableBody3D::_bind_methods() {
AnimatableBody3D::AnimatableBody3D() :
StaticBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) {
- PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback);
+ PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), callable_mp(this, &AnimatableBody3D::_body_state_changed));
}
void RigidBody3D::_body_enter_tree(ObjectID p_id) {
@@ -488,11 +483,6 @@ struct _RigidBodyInOut {
int local_shape = 0;
};
-void RigidBody3D::_body_state_changed_callback(void *p_instance, PhysicsDirectBodyState3D *p_state) {
- RigidBody3D *body = (RigidBody3D *)p_instance;
- body->_body_state_changed(p_state);
-}
-
void RigidBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) {
set_ignore_transform_notification(true);
set_global_transform(p_state->get_transform());
@@ -982,10 +972,10 @@ TypedArray<Node3D> RigidBody3D::get_colliding_bodies() const {
return ret;
}
-TypedArray<String> RigidBody3D::get_configuration_warnings() const {
+PackedStringArray RigidBody3D::get_configuration_warnings() const {
Transform3D t = get_transform();
- TypedArray<String> warnings = Node::get_configuration_warnings();
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (ABS(t.basis.get_column(0).length() - 1.0) > 0.05 || ABS(t.basis.get_column(1).length() - 1.0) > 0.05 || ABS(t.basis.get_column(2).length() - 1.0) > 0.05) {
warnings.push_back(RTR("Size changes to RigidBody will be overridden by the physics engine when running.\nChange the size in children collision shapes instead."));
@@ -1139,7 +1129,7 @@ void RigidBody3D::_validate_property(PropertyInfo &p_property) const {
RigidBody3D::RigidBody3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) {
- PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback);
+ PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), callable_mp(this, &RigidBody3D::_body_state_changed));
}
RigidBody3D::~RigidBody3D() {
@@ -1210,7 +1200,6 @@ bool CharacterBody3D::move_and_slide() {
if (!current_platform_velocity.is_zero_approx()) {
PhysicsServer3D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin);
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
parameters.exclude_bodies.insert(platform_rid);
if (platform_object_id.is_valid()) {
@@ -1274,8 +1263,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer3D::MotionParameters parameters(get_global_transform(), motion, margin);
- parameters.max_collisions = 4;
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
+ parameters.max_collisions = 6; // There can be 4 collisions between 2 walls + 2 more for the floor.
PhysicsServer3D::MotionResult result;
bool collided = move_and_collide(parameters, result, false, !sliding_enabled);
@@ -1520,7 +1508,6 @@ void CharacterBody3D::_move_and_slide_floating(double p_delta) {
bool first_slide = true;
for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer3D::MotionParameters parameters(get_global_transform(), motion, margin);
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
PhysicsServer3D::MotionResult result;
bool collided = move_and_collide(parameters, result, false, false);
@@ -1575,7 +1562,7 @@ void CharacterBody3D::_snap_on_floor(bool p_was_on_floor, bool p_vel_dir_facing_
PhysicsServer3D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
parameters.max_collisions = 4;
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
+ parameters.recovery_as_collision = true; // Report margin recovery as collision to improve floor detection.
parameters.collide_separation_ray = true;
PhysicsServer3D::MotionResult result;
@@ -1611,7 +1598,7 @@ bool CharacterBody3D::_on_floor_if_snapped(bool p_was_on_floor, bool p_vel_dir_f
PhysicsServer3D::MotionParameters parameters(get_global_transform(), -up_direction * length, margin);
parameters.max_collisions = 4;
- parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
+ parameters.recovery_as_collision = true; // Report margin recovery as collision to improve floor detection.
parameters.collide_separation_ray = true;
PhysicsServer3D::MotionResult result;
@@ -1810,7 +1797,7 @@ Ref<KinematicCollision3D> CharacterBody3D::_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;
}
@@ -2903,11 +2890,6 @@ void PhysicalBone3D::_notification(int p_what) {
}
}
-void PhysicalBone3D::_body_state_changed_callback(void *p_instance, PhysicsDirectBodyState3D *p_state) {
- PhysicalBone3D *bone = (PhysicalBone3D *)p_instance;
- bone->_body_state_changed(p_state);
-}
-
void PhysicalBone3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) {
if (!simulate_physics || !_internal_simulate_physics) {
return;
@@ -3425,7 +3407,7 @@ void PhysicalBone3D::_start_physics_simulation() {
PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer());
PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask());
PhysicsServer3D::get_singleton()->body_set_collision_priority(get_rid(), get_collision_priority());
- PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback);
+ PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), callable_mp(this, &PhysicalBone3D::_body_state_changed));
set_as_top_level(true);
_internal_simulate_physics = true;
}
@@ -3446,7 +3428,7 @@ void PhysicalBone3D::_stop_physics_simulation() {
PhysicsServer3D::get_singleton()->body_set_collision_priority(get_rid(), 1.0);
}
if (_internal_simulate_physics) {
- PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), nullptr, nullptr);
+ PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), Callable());
parent_skeleton->set_bone_global_pose_override(bone_id, Transform3D(), 0.0, false);
set_as_top_level(false);
_internal_simulate_physics = false;
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index 8e0296fd9b..4b874b91d9 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -325,7 +325,7 @@ public:
void set_constant_torque(const Vector3 &p_torque);
Vector3 get_constant_torque() const;
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
RigidBody3D();
~RigidBody3D();
diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp
index 9979052385..ff05e88241 100644
--- a/scene/3d/remote_transform_3d.cpp
+++ b/scene/3d/remote_transform_3d.cpp
@@ -178,8 +178,8 @@ void RemoteTransform3D::force_update_cache() {
_update_cache();
}
-TypedArray<String> RemoteTransform3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray RemoteTransform3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!has_node(remote_node) || !Object::cast_to<Node3D>(get_node(remote_node))) {
warnings.push_back(RTR("The \"Remote Path\" property must point to a valid Node3D or Node3D-derived node to work."));
diff --git a/scene/3d/remote_transform_3d.h b/scene/3d/remote_transform_3d.h
index ab134c1261..cc83661f26 100644
--- a/scene/3d/remote_transform_3d.h
+++ b/scene/3d/remote_transform_3d.h
@@ -70,7 +70,7 @@ public:
void force_update_cache();
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
RemoteTransform3D();
};
diff --git a/scene/3d/shape_cast_3d.cpp b/scene/3d/shape_cast_3d.cpp
index a2fecf9c31..e7d1a8ec7d 100644
--- a/scene/3d/shape_cast_3d.cpp
+++ b/scene/3d/shape_cast_3d.cpp
@@ -167,8 +167,8 @@ void ShapeCast3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_shape_custom_color"), "set_debug_shape_custom_color", "get_debug_shape_custom_color");
}
-TypedArray<String> ShapeCast3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node3D::get_configuration_warnings();
+PackedStringArray ShapeCast3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node3D::get_configuration_warnings();
if (shape.is_null()) {
warnings.push_back(RTR("This node cannot interact with other objects unless a Shape3D is assigned."));
diff --git a/scene/3d/shape_cast_3d.h b/scene/3d/shape_cast_3d.h
index 5bda15e4b0..2526d8d32c 100644
--- a/scene/3d/shape_cast_3d.h
+++ b/scene/3d/shape_cast_3d.h
@@ -136,7 +136,7 @@ public:
void remove_exception(const Object *p_object);
void clear_exceptions();
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
};
#endif // SHAPE_CAST_3D_H
diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp
index 47858b372c..2466b71aea 100644
--- a/scene/3d/soft_body_3d.cpp
+++ b/scene/3d/soft_body_3d.cpp
@@ -384,8 +384,8 @@ void SoftBody3D::_bind_methods() {
BIND_ENUM_CONSTANT(DISABLE_MODE_KEEP_ACTIVE);
}
-TypedArray<String> SoftBody3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray SoftBody3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (mesh.is_null()) {
warnings.push_back(RTR("This body will be ignored until you set a mesh."));
diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h
index 40f3d6f1f4..9ec1f18396 100644
--- a/scene/3d/soft_body_3d.h
+++ b/scene/3d/soft_body_3d.h
@@ -125,7 +125,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
public:
RID get_physics_rid() const { return physics_rid; }
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 380172f396..4b83bcdfc4 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -87,6 +87,182 @@ void SpriteBase3D::_notification(int p_what) {
}
}
+void SpriteBase3D::draw_texture_rect(Ref<Texture2D> p_texture, Rect2 p_dst_rect, Rect2 p_src_rect) {
+ ERR_FAIL_COND(p_texture.is_null());
+
+ Rect2 final_rect;
+ Rect2 final_src_rect;
+ if (!p_texture->get_rect_region(p_dst_rect, p_src_rect, final_rect, final_src_rect)) {
+ return;
+ }
+
+ if (final_rect.size.x == 0 || final_rect.size.y == 0) {
+ return;
+ }
+
+ // 2D: 3D plane (axes match exactly when `axis == Vector3::AXIS_Z`):
+ // -X+ -X+
+ // - +
+ // Y +--------+ +--------+ +--------+ Y +--------+
+ // + | +--+ | | | (2) | | - | 0--1 |
+ // | |ab| | (1) | +--+ | (3) | 3--2 | | |ab| |
+ // | |cd| | --> | |ab| | --> | |cd| | <==> | |cd| |
+ // | +--+ | | |cd| | | |ab| | | 3--2 |
+ // | | | +--+ | | 0--1 | | |
+ // +--------+ +--------+ +--------+ +--------+
+
+ // (1) Y-wise shift `final_rect` within `p_dst_rect` so after inverting Y
+ // axis distances between top/bottom borders will be preserved (so for
+ // example AtlasTextures with vertical margins will look the same in 2D/3D).
+ final_rect.position.y = (p_dst_rect.position.y + p_dst_rect.size.y) - ((final_rect.position.y + final_rect.size.y) - p_dst_rect.position.y);
+
+ Color color = _get_color_accum();
+
+ real_t pixel_size = get_pixel_size();
+
+ // (2) Order vertices (0123) bottom-top in 2D / top-bottom in 3D.
+ Vector2 vertices[4] = {
+ (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
+ (final_rect.position + final_rect.size) * pixel_size,
+ (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
+ final_rect.position * pixel_size,
+ };
+
+ Vector2 src_tsize = p_texture->get_size();
+
+ // Properly setup UVs for impostor textures (AtlasTexture).
+ Ref<AtlasTexture> atlas_tex = p_texture;
+ if (atlas_tex != nullptr) {
+ src_tsize[0] = atlas_tex->get_atlas()->get_width();
+ src_tsize[1] = atlas_tex->get_atlas()->get_height();
+ }
+
+ // (3) Assign UVs (abcd) according to the vertices order (bottom-top in 2D / top-bottom in 3D).
+ Vector2 uvs[4] = {
+ final_src_rect.position / src_tsize,
+ (final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / src_tsize,
+ (final_src_rect.position + final_src_rect.size) / src_tsize,
+ (final_src_rect.position + Vector2(0, final_src_rect.size.y)) / src_tsize,
+ };
+
+ if (is_flipped_h()) {
+ SWAP(uvs[0], uvs[1]);
+ SWAP(uvs[2], uvs[3]);
+ }
+
+ if (is_flipped_v()) {
+ SWAP(uvs[0], uvs[3]);
+ SWAP(uvs[1], uvs[2]);
+ }
+
+ Vector3 normal;
+ int axis = get_axis();
+ normal[axis] = 1.0;
+
+ Plane tangent;
+ if (axis == Vector3::AXIS_X) {
+ tangent = Plane(0, 0, -1, 1);
+ } else {
+ tangent = Plane(1, 0, 0, 1);
+ }
+
+ int x_axis = ((axis + 1) % 3);
+ int y_axis = ((axis + 2) % 3);
+
+ if (axis != Vector3::AXIS_Z) {
+ SWAP(x_axis, y_axis);
+
+ for (int i = 0; i < 4; i++) {
+ //uvs[i] = Vector2(1.0,1.0)-uvs[i];
+ //SWAP(vertices[i].x,vertices[i].y);
+ if (axis == Vector3::AXIS_Y) {
+ vertices[i].y = -vertices[i].y;
+ } else if (axis == Vector3::AXIS_X) {
+ vertices[i].x = -vertices[i].x;
+ }
+ }
+ }
+
+ AABB aabb;
+
+ // Everything except position and UV is compressed.
+ uint8_t *vertex_write_buffer = vertex_buffer.ptrw();
+ uint8_t *attribute_write_buffer = attribute_buffer.ptrw();
+
+ uint32_t v_normal;
+ {
+ Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
+
+ Vector2 res = n.octahedron_encode();
+ uint32_t value = 0;
+ value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
+ value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
+
+ v_normal = value;
+ }
+ uint32_t v_tangent;
+ {
+ Plane t = tangent;
+ Vector2 res = t.normal.octahedron_tangent_encode(t.d);
+ uint32_t value = 0;
+ value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
+ value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
+
+ v_tangent = value;
+ }
+
+ uint8_t v_color[4] = {
+ uint8_t(CLAMP(color.r * 255.0, 0.0, 255.0)),
+ uint8_t(CLAMP(color.g * 255.0, 0.0, 255.0)),
+ uint8_t(CLAMP(color.b * 255.0, 0.0, 255.0)),
+ uint8_t(CLAMP(color.a * 255.0, 0.0, 255.0))
+ };
+
+ for (int i = 0; i < 4; i++) {
+ Vector3 vtx;
+ vtx[x_axis] = vertices[i][0];
+ vtx[y_axis] = vertices[i][1];
+ if (i == 0) {
+ aabb.position = vtx;
+ aabb.size = Vector3();
+ } else {
+ aabb.expand_to(vtx);
+ }
+
+ float v_uv[2] = { (float)uvs[i].x, (float)uvs[i].y };
+ memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_TEX_UV]], v_uv, 8);
+
+ float v_vertex[3] = { (float)vtx.x, (float)vtx.y, (float)vtx.z };
+
+ memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3);
+ memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_NORMAL]], &v_normal, 4);
+ memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_TANGENT]], &v_tangent, 4);
+ memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_COLOR]], v_color, 4);
+ }
+
+ RID mesh = get_mesh();
+ RS::get_singleton()->mesh_surface_update_vertex_region(mesh, 0, 0, vertex_buffer);
+ RS::get_singleton()->mesh_surface_update_attribute_region(mesh, 0, 0, attribute_buffer);
+
+ RS::get_singleton()->mesh_set_custom_aabb(mesh, aabb);
+ set_aabb(aabb);
+
+ RID shader_rid;
+ StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, false, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), get_texture_filter(), &shader_rid);
+ if (last_shader != shader_rid) {
+ RS::get_singleton()->material_set_shader(get_material(), shader_rid);
+ last_shader = shader_rid;
+ }
+ if (last_texture != p_texture->get_rid()) {
+ RS::get_singleton()->material_set_param(get_material(), "texture_albedo", p_texture->get_rid());
+ last_texture = p_texture->get_rid();
+ }
+ if (get_alpha_cut_mode() == ALPHA_CUT_DISABLED) {
+ RS::get_singleton()->material_set_render_priority(get_material(), get_render_priority());
+ RS::get_singleton()->mesh_surface_set_material(mesh, 0, get_material());
+ }
+}
+
void SpriteBase3D::set_centered(bool p_center) {
centered = p_center;
_queue_redraw();
@@ -464,171 +640,17 @@ void Sprite3D::_draw() {
}
Size2 frame_size = base_rect.size / Size2(hframes, vframes);
- Point2 frame_offset = Point2(frame % hframes, frame / hframes);
- frame_offset *= frame_size;
+ Point2 frame_offset = Point2(frame % hframes, frame / hframes) * frame_size;
- Point2 dest_offset = get_offset();
+ Point2 dst_offset = get_offset();
if (is_centered()) {
- dest_offset -= frame_size / 2;
+ dst_offset -= frame_size / 2.0f;
}
Rect2 src_rect(base_rect.position + frame_offset, frame_size);
- Rect2 final_dst_rect(dest_offset, frame_size);
- Rect2 final_rect;
- Rect2 final_src_rect;
- if (!texture->get_rect_region(final_dst_rect, src_rect, final_rect, final_src_rect)) {
- return;
- }
-
- if (final_rect.size.x == 0 || final_rect.size.y == 0) {
- return;
- }
-
- Color color = _get_color_accum();
-
- real_t pixel_size = get_pixel_size();
-
- Vector2 vertices[4] = {
-
- (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
- (final_rect.position + final_rect.size) * pixel_size,
- (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
- final_rect.position * pixel_size,
-
- };
-
- Vector2 src_tsize = tsize;
-
- // Properly setup UVs for impostor textures (AtlasTexture).
- Ref<AtlasTexture> atlas_tex = texture;
- if (atlas_tex != nullptr) {
- src_tsize[0] = atlas_tex->get_atlas()->get_width();
- src_tsize[1] = atlas_tex->get_atlas()->get_height();
- }
-
- Vector2 uvs[4] = {
- final_src_rect.position / src_tsize,
- (final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / src_tsize,
- (final_src_rect.position + final_src_rect.size) / src_tsize,
- (final_src_rect.position + Vector2(0, final_src_rect.size.y)) / src_tsize,
- };
-
- if (is_flipped_h()) {
- SWAP(uvs[0], uvs[1]);
- SWAP(uvs[2], uvs[3]);
- }
-
- if (is_flipped_v()) {
- SWAP(uvs[0], uvs[3]);
- SWAP(uvs[1], uvs[2]);
- }
-
- Vector3 normal;
- int axis = get_axis();
- normal[axis] = 1.0;
-
- Plane tangent;
- if (axis == Vector3::AXIS_X) {
- tangent = Plane(0, 0, -1, 1);
- } else {
- tangent = Plane(1, 0, 0, 1);
- }
-
- int x_axis = ((axis + 1) % 3);
- int y_axis = ((axis + 2) % 3);
-
- if (axis != Vector3::AXIS_Z) {
- SWAP(x_axis, y_axis);
-
- for (int i = 0; i < 4; i++) {
- //uvs[i] = Vector2(1.0,1.0)-uvs[i];
- //SWAP(vertices[i].x,vertices[i].y);
- if (axis == Vector3::AXIS_Y) {
- vertices[i].y = -vertices[i].y;
- } else if (axis == Vector3::AXIS_X) {
- vertices[i].x = -vertices[i].x;
- }
- }
- }
-
- AABB aabb;
-
- // Everything except position and UV is compressed.
- uint8_t *vertex_write_buffer = vertex_buffer.ptrw();
- uint8_t *attribute_write_buffer = attribute_buffer.ptrw();
-
- uint32_t v_normal;
- {
- Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
-
- Vector2 res = n.octahedron_encode();
- uint32_t value = 0;
- value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
- value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
-
- v_normal = value;
- }
- uint32_t v_tangent;
- {
- Plane t = tangent;
- Vector2 res = t.normal.octahedron_tangent_encode(t.d);
- uint32_t value = 0;
- value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
- value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
+ Rect2 dst_rect(dst_offset, frame_size);
- v_tangent = value;
- }
-
- uint8_t v_color[4] = {
- uint8_t(CLAMP(color.r * 255.0, 0.0, 255.0)),
- uint8_t(CLAMP(color.g * 255.0, 0.0, 255.0)),
- uint8_t(CLAMP(color.b * 255.0, 0.0, 255.0)),
- uint8_t(CLAMP(color.a * 255.0, 0.0, 255.0))
- };
-
- for (int i = 0; i < 4; i++) {
- Vector3 vtx;
- vtx[x_axis] = vertices[i][0];
- vtx[y_axis] = vertices[i][1];
- if (i == 0) {
- aabb.position = vtx;
- aabb.size = Vector3();
- } else {
- aabb.expand_to(vtx);
- }
-
- float v_uv[2] = { (float)uvs[i].x, (float)uvs[i].y };
- memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_TEX_UV]], v_uv, 8);
-
- float v_vertex[3] = { (float)vtx.x, (float)vtx.y, (float)vtx.z };
-
- memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3);
- memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_NORMAL]], &v_normal, 4);
- memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_TANGENT]], &v_tangent, 4);
- memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_COLOR]], v_color, 4);
- }
-
- RID mesh = get_mesh();
- RS::get_singleton()->mesh_surface_update_vertex_region(mesh, 0, 0, vertex_buffer);
- RS::get_singleton()->mesh_surface_update_attribute_region(mesh, 0, 0, attribute_buffer);
-
- RS::get_singleton()->mesh_set_custom_aabb(mesh, aabb);
- set_aabb(aabb);
-
- RID shader_rid;
- StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, false, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), get_texture_filter(), &shader_rid);
- if (last_shader != shader_rid) {
- RS::get_singleton()->material_set_shader(get_material(), shader_rid);
- last_shader = shader_rid;
- }
- if (last_texture != texture->get_rid()) {
- RS::get_singleton()->material_set_param(get_material(), "texture_albedo", texture->get_rid());
- last_texture = texture->get_rid();
- }
- if (get_alpha_cut_mode() == ALPHA_CUT_DISABLED) {
- RS::get_singleton()->material_set_render_priority(get_material(), get_render_priority());
- RS::get_singleton()->mesh_surface_set_material(mesh, 0, get_material());
- }
+ draw_texture_rect(texture, dst_rect, src_rect);
}
void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
@@ -831,158 +853,7 @@ void AnimatedSprite3D::_draw() {
Rect2 dst_rect(ofs, tsize);
- Rect2 final_rect;
- Rect2 final_src_rect;
- if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect)) {
- return;
- }
-
- if (final_rect.size.x == 0 || final_rect.size.y == 0) {
- return;
- }
-
- Color color = _get_color_accum();
-
- real_t pixel_size = get_pixel_size();
-
- Vector2 vertices[4] = {
-
- (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
- (final_rect.position + final_rect.size) * pixel_size,
- (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
- final_rect.position * pixel_size,
-
- };
-
- Vector2 src_tsize = tsize;
-
- // Properly setup UVs for impostor textures (AtlasTexture).
- Ref<AtlasTexture> atlas_tex = texture;
- if (atlas_tex != nullptr) {
- src_tsize[0] = atlas_tex->get_atlas()->get_width();
- src_tsize[1] = atlas_tex->get_atlas()->get_height();
- }
-
- Vector2 uvs[4] = {
- final_src_rect.position / src_tsize,
- (final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / src_tsize,
- (final_src_rect.position + final_src_rect.size) / src_tsize,
- (final_src_rect.position + Vector2(0, final_src_rect.size.y)) / src_tsize,
- };
-
- if (is_flipped_h()) {
- SWAP(uvs[0], uvs[1]);
- SWAP(uvs[2], uvs[3]);
- }
- if (is_flipped_v()) {
- SWAP(uvs[0], uvs[3]);
- SWAP(uvs[1], uvs[2]);
- }
-
- Vector3 normal;
- int axis = get_axis();
- normal[axis] = 1.0;
-
- Plane tangent;
- if (axis == Vector3::AXIS_X) {
- tangent = Plane(0, 0, -1, -1);
- } else {
- tangent = Plane(1, 0, 0, -1);
- }
-
- int x_axis = ((axis + 1) % 3);
- int y_axis = ((axis + 2) % 3);
-
- if (axis != Vector3::AXIS_Z) {
- SWAP(x_axis, y_axis);
-
- for (int i = 0; i < 4; i++) {
- //uvs[i] = Vector2(1.0,1.0)-uvs[i];
- //SWAP(vertices[i].x,vertices[i].y);
- if (axis == Vector3::AXIS_Y) {
- vertices[i].y = -vertices[i].y;
- } else if (axis == Vector3::AXIS_X) {
- vertices[i].x = -vertices[i].x;
- }
- }
- }
-
- AABB aabb;
-
- // Everything except position and UV is compressed.
- uint8_t *vertex_write_buffer = vertex_buffer.ptrw();
- uint8_t *attribute_write_buffer = attribute_buffer.ptrw();
-
- uint32_t v_normal;
- {
- Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
-
- Vector2 res = n.octahedron_encode();
- uint32_t value = 0;
- value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
- value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
-
- v_normal = value;
- }
- uint32_t v_tangent;
- {
- Plane t = tangent;
- Vector2 res = t.normal.octahedron_tangent_encode(t.d);
- uint32_t value = 0;
- value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
- value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
- v_tangent = value;
- }
-
- uint8_t v_color[4] = {
- uint8_t(CLAMP(color.r * 255.0, 0.0, 255.0)),
- uint8_t(CLAMP(color.g * 255.0, 0.0, 255.0)),
- uint8_t(CLAMP(color.b * 255.0, 0.0, 255.0)),
- uint8_t(CLAMP(color.a * 255.0, 0.0, 255.0))
- };
-
- for (int i = 0; i < 4; i++) {
- Vector3 vtx;
- vtx[x_axis] = vertices[i][0];
- vtx[y_axis] = vertices[i][1];
- if (i == 0) {
- aabb.position = vtx;
- aabb.size = Vector3();
- } else {
- aabb.expand_to(vtx);
- }
-
- float v_uv[2] = { (float)uvs[i].x, (float)uvs[i].y };
- memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_TEX_UV]], v_uv, 8);
-
- float v_vertex[3] = { (float)vtx.x, (float)vtx.y, (float)vtx.z };
- memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_VERTEX]], &v_vertex, sizeof(float) * 3);
- memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_NORMAL]], &v_normal, 4);
- memcpy(&vertex_write_buffer[i * vertex_stride + mesh_surface_offsets[RS::ARRAY_TANGENT]], &v_tangent, 4);
- memcpy(&attribute_write_buffer[i * attrib_stride + mesh_surface_offsets[RS::ARRAY_COLOR]], v_color, 4);
- }
-
- RID mesh = get_mesh();
- RS::get_singleton()->mesh_surface_update_vertex_region(mesh, 0, 0, vertex_buffer);
- RS::get_singleton()->mesh_surface_update_attribute_region(mesh, 0, 0, attribute_buffer);
-
- RS::get_singleton()->mesh_set_custom_aabb(mesh, aabb);
- set_aabb(aabb);
-
- RID shader_rid;
- StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, false, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), get_texture_filter(), &shader_rid);
- if (last_shader != shader_rid) {
- RS::get_singleton()->material_set_shader(get_material(), shader_rid);
- last_shader = shader_rid;
- }
- if (last_texture != texture->get_rid()) {
- RS::get_singleton()->material_set_param(get_material(), "texture_albedo", texture->get_rid());
- last_texture = texture->get_rid();
- }
- if (get_alpha_cut_mode() == ALPHA_CUT_DISABLED) {
- RS::get_singleton()->material_set_render_priority(get_material(), get_render_priority());
- RS::get_singleton()->mesh_surface_set_material(mesh, 0, get_material());
- }
+ draw_texture_rect(texture, dst_rect, src_rect);
}
void AnimatedSprite3D::_validate_property(PropertyInfo &p_property) const {
@@ -1285,8 +1156,8 @@ StringName AnimatedSprite3D::get_animation() const {
return animation;
}
-TypedArray<String> AnimatedSprite3D::get_configuration_warnings() const {
- TypedArray<String> warnings = SpriteBase3D::get_configuration_warnings();
+PackedStringArray AnimatedSprite3D::get_configuration_warnings() const {
+ PackedStringArray warnings = SpriteBase3D::get_configuration_warnings();
if (frames.is_null()) {
warnings.push_back(RTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames."));
}
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index f6ad1bbdb8..edc48c7b71 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -80,6 +80,9 @@ private:
RID mesh;
RID material;
+ RID last_shader;
+ RID last_texture;
+
bool flags[FLAG_MAX] = {};
AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
@@ -94,6 +97,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
virtual void _draw() = 0;
+ void draw_texture_rect(Ref<Texture2D> p_texture, Rect2 p_dst_rect, Rect2 p_src_rect);
_FORCE_INLINE_ void set_aabb(const AABB &p_aabb) { aabb = p_aabb; }
_FORCE_INLINE_ RID &get_mesh() { return mesh; }
_FORCE_INLINE_ RID &get_material() { return material; }
@@ -167,9 +171,6 @@ class Sprite3D : public SpriteBase3D {
int vframes = 1;
int hframes = 1;
- RID last_shader;
- RID last_texture;
-
protected:
virtual void _draw() override;
static void _bind_methods();
@@ -225,9 +226,6 @@ class AnimatedSprite3D : public SpriteBase3D {
double _get_frame_duration();
void _reset_timeout();
- RID last_shader;
- RID last_texture;
-
protected:
virtual void _draw() override;
static void _bind_methods();
@@ -255,7 +253,7 @@ public:
virtual Rect2 get_item_rect() const override;
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
AnimatedSprite3D();
diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp
index d61b49eaa7..36b5e61f45 100644
--- a/scene/3d/vehicle_body_3d.cpp
+++ b/scene/3d/vehicle_body_3d.cpp
@@ -105,8 +105,8 @@ void VehicleWheel3D::_notification(int p_what) {
}
}
-TypedArray<String> VehicleWheel3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray VehicleWheel3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Object::cast_to<VehicleBody3D>(get_parent())) {
warnings.push_back(RTR("VehicleWheel3D serves to provide a wheel system to a VehicleBody3D. Please use it as a child of a VehicleBody3D."));
diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h
index 5c4f4beaea..a6a49ee88a 100644
--- a/scene/3d/vehicle_body_3d.h
+++ b/scene/3d/vehicle_body_3d.h
@@ -147,7 +147,7 @@ public:
void set_steering(real_t p_steering);
real_t get_steering() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
VehicleWheel3D();
};
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index db9f68544b..e93ad5ecbf 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -385,8 +385,8 @@ bool GeometryInstance3D::is_ignoring_occlusion_culling() {
return ignore_occlusion_culling;
}
-TypedArray<String> GeometryInstance3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray GeometryInstance3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!Math::is_zero_approx(visibility_range_end) && visibility_range_end <= visibility_range_begin) {
warnings.push_back(RTR("The GeometryInstance3D visibility range's End distance is set to a non-zero value, but is lower than the Begin distance.\nThis means the GeometryInstance3D will never be visible.\nTo resolve this, set the End distance to 0 or to a value greater than the Begin distance."));
diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h
index 100d8d8836..4755545516 100644
--- a/scene/3d/visual_instance_3d.h
+++ b/scene/3d/visual_instance_3d.h
@@ -186,7 +186,7 @@ public:
void set_ignore_occlusion_culling(bool p_enabled);
bool is_ignoring_occlusion_culling();
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
GeometryInstance3D();
virtual ~GeometryInstance3D();
};
diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp
index c97af087bf..1b1ac32207 100644
--- a/scene/3d/voxel_gi.cpp
+++ b/scene/3d/voxel_gi.cpp
@@ -468,8 +468,8 @@ AABB VoxelGI::get_aabb() const {
return AABB(-extents, extents * 2);
}
-TypedArray<String> VoxelGI::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray VoxelGI::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (RenderingServer::get_singleton()->is_low_end()) {
warnings.push_back(RTR("VoxelGIs are not supported by the OpenGL video driver.\nUse a LightmapGI instead."));
diff --git a/scene/3d/voxel_gi.h b/scene/3d/voxel_gi.h
index b31ae4cd95..fc10091d4f 100644
--- a/scene/3d/voxel_gi.h
+++ b/scene/3d/voxel_gi.h
@@ -157,7 +157,7 @@ public:
virtual AABB get_aabb() const override;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
VoxelGI();
~VoxelGI();
diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp
index ae7d79e8b0..6cc5e9ef20 100644
--- a/scene/3d/world_environment.cpp
+++ b/scene/3d/world_environment.cpp
@@ -135,8 +135,8 @@ Ref<CameraAttributes> WorldEnvironment::get_camera_attributes() const {
return camera_attributes;
}
-TypedArray<String> WorldEnvironment::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray WorldEnvironment::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!environment.is_valid() && !camera_attributes.is_valid()) {
warnings.push_back(RTR("To have any visible effect, WorldEnvironment requires its \"Environment\" property to contain an Environment, its \"Camera Attributes\" property to contain a CameraAttributes resource, or both."));
diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h
index 07f243c750..cc46a06b4c 100644
--- a/scene/3d/world_environment.h
+++ b/scene/3d/world_environment.h
@@ -55,7 +55,7 @@ public:
void set_camera_attributes(const Ref<CameraAttributes> &p_camera_attributes);
Ref<CameraAttributes> get_camera_attributes() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
WorldEnvironment();
};
diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp
index de765d7ccb..4401d22f30 100644
--- a/scene/3d/xr_nodes.cpp
+++ b/scene/3d/xr_nodes.cpp
@@ -88,8 +88,8 @@ void XRCamera3D::_pose_changed(const Ref<XRPose> &p_pose) {
}
}
-TypedArray<String> XRCamera3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray XRCamera3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (is_visible() && is_inside_tree()) {
// must be child node of XROrigin3D!
@@ -414,8 +414,8 @@ XRNode3D::~XRNode3D() {
xr_server->disconnect("tracker_removed", callable_mp(this, &XRNode3D::_removed_tracker));
}
-TypedArray<String> XRNode3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray XRNode3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (is_visible() && is_inside_tree()) {
// must be child node of XROrigin!
@@ -582,8 +582,8 @@ Plane XRAnchor3D::get_plane() const {
////////////////////////////////////////////////////////////////////////////////////////////////////
-TypedArray<String> XROrigin3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray XROrigin3D::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (is_visible() && is_inside_tree()) {
if (tracked_camera == nullptr) {
diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h
index 312bef7856..ef846cc3a3 100644
--- a/scene/3d/xr_nodes.h
+++ b/scene/3d/xr_nodes.h
@@ -55,7 +55,7 @@ protected:
void _pose_changed(const Ref<XRPose> &p_pose);
public:
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
virtual Vector3 project_local_ray_normal(const Point2 &p_pos) const override;
virtual Point2 unproject_position(const Vector3 &p_pos) const override;
@@ -107,7 +107,7 @@ public:
Ref<XRPose> get_pose();
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
XRNode3D();
~XRNode3D();
@@ -187,7 +187,7 @@ protected:
static void _bind_methods();
public:
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
void set_tracked_camera(XRCamera3D *p_tracked_camera);
XRCamera3D *get_tracked_camera() const;
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 1efbaacb3b..c063d8f1bf 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -217,19 +217,19 @@ Variant AnimationNodeOneShot::get_parameter_default_value(const StringName &p_pa
}
}
-void AnimationNodeOneShot::set_fadein_time(float p_time) {
+void AnimationNodeOneShot::set_fadein_time(double p_time) {
fade_in = p_time;
}
-void AnimationNodeOneShot::set_fadeout_time(float p_time) {
+void AnimationNodeOneShot::set_fadeout_time(double p_time) {
fade_out = p_time;
}
-float AnimationNodeOneShot::get_fadein_time() const {
+double AnimationNodeOneShot::get_fadein_time() const {
return fade_in;
}
-float AnimationNodeOneShot::get_fadeout_time() const {
+double AnimationNodeOneShot::get_fadeout_time() const {
return fade_out;
}
@@ -237,11 +237,11 @@ void AnimationNodeOneShot::set_autorestart(bool p_active) {
autorestart = p_active;
}
-void AnimationNodeOneShot::set_autorestart_delay(float p_time) {
+void AnimationNodeOneShot::set_autorestart_delay(double p_time) {
autorestart_delay = p_time;
}
-void AnimationNodeOneShot::set_autorestart_random_delay(float p_time) {
+void AnimationNodeOneShot::set_autorestart_random_delay(double p_time) {
autorestart_random_delay = p_time;
}
@@ -249,11 +249,11 @@ bool AnimationNodeOneShot::has_autorestart() const {
return autorestart;
}
-float AnimationNodeOneShot::get_autorestart_delay() const {
+double AnimationNodeOneShot::get_autorestart_delay() const {
return autorestart_delay;
}
-float AnimationNodeOneShot::get_autorestart_random_delay() const {
+double AnimationNodeOneShot::get_autorestart_random_delay() const {
return autorestart_random_delay;
}
@@ -313,7 +313,7 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_seek_roo
set_parameter(this->prev_active, true);
}
- float blend;
+ real_t blend;
if (time < fade_in) {
if (fade_in > 0) {
@@ -351,7 +351,7 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_seek_roo
set_parameter(this->active, false);
set_parameter(this->prev_active, false);
if (autorestart) {
- float restart_sec = autorestart_delay + Math::randf() * autorestart_random_delay;
+ double restart_sec = autorestart_delay + Math::randd() * autorestart_random_delay;
set_parameter(this->time_to_restart, restart_sec);
}
}
@@ -676,11 +676,11 @@ String AnimationNodeTransition::get_input_caption(int p_input) const {
return inputs[p_input].name;
}
-void AnimationNodeTransition::set_xfade_time(float p_fade) {
+void AnimationNodeTransition::set_xfade_time(double p_fade) {
xfade_time = p_fade;
}
-float AnimationNodeTransition::get_xfade_time() const {
+double AnimationNodeTransition::get_xfade_time() const {
return xfade_time;
}
@@ -748,7 +748,7 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_seek_
} else { // cross-fading from prev to current
- float blend = xfade_time == 0 ? 0 : (prev_xfading / xfade_time);
+ real_t blend = xfade_time == 0 ? 0 : (prev_xfading / xfade_time);
if (xfade_curve.is_valid()) {
blend = xfade_curve->sample(blend);
}
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 59c074cc80..1c31718259 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -102,18 +102,18 @@ public:
};
private:
- float fade_in = 0.0;
- float fade_out = 0.0;
+ double fade_in = 0.0;
+ double fade_out = 0.0;
bool autorestart = false;
- float autorestart_delay = 1.0;
- float autorestart_random_delay = 0.0;
+ double autorestart_delay = 1.0;
+ double autorestart_random_delay = 0.0;
MixMode mix = MIX_MODE_BLEND;
/* bool active;
bool do_start;
- float time;
- float remaining;*/
+ double time;
+ double remaining;*/
StringName active = PNAME("active");
StringName prev_active = "prev_active";
@@ -130,19 +130,19 @@ public:
virtual String get_caption() const override;
- void set_fadein_time(float p_time);
- void set_fadeout_time(float p_time);
+ void set_fadein_time(double p_time);
+ void set_fadeout_time(double p_time);
- float get_fadein_time() const;
- float get_fadeout_time() const;
+ double get_fadein_time() const;
+ double get_fadeout_time() const;
void set_autorestart(bool p_active);
- void set_autorestart_delay(float p_time);
- void set_autorestart_random_delay(float p_time);
+ void set_autorestart_delay(double p_time);
+ void set_autorestart_random_delay(double p_time);
bool has_autorestart() const;
- float get_autorestart_delay() const;
- float get_autorestart_random_delay() const;
+ double get_autorestart_delay() const;
+ double get_autorestart_random_delay() const;
void set_mix_mode(MixMode p_mix);
MixMode get_mix_mode() const;
@@ -285,9 +285,9 @@ class AnimationNodeTransition : public AnimationNodeSync {
int enabled_inputs = 0;
/*
- float prev_xfading;
+ double prev_xfading;
int prev;
- float time;
+ double time;
int current;
int prev_current; */
@@ -297,7 +297,7 @@ class AnimationNodeTransition : public AnimationNodeSync {
StringName current = PNAME("current");
StringName prev_current = "prev_current";
- float xfade_time = 0.0;
+ double xfade_time = 0.0;
Ref<Curve> xfade_curve;
bool from_start = true;
@@ -322,8 +322,8 @@ public:
void set_input_caption(int p_input, const String &p_name);
String get_input_caption(int p_input) const;
- void set_xfade_time(float p_fade);
- float get_xfade_time() const;
+ void set_xfade_time(double p_fade);
+ double get_xfade_time() const;
void set_xfade_curve(const Ref<Curve> &p_curve);
Ref<Curve> get_xfade_curve() const;
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 49a59de9b2..facffb99ee 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "animation_node_state_machine.h"
+#include "scene/main/window.h"
/////////////////////////////////////////////////
@@ -169,7 +170,7 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
ADD_GROUP("Advance", "advance_");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "advance_condition"), "set_advance_condition", "get_advance_condition");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "advance_expression", PROPERTY_HINT_EXPRESSION, ""), "set_advance_expression", "get_advance_expression");
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "advance_expression_base_node"), "set_advance_expression_base_node", "get_advance_expression_base_node");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "advance_expression_base_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node"), "set_advance_expression_base_node", "get_advance_expression_base_node");
ADD_GROUP("Disabling", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
@@ -656,13 +657,15 @@ bool AnimationNodeStateMachinePlayback::_check_advance_condition(const Ref<Anima
ERR_FAIL_COND_V(tree_base == nullptr, false);
NodePath advance_expression_base_node_path;
- if (!transition->advance_expression_base_node.is_empty()) {
- advance_expression_base_node_path = transition->advance_expression_base_node;
+ Node *expression_base = nullptr;
+ if (!transition->get_advance_expression_base_node().is_empty()) {
+ advance_expression_base_node_path = transition->get_advance_expression_base_node();
+ expression_base = tree_base->get_tree()->get_root()->get_child(0)->get_node_or_null(advance_expression_base_node_path);
} else {
advance_expression_base_node_path = tree_base->get_advance_expression_base_node();
+ expression_base = tree_base->get_node_or_null(advance_expression_base_node_path);
}
- Node *expression_base = tree_base->get_node_or_null(advance_expression_base_node_path);
if (expression_base) {
Ref<Expression> exp = transition->expression;
bool ret = exp->execute(Array(), expression_base, false, Engine::get_singleton()->is_editor_hint()); // Avoids allowing the user to crash the system with an expression by only allowing const calls.
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index ce9406883d..54b10d9d57 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -156,7 +156,7 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
} else if (name == "blend_times") {
Vector<BlendKey> keys;
- for (const KeyValue<BlendKey, float> &E : blend_times) {
+ for (const KeyValue<BlendKey, double> &E : blend_times) {
keys.ordered_insert(E.key);
}
@@ -216,7 +216,7 @@ void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::ARRAY, "blend_times", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
}
-void AnimationPlayer::advance(float p_time) {
+void AnimationPlayer::advance(double p_time) {
_animation_process(p_time);
}
@@ -1287,7 +1287,7 @@ void AnimationPlayer::_animation_removed(const StringName &p_name, const StringN
// Erase blends if needed
List<BlendKey> to_erase;
- for (const KeyValue<BlendKey, float> &E : blend_times) {
+ for (const KeyValue<BlendKey, double> &E : blend_times) {
BlendKey bk = E.key;
if (bk.from == name || bk.to == name) {
to_erase.push_back(bk);
@@ -1303,8 +1303,8 @@ void AnimationPlayer::_animation_removed(const StringName &p_name, const StringN
void AnimationPlayer::_rename_animation(const StringName &p_from_name, const StringName &p_to_name) {
// Rename autoplay or blends if needed.
List<BlendKey> to_erase;
- HashMap<BlendKey, float, BlendKey> to_insert;
- for (const KeyValue<BlendKey, float> &E : blend_times) {
+ HashMap<BlendKey, double, BlendKey> to_insert;
+ for (const KeyValue<BlendKey, double> &E : blend_times) {
BlendKey bk = E.key;
BlendKey new_bk = bk;
bool erase = false;
@@ -1523,7 +1523,7 @@ void AnimationPlayer::get_animation_list(List<StringName> *p_animations) const {
}
}
-void AnimationPlayer::set_blend_time(const StringName &p_animation1, const StringName &p_animation2, float p_time) {
+void AnimationPlayer::set_blend_time(const StringName &p_animation1, const StringName &p_animation2, double p_time) {
ERR_FAIL_COND_MSG(!animation_set.has(p_animation1), vformat("Animation not found: %s.", p_animation1));
ERR_FAIL_COND_MSG(!animation_set.has(p_animation2), vformat("Animation not found: %s.", p_animation2));
ERR_FAIL_COND_MSG(p_time < 0, "Blend time cannot be smaller than 0.");
@@ -1538,7 +1538,7 @@ void AnimationPlayer::set_blend_time(const StringName &p_animation1, const Strin
}
}
-float AnimationPlayer::get_blend_time(const StringName &p_animation1, const StringName &p_animation2) const {
+double AnimationPlayer::get_blend_time(const StringName &p_animation1, const StringName &p_animation2) const {
BlendKey bk;
bk.from = p_animation1;
bk.to = p_animation2;
@@ -1571,11 +1571,11 @@ void AnimationPlayer::clear_queue() {
queued.clear();
}
-void AnimationPlayer::play_backwards(const StringName &p_name, float p_custom_blend) {
+void AnimationPlayer::play_backwards(const StringName &p_name, double p_custom_blend) {
play(p_name, p_custom_blend, -1, true);
}
-void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float p_custom_scale, bool p_from_end) {
+void AnimationPlayer::play(const StringName &p_name, double p_custom_blend, float p_custom_scale, bool p_from_end) {
StringName name = p_name;
if (String(name) == "") {
@@ -1587,7 +1587,7 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
Playback &c = playback;
if (c.current.from) {
- float blend_time = 0.0;
+ double blend_time = 0.0;
// find if it can blend
BlendKey bk;
bk.from = c.current.from->name;
@@ -1741,7 +1741,7 @@ void AnimationPlayer::seek(double p_time, bool p_update) {
}
}
-void AnimationPlayer::seek_delta(double p_time, float p_delta) {
+void AnimationPlayer::seek_delta(double p_time, double p_delta) {
if (!playback.current.from) {
if (playback.assigned) {
ERR_FAIL_COND_MSG(!animation_set.has(playback.assigned), vformat("Animation not found: %s.", playback.assigned));
@@ -1762,12 +1762,12 @@ bool AnimationPlayer::is_valid() const {
return (playback.current.from);
}
-float AnimationPlayer::get_current_animation_position() const {
+double AnimationPlayer::get_current_animation_position() const {
ERR_FAIL_COND_V_MSG(!playback.current.from, 0, "AnimationPlayer has no current animation");
return playback.current.pos;
}
-float AnimationPlayer::get_current_animation_length() const {
+double AnimationPlayer::get_current_animation_length() const {
ERR_FAIL_COND_V_MSG(!playback.current.from, 0, "AnimationPlayer has no current animation");
return playback.current.from->animation->get_length();
}
@@ -1933,11 +1933,11 @@ StringName AnimationPlayer::animation_get_next(const StringName &p_animation) co
return animation_set[p_animation].next;
}
-void AnimationPlayer::set_default_blend_time(float p_default) {
+void AnimationPlayer::set_default_blend_time(double p_default) {
default_blend_time = p_default;
}
-float AnimationPlayer::get_default_blend_time() const {
+double AnimationPlayer::get_default_blend_time() const {
return default_blend_time;
}
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index caf1387ff0..4f32927d25 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -191,7 +191,7 @@ private:
uint64_t accum_pass = 1;
float speed_scale = 1.0;
- float default_blend_time = 0.0;
+ double default_blend_time = 0.0;
struct AnimationData {
String name;
@@ -230,7 +230,7 @@ private:
}
};
- HashMap<BlendKey, float, BlendKey> blend_times;
+ HashMap<BlendKey, double, BlendKey> blend_times;
struct PlaybackData {
AnimationData *from = nullptr;
@@ -241,8 +241,8 @@ private:
struct Blend {
PlaybackData data;
- float blend_time = 0.0;
- float blend_left = 0.0;
+ double blend_time = 0.0;
+ double blend_left = 0.0;
};
struct Playback {
@@ -334,17 +334,17 @@ public:
void get_animation_list(List<StringName> *p_animations) const;
bool has_animation(const StringName &p_name) const;
- void set_blend_time(const StringName &p_animation1, const StringName &p_animation2, float p_time);
- float get_blend_time(const StringName &p_animation1, const StringName &p_animation2) const;
+ void set_blend_time(const StringName &p_animation1, const StringName &p_animation2, double p_time);
+ double get_blend_time(const StringName &p_animation1, const StringName &p_animation2) const;
void animation_set_next(const StringName &p_animation, const StringName &p_next);
StringName animation_get_next(const StringName &p_animation) const;
- void set_default_blend_time(float p_default);
- float get_default_blend_time() const;
+ void set_default_blend_time(double p_default);
+ double get_default_blend_time() const;
- void play(const StringName &p_name = StringName(), float p_custom_blend = -1, float p_custom_scale = 1.0, bool p_from_end = false);
- void play_backwards(const StringName &p_name = StringName(), float p_custom_blend = -1);
+ void play(const StringName &p_name = StringName(), double p_custom_blend = -1, float p_custom_scale = 1.0, bool p_from_end = false);
+ void play_backwards(const StringName &p_name = StringName(), double p_custom_blend = -1);
void queue(const StringName &p_name);
Vector<String> get_queue();
void clear_queue();
@@ -378,11 +378,11 @@ public:
bool is_movie_quit_on_finish_enabled() const;
void seek(double p_time, bool p_update = false);
- void seek_delta(double p_time, float p_delta);
- float get_current_animation_position() const;
- float get_current_animation_length() const;
+ void seek_delta(double p_time, double p_delta);
+ double get_current_animation_position() const;
+ double get_current_animation_length() const;
- void advance(float p_time);
+ void advance(double p_time);
void set_root(const NodePath &p_root);
NodePath get_root() const;
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 776706d7f3..05a4a2d024 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -1745,7 +1745,7 @@ Variant AnimationTree::_post_process_key_value(const Ref<Animation> &p_anim, int
return p_value;
}
-void AnimationTree::advance(real_t p_time) {
+void AnimationTree::advance(double p_time) {
_process_graph(p_time);
}
@@ -1849,8 +1849,8 @@ uint64_t AnimationTree::get_last_process_pass() const {
return process_pass;
}
-TypedArray<String> AnimationTree::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray AnimationTree::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!root.is_valid()) {
warnings.push_back(RTR("No root AnimationNode for the graph is set."));
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 573448be93..96c1279f82 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -342,7 +342,7 @@ public:
void set_advance_expression_base_node(const NodePath &p_advance_expression_base_node);
NodePath get_advance_expression_base_node() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
bool is_state_invalid() const;
String get_invalid_state_reason() const;
@@ -353,7 +353,7 @@ public:
Transform3D get_root_motion_transform() const;
real_t get_connection_activity(const StringName &p_path, int p_connection) const;
- void advance(real_t p_time);
+ void advance(double p_time);
void rename_parameter(const String &p_base, const String &p_new_base);
diff --git a/scene/animation/easing_equations.h b/scene/animation/easing_equations.h
index 094829e406..03d9e16454 100644
--- a/scene/animation/easing_equations.h
+++ b/scene/animation/easing_equations.h
@@ -28,6 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef EASING_EQUATIONS_H
+#define EASING_EQUATIONS_H
+
/*
* Derived from Robert Penner's easing equations: http://robertpenner.com/easing/
*
@@ -52,9 +55,6 @@
* SOFTWARE.
*/
-#ifndef EASING_EQUATIONS_H
-#define EASING_EQUATIONS_H
-
namespace linear {
static real_t in(real_t t, real_t b, real_t c, real_t d) {
return c * t / d + b;
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index b02f1959b7..4a0f870406 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -71,16 +71,16 @@ void Tween::start_tweeners() {
}
}
-Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property, Variant p_to, float p_duration) {
+Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property, Variant p_to, double p_duration) {
ERR_FAIL_NULL_V(p_target, nullptr);
ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
Variant::Type property_type = p_target->get_indexed(p_property.get_as_property_path().get_subnames()).get_type();
if (property_type != p_to.get_type()) {
- // Cast p_to between floats and ints to avoid minor annoyances.
+ // Cast p_to between double and int to avoid minor annoyances.
if (property_type == Variant::FLOAT && p_to.get_type() == Variant::INT) {
- p_to = float(p_to);
+ p_to = double(p_to);
} else if (property_type == Variant::INT && p_to.get_type() == Variant::FLOAT) {
p_to = int(p_to);
} else {
@@ -93,7 +93,7 @@ Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property
return tweener;
}
-Ref<IntervalTweener> Tween::tween_interval(float p_time) {
+Ref<IntervalTweener> Tween::tween_interval(double p_time) {
ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
@@ -111,7 +111,7 @@ Ref<CallbackTweener> Tween::tween_callback(Callable p_callback) {
return tweener;
}
-Ref<MethodTweener> Tween::tween_method(Callable p_callback, Variant p_from, Variant p_to, float p_duration) {
+Ref<MethodTweener> Tween::tween_method(Callable p_callback, Variant p_from, Variant p_to, double p_duration) {
ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
@@ -245,7 +245,7 @@ Ref<Tween> Tween::chain() {
return this;
}
-bool Tween::custom_step(float p_delta) {
+bool Tween::custom_step(double p_delta) {
bool r = running;
running = true;
bool ret = step(p_delta);
@@ -253,7 +253,7 @@ bool Tween::custom_step(float p_delta) {
return ret;
}
-bool Tween::step(float p_delta) {
+bool Tween::step(double p_delta) {
if (dead) {
return false;
}
@@ -282,22 +282,22 @@ bool Tween::step(float p_delta) {
started = true;
}
- float rem_delta = p_delta * speed_scale;
+ double rem_delta = p_delta * speed_scale;
bool step_active = false;
total_time += rem_delta;
#ifdef DEBUG_ENABLED
- float initial_delta = rem_delta;
+ double initial_delta = rem_delta;
bool potential_infinite = false;
#endif
while (rem_delta > 0 && running) {
- float step_delta = rem_delta;
+ double step_delta = rem_delta;
step_active = false;
for (Ref<Tweener> &tweener : tweeners.write[current_step]) {
// Modified inside Tweener.step().
- float temp_delta = rem_delta;
+ double temp_delta = rem_delta;
// Turns to true if any Tweener returns true (i.e. is still not finished).
step_active = tweener->step(temp_delta) || step_active;
step_delta = MIN(temp_delta, step_delta);
@@ -359,7 +359,7 @@ Node *Tween::get_bound_node() const {
}
}
-float Tween::get_total_time() const {
+double Tween::get_total_time() const {
return total_time;
}
@@ -373,7 +373,7 @@ real_t Tween::run_equation(TransitionType p_trans_type, EaseType p_ease_type, re
return func(p_time, p_initial, p_delta, p_duration);
}
-Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, float p_time, float p_duration, TransitionType p_trans, EaseType p_ease) {
+Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, double p_time, double p_duration, TransitionType p_trans, EaseType p_ease) {
ERR_FAIL_INDEX_V(p_trans, TransitionType::TRANS_MAX, Variant());
ERR_FAIL_INDEX_V(p_ease, EaseType::EASE_MAX, Variant());
@@ -480,7 +480,7 @@ Ref<PropertyTweener> PropertyTweener::set_ease(Tween::EaseType p_ease) {
return this;
}
-Ref<PropertyTweener> PropertyTweener::set_delay(float p_delay) {
+Ref<PropertyTweener> PropertyTweener::set_delay(double p_delay) {
delay = p_delay;
return this;
}
@@ -506,7 +506,7 @@ void PropertyTweener::start() {
delta_val = Animation::subtract_variant(final_val, initial_val);
}
-bool PropertyTweener::step(float &r_delta) {
+bool PropertyTweener::step(double &r_delta) {
if (finished) {
// This is needed in case there's a parallel Tweener with longer duration.
return false;
@@ -523,7 +523,7 @@ bool PropertyTweener::step(float &r_delta) {
return true;
}
- float time = MIN(elapsed_time - delay, duration);
+ double time = MIN(elapsed_time - delay, duration);
if (time < duration) {
target_instance->set_indexed(property, tween->interpolate_variant(initial_val, delta_val, time, duration, trans_type, ease_type));
r_delta = 0;
@@ -556,7 +556,7 @@ void PropertyTweener::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_delay", "delay"), &PropertyTweener::set_delay);
}
-PropertyTweener::PropertyTweener(Object *p_target, NodePath p_property, Variant p_to, float p_duration) {
+PropertyTweener::PropertyTweener(Object *p_target, NodePath p_property, Variant p_to, double p_duration) {
target = p_target->get_instance_id();
property = p_property.get_as_property_path().get_subnames();
initial_val = p_target->get_indexed(property);
@@ -574,7 +574,7 @@ void IntervalTweener::start() {
finished = false;
}
-bool IntervalTweener::step(float &r_delta) {
+bool IntervalTweener::step(double &r_delta) {
if (finished) {
return false;
}
@@ -592,7 +592,7 @@ bool IntervalTweener::step(float &r_delta) {
}
}
-IntervalTweener::IntervalTweener(float p_time) {
+IntervalTweener::IntervalTweener(double p_time) {
duration = p_time;
}
@@ -600,7 +600,7 @@ IntervalTweener::IntervalTweener() {
ERR_FAIL_MSG("Can't create empty IntervalTweener. Use get_tree().tween_interval() instead.");
}
-Ref<CallbackTweener> CallbackTweener::set_delay(float p_delay) {
+Ref<CallbackTweener> CallbackTweener::set_delay(double p_delay) {
delay = p_delay;
return this;
}
@@ -610,7 +610,7 @@ void CallbackTweener::start() {
finished = false;
}
-bool CallbackTweener::step(float &r_delta) {
+bool CallbackTweener::step(double &r_delta) {
if (finished) {
return false;
}
@@ -646,7 +646,7 @@ CallbackTweener::CallbackTweener() {
ERR_FAIL_MSG("Can't create empty CallbackTweener. Use get_tree().tween_callback() instead.");
}
-Ref<MethodTweener> MethodTweener::set_delay(float p_delay) {
+Ref<MethodTweener> MethodTweener::set_delay(double p_delay) {
delay = p_delay;
return this;
}
@@ -666,7 +666,7 @@ void MethodTweener::start() {
finished = false;
}
-bool MethodTweener::step(float &r_delta) {
+bool MethodTweener::step(double &r_delta) {
if (finished) {
return false;
}
@@ -679,7 +679,7 @@ bool MethodTweener::step(float &r_delta) {
}
Variant current_val;
- float time = MIN(elapsed_time - delay, duration);
+ double time = MIN(elapsed_time - delay, duration);
if (time < duration) {
current_val = tween->interpolate_variant(initial_val, delta_val, time, duration, trans_type, ease_type);
} else {
@@ -722,7 +722,7 @@ void MethodTweener::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ease", "ease"), &MethodTweener::set_ease);
}
-MethodTweener::MethodTweener(Callable p_callback, Variant p_from, Variant p_to, float p_duration) {
+MethodTweener::MethodTweener(Callable p_callback, Variant p_from, Variant p_to, double p_duration) {
callback = p_callback;
initial_val = p_from;
delta_val = Animation::subtract_variant(p_to, p_from);
diff --git a/scene/animation/tween.h b/scene/animation/tween.h
index da7a8b5d71..345974ecc5 100644
--- a/scene/animation/tween.h
+++ b/scene/animation/tween.h
@@ -42,13 +42,13 @@ class Tweener : public RefCounted {
public:
virtual void set_tween(Ref<Tween> p_tween);
virtual void start() = 0;
- virtual bool step(float &r_delta) = 0;
+ virtual bool step(double &r_delta) = 0;
void clear_tween();
protected:
static void _bind_methods();
Ref<Tween> tween;
- float elapsed_time = 0;
+ double elapsed_time = 0;
bool finished = false;
};
@@ -103,7 +103,7 @@ private:
ObjectID bound_node;
Vector<List<Ref<Tweener>>> tweeners;
- float total_time = 0;
+ double total_time = 0;
int current_step = -1;
int loops = 1;
int loops_done = 0;
@@ -129,13 +129,13 @@ protected:
static void _bind_methods();
public:
- Ref<PropertyTweener> tween_property(Object *p_target, NodePath p_property, Variant p_to, float p_duration);
- Ref<IntervalTweener> tween_interval(float p_time);
+ Ref<PropertyTweener> tween_property(Object *p_target, NodePath p_property, Variant p_to, double p_duration);
+ Ref<IntervalTweener> tween_interval(double p_time);
Ref<CallbackTweener> tween_callback(Callable p_callback);
- Ref<MethodTweener> tween_method(Callable p_callback, Variant p_from, Variant p_to, float p_duration);
+ Ref<MethodTweener> tween_method(Callable p_callback, Variant p_from, Variant p_to, double p_duration);
void append(Ref<Tweener> p_tweener);
- bool custom_step(float p_delta);
+ bool custom_step(double p_delta);
void stop();
void pause();
void play();
@@ -163,12 +163,12 @@ public:
Ref<Tween> chain();
static real_t run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t t, real_t b, real_t c, real_t d);
- static Variant interpolate_variant(Variant p_initial_val, Variant p_delta_val, float p_time, float p_duration, Tween::TransitionType p_trans, Tween::EaseType p_ease);
+ static Variant interpolate_variant(Variant p_initial_val, Variant p_delta_val, double p_time, double p_duration, Tween::TransitionType p_trans, Tween::EaseType p_ease);
- bool step(float p_delta);
+ bool step(double p_delta);
bool can_process(bool p_tree_paused) const;
Node *get_bound_node() const;
- float get_total_time() const;
+ double get_total_time() const;
Tween();
Tween(bool p_valid);
@@ -188,13 +188,13 @@ public:
Ref<PropertyTweener> as_relative();
Ref<PropertyTweener> set_trans(Tween::TransitionType p_trans);
Ref<PropertyTweener> set_ease(Tween::EaseType p_ease);
- Ref<PropertyTweener> set_delay(float p_delay);
+ Ref<PropertyTweener> set_delay(double p_delay);
void set_tween(Ref<Tween> p_tween) override;
void start() override;
- bool step(float &r_delta) override;
+ bool step(double &r_delta) override;
- PropertyTweener(Object *p_target, NodePath p_property, Variant p_to, float p_duration);
+ PropertyTweener(Object *p_target, NodePath p_property, Variant p_to, double p_duration);
PropertyTweener();
protected:
@@ -208,11 +208,11 @@ private:
Variant final_val;
Variant delta_val;
- float duration = 0;
+ double duration = 0;
Tween::TransitionType trans_type = Tween::TRANS_MAX; // This is set inside set_tween();
Tween::EaseType ease_type = Tween::EASE_MAX;
- float delay = 0;
+ double delay = 0;
bool do_continue = true;
bool relative = false;
};
@@ -222,23 +222,23 @@ class IntervalTweener : public Tweener {
public:
void start() override;
- bool step(float &r_delta) override;
+ bool step(double &r_delta) override;
- IntervalTweener(float p_time);
+ IntervalTweener(double p_time);
IntervalTweener();
private:
- float duration = 0;
+ double duration = 0;
};
class CallbackTweener : public Tweener {
GDCLASS(CallbackTweener, Tweener);
public:
- Ref<CallbackTweener> set_delay(float p_delay);
+ Ref<CallbackTweener> set_delay(double p_delay);
void start() override;
- bool step(float &r_delta) override;
+ bool step(double &r_delta) override;
CallbackTweener(Callable p_callback);
CallbackTweener();
@@ -248,7 +248,7 @@ protected:
private:
Callable callback;
- float delay = 0;
+ double delay = 0;
};
class MethodTweener : public Tweener {
@@ -257,21 +257,21 @@ class MethodTweener : public Tweener {
public:
Ref<MethodTweener> set_trans(Tween::TransitionType p_trans);
Ref<MethodTweener> set_ease(Tween::EaseType p_ease);
- Ref<MethodTweener> set_delay(float p_delay);
+ Ref<MethodTweener> set_delay(double p_delay);
void set_tween(Ref<Tween> p_tween) override;
void start() override;
- bool step(float &r_delta) override;
+ bool step(double &r_delta) override;
- MethodTweener(Callable p_callback, Variant p_from, Variant p_to, float p_duration);
+ MethodTweener(Callable p_callback, Variant p_from, Variant p_to, double p_duration);
MethodTweener();
protected:
static void _bind_methods();
private:
- float duration = 0;
- float delay = 0;
+ double duration = 0;
+ double delay = 0;
Tween::TransitionType trans_type = Tween::TRANS_MAX;
Tween::EaseType ease_type = Tween::EASE_MAX;
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index cf467ceafb..af6a99ca62 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -264,7 +264,7 @@ bool BaseButton::is_hovered() const {
BaseButton::DrawMode BaseButton::get_draw_mode() const {
if (status.disabled) {
return DRAW_DISABLED;
- };
+ }
if (!status.press_attempt && status.hovering) {
if (status.pressed) {
@@ -273,8 +273,7 @@ BaseButton::DrawMode BaseButton::get_draw_mode() const {
return DRAW_HOVER;
} else {
- /* determine if pressed or not */
-
+ // Determine if pressed or not.
bool pressing;
if (status.press_attempt) {
pressing = (status.pressing_inside || keep_pressed_outside);
@@ -291,8 +290,6 @@ BaseButton::DrawMode BaseButton::get_draw_mode() const {
return DRAW_NORMAL;
}
}
-
- return DRAW_NORMAL;
}
void BaseButton::set_toggle_mode(bool p_on) {
@@ -469,7 +466,7 @@ void BaseButton::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_pressed_outside"), "set_keep_pressed_outside", "is_keep_pressed_outside");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "Shortcut"), "set_shortcut", "get_shortcut");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "button_group", PROPERTY_HINT_RESOURCE_TYPE, "ButtonGroup"), "set_button_group", "get_button_group");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut_context", PROPERTY_HINT_RESOURCE_TYPE, "Node"), "set_shortcut_context", "get_shortcut_context");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut_context", PROPERTY_HINT_NODE_TYPE, "Node"), "set_shortcut_context", "get_shortcut_context");
BIND_ENUM_CONSTANT(DRAW_NORMAL);
BIND_ENUM_CONSTANT(DRAW_PRESSED);
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index f6e0e4216d..8069ab465b 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -1216,30 +1216,39 @@ bool CodeEdit::is_drawing_executing_lines_gutter() const {
}
void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) {
+ bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT);
+
if (draw_breakpoints && breakpoint_icon.is_valid()) {
bool hovering = p_region.has_point(get_local_mouse_pos());
bool breakpointed = is_line_breakpointed(p_line);
- if (breakpointed || (hovering && !is_dragging_cursor())) {
+ if (breakpointed || (hovering && !is_dragging_cursor() && !shift_pressed)) {
int padding = p_region.size.x / 6;
Rect2 icon_region = p_region;
icon_region.position += Point2(padding, padding);
icon_region.size -= Point2(padding, padding) * 2;
- // Darken icon when hovering & not yet breakpointed.
- Color use_color = hovering && !breakpointed ? breakpoint_color.darkened(0.4) : breakpoint_color;
+ // Darken icon when hovering, shift not pressed & not yet breakpointed.
+ Color use_color = hovering && !breakpointed && !shift_pressed ? breakpoint_color.darkened(0.4) : breakpoint_color;
breakpoint_icon->draw_rect(get_canvas_item(), icon_region, false, use_color);
}
}
- if (draw_bookmarks && is_line_bookmarked(p_line) && bookmark_icon.is_valid()) {
- int horizontal_padding = p_region.size.x / 2;
- int vertical_padding = p_region.size.y / 4;
+ if (draw_bookmarks && bookmark_icon.is_valid()) {
+ bool hovering = p_region.has_point(get_local_mouse_pos());
+ bool bookmarked = is_line_bookmarked(p_line);
- Rect2 bookmark_region = p_region;
- bookmark_region.position += Point2(horizontal_padding, 0);
- bookmark_region.size -= Point2(horizontal_padding * 1.1, vertical_padding);
- bookmark_icon->draw_rect(get_canvas_item(), bookmark_region, false, bookmark_color);
+ if (bookmarked || (hovering && !is_dragging_cursor() && shift_pressed)) {
+ int horizontal_padding = p_region.size.x / 2;
+ int vertical_padding = p_region.size.y / 4;
+ Rect2 icon_region = p_region;
+ icon_region.position += Point2(horizontal_padding, 0);
+ icon_region.size -= Point2(horizontal_padding * 1.1, vertical_padding);
+
+ // Darken icon when hovering, shift pressed & not yet bookmarked.
+ Color use_color = hovering && !bookmarked && shift_pressed ? bookmark_color.darkened(0.4) : bookmark_color;
+ bookmark_icon->draw_rect(get_canvas_item(), icon_region, false, use_color);
+ }
}
if (draw_executing_lines && is_line_executing(p_line) && executing_line_icon.is_valid()) {
@@ -2378,9 +2387,13 @@ int CodeEdit::_get_auto_brace_pair_close_at_pos(int p_line, int p_col) {
/* Gutters */
void CodeEdit::_gutter_clicked(int p_line, int p_gutter) {
+ bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT);
+
if (p_gutter == main_gutter) {
- if (draw_breakpoints) {
+ if (draw_breakpoints && !shift_pressed) {
set_line_as_breakpoint(p_line, !is_line_breakpointed(p_line));
+ } else if (draw_bookmarks && shift_pressed) {
+ set_line_as_bookmarked(p_line, !is_line_bookmarked(p_line));
}
return;
}
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 4a1f2ab7c6..5751c54877 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -427,12 +427,15 @@ void ColorPicker::_html_submitted(const String &p_html) {
return;
}
- float last_alpha = color.a;
+ Color previous_color = color;
color = Color::html(p_html);
if (!is_editing_alpha()) {
- color.a = last_alpha;
+ color.a = previous_color.a;
}
+ if (color == previous_color) {
+ return;
+ }
if (!is_inside_tree()) {
return;
}
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index 5512c0f1fd..3c29c37479 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -192,8 +192,8 @@ void Container::_notification(int p_what) {
}
}
-TypedArray<String> Container::get_configuration_warnings() const {
- TypedArray<String> warnings = Control::get_configuration_warnings();
+PackedStringArray Container::get_configuration_warnings() const {
+ PackedStringArray warnings = Control::get_configuration_warnings();
if (get_class() == "Container" && get_script().is_null()) {
warnings.push_back(RTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, use a plain Control node instead."));
diff --git a/scene/gui/container.h b/scene/gui/container.h
index 9ec4ad3200..21bdb95186 100644
--- a/scene/gui/container.h
+++ b/scene/gui/container.h
@@ -63,7 +63,7 @@ public:
virtual Vector<int> get_allowed_size_flags_horizontal() const;
virtual Vector<int> get_allowed_size_flags_vertical() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
Container();
};
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 347fe9aa11..dc9294df6d 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -213,8 +213,8 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List
}
}
-TypedArray<String> Control::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray Control::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (data.mouse_filter == MOUSE_FILTER_IGNORE && !data.tooltip.is_empty()) {
warnings.push_back(RTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."));
@@ -2225,7 +2225,19 @@ void Control::_window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, cons
void Control::set_default_cursor_shape(CursorShape p_shape) {
ERR_FAIL_INDEX(int(p_shape), CURSOR_MAX);
+ if (data.default_cursor == p_shape) {
+ return;
+ }
data.default_cursor = p_shape;
+
+ if (!is_inside_tree()) {
+ return;
+ }
+ if (!get_global_rect().has_point(get_global_mouse_position())) {
+ return;
+ }
+
+ get_viewport()->get_base_window()->update_mouse_cursor_shape();
}
Control::CursorShape Control::get_default_cursor_shape() const {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 38cafd835a..ee6443c81c 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -387,7 +387,7 @@ public:
// Editor integration.
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
virtual bool is_text_field() const;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 57f27e299f..cf7f439aef 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -172,18 +172,20 @@ void FileDialog::shortcut_input(const Ref<InputEvent> &p_event) {
void FileDialog::set_enable_multiple_selection(bool p_enable) {
tree->set_select_mode(p_enable ? Tree::SELECT_MULTI : Tree::SELECT_SINGLE);
-};
+}
Vector<String> FileDialog::get_selected_files() const {
Vector<String> list;
TreeItem *item = tree->get_root();
- while ((item = tree->get_next_selected(item))) {
+ item = tree->get_next_selected(item);
+ while (item) {
list.push_back(dir_access->get_current_dir().path_join(item->get_text(0)));
- };
+ item = tree->get_next_selected(item);
+ }
return list;
-};
+}
void FileDialog::update_dir() {
if (root_prefix.is_empty()) {
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 5a0236268b..7295ab9e9d 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -190,8 +190,8 @@ void GraphEditMinimap::_adjust_graph_scroll(const Vector2 &p_offset) {
ge->set_scroll_ofs(p_offset + graph_offset - camera_size / 2);
}
-TypedArray<String> GraphEdit::get_configuration_warnings() const {
- TypedArray<String> warnings = Control::get_configuration_warnings();
+PackedStringArray GraphEdit::get_configuration_warnings() const {
+ PackedStringArray warnings = Control::get_configuration_warnings();
warnings.push_back(RTR("Please be aware that GraphEdit and GraphNode will undergo extensive refactoring in a future beta version involving compatibility-breaking API changes."));
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 0fe9e7c555..101087bdbd 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -287,7 +287,7 @@ protected:
GDVIRTUAL4R(bool, _is_node_hover_valid, StringName, int, StringName, int);
public:
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
Error connect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
bool is_node_connected(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 008109da65..357f2480bd 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -662,19 +662,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
pos.x = get_size().width - pos.x;
}
- int closest = -1;
-
- for (int i = 0; i < items.size(); i++) {
- Rect2 rc = items[i].rect_cache;
- if (i % current_columns == current_columns - 1) {
- rc.size.width = get_size().width; //not right but works
- }
-
- if (rc.has_point(pos)) {
- closest = i;
- break;
- }
- }
+ int closest = get_item_at_position(mb->get_position(), true);
if (closest != -1 && (mb->get_button_index() == MouseButton::LEFT || (allow_rmb_select && mb->get_button_index() == MouseButton::RIGHT))) {
int i = closest;
@@ -1467,7 +1455,7 @@ int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const {
for (int i = 0; i < items.size(); i++) {
Rect2 rc = items[i].rect_cache;
if (i % current_columns == current_columns - 1) {
- rc.size.width = get_size().width - rc.position.x; //make sure you can still select the last item when clicking past the column
+ rc.size.width = get_size().width - rc.position.x; // Make sure you can still select the last item when clicking past the column.
}
if (rc.has_point(pos)) {
diff --git a/scene/gui/menu_bar.cpp b/scene/gui/menu_bar.cpp
index d6bf84ea5a..75592a1b99 100644
--- a/scene/gui/menu_bar.cpp
+++ b/scene/gui/menu_bar.cpp
@@ -703,7 +703,7 @@ void MenuBar::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "start_index"), "set_start_index", "get_start_index");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "switch_on_hover"), "set_switch_on_hover", "is_switch_on_hover");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "prefer_global_menu"), "set_prefer_global_menu", "is_prefer_global_menu");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut_context", PROPERTY_HINT_RESOURCE_TYPE, "Node"), "set_shortcut_context", "get_shortcut_context");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut_context", PROPERTY_HINT_NODE_TYPE, "Node"), "set_shortcut_context", "get_shortcut_context");
ADD_GROUP("BiDi", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index d4a4efd578..10e13042a7 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -1762,7 +1762,7 @@ void PopupMenu::clear() {
void PopupMenu::_ref_shortcut(Ref<Shortcut> p_sc) {
if (!shortcut_refcount.has(p_sc)) {
shortcut_refcount[p_sc] = 1;
- p_sc->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw));
+ p_sc->connect("changed", callable_mp(this, &PopupMenu::_shortcut_changed));
} else {
shortcut_refcount[p_sc] += 1;
}
@@ -1772,11 +1772,18 @@ void PopupMenu::_unref_shortcut(Ref<Shortcut> p_sc) {
ERR_FAIL_COND(!shortcut_refcount.has(p_sc));
shortcut_refcount[p_sc]--;
if (shortcut_refcount[p_sc] == 0) {
- p_sc->disconnect("changed", callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw));
+ p_sc->disconnect("changed", callable_mp(this, &PopupMenu::_shortcut_changed));
shortcut_refcount.erase(p_sc);
}
}
+void PopupMenu::_shortcut_changed() {
+ for (int i = 0; i < items.size(); i++) {
+ items.write[i].dirty = true;
+ }
+ control->queue_redraw();
+}
+
// Hide on item selection determines whether or not the popup will close after item selection
void PopupMenu::set_hide_on_item_selection(bool p_enabled) {
hide_on_item_selection = p_enabled;
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index ad7909842e..89d3904456 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -121,6 +121,8 @@ class PopupMenu : public Popup {
void _ref_shortcut(Ref<Shortcut> p_sc);
void _unref_shortcut(Ref<Shortcut> p_sc);
+ void _shortcut_changed();
+
bool allow_search = true;
uint64_t search_time_msec = 0;
String search_string = "";
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index 1eb412abaf..2d2b3e413d 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -30,8 +30,8 @@
#include "range.h"
-TypedArray<String> Range::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray Range::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (shared->exp_ratio && shared->min <= 0) {
warnings.push_back(RTR("If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."));
diff --git a/scene/gui/range.h b/scene/gui/range.h
index 87bd0d88af..19452243cf 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -100,7 +100,7 @@ public:
void share(Range *p_range);
void unshare();
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
Range();
~Range();
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 3a238e9edd..7ea46a0b4f 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -52,7 +52,7 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) co
} else if (p_item->E->next()) {
return p_item->E->next()->get();
} else {
- //go up until something with a next is found
+ // Go up until something with a next is found.
while (p_item->parent && !p_item->E->next()) {
p_item = p_item->parent;
}
@@ -72,7 +72,7 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) co
} else if (p_item->E->next()) {
return p_item->E->next()->get();
} else {
- //go up until something with a next is found
+ // Go up until something with a next is found.
while (p_item->type != ITEM_FRAME && !p_item->E->next()) {
p_item = p_item->parent;
}
@@ -84,8 +84,6 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) co
}
}
}
-
- return nullptr;
}
RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) const {
@@ -97,7 +95,7 @@ RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) co
} else if (p_item->E->prev()) {
return p_item->E->prev()->get();
} else {
- //go back until something with a prev is found
+ // Go back until something with a prev is found.
while (p_item->parent && !p_item->E->prev()) {
p_item = p_item->parent;
}
@@ -117,7 +115,7 @@ RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) co
} else if (p_item->E->prev()) {
return p_item->E->prev()->get();
} else {
- //go back until something with a prev is found
+ // Go back until something with a prev is found.
while (p_item->type != ITEM_FRAME && !p_item->E->prev()) {
p_item = p_item->parent;
}
@@ -129,8 +127,6 @@ RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) co
}
}
}
-
- return nullptr;
}
Rect2 RichTextLabel::_get_text_rect() {
@@ -965,17 +961,18 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
uint32_t gl = glyphs[i].index;
uint16_t gl_fl = glyphs[i].flags;
uint8_t gl_cn = glyphs[i].count;
- bool cprev = false;
+ bool cprev_cluster = false;
+ bool cprev_conn = false;
if (gl_cn == 0) { // Parts of the same cluster, always connected.
- cprev = true;
+ cprev_cluster = true;
}
if (gl_fl & TextServer::GRAPHEME_IS_RTL) { // Check if previous grapheme cluster is connected.
if (i > 0 && (glyphs[i - 1].flags & TextServer::GRAPHEME_IS_CONNECTED)) {
- cprev = true;
+ cprev_conn = true;
}
} else {
if (glyphs[i].flags & TextServer::GRAPHEME_IS_CONNECTED) {
- cprev = true;
+ cprev_conn = true;
}
}
@@ -994,6 +991,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
for (int j = 0; j < fx_stack.size(); j++) {
ItemFX *item_fx = fx_stack[j];
+ bool cn = cprev_cluster || (cprev_conn && item_fx->connected);
+
if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) {
ItemCustomFX *item_custom = static_cast<ItemCustomFX *>(item_fx);
@@ -1024,7 +1023,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
} else if (item_fx->type == ITEM_SHAKE) {
ItemShake *item_shake = static_cast<ItemShake *>(item_fx);
- if (!cprev) {
+ if (!cn) {
uint64_t char_current_rand = item_shake->offset_random(glyphs[i].start);
uint64_t char_previous_rand = item_shake->offset_previous_random(glyphs[i].start);
uint64_t max_rand = 2147483647;
@@ -1038,7 +1037,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
} else if (item_fx->type == ITEM_WAVE) {
ItemWave *item_wave = static_cast<ItemWave *>(item_fx);
- if (!cprev) {
+ if (!cn) {
double value = Math::sin(item_wave->frequency * item_wave->elapsed_time + ((p_ofs.x + gloff.x) / 50)) * (item_wave->amplitude / 10.0f);
item_wave->prev_off = Point2(0, 1) * value;
}
@@ -1046,7 +1045,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
} else if (item_fx->type == ITEM_TORNADO) {
ItemTornado *item_tornado = static_cast<ItemTornado *>(item_fx);
- if (!cprev) {
+ if (!cn) {
double torn_x = Math::sin(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + gloff.x) / 50)) * (item_tornado->radius);
double torn_y = Math::cos(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + gloff.x) / 50)) * (item_tornado->radius);
item_tornado->prev_off = Point2(torn_x, torn_y);
@@ -1181,17 +1180,18 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
uint32_t gl = glyphs[i].index;
uint16_t gl_fl = glyphs[i].flags;
uint8_t gl_cn = glyphs[i].count;
- bool cprev = false;
+ bool cprev_cluster = false;
+ bool cprev_conn = false;
if (gl_cn == 0) { // Parts of the same grapheme cluster, always connected.
- cprev = true;
+ cprev_cluster = true;
}
if (gl_fl & TextServer::GRAPHEME_IS_RTL) { // Check if previous grapheme cluster is connected.
if (i > 0 && (glyphs[i - 1].flags & TextServer::GRAPHEME_IS_CONNECTED)) {
- cprev = true;
+ cprev_conn = true;
}
} else {
if (glyphs[i].flags & TextServer::GRAPHEME_IS_CONNECTED) {
- cprev = true;
+ cprev_conn = true;
}
}
@@ -1209,6 +1209,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
for (int j = 0; j < fx_stack.size(); j++) {
ItemFX *item_fx = fx_stack[j];
+ bool cn = cprev_cluster || (cprev_conn && item_fx->connected);
+
if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) {
ItemCustomFX *item_custom = static_cast<ItemCustomFX *>(item_fx);
@@ -1239,7 +1241,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
} else if (item_fx->type == ITEM_SHAKE) {
ItemShake *item_shake = static_cast<ItemShake *>(item_fx);
- if (!cprev) {
+ if (!cn) {
uint64_t char_current_rand = item_shake->offset_random(glyphs[i].start);
uint64_t char_previous_rand = item_shake->offset_previous_random(glyphs[i].start);
uint64_t max_rand = 2147483647;
@@ -1253,7 +1255,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
} else if (item_fx->type == ITEM_WAVE) {
ItemWave *item_wave = static_cast<ItemWave *>(item_fx);
- if (!cprev) {
+ if (!cn) {
double value = Math::sin(item_wave->frequency * item_wave->elapsed_time + ((p_ofs.x + off.x) / 50)) * (item_wave->amplitude / 10.0f);
item_wave->prev_off = Point2(0, 1) * value;
}
@@ -1261,7 +1263,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
} else if (item_fx->type == ITEM_TORNADO) {
ItemTornado *item_tornado = static_cast<ItemTornado *>(item_fx);
- if (!cprev) {
+ if (!cn) {
double torn_x = Math::sin(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + off.x) / 50)) * (item_tornado->radius);
double torn_y = Math::cos(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + off.x) / 50)) * (item_tornado->radius);
item_tornado->prev_off = Point2(torn_x, torn_y);
@@ -2190,24 +2192,69 @@ RichTextLabel::ItemFont *RichTextLabel::_find_font(Item *p_item) {
ItemFont *fi = static_cast<ItemFont *>(fontitem);
switch (fi->def_font) {
case NORMAL_FONT: {
- fi->font = theme_cache.normal_font;
- fi->font_size = theme_cache.normal_font_size;
+ if (fi->variation) {
+ Ref<FontVariation> fc = fi->font;
+ if (fc.is_valid()) {
+ fc->set_base_font(theme_cache.normal_font);
+ }
+ } else {
+ fi->font = theme_cache.normal_font;
+ }
+ if (fi->def_size) {
+ fi->font_size = theme_cache.normal_font_size;
+ }
} break;
case BOLD_FONT: {
- fi->font = theme_cache.bold_font;
- fi->font_size = theme_cache.bold_font_size;
+ if (fi->variation) {
+ Ref<FontVariation> fc = fi->font;
+ if (fc.is_valid()) {
+ fc->set_base_font(theme_cache.bold_font);
+ }
+ } else {
+ fi->font = theme_cache.bold_font;
+ }
+ if (fi->def_size) {
+ fi->font_size = theme_cache.bold_font_size;
+ }
} break;
case ITALICS_FONT: {
- fi->font = theme_cache.italics_font;
- fi->font_size = theme_cache.italics_font_size;
+ if (fi->variation) {
+ Ref<FontVariation> fc = fi->font;
+ if (fc.is_valid()) {
+ fc->set_base_font(theme_cache.italics_font);
+ }
+ } else {
+ fi->font = theme_cache.italics_font;
+ }
+ if (fi->def_size) {
+ fi->font_size = theme_cache.italics_font_size;
+ }
} break;
case BOLD_ITALICS_FONT: {
- fi->font = theme_cache.bold_italics_font;
- fi->font_size = theme_cache.bold_italics_font_size;
+ if (fi->variation) {
+ Ref<FontVariation> fc = fi->font;
+ if (fc.is_valid()) {
+ fc->set_base_font(theme_cache.bold_italics_font);
+ }
+ } else {
+ fi->font = theme_cache.bold_italics_font;
+ }
+ if (fi->def_size) {
+ fi->font_size = theme_cache.bold_italics_font_size;
+ }
} break;
case MONO_FONT: {
- fi->font = theme_cache.mono_font;
- fi->font_size = theme_cache.mono_font_size;
+ if (fi->variation) {
+ Ref<FontVariation> fc = fi->font;
+ if (fc.is_valid()) {
+ fc->set_base_font(theme_cache.mono_font);
+ }
+ } else {
+ fi->font = theme_cache.mono_font;
+ }
+ if (fi->def_size) {
+ fi->font_size = theme_cache.mono_font_size;
+ }
} break;
default: {
} break;
@@ -3028,14 +3075,30 @@ void RichTextLabel::push_dropcap(const String &p_string, const Ref<Font> &p_font
_add_item(item, false);
}
-void RichTextLabel::_push_def_font(DefaultFont p_font) {
+void RichTextLabel::_push_def_font_var(DefaultFont p_def_font, const Ref<Font> &p_font, int p_size) {
+ _stop_thread();
+ MutexLock data_lock(data_mutex);
+
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
+ ItemFont *item = memnew(ItemFont);
+
+ item->def_font = p_def_font;
+ item->variation = true;
+ item->font = p_font;
+ item->font_size = p_size;
+ item->def_size = (p_size <= 0);
+ _add_item(item, true);
+}
+
+void RichTextLabel::_push_def_font(DefaultFont p_def_font) {
_stop_thread();
MutexLock data_lock(data_mutex);
ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemFont *item = memnew(ItemFont);
- item->def_font = p_font;
+ item->def_font = p_def_font;
+ item->def_size = true;
_add_item(item, true);
}
@@ -3236,33 +3299,36 @@ void RichTextLabel::push_fade(int p_start_index, int p_length) {
_add_item(item, true);
}
-void RichTextLabel::push_shake(int p_strength = 10, float p_rate = 24.0f) {
+void RichTextLabel::push_shake(int p_strength = 10, float p_rate = 24.0f, bool p_connected = true) {
_stop_thread();
MutexLock data_lock(data_mutex);
ItemShake *item = memnew(ItemShake);
item->strength = p_strength;
item->rate = p_rate;
+ item->connected = p_connected;
_add_item(item, true);
}
-void RichTextLabel::push_wave(float p_frequency = 1.0f, float p_amplitude = 10.0f) {
+void RichTextLabel::push_wave(float p_frequency = 1.0f, float p_amplitude = 10.0f, bool p_connected = true) {
_stop_thread();
MutexLock data_lock(data_mutex);
ItemWave *item = memnew(ItemWave);
item->frequency = p_frequency;
item->amplitude = p_amplitude;
+ item->connected = p_connected;
_add_item(item, true);
}
-void RichTextLabel::push_tornado(float p_frequency = 1.0f, float p_radius = 10.0f) {
+void RichTextLabel::push_tornado(float p_frequency = 1.0f, float p_radius = 10.0f, bool p_connected = true) {
_stop_thread();
MutexLock data_lock(data_mutex);
ItemTornado *item = memnew(ItemTornado);
item->frequency = p_frequency;
item->radius = p_radius;
+ item->connected = p_connected;
_add_item(item, true);
}
@@ -4113,24 +4179,21 @@ void RichTextLabel::append_text(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front("font_size");
- } else if (tag.begins_with("opentype_features=")) {
- String fnt_ftr = tag.substr(18, tag.length());
+ } else if (tag.begins_with("opentype_features=") || tag.begins_with("otf=")) {
+ int value_pos = tag.find("=");
+ String fnt_ftr = tag.substr(value_pos + 1);
Vector<String> subtag = fnt_ftr.split(",");
if (subtag.size() > 0) {
Ref<Font> font = theme_cache.normal_font;
- int font_size = 0;
+ DefaultFont def_font = NORMAL_FONT;
+
ItemFont *font_it = _find_font(current);
if (font_it) {
if (font_it->font.is_valid()) {
font = font_it->font;
- }
- if (font_it->font_size > 0) {
- font_size = font_it->font_size;
+ def_font = font_it->def_font;
}
}
- Ref<FontVariation> fc;
- fc.instantiate();
- fc->set_base_font(font);
Dictionary features;
for (int i = 0; i < subtag.size(); i++) {
Vector<String> subtag_a = subtag[i].split("=");
@@ -4140,11 +4203,21 @@ void RichTextLabel::append_text(const String &p_bbcode) {
features[TS->name_to_tag(subtag_a[0])] = 1;
}
}
+
+ Ref<FontVariation> fc;
+ fc.instantiate();
+
+ fc->set_base_font(font);
fc->set_opentype_features(features);
- push_font(fc, font_size);
+
+ if (def_font != CUSTOM_FONT) {
+ _push_def_font_var(def_font, fc);
+ } else {
+ push_font(fc);
+ }
}
pos = brk_end + 1;
- tag_stack.push_front("opentype_features");
+ tag_stack.push_front(tag.substr(0, value_pos));
} else if (tag.begins_with("font=")) {
String fnt = tag.substr(5, tag.length());
@@ -4160,9 +4233,21 @@ void RichTextLabel::append_text(const String &p_bbcode) {
} else if (tag.begins_with("font ")) {
Vector<String> subtag = tag.substr(2, tag.length()).split(" ");
+ Ref<Font> font = theme_cache.normal_font;
+ DefaultFont def_font = NORMAL_FONT;
+
+ ItemFont *font_it = _find_font(current);
+ if (font_it) {
+ if (font_it->font.is_valid()) {
+ font = font_it->font;
+ def_font = font_it->def_font;
+ }
+ }
+
Ref<FontVariation> fc;
fc.instantiate();
- int fnt_size = 0;
+
+ int fnt_size = -1;
for (int i = 1; i < subtag.size(); i++) {
Vector<String> subtag_a = subtag[i].split("=", true, 2);
if (subtag_a.size() == 2) {
@@ -4170,7 +4255,8 @@ void RichTextLabel::append_text(const String &p_bbcode) {
String fnt = subtag_a[1];
Ref<Font> font_data = ResourceLoader::load(fnt, "Font");
if (font_data.is_valid()) {
- fc->set_base_font(font_data);
+ font = font_data;
+ def_font = CUSTOM_FONT;
}
} else if (subtag_a[0] == "size" || subtag_a[0] == "s") {
fnt_size = subtag_a[1].to_int();
@@ -4224,7 +4310,14 @@ void RichTextLabel::append_text(const String &p_bbcode) {
}
}
}
- push_font(fc, fnt_size);
+ fc->set_base_font(font);
+
+ if (def_font != CUSTOM_FONT) {
+ _push_def_font_var(def_font, fc, fnt_size);
+ } else {
+ push_font(fc, fnt_size);
+ }
+
pos = brk_end + 1;
tag_stack.push_front("font");
@@ -4265,7 +4358,13 @@ void RichTextLabel::append_text(const String &p_bbcode) {
rate = rate_option->value.to_float();
}
- push_shake(strength, rate);
+ bool connected = true;
+ OptionMap::Iterator connected_option = bbcode_options.find("connected");
+ if (connected_option) {
+ connected = connected_option->value.to_int();
+ }
+
+ push_shake(strength, rate, connected);
pos = brk_end + 1;
tag_stack.push_front("shake");
set_process_internal(true);
@@ -4282,7 +4381,13 @@ void RichTextLabel::append_text(const String &p_bbcode) {
period = period_option->value.to_float();
}
- push_wave(period, amplitude);
+ bool connected = true;
+ OptionMap::Iterator connected_option = bbcode_options.find("connected");
+ if (connected_option) {
+ connected = connected_option->value.to_int();
+ }
+
+ push_wave(period, amplitude, connected);
pos = brk_end + 1;
tag_stack.push_front("wave");
set_process_internal(true);
@@ -4299,7 +4404,13 @@ void RichTextLabel::append_text(const String &p_bbcode) {
frequency = frequency_option->value.to_float();
}
- push_tornado(frequency, radius);
+ bool connected = true;
+ OptionMap::Iterator connected_option = bbcode_options.find("connected");
+ if (connected_option) {
+ connected = connected_option->value.to_int();
+ }
+
+ push_tornado(frequency, radius, connected);
pos = brk_end + 1;
tag_stack.push_front("tornado");
set_process_internal(true);
@@ -4676,7 +4787,10 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
queue_redraw();
return true;
}
- p_search_previous ? current_line-- : current_line++;
+
+ if (current_line != ending_line) {
+ p_search_previous ? current_line-- : current_line++;
+ }
}
if (p_from_selection && selection.active) {
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 2a5ec4b5d5..71123602ad 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -189,6 +189,8 @@ private:
struct ItemFont : public Item {
DefaultFont def_font = CUSTOM_FONT;
Ref<Font> font;
+ bool variation = false;
+ bool def_size = false;
int font_size = 0;
ItemFont() { type = ITEM_FONT; }
};
@@ -282,6 +284,7 @@ private:
struct ItemFX : public Item {
double elapsed_time = 0.f;
+ bool connected = true;
};
struct ItemShake : public ItemFX {
@@ -570,7 +573,8 @@ public:
void add_newline();
bool remove_line(const int p_line);
void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0));
- void _push_def_font(DefaultFont p_font);
+ void _push_def_font(DefaultFont p_def_font);
+ void _push_def_font_var(DefaultFont p_def_font, const Ref<Font> &p_font, int p_size = -1);
void push_font(const Ref<Font> &p_font, int p_size = 0);
void push_font_size(int p_font_size);
void push_outline_size(int p_font_size);
@@ -590,9 +594,9 @@ public:
void push_hint(const String &p_string);
void push_table(int p_columns, InlineAlignment p_alignment = INLINE_ALIGNMENT_TOP);
void push_fade(int p_start_index, int p_length);
- void push_shake(int p_strength, float p_rate);
- void push_wave(float p_frequency, float p_amplitude);
- void push_tornado(float p_frequency, float p_radius);
+ void push_shake(int p_strength, float p_rate, bool p_connected);
+ void push_wave(float p_frequency, float p_amplitude, bool p_connected);
+ void push_tornado(float p_frequency, float p_radius, bool p_connected);
void push_rainbow(float p_saturation, float p_value, float p_frequency);
void push_bgcolor(const Color &p_color);
void push_fgcolor(const Color &p_color);
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index c12ac115b7..761072c5bc 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -501,8 +501,8 @@ void ScrollContainer::set_follow_focus(bool p_follow) {
follow_focus = p_follow;
}
-TypedArray<String> ScrollContainer::get_configuration_warnings() const {
- TypedArray<String> warnings = Container::get_configuration_warnings();
+PackedStringArray ScrollContainer::get_configuration_warnings() const {
+ PackedStringArray warnings = Container::get_configuration_warnings();
int found = 0;
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index f4899846f4..0079358ef7 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -114,7 +114,7 @@ public:
VScrollBar *get_v_scroll_bar();
void ensure_control_visible(Control *p_control);
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
ScrollContainer();
};
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index 88e68ec763..3ad84cbc6d 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -227,8 +227,8 @@ void SubViewportContainer::unhandled_input(const Ref<InputEvent> &p_event) {
}
}
-TypedArray<String> SubViewportContainer::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray SubViewportContainer::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
bool has_viewport = false;
for (int i = 0; i < get_child_count(); i++) {
diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h
index 5b488fb79e..63a58b5f07 100644
--- a/scene/gui/subviewport_container.h
+++ b/scene/gui/subviewport_container.h
@@ -58,7 +58,7 @@ public:
virtual Vector<int> get_allowed_size_flags_horizontal() const override;
virtual Vector<int> get_allowed_size_flags_vertical() const override;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
SubViewportContainer();
};
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 1df698a108..ab4808d312 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -519,12 +519,12 @@ void TabContainer::_refresh_tab_names() {
}
void TabContainer::add_child_notify(Node *p_child) {
+ Container::add_child_notify(p_child);
+
if (p_child == tab_bar) {
return;
}
- Container::add_child_notify(p_child);
-
Control *c = Object::cast_to<Control>(p_child);
if (!c || c->is_set_as_top_level()) {
return;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 318447ecd8..38302136d6 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1201,13 +1201,14 @@ void TextEdit::_notification(int p_what) {
current_color.a = font_readonly_color.a;
}
}
+ Color gl_color = current_color;
if (selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection
int sel_from = (line > selection.from_line) ? TS->shaped_text_get_range(rid).x : selection.from_column;
int sel_to = (line < selection.to_line) ? TS->shaped_text_get_range(rid).y : selection.to_column;
if (glyphs[j].start >= sel_from && glyphs[j].end <= sel_to && override_selected_font_color) {
- current_color = font_selected_color;
+ gl_color = font_selected_color;
}
}
@@ -1217,29 +1218,29 @@ void TextEdit::_notification(int p_what) {
if ((brace_open_match_line == line && brace_open_match_column == glyphs[j].start) ||
(caret.column == glyphs[j].start && caret.line == line && caret_wrap_index == line_wrap_index && (brace_open_matching || brace_open_mismatch))) {
if (brace_open_mismatch) {
- current_color = brace_mismatch_color;
+ gl_color = brace_mismatch_color;
}
Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1));
- draw_rect(rect, current_color);
+ draw_rect(rect, gl_color);
}
if ((brace_close_match_line == line && brace_close_match_column == glyphs[j].start) ||
(caret.column == glyphs[j].start + 1 && caret.line == line && caret_wrap_index == line_wrap_index && (brace_close_matching || brace_close_mismatch))) {
if (brace_close_mismatch) {
- current_color = brace_mismatch_color;
+ gl_color = brace_mismatch_color;
}
Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1));
- draw_rect(rect, current_color);
+ draw_rect(rect, gl_color);
}
}
if (draw_tabs && ((glyphs[j].flags & TextServer::GRAPHEME_IS_TAB) == TextServer::GRAPHEME_IS_TAB)) {
int yofs = (text_height - tab_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
- tab_icon->draw(ci, Point2(char_pos, ofs_y + yofs), current_color);
+ tab_icon->draw(ci, Point2(char_pos, ofs_y + yofs), gl_color);
} else if (draw_spaces && ((glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE)) {
int yofs = (text_height - space_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
int xofs = (glyphs[j].advance * glyphs[j].repeat - space_icon->get_width()) / 2;
- space_icon->draw(ci, Point2(char_pos + xofs, ofs_y + yofs), current_color);
+ space_icon->draw(ci, Point2(char_pos + xofs, ofs_y + yofs), gl_color);
}
}
@@ -1247,10 +1248,10 @@ void TextEdit::_notification(int p_what) {
for (int k = 0; k < glyphs[j].repeat; k++) {
if (!clipped && (char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) {
if (glyphs[j].font_rid != RID()) {
- TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, current_color);
+ TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color);
had_glyphs_drawn = true;
} else if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
- TS->draw_hex_code_box(ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, current_color);
+ TS->draw_hex_code_box(ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color);
had_glyphs_drawn = true;
}
}
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 237c78407b..f82a853e56 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -563,6 +563,57 @@ bool TreeItem::is_collapsed() {
return collapsed;
}
+void TreeItem::set_collapsed_recursive(bool p_collapsed) {
+ if (!tree) {
+ return;
+ }
+
+ set_collapsed(p_collapsed);
+
+ TreeItem *child = get_first_child();
+ while (child) {
+ child->set_collapsed_recursive(p_collapsed);
+ child = child->get_next();
+ }
+}
+
+bool TreeItem::_is_any_collapsed(bool p_only_visible) {
+ TreeItem *child = get_first_child();
+
+ // Check on children directly first (avoid recursing if possible).
+ while (child) {
+ if (child->get_first_child() && child->is_collapsed() && (!p_only_visible || (child->is_visible() && child->get_visible_child_count()))) {
+ return true;
+ }
+ child = child->get_next();
+ }
+
+ child = get_first_child();
+
+ // Otherwise recurse on children.
+ while (child) {
+ if (child->get_first_child() && (!p_only_visible || (child->is_visible() && child->get_visible_child_count())) && child->_is_any_collapsed(p_only_visible)) {
+ return true;
+ }
+ child = child->get_next();
+ }
+
+ return false;
+}
+
+bool TreeItem::is_any_collapsed(bool p_only_visible) {
+ if (p_only_visible && !is_visible()) {
+ return false;
+ }
+
+ // Collapsed if this is collapsed and it has children (only considers visible if only visible is set).
+ if (is_collapsed() && get_first_child() && (!p_only_visible || get_visible_child_count())) {
+ return true;
+ }
+
+ return _is_any_collapsed(p_only_visible);
+}
+
void TreeItem::set_visible(bool p_visible) {
if (visible == p_visible) {
return;
@@ -1406,6 +1457,9 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collapsed", "enable"), &TreeItem::set_collapsed);
ClassDB::bind_method(D_METHOD("is_collapsed"), &TreeItem::is_collapsed);
+ ClassDB::bind_method(D_METHOD("set_collapsed_recursive", "enable"), &TreeItem::set_collapsed_recursive);
+ ClassDB::bind_method(D_METHOD("is_any_collapsed", "only_visible"), &TreeItem::is_any_collapsed, DEFVAL(false));
+
ClassDB::bind_method(D_METHOD("set_visible", "enable"), &TreeItem::set_visible);
ClassDB::bind_method(D_METHOD("is_visible"), &TreeItem::is_visible);
@@ -2572,7 +2626,11 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
}
if (!p_item->disable_folding && !hide_folding && p_item->first_child && (p_pos.x >= x_ofs && p_pos.x < (x_ofs + theme_cache.item_margin))) {
- p_item->set_collapsed(!p_item->is_collapsed());
+ if (enable_recursive_folding && p_mod->is_shift_pressed()) {
+ p_item->set_collapsed_recursive(!p_item->is_collapsed());
+ } else {
+ p_item->set_collapsed(!p_item->is_collapsed());
+ }
return -1;
}
@@ -2623,7 +2681,11 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
}
if (!p_item->disable_folding && !hide_folding && !p_item->cells[col].editable && !p_item->cells[col].selectable && p_item->get_first_child()) {
- p_item->set_collapsed(!p_item->is_collapsed());
+ if (enable_recursive_folding && p_mod->is_shift_pressed()) {
+ p_item->set_collapsed_recursive(!p_item->is_collapsed());
+ } else {
+ p_item->set_collapsed(!p_item->is_collapsed());
+ }
return -1; //collapse/uncollapse because nothing can be done with item
}
@@ -5026,6 +5088,14 @@ bool Tree::is_folding_hidden() const {
return hide_folding;
}
+void Tree::set_enable_recursive_folding(bool p_enable) {
+ enable_recursive_folding = p_enable;
+}
+
+bool Tree::is_recursive_folding_enabled() const {
+ return enable_recursive_folding;
+}
+
void Tree::set_drop_mode_flags(int p_flags) {
if (drop_mode_flags == p_flags) {
return;
@@ -5129,6 +5199,9 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_hide_folding", "hide"), &Tree::set_hide_folding);
ClassDB::bind_method(D_METHOD("is_folding_hidden"), &Tree::is_folding_hidden);
+ ClassDB::bind_method(D_METHOD("set_enable_recursive_folding", "enable"), &Tree::set_enable_recursive_folding);
+ ClassDB::bind_method(D_METHOD("is_recursive_folding_enabled"), &Tree::is_recursive_folding_enabled);
+
ClassDB::bind_method(D_METHOD("set_drop_mode_flags", "flags"), &Tree::set_drop_mode_flags);
ClassDB::bind_method(D_METHOD("get_drop_mode_flags"), &Tree::get_drop_mode_flags);
@@ -5143,6 +5216,7 @@ void Tree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_reselect"), "set_allow_reselect", "get_allow_reselect");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_recursive_folding"), "set_enable_recursive_folding", "is_recursive_folding_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_root"), "set_hide_root", "is_root_hidden");
ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In Between"), "set_drop_mode_flags", "get_drop_mode_flags");
ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Row,Multi"), "set_select_mode", "get_select_mode");
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 450943c048..f994a5cec1 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -173,6 +173,8 @@ private:
}
}
+ bool _is_any_collapsed(bool p_only_visible);
+
protected:
static void _bind_methods();
@@ -272,6 +274,9 @@ public:
void set_collapsed(bool p_collapsed);
bool is_collapsed();
+ void set_collapsed_recursive(bool p_collapsed);
+ bool is_any_collapsed(bool p_only_visible = false);
+
void set_visible(bool p_visible);
bool is_visible();
@@ -613,6 +618,8 @@ private:
bool hide_folding = false;
+ bool enable_recursive_folding = true;
+
int _count_selected_items(TreeItem *p_from) const;
bool _is_branch_selected(TreeItem *p_from) const;
bool _is_sibling_branch_selected(TreeItem *p_from) const;
@@ -712,6 +719,9 @@ public:
void set_hide_folding(bool p_hide);
bool is_folding_hidden() const;
+ void set_enable_recursive_folding(bool p_enable);
+ bool is_recursive_folding_enabled() const;
+
void set_drop_mode_flags(int p_flags);
int get_drop_mode_flags() const;
diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp
index 1e03ed6e76..0ea49b1645 100644
--- a/scene/gui/video_stream_player.cpp
+++ b/scene/gui/video_stream_player.cpp
@@ -381,14 +381,14 @@ String VideoStreamPlayer::get_stream_name() const {
return stream->get_name();
}
-float VideoStreamPlayer::get_stream_position() const {
+double VideoStreamPlayer::get_stream_position() const {
if (playback.is_null()) {
return 0;
}
return playback->get_playback_position();
}
-void VideoStreamPlayer::set_stream_position(float p_position) {
+void VideoStreamPlayer::set_stream_position(double p_position) {
if (playback.is_valid()) {
playback->seek(p_position);
}
diff --git a/scene/gui/video_stream_player.h b/scene/gui/video_stream_player.h
index 9974eb8488..b1ba8a65d7 100644
--- a/scene/gui/video_stream_player.h
+++ b/scene/gui/video_stream_player.h
@@ -105,8 +105,8 @@ public:
float get_volume_db() const;
String get_stream_name() const;
- float get_stream_position() const;
- void set_stream_position(float p_position);
+ double get_stream_position() const;
+ void set_stream_position(double p_position);
void set_autoplay(bool p_enable);
bool has_autoplay() const;
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index bec378dd91..2c395ec07d 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -32,9 +32,6 @@
#include "core/io/compression.h"
#include "scene/main/timer.h"
-void HTTPRequest::_redirect_request(const String &p_new_url) {
-}
-
Error HTTPRequest::_request() {
return client->connect_to_host(url, port, use_tls, validate_tls);
}
@@ -48,6 +45,7 @@ Error HTTPRequest::_parse_url(const String &p_url) {
body_len = -1;
body.clear();
downloaded.set(0);
+ final_body_size.set(0);
redirections = 0;
String scheme;
@@ -153,7 +151,7 @@ Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_cust
client->set_blocking_mode(false);
err = _request();
if (err != OK) {
- call_deferred(SNAME("_request_done"), RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
+ _defer_done(RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
return ERR_CANT_CONNECT;
}
@@ -169,7 +167,7 @@ void HTTPRequest::_thread_func(void *p_userdata) {
Error err = hr->_request();
if (err != OK) {
- hr->call_deferred(SNAME("_request_done"), RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
+ hr->_defer_done(RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
} else {
while (!hr->thread_request_quit.is_set()) {
bool exit = hr->_update_connection();
@@ -198,6 +196,7 @@ void HTTPRequest::cancel_request() {
}
file.unref();
+ decompressor.unref();
client->close();
body.clear();
got_response = false;
@@ -208,7 +207,7 @@ void HTTPRequest::cancel_request() {
bool HTTPRequest::_handle_response(bool *ret_value) {
if (!client->has_response()) {
- call_deferred(SNAME("_request_done"), RESULT_NO_RESPONSE, 0, PackedStringArray(), PackedByteArray());
+ _defer_done(RESULT_NO_RESPONSE, 0, PackedStringArray(), PackedByteArray());
*ret_value = true;
return true;
}
@@ -219,6 +218,9 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
client->get_response_headers(&rheaders);
response_headers.clear();
downloaded.set(0);
+ final_body_size.set(0);
+ decompressor.unref();
+
for (const String &E : rheaders) {
response_headers.push_back(E);
}
@@ -227,7 +229,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
// Handle redirect.
if (max_redirects >= 0 && redirections >= max_redirects) {
- call_deferred(SNAME("_request_done"), RESULT_REDIRECT_LIMIT_REACHED, response_code, response_headers, PackedByteArray());
+ _defer_done(RESULT_REDIRECT_LIMIT_REACHED, response_code, response_headers, PackedByteArray());
*ret_value = true;
return true;
}
@@ -259,6 +261,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
body_len = -1;
body.clear();
downloaded.set(0);
+ final_body_size.set(0);
redirections = new_redirs;
*ret_value = false;
return true;
@@ -266,13 +269,26 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
}
}
+ // Check if we need to start streaming decompression.
+ String content_encoding;
+ if (accept_gzip) {
+ content_encoding = get_header_value(response_headers, "Content-Encoding").to_lower();
+ }
+ if (content_encoding == "gzip") {
+ decompressor.instantiate();
+ decompressor->start_decompression(false, get_download_chunk_size() * 2);
+ } else if (content_encoding == "deflate") {
+ decompressor.instantiate();
+ decompressor->start_decompression(true, get_download_chunk_size() * 2);
+ }
+
return false;
}
bool HTTPRequest::_update_connection() {
switch (client->get_status()) {
case HTTPClient::STATUS_DISCONNECTED: {
- call_deferred(SNAME("_request_done"), RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
+ _defer_done(RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
return true; // End it, since it's disconnected.
} break;
case HTTPClient::STATUS_RESOLVING: {
@@ -281,7 +297,7 @@ bool HTTPRequest::_update_connection() {
return false;
} break;
case HTTPClient::STATUS_CANT_RESOLVE: {
- call_deferred(SNAME("_request_done"), RESULT_CANT_RESOLVE, 0, PackedStringArray(), PackedByteArray());
+ _defer_done(RESULT_CANT_RESOLVE, 0, PackedStringArray(), PackedByteArray());
return true;
} break;
@@ -291,7 +307,7 @@ bool HTTPRequest::_update_connection() {
return false;
} break; // Connecting to IP.
case HTTPClient::STATUS_CANT_CONNECT: {
- call_deferred(SNAME("_request_done"), RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
+ _defer_done(RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
return true;
} break;
@@ -306,16 +322,16 @@ bool HTTPRequest::_update_connection() {
return ret_value;
}
- call_deferred(SNAME("_request_done"), RESULT_SUCCESS, response_code, response_headers, PackedByteArray());
+ _defer_done(RESULT_SUCCESS, response_code, response_headers, PackedByteArray());
return true;
}
if (body_len < 0) {
// Chunked transfer is done.
- call_deferred(SNAME("_request_done"), RESULT_SUCCESS, response_code, response_headers, body);
+ _defer_done(RESULT_SUCCESS, response_code, response_headers, body);
return true;
}
- call_deferred(SNAME("_request_done"), RESULT_CHUNKED_BODY_SIZE_MISMATCH, response_code, response_headers, PackedByteArray());
+ _defer_done(RESULT_CHUNKED_BODY_SIZE_MISMATCH, response_code, response_headers, PackedByteArray());
return true;
// Request might have been done.
} else {
@@ -324,7 +340,7 @@ bool HTTPRequest::_update_connection() {
int size = request_data.size();
Error err = client->request(method, request_string, headers, size > 0 ? request_data.ptr() : nullptr, size);
if (err != OK) {
- call_deferred(SNAME("_request_done"), RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray());
+ _defer_done(RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray());
return true;
}
@@ -347,7 +363,7 @@ bool HTTPRequest::_update_connection() {
}
if (!client->is_response_chunked() && client->get_response_body_length() == 0) {
- call_deferred(SNAME("_request_done"), RESULT_SUCCESS, response_code, response_headers, PackedByteArray());
+ _defer_done(RESULT_SUCCESS, response_code, response_headers, PackedByteArray());
return true;
}
@@ -356,14 +372,14 @@ bool HTTPRequest::_update_connection() {
body_len = client->get_response_body_length();
if (body_size_limit >= 0 && body_len > body_size_limit) {
- call_deferred(SNAME("_request_done"), RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray());
+ _defer_done(RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray());
return true;
}
if (!download_to_file.is_empty()) {
file = FileAccess::open(download_to_file, FileAccess::WRITE);
if (file.is_null()) {
- call_deferred(SNAME("_request_done"), RESULT_DOWNLOAD_FILE_CANT_OPEN, response_code, response_headers, PackedByteArray());
+ _defer_done(RESULT_DOWNLOAD_FILE_CANT_OPEN, response_code, response_headers, PackedByteArray());
return true;
}
}
@@ -375,14 +391,33 @@ bool HTTPRequest::_update_connection() {
}
PackedByteArray chunk = client->read_response_body_chunk();
+ downloaded.add(chunk.size());
+
+ // Decompress chunk if needed.
+ if (decompressor.is_valid()) {
+ Error err = decompressor->put_data(chunk.ptr(), chunk.size());
+ if (err == OK) {
+ chunk.resize(decompressor->get_available_bytes());
+ err = decompressor->get_data(chunk.ptrw(), chunk.size());
+ }
+ if (err != OK) {
+ _defer_done(RESULT_BODY_DECOMPRESS_FAILED, response_code, response_headers, PackedByteArray());
+ return true;
+ }
+ }
+ final_body_size.add(chunk.size());
+
+ if (body_size_limit >= 0 && final_body_size.get() > body_size_limit) {
+ _defer_done(RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray());
+ return true;
+ }
if (chunk.size()) {
- downloaded.add(chunk.size());
if (file.is_valid()) {
const uint8_t *r = chunk.ptr();
file->store_buffer(r, chunk.size());
if (file->get_error() != OK) {
- call_deferred(SNAME("_request_done"), RESULT_DOWNLOAD_FILE_WRITE_ERROR, response_code, response_headers, PackedByteArray());
+ _defer_done(RESULT_DOWNLOAD_FILE_WRITE_ERROR, response_code, response_headers, PackedByteArray());
return true;
}
} else {
@@ -390,19 +425,14 @@ bool HTTPRequest::_update_connection() {
}
}
- if (body_size_limit >= 0 && downloaded.get() > body_size_limit) {
- call_deferred(SNAME("_request_done"), RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray());
- return true;
- }
-
if (body_len >= 0) {
if (downloaded.get() == body_len) {
- call_deferred(SNAME("_request_done"), RESULT_SUCCESS, response_code, response_headers, body);
+ _defer_done(RESULT_SUCCESS, response_code, response_headers, body);
return true;
}
} else if (client->get_status() == HTTPClient::STATUS_DISCONNECTED) {
// We read till EOF, with no errors. Request is done.
- call_deferred(SNAME("_request_done"), RESULT_SUCCESS, response_code, response_headers, body);
+ _defer_done(RESULT_SUCCESS, response_code, response_headers, body);
return true;
}
@@ -410,11 +440,11 @@ bool HTTPRequest::_update_connection() {
} break; // Request resulted in body: break which must be read.
case HTTPClient::STATUS_CONNECTION_ERROR: {
- call_deferred(SNAME("_request_done"), RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray());
+ _defer_done(RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray());
return true;
} break;
case HTTPClient::STATUS_TLS_HANDSHAKE_ERROR: {
- call_deferred(SNAME("_request_done"), RESULT_TLS_HANDSHAKE_ERROR, 0, PackedStringArray(), PackedByteArray());
+ _defer_done(RESULT_TLS_HANDSHAKE_ERROR, 0, PackedStringArray(), PackedByteArray());
return true;
} break;
}
@@ -422,41 +452,13 @@ bool HTTPRequest::_update_connection() {
ERR_FAIL_V(false);
}
+void HTTPRequest::_defer_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data) {
+ call_deferred(SNAME("_request_done"), p_status, p_code, p_headers, p_data);
+}
+
void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data) {
cancel_request();
- // Determine if the request body is compressed.
- bool is_compressed;
- String content_encoding = get_header_value(p_headers, "Content-Encoding").to_lower();
- Compression::Mode mode;
- if (content_encoding == "gzip") {
- mode = Compression::Mode::MODE_GZIP;
- is_compressed = true;
- } else if (content_encoding == "deflate") {
- mode = Compression::Mode::MODE_DEFLATE;
- is_compressed = true;
- } else {
- is_compressed = false;
- }
-
- if (accept_gzip && is_compressed && p_data.size() > 0) {
- // Decompress request body
- PackedByteArray decompressed;
- int result = Compression::decompress_dynamic(&decompressed, body_size_limit, p_data.ptr(), p_data.size(), mode);
- if (result == OK) {
- emit_signal(SNAME("request_completed"), p_status, p_code, p_headers, decompressed);
- return;
- } else if (result == -5) {
- WARN_PRINT("Decompressed size of HTTP response body exceeded body_size_limit");
- p_status = RESULT_BODY_SIZE_LIMIT_EXCEEDED;
- // Just return the raw data if we failed to decompress it.
- } else {
- WARN_PRINT("Failed to decompress HTTP response body");
- p_status = RESULT_BODY_DECOMPRESS_FAILED;
- // Just return the raw data if we failed to decompress it.
- }
- }
-
emit_signal(SNAME("request_completed"), p_status, p_code, p_headers, p_data);
}
@@ -566,7 +568,7 @@ double HTTPRequest::get_timeout() {
void HTTPRequest::_timeout() {
cancel_request();
- call_deferred(SNAME("_request_done"), RESULT_TIMEOUT, 0, PackedStringArray(), PackedByteArray());
+ _defer_done(RESULT_TIMEOUT, 0, PackedStringArray(), PackedByteArray());
}
void HTTPRequest::_bind_methods() {
@@ -594,7 +596,6 @@ void HTTPRequest::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_downloaded_bytes"), &HTTPRequest::get_downloaded_bytes);
ClassDB::bind_method(D_METHOD("get_body_size"), &HTTPRequest::get_body_size);
- ClassDB::bind_method(D_METHOD("_redirect_request"), &HTTPRequest::_redirect_request);
ClassDB::bind_method(D_METHOD("_request_done"), &HTTPRequest::_request_done);
ClassDB::bind_method(D_METHOD("set_timeout", "timeout"), &HTTPRequest::set_timeout);
diff --git a/scene/main/http_request.h b/scene/main/http_request.h
index 290bacd9d2..80445684b0 100644
--- a/scene/main/http_request.h
+++ b/scene/main/http_request.h
@@ -32,6 +32,7 @@
#define HTTP_REQUEST_H
#include "core/io/http_client.h"
+#include "core/io/stream_peer_gzip.h"
#include "core/os/thread.h"
#include "core/templates/safe_refcount.h"
#include "scene/main/node.h"
@@ -84,10 +85,12 @@ private:
String download_to_file;
+ Ref<StreamPeerGZIP> decompressor;
Ref<FileAccess> file;
int body_len = -1;
SafeNumeric<int> downloaded;
+ SafeNumeric<int> final_body_size;
int body_size_limit = -1;
int redirections = 0;
@@ -113,6 +116,7 @@ private:
Thread thread;
+ void _defer_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data);
void _request_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data);
static void _thread_func(void *p_userdata);
diff --git a/scene/main/missing_node.cpp b/scene/main/missing_node.cpp
index 395fdad9e4..7ce527fd9c 100644
--- a/scene/main/missing_node.cpp
+++ b/scene/main/missing_node.cpp
@@ -74,9 +74,9 @@ bool MissingNode::is_recording_properties() const {
return recording_properties;
}
-TypedArray<String> MissingNode::get_configuration_warnings() const {
+PackedStringArray MissingNode::get_configuration_warnings() const {
// The mere existence of this node is warning.
- TypedArray<String> ret;
+ PackedStringArray ret;
ret.push_back(vformat(RTR("This node was saved as class type '%s', which was no longer available when this scene was loaded."), original_class));
ret.push_back(RTR("Data from the original node is kept as a placeholder until this type of node is available again. It can hence be safely re-saved without risk of data loss."));
return ret;
diff --git a/scene/main/missing_node.h b/scene/main/missing_node.h
index d200fbb47f..0003f71f29 100644
--- a/scene/main/missing_node.h
+++ b/scene/main/missing_node.h
@@ -55,7 +55,7 @@ public:
void set_recording_properties(bool p_enable);
bool is_recording_properties() const;
- virtual TypedArray<String> get_configuration_warnings() const override;
+ virtual PackedStringArray get_configuration_warnings() const override;
MissingNode();
};
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 29f4d4fb1c..a2b0f1a825 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2640,21 +2640,19 @@ void Node::clear_internal_tree_resource_paths() {
}
}
-TypedArray<String> Node::get_configuration_warnings() const {
- TypedArray<String> ret;
+PackedStringArray Node::get_configuration_warnings() const {
+ PackedStringArray ret;
Vector<String> warnings;
if (GDVIRTUAL_CALL(_get_configuration_warnings, warnings)) {
- for (int i = 0; i < warnings.size(); i++) {
- ret.push_back(warnings[i]);
- }
+ ret.append_array(warnings);
}
return ret;
}
String Node::get_configuration_warnings_as_string() const {
- TypedArray<String> warnings = get_configuration_warnings();
+ PackedStringArray warnings = get_configuration_warnings();
String all_warnings = String();
for (int i = 0; i < warnings.size(); i++) {
if (i > 0) {
@@ -2662,7 +2660,7 @@ String Node::get_configuration_warnings_as_string() const {
}
// Format as a bullet point list to make multiple warnings easier to distinguish
// from each other.
- all_warnings += String::utf8("• ") + String(warnings[i]);
+ all_warnings += String::utf8("• ") + warnings[i];
}
return all_warnings;
}
diff --git a/scene/main/node.h b/scene/main/node.h
index 13a938ef97..4e6530cccd 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -477,7 +477,7 @@ public:
_FORCE_INLINE_ Viewport *get_viewport() const { return data.viewport; }
- virtual TypedArray<String> get_configuration_warnings() const;
+ virtual PackedStringArray get_configuration_warnings() const;
String get_configuration_warnings_as_string() const;
void update_configuration_warnings();
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index c18aa5aaa2..3f71de1b18 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -510,7 +510,7 @@ bool SceneTree::process(double p_time) {
return _quit;
}
-void SceneTree::process_timers(float p_delta, bool p_physics_frame) {
+void SceneTree::process_timers(double p_delta, bool p_physics_frame) {
List<Ref<SceneTreeTimer>>::Element *L = timers.back(); //last element
for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E;) {
@@ -542,7 +542,7 @@ void SceneTree::process_timers(float p_delta, bool p_physics_frame) {
}
}
-void SceneTree::process_tweens(float p_delta, bool p_physics) {
+void SceneTree::process_tweens(double p_delta, bool p_physics) {
// This methods works similarly to how SceneTreeTimers are handled.
List<Ref<Tween>>::Element *L = tweens.back();
@@ -1085,6 +1085,7 @@ void SceneTree::_change_scene(Node *p_to) {
if (p_to) {
current_scene = p_to;
root->add_child(p_to);
+ root->update_mouse_cursor_shape();
}
}
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 031a331a99..a460e40597 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -180,8 +180,8 @@ private:
void node_added(Node *p_node);
void node_removed(Node *p_node);
void node_renamed(Node *p_node);
- void process_timers(float p_delta, bool p_physics_frame);
- void process_tweens(float p_delta, bool p_physics_frame);
+ void process_timers(double p_delta, bool p_physics_frame);
+ void process_tweens(double p_delta, bool p_physics_frame);
Group *add_to_group(const StringName &p_group, Node *p_node);
void remove_from_group(const StringName &p_group, Node *p_node);
diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp
index 13034c5447..455b8c6866 100644
--- a/scene/main/shader_globals_override.cpp
+++ b/scene/main/shader_globals_override.cpp
@@ -271,8 +271,8 @@ void ShaderGlobalsOverride::_notification(int p_what) {
}
}
-TypedArray<String> ShaderGlobalsOverride::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray ShaderGlobalsOverride::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (!active) {
warnings.push_back(RTR("ShaderGlobalsOverride is not active because another node of the same type is in the scene."));
diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h
index af99bf9aa7..f3d0074f28 100644
--- a/scene/main/shader_globals_override.h
+++ b/scene/main/shader_globals_override.h
@@ -58,7 +58,7 @@ protected:
static void _bind_methods();
public:
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
ShaderGlobalsOverride();
};
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index bb9359ef59..210b60171a 100644
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -180,8 +180,8 @@ void Timer::_set_process(bool p_process, bool p_force) {
processing = p_process;
}
-TypedArray<String> Timer::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray Timer::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (wait_time < 0.05 - CMP_EPSILON) {
warnings.push_back(RTR("Very low timer wait times (< 0.05 seconds) may behave in significantly different ways depending on the rendered or physics frame rate.\nConsider using a script's process loop instead of relying on a Timer for very low wait times."));
diff --git a/scene/main/timer.h b/scene/main/timer.h
index 8785d31a8a..53503e31b2 100644
--- a/scene/main/timer.h
+++ b/scene/main/timer.h
@@ -73,7 +73,7 @@ public:
double get_time_left() const;
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
void set_timer_process_callback(TimerProcessCallback p_callback);
TimerProcessCallback get_timer_process_callback() const;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 879d494909..549cc19cb1 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1576,7 +1576,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.drag_preview_id = ObjectID();
}
_propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- // Change mouse accordingly.
+ get_base_window()->update_mouse_cursor_shape();
}
_gui_cancel_tooltip();
@@ -1597,7 +1597,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.dragging = false;
gui.drag_mouse_over = nullptr;
_propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- // Change mouse accordingly.
+ get_base_window()->update_mouse_cursor_shape();
}
gui.mouse_focus_mask &= ~mouse_button_to_mask(mb->get_button_index()); // Remove from mask.
@@ -2872,8 +2872,8 @@ Variant Viewport::gui_get_drag_data() const {
return gui.drag_data;
}
-TypedArray<String> Viewport::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+PackedStringArray Viewport::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
if (size.x <= 1 || size.y <= 1) {
warnings.push_back(RTR("The Viewport size must be greater than or equal to 2 pixels on both dimensions to render anything."));
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index c7c474c70f..471dc41246 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -581,7 +581,7 @@ public:
void gui_release_focus();
Control *gui_get_focus_owner();
- TypedArray<String> get_configuration_warnings() const override;
+ PackedStringArray get_configuration_warnings() const override;
void set_debug_draw(DebugDraw p_debug_draw);
DebugDraw get_debug_draw() const;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index ebe9587b31..64869b2936 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -389,9 +389,24 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
_propagate_window_notification(this, NOTIFICATION_WM_DPI_CHANGE);
emit_signal(SNAME("dpi_changed"));
} break;
+ case DisplayServer::WINDOW_EVENT_TITLEBAR_CHANGE: {
+ emit_signal(SNAME("titlebar_changed"));
+ } break;
}
}
+void Window::update_mouse_cursor_shape() {
+ // The default shape is set in Viewport::_gui_input_event. To instantly
+ // see the shape in the viewport we need to trigger a mouse motion event.
+ Ref<InputEventMouseMotion> mm;
+ Vector2 pos = get_mouse_position();
+ Transform2D xform = get_global_canvas_transform().affine_inverse();
+ mm.instantiate();
+ mm->set_position(pos);
+ mm->set_global_position(xform.xform(pos));
+ push_input(mm);
+}
+
void Window::show() {
set_visible(true);
}
@@ -1248,6 +1263,15 @@ void Window::popup(const Rect2i &p_screen_rect) {
set_transient(true);
set_visible(true);
+
+ int screen_id = DisplayServer::get_singleton()->window_get_current_screen(get_window_id());
+ Rect2i screen_rect = DisplayServer::get_singleton()->screen_get_usable_rect(screen_id);
+ if (screen_rect != Rect2i() && !screen_rect.intersects(Rect2i(position, size))) {
+ ERR_PRINT(vformat("Window %d spawned at invalid position: %s.", get_window_id(), position));
+ // Window appeared on unavailable screen area, so force it to the center.
+ set_position(screen_rect.size / 2 - size / 2);
+ }
+
_post_popup();
notification(NOTIFICATION_POST_POPUP);
}
@@ -1782,6 +1806,7 @@ void Window::_bind_methods() {
ADD_SIGNAL(MethodInfo("visibility_changed"));
ADD_SIGNAL(MethodInfo("about_to_popup"));
ADD_SIGNAL(MethodInfo("theme_changed"));
+ ADD_SIGNAL(MethodInfo("titlebar_changed"));
BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED);
BIND_CONSTANT(NOTIFICATION_THEME_CHANGED);
diff --git a/scene/main/window.h b/scene/main/window.h
index 8c6ca65436..786f0ada38 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -220,6 +220,8 @@ public:
void set_visible(bool p_visible);
bool is_visible() const;
+ void update_mouse_cursor_shape();
+
void show();
void hide();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 72c57f1bfc..e536aeee51 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -794,6 +794,7 @@ void register_scene_types() {
GDREGISTER_CLASS(CylinderMesh);
GDREGISTER_CLASS(PlaneMesh);
GDREGISTER_CLASS(PrismMesh);
+ GDREGISTER_CLASS(QuadMesh);
GDREGISTER_CLASS(SphereMesh);
GDREGISTER_CLASS(TextMesh);
GDREGISTER_CLASS(TorusMesh);
@@ -959,7 +960,6 @@ void register_scene_types() {
ClassDB::add_compatibility_class("Navigation3D", "Node3D");
ClassDB::add_compatibility_class("Navigation2D", "Node2D");
ClassDB::add_compatibility_class("OpenSimplexNoise", "FastNoiseLite");
- ClassDB::add_compatibility_class("QuadMesh", "PlaneMesh");
ClassDB::add_compatibility_class("ToolButton", "Button");
ClassDB::add_compatibility_class("YSort", "Node2D");
// Portal and room occlusion was replaced by raster occlusion (OccluderInstance3D node).
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index a52bfe97e7..f2ac1c2e58 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -2102,11 +2102,9 @@ bool Animation::track_is_compressed(int p_track) const {
return bst->compressed_track >= 0;
} break;
default: {
- return false; //animation does not really use transitions
+ return false; // Animation does not really use transitions.
} break;
}
-
- ERR_FAIL_V(false);
}
void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p_value) {
diff --git a/scene/resources/audio_stream_wav.cpp b/scene/resources/audio_stream_wav.cpp
index a87c8272ea..9bd1e84524 100644
--- a/scene/resources/audio_stream_wav.cpp
+++ b/scene/resources/audio_stream_wav.cpp
@@ -33,7 +33,7 @@
#include "core/io/file_access.h"
#include "core/io/marshalls.h"
-void AudioStreamPlaybackWAV::start(float p_from_pos) {
+void AudioStreamPlaybackWAV::start(double p_from_pos) {
if (base->format == AudioStreamWAV::FORMAT_IMA_ADPCM) {
//no seeking in IMA_ADPCM
for (int i = 0; i < 2; i++) {
@@ -67,16 +67,16 @@ int AudioStreamPlaybackWAV::get_loop_count() const {
return 0;
}
-float AudioStreamPlaybackWAV::get_playback_position() const {
+double AudioStreamPlaybackWAV::get_playback_position() const {
return float(offset >> MIX_FRAC_BITS) / base->mix_rate;
}
-void AudioStreamPlaybackWAV::seek(float p_time) {
+void AudioStreamPlaybackWAV::seek(double p_time) {
if (base->format == AudioStreamWAV::FORMAT_IMA_ADPCM) {
return; //no seeking in ima-adpcm
}
- float max = base->get_length();
+ double max = base->get_length();
if (p_time < 0) {
p_time = 0;
} else if (p_time >= max) {
@@ -463,7 +463,7 @@ bool AudioStreamWAV::is_stereo() const {
return stereo;
}
-float AudioStreamWAV::get_length() const {
+double AudioStreamWAV::get_length() const {
int len = data_bytes;
switch (format) {
case AudioStreamWAV::FORMAT_8_BITS:
@@ -481,7 +481,7 @@ float AudioStreamWAV::get_length() const {
len /= 2;
}
- return float(len) / mix_rate;
+ return double(len) / mix_rate;
}
bool AudioStreamWAV::is_monophonic() const {
diff --git a/scene/resources/audio_stream_wav.h b/scene/resources/audio_stream_wav.h
index d800388d96..d0edc52031 100644
--- a/scene/resources/audio_stream_wav.h
+++ b/scene/resources/audio_stream_wav.h
@@ -64,14 +64,14 @@ class AudioStreamPlaybackWAV : public AudioStreamPlayback {
void do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm);
public:
- virtual void start(float p_from_pos = 0.0) override;
+ virtual void start(double p_from_pos = 0.0) override;
virtual void stop() override;
virtual bool is_playing() const override;
virtual int get_loop_count() const override; //times it looped
- virtual float get_playback_position() const override;
- virtual void seek(float p_time) override;
+ virtual double get_playback_position() const override;
+ virtual void seek(double p_time) override;
virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override;
@@ -137,7 +137,7 @@ public:
void set_stereo(bool p_enable);
bool is_stereo() const;
- virtual float get_length() const override; //if supported, otherwise return 0
+ virtual double get_length() const override; //if supported, otherwise return 0
virtual bool is_monophonic() const override;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 869d582935..f03e3813cc 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -43,6 +43,8 @@
#include "modules/svg/image_loader_svg.h"
#endif
+static const int default_font_size = 16;
+
static float scale = 1.0;
static const int default_margin = 4;
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index 003934ce90..5243bcefa7 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -33,8 +33,6 @@
#include "scene/resources/theme.h"
-const int default_font_size = 16;
-
void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &bold_font, const Ref<Font> &bold_italics_font, const Ref<Font> &italics_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel = TextServer::SUBPIXEL_POSITIONING_AUTO, TextServer::Hinting p_font_hinting = TextServer::HINTING_LIGHT, TextServer::FontAntialiasing p_font_antialiased = TextServer::FONT_ANTIALIASING_GRAY, bool p_font_msdf = false, bool p_font_generate_mipmaps = false);
diff --git a/scene/resources/fog_material.cpp b/scene/resources/fog_material.cpp
index 0395ed0346..46b44d681f 100644
--- a/scene/resources/fog_material.cpp
+++ b/scene/resources/fog_material.cpp
@@ -122,7 +122,7 @@ void FogMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_density_texture", "density_texture"), &FogMaterial::set_density_texture);
ClassDB::bind_method(D_METHOD("get_density_texture"), &FogMaterial::get_density_texture);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "density", PROPERTY_HINT_RANGE, "0.0,16.0,0.0001,or_greater,or_less"), "set_density", "get_density");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "density", PROPERTY_HINT_RANGE, "-8.0,8.0,0.0001,or_greater,or_less"), "set_density", "get_density");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo", PROPERTY_HINT_COLOR_NO_ALPHA), "set_albedo", "get_albedo");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "emission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_emission", "get_emission");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height_falloff", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_height_falloff", "get_height_falloff");
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 3d9e4e4a63..410bbdbb40 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -127,16 +127,18 @@ void Font::_invalidate_rids() {
}
bool Font::_is_cyclic(const Ref<Font> &p_f, int p_depth) const {
- ERR_FAIL_COND_V(p_depth > MAX_FALLBACK_DEPTH, false);
+ ERR_FAIL_COND_V(p_depth > MAX_FALLBACK_DEPTH, true);
if (p_f.is_null()) {
return false;
}
+ if (p_f == this) {
+ return true;
+ }
for (int i = 0; i < p_f->fallbacks.size(); i++) {
const Ref<Font> &f = p_f->fallbacks[i];
- if (f == this) {
+ if (_is_cyclic(f, p_depth + 1)) {
return true;
}
- return _is_cyclic(f, p_depth + 1);
}
return false;
}
@@ -147,7 +149,10 @@ void Font::reset_state() {
// Fallbacks.
void Font::set_fallbacks(const TypedArray<Font> &p_fallbacks) {
- ERR_FAIL_COND(_is_cyclic(this, 0));
+ for (int i = 0; i < p_fallbacks.size(); i++) {
+ const Ref<Font> &f = p_fallbacks[i];
+ ERR_FAIL_COND_MSG(_is_cyclic(f, 0), "Cyclic font fallback.");
+ }
for (int i = 0; i < fallbacks.size(); i++) {
Ref<Font> f = fallbacks[i];
if (f.is_valid()) {
@@ -272,13 +277,15 @@ Size2 Font::get_string_size(const String &p_text, HorizontalAlignment p_alignmen
buffer->set_direction(p_direction);
buffer->set_orientation(p_orientation);
buffer->add_string(p_text, Ref<Font>(this), p_font_size);
- if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
- buffer->set_horizontal_alignment(p_alignment);
- buffer->set_width(p_width);
- buffer->set_flags(p_jst_flags);
- }
cache.insert(hash, buffer);
}
+
+ buffer->set_width(p_width);
+ buffer->set_horizontal_alignment(p_alignment);
+ if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ buffer->set_flags(p_jst_flags);
+ }
+
return buffer->get_size();
}
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index c1e30dd93c..838927e34f 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -3123,8 +3123,6 @@ bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value)
WARN_PRINT("Godot 3.x SpatialMaterial remapped parameter not found: " + String(p_name));
return true;
}
-
- return false;
}
#endif // DISABLE_DEPRECATED
diff --git a/scene/resources/particle_process_material.h b/scene/resources/particle_process_material.h
index fe4741d6e5..9430e5797d 100644
--- a/scene/resources/particle_process_material.h
+++ b/scene/resources/particle_process_material.h
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/templates/rid.h"
-#include "scene/resources/material.h"
-
#ifndef PARTICLE_PROCESS_MATERIAL_H
#define PARTICLE_PROCESS_MATERIAL_H
+#include "core/templates/rid.h"
+#include "scene/resources/material.h"
+
/*
TODO:
-Path following
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 280477ebfa..ee61f0ac55 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -262,6 +262,19 @@ public:
VARIANT_ENUM_CAST(PlaneMesh::Orientation)
+/*
+ A flat rectangle, inherits from PlaneMesh but defaults to facing the Z-plane.
+*/
+class QuadMesh : public PlaneMesh {
+ GDCLASS(QuadMesh, PlaneMesh);
+
+public:
+ QuadMesh() {
+ set_orientation(FACE_Z);
+ set_size(Size2(1, 1));
+ }
+};
+
/**
A prism shapen, handy for ramps, triangles, etc.
*/
diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h
index fbb202d8d8..3de1a4b26f 100644
--- a/scene/resources/sky_material.h
+++ b/scene/resources/sky_material.h
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/templates/rid.h"
-#include "scene/resources/material.h"
-
#ifndef SKY_MATERIAL_H
#define SKY_MATERIAL_H
+#include "core/templates/rid.h"
+#include "scene/resources/material.h"
+
class ProceduralSkyMaterial : public Material {
GDCLASS(ProceduralSkyMaterial, Material);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index d53dc1a8fc..15678c9281 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -38,6 +38,7 @@
#include "scene/resources/bit_map.h"
#include "scene/resources/mesh.h"
#include "servers/camera/camera_feed.h"
+
int Texture2D::get_width() const {
int ret;
if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) {
@@ -3105,7 +3106,7 @@ Error CompressedTextureLayered::_load_data(const String &p_path, Vector<Ref<Imag
uint32_t layer_count = f->get_32(); //layer count
uint32_t type = f->get_32(); //layer count
- ERR_FAIL_COND_V(type != layered_type, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V((int)type != layered_type, ERR_INVALID_DATA);
uint32_t df = f->get_32(); //data format
mipmap_limit = int(f->get_32());
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index da4b8046a5..4e529de8ee 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -769,15 +769,6 @@ public:
class GradientTexture1D : public Texture2D {
GDCLASS(GradientTexture1D, Texture2D);
-public:
- struct Point {
- float offset = 0.0;
- Color color;
- bool operator<(const Point &p_ponit) const {
- return offset < p_ponit.offset;
- }
- };
-
private:
Ref<Gradient> gradient;
bool update_pending = false;
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 9138a82ba8..ae83e2136f 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -1537,7 +1537,6 @@ Vector<Point2> TileSet::get_terrain_polygon(int p_terrain_set) {
}
return _get_half_offset_terrain_polygon(tile_size, overlap, tile_offset_axis);
}
- return Vector<Point2>();
}
Vector<Point2> TileSet::get_terrain_peering_bit_polygon(int p_terrain_set, TileSet::CellNeighbor p_bit) {
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index 35686b293c..e14081c681 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -50,16 +50,16 @@ public:
virtual void set_loop(bool p_enable) = 0;
virtual bool has_loop() const = 0;
- virtual float get_length() const = 0;
+ virtual double get_length() const = 0;
- virtual float get_playback_position() const = 0;
- virtual void seek(float p_time) = 0;
+ virtual double get_playback_position() const = 0;
+ virtual void seek(double p_time) = 0;
virtual void set_audio_track(int p_idx) = 0;
virtual Ref<Texture2D> get_texture() const = 0;
- virtual void update(float p_delta) = 0;
+ virtual void update(double p_delta) = 0;
virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata) = 0;
virtual int get_channels() const = 0;
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 4116eaa196..3aba550f03 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -90,11 +90,10 @@ public:
struct Varying {
String name;
- VaryingMode mode;
- VaryingType type;
+ VaryingMode mode = VARYING_MODE_MAX;
+ VaryingType type = VARYING_TYPE_MAX;
- Varying() {
- }
+ Varying() {}
Varying(String p_name, VaryingMode p_mode, VaryingType p_type) :
name(p_name), mode(p_mode), type(p_type) {}
diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp
index bdfbb59fa6..df6abe161e 100644
--- a/scene/resources/visual_shader_particle_nodes.cpp
+++ b/scene/resources/visual_shader_particle_nodes.cpp
@@ -1130,31 +1130,38 @@ VisualShaderNodeParticleAccelerator::VisualShaderNodeParticleAccelerator() {
// VisualShaderNodeParticleOutput
String VisualShaderNodeParticleOutput::get_caption() const {
- if (shader_type == VisualShader::TYPE_START) {
- return "StartOutput";
- } else if (shader_type == VisualShader::TYPE_PROCESS) {
- return "ProcessOutput";
- } else if (shader_type == VisualShader::TYPE_COLLIDE) {
- return "CollideOutput";
- } else if (shader_type == VisualShader::TYPE_START_CUSTOM) {
- return "CustomStartOutput";
- } else if (shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
- return "CustomProcessOutput";
+ switch (shader_type) {
+ case VisualShader::TYPE_START:
+ return "StartOutput";
+ case VisualShader::TYPE_PROCESS:
+ return "ProcessOutput";
+ case VisualShader::TYPE_COLLIDE:
+ return "CollideOutput";
+ case VisualShader::TYPE_START_CUSTOM:
+ return "CustomStartOutput";
+ case VisualShader::TYPE_PROCESS_CUSTOM:
+ return "CustomProcessOutput";
+ default:
+ ERR_PRINT(vformat("Unexpected shader_type %d for VisualShaderNodeParticleOutput.", shader_type));
+ return "";
}
- return String();
}
int VisualShaderNodeParticleOutput::get_input_port_count() const {
- if (shader_type == VisualShader::TYPE_START) {
- return 8;
- } else if (shader_type == VisualShader::TYPE_COLLIDE) {
- return 5;
- } else if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
- return 6;
- } else { // TYPE_PROCESS
- return 7;
+ switch (shader_type) {
+ case VisualShader::TYPE_START:
+ return 8;
+ case VisualShader::TYPE_PROCESS:
+ return 7;
+ case VisualShader::TYPE_COLLIDE:
+ return 5;
+ case VisualShader::TYPE_START_CUSTOM:
+ case VisualShader::TYPE_PROCESS_CUSTOM:
+ return 6;
+ default:
+ ERR_PRINT(vformat("Unexpected shader_type %d for VisualShaderNodeParticleOutput.", shader_type));
+ return 0;
}
- return 0;
}
VisualShaderNodeParticleOutput::PortType VisualShaderNodeParticleOutput::get_input_port_type(int p_port) const {