diff options
Diffstat (limited to 'scene')
68 files changed, 888 insertions, 900 deletions
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index bf5671be19..b6902686fe 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -176,7 +176,7 @@ Transform2D Camera2D::get_camera_transform() { Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom); - if (!limit_smoothing_enabled) { + if (!smoothing_enabled || !limit_smoothing_enabled) { if (screen_rect.position.x < limit[SIDE_LEFT]) { screen_rect.position.x = limit[SIDE_LEFT]; } diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 80c17b6e88..8d997bb1f5 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -890,7 +890,7 @@ void CPUParticles2D::_particles_process(double p_delta) { real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand); base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed)); p.rotation = Math::deg2rad(base_angle); //angle - p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + p.custom[1] * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); + p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + tv * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); } //apply color //apply hue rotation diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index f1f4d1b769..4384ec8141 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -170,6 +170,13 @@ void GPUParticles2D::set_trail_section_subdivisions(int p_subdivisions) { update(); } +#ifdef TOOLS_ENABLED +void GPUParticles2D::set_show_visibility_rect(bool p_show_visibility_rect) { + show_visibility_rect = p_show_visibility_rect; + update(); +} +#endif + bool GPUParticles2D::is_trail_enabled() const { return trail_enabled; } @@ -452,7 +459,7 @@ void GPUParticles2D::_notification(int p_what) { RS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid); #ifdef TOOLS_ENABLED - if (Engine::get_singleton()->is_editor_hint() && (this == get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->is_ancestor_of(this))) { + if (show_visibility_rect) { draw_rect(visibility_rect, Color(0, 0.7, 0.9, 0.4), false); } #endif @@ -588,6 +595,9 @@ GPUParticles2D::GPUParticles2D() { set_speed_scale(1); set_fixed_fps(30); set_collision_base_size(collision_base_size); +#ifdef TOOLS_ENABLED + show_visibility_rect = false; +#endif } GPUParticles2D::~GPUParticles2D() { diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index d7eee461b4..a9e66b3051 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -58,7 +58,9 @@ private: bool local_coords; int fixed_fps; bool fractional_delta; - +#ifdef TOOLS_ENABLED + bool show_visibility_rect; +#endif Ref<Material> process_material; DrawOrder draw_order; @@ -81,7 +83,6 @@ protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const override; void _notification(int p_what); - void _update_collision_size(); public: @@ -102,6 +103,10 @@ public: void set_trail_sections(int p_sections); void set_trail_section_subdivisions(int p_subdivisions); +#ifdef TOOLS_ENABLED + void set_show_visibility_rect(bool p_show_visibility_rect); +#endif + bool is_emitting() const; int get_amount() const; double get_lifetime() const; diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index ed30e871d7..40211f2a9b 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -100,16 +100,18 @@ void Path2D::_notification(int p_what) { #endif const Color color = Color(0.5, 0.6, 1.0, 0.7); - for (int i = 0; i < curve->get_point_count(); i++) { - Vector2 prev_p = curve->get_point_position(i); + _cached_draw_pts.resize(curve->get_point_count() * 8); + int count = 0; - for (int j = 1; j <= 8; j++) { - real_t frac = j / 8.0; + for (int i = 0; i < curve->get_point_count(); i++) { + for (int j = 0; j < 8; j++) { + real_t frac = j * (1.0 / 8.0); Vector2 p = curve->interpolate(i, frac); - draw_line(prev_p, p, color, line_width); - prev_p = p; + _cached_draw_pts.set(count++, p); } } + + draw_polyline(_cached_draw_pts, color, line_width, true); } } diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 3b12f025fc..7e8478283f 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -38,6 +38,7 @@ class Path2D : public Node2D { GDCLASS(Path2D, Node2D); Ref<Curve2D> curve; + Vector<Vector2> _cached_draw_pts; void _curve_changed(); diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index efe23c6102..bdcab49e4e 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -391,7 +391,13 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() { PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world_3d->get_space()); for (Camera3D *camera : cameras) { + if (!camera) { + continue; + } Viewport *vp = camera->get_viewport(); + if (!vp) { + continue; + } if (!vp->is_audio_listener_3d()) { continue; } diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index d347d24c2c..b081142fbf 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -881,53 +881,53 @@ void CPUParticles3D::_particles_process(double p_delta) { p.custom[1] = p.time / lifetime; tv = p.time / p.lifetime; - real_t tex_linear_velocity = 0.0; + real_t tex_linear_velocity = 1.0; if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv); } - real_t tex_orbit_velocity = 0.0; + real_t tex_orbit_velocity = 1.0; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv); } } - real_t tex_angular_velocity = 0.0; + real_t tex_angular_velocity = 1.0; if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) { tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv); } - real_t tex_linear_accel = 0.0; + real_t tex_linear_accel = 1.0; if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) { tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv); } - real_t tex_tangential_accel = 0.0; + real_t tex_tangential_accel = 1.0; if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) { tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv); } - real_t tex_radial_accel = 0.0; + real_t tex_radial_accel = 1.0; if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) { tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv); } - real_t tex_damping = 0.0; + real_t tex_damping = 1.0; if (curve_parameters[PARAM_DAMPING].is_valid()) { tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv); } - real_t tex_angle = 0.0; + real_t tex_angle = 1.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } - real_t tex_anim_speed = 0.0; + real_t tex_anim_speed = 1.0; if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) { tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv); } - real_t tex_anim_offset = 0.0; + real_t tex_anim_offset = 1.0; if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) { tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv); } @@ -984,7 +984,7 @@ void CPUParticles3D::_particles_process(double p_delta) { real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand); base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed)); p.custom[0] = Math::deg2rad(base_angle); //angle - p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + p.custom[1] * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); //angle + p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + tv * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); //angle } //apply color //apply hue rotation diff --git a/scene/3d/proximity_group_3d.cpp b/scene/3d/proximity_group_3d.cpp deleted file mode 100644 index 23df00c1f6..0000000000 --- a/scene/3d/proximity_group_3d.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/*************************************************************************/ -/* proximity_group_3d.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "proximity_group_3d.h" - -#include "core/math/math_funcs.h" - -void ProximityGroup3D::_clear_groups() { - Map<StringName, uint32_t>::Element *E; - const int size = 16; - - do { - StringName remove_list[size]; - E = groups.front(); - int num = 0; - while (E && num < size) { - if (E->get() != group_version) { - remove_list[num++] = E->key(); - } - - E = E->next(); - } - for (int i = 0; i < num; i++) { - groups.erase(remove_list[i]); - } - } while (E); -} - -void ProximityGroup3D::_update_groups() { - if (grid_radius == Vector3(0, 0, 0)) { - return; - } - - ++group_version; - - Vector3 pos = get_global_transform().get_origin(); - Vector3 vcell = pos / cell_size; - int cell[3] = { Math::fast_ftoi(vcell.x), Math::fast_ftoi(vcell.y), Math::fast_ftoi(vcell.z) }; - - _add_groups(cell, group_name, 0); - - _clear_groups(); -} - -void ProximityGroup3D::_add_groups(int *p_cell, String p_base, int p_depth) { - p_base = p_base + "|"; - if (grid_radius[p_depth] == 0) { - if (p_depth == 2) { - _new_group(p_base); - } else { - _add_groups(p_cell, p_base, p_depth + 1); - } - } - - int start = p_cell[p_depth] - grid_radius[p_depth]; - int end = p_cell[p_depth] + grid_radius[p_depth]; - - for (int i = start; i <= end; i++) { - String gname = p_base + itos(i); - if (p_depth == 2) { - _new_group(gname); - } else { - _add_groups(p_cell, gname, p_depth + 1); - } - } -} - -void ProximityGroup3D::_new_group(StringName p_name) { - const Map<StringName, uint32_t>::Element *E = groups.find(p_name); - if (!E) { - add_to_group(p_name); - } - - groups[p_name] = group_version; -} - -void ProximityGroup3D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_EXIT_TREE: - ++group_version; - _clear_groups(); - break; - case NOTIFICATION_TRANSFORM_CHANGED: - _update_groups(); - break; - } -} - -void ProximityGroup3D::broadcast(String p_method, Variant p_parameters) { - Map<StringName, uint32_t>::Element *E; - E = groups.front(); - while (E) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFAULT, E->key(), "_proximity_group_broadcast", p_method, p_parameters); - E = E->next(); - } -} - -void ProximityGroup3D::_proximity_group_broadcast(String p_method, Variant p_parameters) { - if (dispatch_mode == MODE_PROXY) { - ERR_FAIL_COND(!is_inside_tree()); - get_parent()->call(p_method, p_parameters); - } else { - emit_signal(SNAME("broadcast"), p_method, p_parameters); - } -} - -void ProximityGroup3D::set_group_name(const String &p_group_name) { - group_name = p_group_name; -} - -String ProximityGroup3D::get_group_name() const { - return group_name; -} - -void ProximityGroup3D::set_dispatch_mode(DispatchMode p_mode) { - dispatch_mode = p_mode; -} - -ProximityGroup3D::DispatchMode ProximityGroup3D::get_dispatch_mode() const { - return dispatch_mode; -} - -void ProximityGroup3D::set_grid_radius(const Vector3 &p_radius) { - grid_radius = p_radius; -} - -Vector3 ProximityGroup3D::get_grid_radius() const { - return grid_radius; -} - -void ProximityGroup3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_group_name", "name"), &ProximityGroup3D::set_group_name); - ClassDB::bind_method(D_METHOD("get_group_name"), &ProximityGroup3D::get_group_name); - ClassDB::bind_method(D_METHOD("set_dispatch_mode", "mode"), &ProximityGroup3D::set_dispatch_mode); - ClassDB::bind_method(D_METHOD("get_dispatch_mode"), &ProximityGroup3D::get_dispatch_mode); - ClassDB::bind_method(D_METHOD("set_grid_radius", "radius"), &ProximityGroup3D::set_grid_radius); - ClassDB::bind_method(D_METHOD("get_grid_radius"), &ProximityGroup3D::get_grid_radius); - - ClassDB::bind_method(D_METHOD("broadcast", "method", "parameters"), &ProximityGroup3D::broadcast); - - ClassDB::bind_method(D_METHOD("_proximity_group_broadcast", "method", "parameters"), &ProximityGroup3D::_proximity_group_broadcast); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "group_name"), "set_group_name", "get_group_name"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dispatch_mode", PROPERTY_HINT_ENUM, "Proxy,Signal"), "set_dispatch_mode", "get_dispatch_mode"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "grid_radius"), "set_grid_radius", "get_grid_radius"); - - ADD_SIGNAL(MethodInfo("broadcast", PropertyInfo(Variant::STRING, "method"), PropertyInfo(Variant::ARRAY, "parameters"))); - - BIND_ENUM_CONSTANT(MODE_PROXY); - BIND_ENUM_CONSTANT(MODE_SIGNAL); -} - -ProximityGroup3D::ProximityGroup3D() { - set_notify_transform(true); -} diff --git a/scene/3d/proximity_group_3d.h b/scene/3d/proximity_group_3d.h deleted file mode 100644 index e45adc3040..0000000000 --- a/scene/3d/proximity_group_3d.h +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************/ -/* proximity_group_3d.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef PROXIMITY_GROUP_H -#define PROXIMITY_GROUP_H - -#include "node_3d.h" - -class ProximityGroup3D : public Node3D { - GDCLASS(ProximityGroup3D, Node3D); - -public: - enum DispatchMode { - MODE_PROXY, - MODE_SIGNAL, - }; - -private: - Map<StringName, uint32_t> groups; - - String group_name; - DispatchMode dispatch_mode = MODE_PROXY; - Vector3 grid_radius = Vector3(1, 1, 1); - - real_t cell_size = 1.0; - uint32_t group_version = 0; - - void _clear_groups(); - void _update_groups(); - void _add_groups(int *p_cell, String p_base, int p_depth); - void _new_group(StringName p_name); - - void _proximity_group_broadcast(String p_method, Variant p_parameters); - -protected: - void _notification(int p_what); - - static void _bind_methods(); - -public: - void set_group_name(const String &p_group_name); - String get_group_name() const; - - void set_dispatch_mode(DispatchMode p_mode); - DispatchMode get_dispatch_mode() const; - - void set_grid_radius(const Vector3 &p_radius); - Vector3 get_grid_radius() const; - - void broadcast(String p_method, Variant p_parameters); - - ProximityGroup3D(); - ~ProximityGroup3D() {} -}; - -VARIANT_ENUM_CAST(ProximityGroup3D::DispatchMode); - -#endif // PROXIMITY_GROUP_H diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index 5546b88fb1..d9907430fc 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -100,12 +100,11 @@ SoftDynamicBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) { offset = obj_tocopy.offset; } -SoftDynamicBody3D::PinnedPoint &SoftDynamicBody3D::PinnedPoint::operator=(const PinnedPoint &obj) { +void SoftDynamicBody3D::PinnedPoint::operator=(const PinnedPoint &obj) { point_index = obj.point_index; spatial_attachment_path = obj.spatial_attachment_path; spatial_attachment = obj.spatial_attachment; offset = obj.offset; - return *this; } void SoftDynamicBody3D::_update_pickable() { diff --git a/scene/3d/soft_dynamic_body_3d.h b/scene/3d/soft_dynamic_body_3d.h index 57e116aa05..daef9acac0 100644 --- a/scene/3d/soft_dynamic_body_3d.h +++ b/scene/3d/soft_dynamic_body_3d.h @@ -80,7 +80,7 @@ public: PinnedPoint(); PinnedPoint(const PinnedPoint &obj_tocopy); - PinnedPoint &operator=(const PinnedPoint &obj); + void operator=(const PinnedPoint &obj); }; private: diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 90af70e7c2..197a5c0f27 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -625,6 +625,7 @@ void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) { texture->connect(CoreStringNames::get_singleton()->changed, Callable(this, "_queue_update")); } _queue_update(); + emit_signal(SceneStringNames::get_singleton()->texture_changed); } Ref<Texture2D> Sprite3D::get_texture() const { @@ -780,6 +781,7 @@ void Sprite3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); ADD_SIGNAL(MethodInfo("frame_changed")); + ADD_SIGNAL(MethodInfo("texture_changed")); } Sprite3D::Sprite3D() { diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index 26fa43b969..4eeb987dde 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -133,8 +133,8 @@ Ref<CameraEffects> WorldEnvironment::get_camera_effects() const { TypedArray<String> WorldEnvironment::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); - if (!environment.is_valid()) { - warnings.push_back(TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect.")); + if (!environment.is_valid() && !camera_effects.is_valid()) { + warnings.push_back(TTR("To have any visible effect, WorldEnvironment requires its \"Environment\" property to contain an Environment, its \"Camera Effects\" property to contain a CameraEffects resource, or both.")); } if (!is_inside_tree()) { diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 93339711bd..b9435b6692 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -1754,7 +1754,7 @@ Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_o Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { ERR_FAIL_COND_V(!can_apply_reset(), Ref<AnimatedValuesBackup>()); - Ref<Animation> reset_anim = animation_set["RESET"].animation; + Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation; ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>()); Node *root_node = get_node_or_null(root); @@ -1762,8 +1762,8 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { AnimationPlayer *aux_player = memnew(AnimationPlayer); EditorNode::get_singleton()->add_child(aux_player); - aux_player->add_animation("RESET", reset_anim); - aux_player->set_assigned_animation("RESET"); + aux_player->add_animation(SceneStringNames::get_singleton()->RESET, reset_anim); + aux_player->set_assigned_animation(SceneStringNames::get_singleton()->RESET); // Forcing the use of the original root because the scene where original player belongs may be not the active one Node *root = get_node(get_root()); Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(root); @@ -1785,7 +1785,7 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { } bool AnimationPlayer::can_apply_reset() const { - return has_animation("RESET") && playback.assigned != StringName("RESET"); + return has_animation(SceneStringNames::get_singleton()->RESET) && playback.assigned != SceneStringNames::get_singleton()->RESET; } #endif diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index ea04918988..1b07c086c0 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -198,7 +198,7 @@ private: struct PlaybackData { AnimationData *from = nullptr; - float pos = 0.0; + double pos = 0.0; float speed_scale = 1.0; }; diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index 3c8949ddfb..56c04b32e3 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -367,7 +367,7 @@ void SceneDebuggerObject::serialize(Array &r_arr, int p_max_size) { PropertyHint hint = pi.hint; String hint_string = pi.hint_string; - if (!res.is_null()) { + if (!res.is_null() && !res->get_path().is_empty()) { var = res->get_path(); } else { //only send information that can be sent.. int len = 0; //test how big is this to encode diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index cb9f13e970..83c392614b 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -295,7 +295,7 @@ void BoxContainer::_notification(int p_what) { _resort(); } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); } break; case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 9818c8f0cc..2932707401 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -82,13 +82,13 @@ void Button::_notification(int p_what) { xl_text = atr(text); _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_THEME_CHANGED: { _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_DRAW: { @@ -368,7 +368,7 @@ void Button::set_text(const String &p_text) { _shape(); update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -428,7 +428,7 @@ void Button::set_icon(const Ref<Texture2D> &p_icon) { if (icon != p_icon) { icon = p_icon; update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -440,7 +440,7 @@ void Button::set_expand_icon(bool p_enabled) { if (expand_icon != p_enabled) { expand_icon = p_enabled; update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -463,7 +463,7 @@ void Button::set_clip_text(bool p_enabled) { if (clip_text != p_enabled) { clip_text = p_enabled; update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -484,7 +484,7 @@ Button::TextAlign Button::get_text_align() const { void Button::set_icon_align(TextAlign p_align) { icon_align = p_align; - minimum_size_changed(); + update_minimum_size(); update(); } diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp index 909516e7ef..e17552006f 100644 --- a/scene/gui/center_container.cpp +++ b/scene/gui/center_container.cpp @@ -61,7 +61,7 @@ void CenterContainer::set_use_top_left(bool p_enable) { use_top_left = p_enable; - minimum_size_changed(); + update_minimum_size(); queue_sort(); } diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index a1bd82f6f7..81afa53d85 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -35,7 +35,7 @@ void Container::_child_minsize_changed() { //Size2 ms = get_combined_minimum_size(); //if (ms.width > get_size().width || ms.height > get_size().height) { - minimum_size_changed(); + update_minimum_size(); queue_sort(); } @@ -51,7 +51,7 @@ void Container::add_child_notify(Node *p_child) { control->connect(SNAME("minimum_size_changed"), callable_mp(this, &Container::_child_minsize_changed)); control->connect(SNAME("visibility_changed"), callable_mp(this, &Container::_child_minsize_changed)); - minimum_size_changed(); + update_minimum_size(); queue_sort(); } @@ -62,7 +62,7 @@ void Container::move_child_notify(Node *p_child) { return; } - minimum_size_changed(); + update_minimum_size(); queue_sort(); } @@ -78,7 +78,7 @@ void Container::remove_child_notify(Node *p_child) { control->disconnect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed)); control->disconnect("visibility_changed", callable_mp(this, &Container::_child_minsize_changed)); - minimum_size_changed(); + update_minimum_size(); queue_sort(); } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 9f715be155..fd6fb48412 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -192,7 +192,7 @@ void Control::set_custom_minimum_size(const Size2 &p_custom) { return; } data.custom_minimum_size = p_custom; - minimum_size_changed(); + update_minimum_size(); } Size2 Control::get_custom_minimum_size() const { @@ -213,7 +213,7 @@ void Control::_update_minimum_size_cache() { data.minimum_size_valid = true; if (size_changed) { - minimum_size_changed(); + update_minimum_size(); } } @@ -713,7 +713,7 @@ void Control::_notification(int p_notification) { update(); } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -2534,7 +2534,7 @@ void Control::grab_click_focus() { get_viewport()->_gui_grab_click_focus(this); } -void Control::minimum_size_changed() { +void Control::update_minimum_size() { if (!is_inside_tree() || data.block_minimum_size_adjust) { return; } @@ -2590,7 +2590,7 @@ Control *Control::get_focus_owner() const { void Control::warp_mouse(const Point2 &p_to_pos) { ERR_FAIL_COND(!is_inside_tree()); - get_viewport()->warp_mouse(get_global_transform().xform(p_to_pos)); + get_viewport()->warp_mouse(get_screen_transform().xform(p_to_pos)); } bool Control::is_text_field() const { @@ -2696,7 +2696,7 @@ real_t Control::get_rotation() const { void Control::_override_changed() { notification(NOTIFICATION_THEME_CHANGED); emit_signal(SceneStringNames::get_singleton()->theme_changed); - minimum_size_changed(); // overrides are likely to affect minimum size + update_minimum_size(); // Overrides are likely to affect minimum size. } void Control::set_pivot_offset(const Vector2 &p_pivot) { @@ -2977,7 +2977,7 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("warp_mouse", "to_position"), &Control::warp_mouse); - ClassDB::bind_method(D_METHOD("minimum_size_changed"), &Control::minimum_size_changed); + ClassDB::bind_method(D_METHOD("update_minimum_size"), &Control::update_minimum_size); ClassDB::bind_method(D_METHOD("set_layout_direction", "direction"), &Control::set_layout_direction); ClassDB::bind_method(D_METHOD("get_layout_direction"), &Control::get_layout_direction); diff --git a/scene/gui/control.h b/scene/gui/control.h index 1a94cc68a6..4cc949d0a8 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -441,7 +441,7 @@ public: void set_stretch_ratio(real_t p_ratio); real_t get_stretch_ratio() const; - void minimum_size_changed(); + void update_minimum_size(); /* FOCUS */ diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 44853fc006..e3754c4d38 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -473,6 +473,13 @@ void FileDialog::update_file_list() { dir_access->list_dir_begin(); + if (dir_access->is_readable(dir_access->get_current_dir().utf8().get_data())) { + message->hide(); + } else { + message->set_text(TTRC("You don't have permission to access contents of this folder.")); + message->show(); + } + TreeItem *root = tree->create_item(); Ref<Texture2D> folder = vbox->get_theme_icon(SNAME("folder"), SNAME("FileDialog")); Ref<Texture2D> file_icon = vbox->get_theme_icon(SNAME("file"), SNAME("FileDialog")); @@ -482,17 +489,11 @@ void FileDialog::update_file_list() { List<String> dirs; bool is_hidden; - String item; - - if (dir_access->is_readable(dir_access->get_current_dir().utf8().get_data())) { - message->hide(); - } else { - message->set_text(TTRC("You don't have permission to access contents of this folder.")); - message->show(); - } + String item = dir_access->get_next(); - while ((item = dir_access->get_next()) != "") { + while (!item.is_empty()) { if (item == "." || item == "..") { + item = dir_access->get_next(); continue; } @@ -505,6 +506,7 @@ void FileDialog::update_file_list() { dirs.push_back(item); } } + item = dir_access->get_next(); } dirs.sort_custom<NaturalNoCaseComparator>(); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index e7d98a686f..b0050f028b 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1166,7 +1166,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { top_layer->update(); minimap->update(); } else { - emit_signal(SNAME("popup_request"), b->get_global_position()); + emit_signal(SNAME("popup_request"), get_screen_position() + b->get_position()); } } } diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index e7094c89b1..3177911a70 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -442,7 +442,7 @@ void GraphNode::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; } @@ -666,7 +666,7 @@ void GraphNode::set_title(const String &p_title) { _shape(); update(); - minimum_size_changed(); + update_minimum_size(); } String GraphNode::get_title() const { diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 2beb2624d2..624330cdf6 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -182,7 +182,7 @@ void GridContainer::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); } break; case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { @@ -195,7 +195,7 @@ void GridContainer::set_columns(int p_columns) { ERR_FAIL_COND(p_columns < 1); columns = p_columns; queue_sort(); - minimum_size_changed(); + update_minimum_size(); } int GridContainer::get_columns() const { diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 408ef53e89..857058f94e 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -1037,7 +1037,7 @@ void ItemList::_notification(int p_what) { } } - minimum_size_changed(); + update_minimum_size(); shape_changed = false; } @@ -1663,7 +1663,7 @@ void ItemList::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "max_text_lines", PROPERTY_HINT_RANGE, "1,10,1,or_greater"), "set_max_text_lines", "get_max_text_lines"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_height"), "set_auto_height", "has_auto_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior"); - ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "item_"); + ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_"); ADD_GROUP("Columns", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_columns", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), "set_max_columns", "get_max_columns"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "same_column_width"), "set_same_column_width", "is_same_column_width"); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 50908f6a77..3e1b9c9ceb 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -44,7 +44,7 @@ void Label::set_autowrap_mode(Label::AutowrapMode p_mode) { update(); if (clip || overrun_behavior != OVERRUN_NO_TRIMMING) { - minimum_size_changed(); + update_minimum_size(); } } @@ -207,7 +207,7 @@ void Label::_shape() { _update_visible(); if (autowrap_mode == AUTOWRAP_OFF || !clip || overrun_behavior == OVERRUN_NO_TRIMMING) { - minimum_size_changed(); + update_minimum_size(); } } @@ -592,7 +592,7 @@ void Label::set_text(const String &p_string) { visible_chars = get_total_character_count() * percent_visible; } update(); - minimum_size_changed(); + update_minimum_size(); } void Label::set_text_direction(Control::TextDirection p_text_direction) { @@ -668,7 +668,7 @@ String Label::get_language() const { void Label::set_clip_text(bool p_clip) { clip = p_clip; update(); - minimum_size_changed(); + update_minimum_size(); } bool Label::is_clipping_text() const { @@ -682,7 +682,7 @@ void Label::set_text_overrun_behavior(Label::OverrunBehavior p_behavior) { } update(); if (clip || overrun_behavior != OVERRUN_NO_TRIMMING) { - minimum_size_changed(); + update_minimum_size(); } } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 69b08fda3c..80f723de62 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -227,7 +227,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { } if (b->is_pressed() && b->get_button_index() == MouseButton::RIGHT && context_menu_enabled) { _ensure_menu(); - menu->set_position(get_screen_transform().xform(get_local_mouse_position())); + menu->set_position(get_screen_position() + get_local_mouse_position()); menu->reset_size(); menu->popup(); grab_focus(); @@ -322,7 +322,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { deselect(); selection.start_column = caret_column; selection.creating = true; - } else if (selection.enabled) { + } else if (selection.enabled && !selection.double_click) { selection.drag_attempt = true; } } @@ -392,7 +392,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { if (k->is_action("ui_menu", true)) { _ensure_menu(); Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + get_theme_font(SNAME("font"))->get_height(get_theme_font_size(SNAME("font_size")))) / 2); - menu->set_position(get_global_transform().xform(pos)); + menu->set_position(get_screen_position() + pos); menu->reset_size(); menu->popup(); menu->grab_focus(); @@ -588,13 +588,19 @@ void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) { if (p_data.get_type() == Variant::STRING && is_editable()) { set_caret_at_pixel_pos(p_point.x); int caret_column_tmp = caret_column; + bool is_inside_sel = selection.enabled && caret_column >= selection.begin && caret_column <= selection.end; + if (Input::get_singleton()->is_key_pressed(Key::CTRL)) { + is_inside_sel = selection.enabled && caret_column > selection.begin && caret_column < selection.end; + } if (selection.drag_attempt) { selection.drag_attempt = false; - if (caret_column < selection.begin || caret_column > selection.end) { - if (caret_column_tmp > selection.end) { - caret_column_tmp = caret_column_tmp - (selection.end - selection.begin); + if (!is_inside_sel) { + if (!Input::get_singleton()->is_key_pressed(Key::CTRL)) { + if (caret_column_tmp > selection.end) { + caret_column_tmp = caret_column_tmp - (selection.end - selection.begin); + } + selection_delete(); } - selection_delete(); set_caret_column(caret_column_tmp); insert_text_at_caret(p_data); @@ -975,7 +981,7 @@ void LineEdit::_notification(int p_what) { if (is_drag_successful()) { if (selection.drag_attempt) { selection.drag_attempt = false; - if (is_editable()) { + if (is_editable() && !Input::get_singleton()->is_key_pressed(Key::CTRL)) { selection_delete(); } else if (deselect_on_focus_loss_enabled) { deselect(); @@ -1712,7 +1718,7 @@ void LineEdit::set_editable(bool p_editable) { editable = p_editable; - minimum_size_changed(); + update_minimum_size(); update(); } @@ -1942,7 +1948,7 @@ void LineEdit::_editor_settings_changed() { void LineEdit::set_expand_to_text_length_enabled(bool p_enabled) { expand_to_text_length = p_enabled; - minimum_size_changed(); + update_minimum_size(); set_caret_column(caret_column); } @@ -1956,7 +1962,7 @@ void LineEdit::set_clear_button_enabled(bool p_enabled) { } clear_button_enabled = p_enabled; _fit_to_width(); - minimum_size_changed(); + update_minimum_size(); update(); } @@ -2017,7 +2023,7 @@ void LineEdit::set_right_icon(const Ref<Texture2D> &p_icon) { } right_icon = p_icon; _fit_to_width(); - minimum_size_changed(); + update_minimum_size(); update(); } @@ -2081,7 +2087,7 @@ void LineEdit::_shape() { Size2 size = TS->shaped_text_get_size(text_rid); if ((expand_to_text_length && old_size.x != size.x) || (old_size.y != size.y)) { - minimum_size_changed(); + update_minimum_size(); } } diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index c3201186ea..9856247b7c 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -52,7 +52,7 @@ void LinkButton::set_text(const String &p_text) { text = p_text; xl_text = atr(text); _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } @@ -149,7 +149,7 @@ void LinkButton::_notification(int p_what) { xl_text = atr(text); _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { @@ -157,7 +157,7 @@ void LinkButton::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { _shape(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_DRAW: { diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp index 50b4d192a9..af239d67ae 100644 --- a/scene/gui/margin_container.cpp +++ b/scene/gui/margin_container.cpp @@ -90,7 +90,7 @@ void MarginContainer::_notification(int p_what) { } } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); } break; } } diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 39c7b04955..32501b65a0 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -207,7 +207,7 @@ void MenuButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_count"), &MenuButton::get_item_count); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "switch_on_hover"), "set_switch_on_hover", "is_switch_on_hover"); - ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "popup/item_"); + ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "popup/item_"); ADD_SIGNAL(MethodInfo("about_to_popup")); } diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp index 8bf25ac915..ea5c82306d 100644 --- a/scene/gui/nine_patch_rect.cpp +++ b/scene/gui/nine_patch_rect.cpp @@ -97,7 +97,7 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) { if (texture.is_valid()) texture->set_flags(texture->get_flags()&(~Texture::FLAG_REPEAT)); //remove repeat from texture, it looks bad in sprites */ - minimum_size_changed(); + update_minimum_size(); emit_signal(SceneStringNames::get_singleton()->texture_changed); } @@ -109,7 +109,7 @@ void NinePatchRect::set_patch_margin(Side p_side, int p_size) { ERR_FAIL_INDEX((int)p_side, 4); margin[p_side] = p_size; update(); - minimum_size_changed(); + update_minimum_size(); } int NinePatchRect::get_patch_margin(Side p_side) const { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 2e854abb76..d2062a66f9 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -216,7 +216,7 @@ void PopupMenu::_activate_submenu(int p_over) { submenu_pos.x = this_pos.x + submenu_size.width; } - if (submenu_pos.x + submenu_size.width > get_parent_rect().size.width) { + if (submenu_pos.x + submenu_size.width > get_parent_rect().position.x + get_parent_rect().size.width) { submenu_pos.x = this_pos.x - submenu_size.width; } @@ -1762,7 +1762,7 @@ void PopupMenu::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "submenu_popup_delay"), "set_submenu_popup_delay", "get_submenu_popup_delay"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_search"), "set_allow_search", "get_allow_search"); - ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "item_"); + ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "item_"); ADD_SIGNAL(MethodInfo("id_pressed", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("id_focused", PropertyInfo(Variant::INT, "id"))); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index fd19fad667..2cb6ef91b5 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -2190,7 +2190,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { updating_scroll = false; if (fit_content_height) { - minimum_size_changed(); + update_minimum_size(); } return; } @@ -2227,7 +2227,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { updating_scroll = false; if (fit_content_height) { - minimum_size_changed(); + update_minimum_size(); } } @@ -2324,7 +2324,7 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) _invalidate_current_line(current_frame); if (fixed_width != -1) { - minimum_size_changed(); + update_minimum_size(); } } @@ -2755,7 +2755,7 @@ void RichTextLabel::clear() { } if (fixed_width != -1) { - minimum_size_changed(); + update_minimum_size(); } } @@ -2772,7 +2772,7 @@ int RichTextLabel::get_tab_size() const { void RichTextLabel::set_fit_content_height(bool p_enabled) { if (p_enabled != fit_content_height) { fit_content_height = p_enabled; - minimum_size_changed(); + update_minimum_size(); } } @@ -4268,7 +4268,7 @@ int RichTextLabel::get_total_character_count() const { void RichTextLabel::set_fixed_size_to_width(int p_width) { fixed_width = p_width; - minimum_size_changed(); + update_minimum_size(); } Size2 RichTextLabel::get_minimum_size() const { diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 7b2ea46e17..f89623630d 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -467,7 +467,7 @@ void ScrollContainer::set_enable_h_scroll(bool p_enable) { } scroll_h = p_enable; - minimum_size_changed(); + update_minimum_size(); queue_sort(); } @@ -481,7 +481,7 @@ void ScrollContainer::set_enable_v_scroll(bool p_enable) { } scroll_v = p_enable; - minimum_size_changed(); + update_minimum_size(); queue_sort(); } diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index 9f4ec558dc..9c87d07f66 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -68,7 +68,6 @@ class ScrollContainer : public Container { protected: Size2 get_minimum_size() const override; - virtual void gui_input(const Ref<InputEvent> &p_gui_input) override; void _gui_focus_changed(Control *p_control); void _update_dimensions(); void _notification(int p_what); @@ -80,6 +79,8 @@ protected: void _update_scrollbar_position(); public: + virtual void gui_input(const Ref<InputEvent> &p_gui_input) override; + void set_h_scroll(int p_pos); int get_h_scroll() const; diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index 4cc425aad3..f8cabe172c 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -142,7 +142,7 @@ void Slider::gui_input(const Ref<InputEvent> &p_event) { void Slider::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_MOUSE_ENTER: { diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index f30206c943..94a4886fef 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -220,8 +220,8 @@ void SpinBox::_notification(int p_what) { } else if (p_what == NOTIFICATION_TRANSLATION_CHANGED) { _value_changed(0); } else if (p_what == NOTIFICATION_THEME_CHANGED) { - call_deferred(SNAME("minimum_size_changed")); - get_line_edit()->call_deferred(SNAME("minimum_size_changed")); + call_deferred(SNAME("update_minimum_size")); + get_line_edit()->call_deferred(SNAME("update_minimum_size")); } else if (p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) { update(); } diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index 6b53c0220e..106bb7949f 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -201,7 +201,7 @@ void SplitContainer::_notification(int p_what) { } } break; case NOTIFICATION_THEME_CHANGED: { - minimum_size_changed(); + update_minimum_size(); } break; } } diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index 57ee7fd494..da23b0dde8 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -164,7 +164,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { if (rb_hover != -1) { - // pressed + // Right mouse button clicked. emit_signal(SNAME("tab_rmb_clicked"), rb_hover); } @@ -174,7 +174,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { if (cb_pressing && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { if (cb_hover != -1) { - // pressed + // Close button pressed. emit_signal(SNAME("tab_close_pressed"), cb_hover); } @@ -183,7 +183,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { } if (mb->is_pressed() && (mb->get_button_index() == MouseButton::LEFT || (select_with_rmb && mb->get_button_index() == MouseButton::RIGHT))) { - // clicks + // Clicks. Point2 pos = mb->get_position(); if (buttons_visible) { @@ -235,7 +235,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) { return; } - if (tabs[i].cb_rect.has_point(pos)) { + if (tabs[i].cb_rect.has_point(pos) && (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current))) { cb_pressing = true; update(); return; @@ -285,7 +285,7 @@ void TabBar::_notification(int p_what) { _shape(i); } _update_cache(); - minimum_size_changed(); + update_minimum_size(); update(); } break; case NOTIFICATION_RESIZED: { @@ -554,7 +554,7 @@ void TabBar::set_tab_title(int p_tab, const String &p_title) { tabs.write[p_tab].text = p_title; _shape(p_tab); update(); - minimum_size_changed(); + update_minimum_size(); } String TabBar::get_tab_title(int p_tab) const { @@ -621,7 +621,7 @@ void TabBar::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].icon = p_icon; update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TabBar::get_tab_icon(int p_tab) const { @@ -645,7 +645,7 @@ void TabBar::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_butto tabs.write[p_tab].right_button = p_right_button; _update_cache(); update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TabBar::get_tab_right_button(int p_tab) const { @@ -659,7 +659,7 @@ void TabBar::_update_hover() { } const Point2 &pos = get_local_mouse_position(); - // test hovering to display right or close button + // test hovering to display right or close button. int hover_now = -1; int hover_buttons = -1; for (int i = offset; i < tabs.size(); i++) { @@ -684,7 +684,7 @@ void TabBar::_update_hover() { emit_signal(SNAME("tab_hovered"), hover); } - if (hover_buttons == -1) { // no hover + if (hover_buttons == -1) { // No hover. rb_hover = hover_buttons; cb_hover = hover_buttons; } @@ -777,7 +777,7 @@ void TabBar::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) { _update_cache(); call_deferred(SNAME("_update_hover")); update(); - minimum_size_changed(); + update_minimum_size(); } void TabBar::clear_tabs() { @@ -797,7 +797,7 @@ void TabBar::remove_tab(int p_idx) { _update_cache(); call_deferred(SNAME("_update_hover")); update(); - minimum_size_changed(); + update_minimum_size(); if (current < 0) { current = 0; @@ -860,7 +860,7 @@ bool TabBar::can_drop_data(const Point2 &p_point, const Variant &p_data) const { if (from_path == to_path) { return true; } else if (get_tabs_rearrange_group() != -1) { - // drag and drop between other TabBars + // Drag and drop between other TabBars. Node *from_node = get_node(from_path); TabBar *from_tabs = Object::cast_to<TabBar>(from_node); if (from_tabs && from_tabs->get_tabs_rearrange_group() == get_tabs_rearrange_group()) { @@ -895,7 +895,7 @@ void TabBar::drop_data(const Point2 &p_point, const Variant &p_data) { emit_signal(SNAME("active_tab_rearranged"), hover_now); set_current_tab(hover_now); } else if (get_tabs_rearrange_group() != -1) { - // drag and drop between Tabs + // Drag and drop between Tabs. Node *from_node = get_node(from_path); TabBar *from_tabs = Object::cast_to<TabBar>(from_node); if (from_tabs && from_tabs->get_tabs_rearrange_group() == get_tabs_rearrange_group()) { @@ -945,7 +945,7 @@ void TabBar::set_clip_tabs(bool p_clip_tabs) { } clip_tabs = p_clip_tabs; update(); - minimum_size_changed(); + update_minimum_size(); } bool TabBar::get_clip_tabs() const { diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index ff53d91ea3..562f523f53 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -600,7 +600,7 @@ void TabContainer::_on_theme_changed() { _refresh_texts(); - minimum_size_changed(); + update_minimum_size(); if (get_tab_count() > 0) { _repaint(); update(); @@ -995,7 +995,7 @@ void TabContainer::set_tabs_visible(bool p_visible) { } update(); - minimum_size_changed(); + update_minimum_size(); } bool TabContainer::are_tabs_visible() const { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 2cb9d10fca..c54b4dda00 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -39,6 +39,7 @@ #include "core/os/os.h" #include "core/string/string_builder.h" #include "core/string/translation.h" +#include "label.h" #include "scene/main/window.h" @@ -1055,7 +1056,7 @@ void TextEdit::_notification(int p_what) { while (highlighted_word_col != -1) { Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_word_col + start, highlighted_word_col + lookup_symbol_word.length() + start); for (int j = 0; j < sel.size(); j++) { - Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, row_height); + Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y + (line_spacing / 2), sel[j].y - sel[j].x, row_height); if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) { continue; } @@ -1065,9 +1066,9 @@ void TextEdit::_notification(int p_what) { } else if (rect.position.x + rect.size.x > xmargin_end) { rect.size.x = xmargin_end - rect.position.x; } - rect.position.y = TS->shaped_text_get_ascent(rid) + font->get_underline_position(font_size); - rect.size.y = font->get_underline_thickness(font_size); - draw_rect(rect, font_selected_color); + rect.position.y += ceil(TS->shaped_text_get_ascent(rid)) + ceil(font->get_underline_position(font_size)); + rect.size.y = MAX(1, font->get_underline_thickness(font_size)); + draw_rect(rect, color); } highlighted_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_word_col + 1); @@ -1224,7 +1225,7 @@ void TextEdit::_notification(int p_what) { if (caret.draw_pos.x >= xmargin_beg && caret.draw_pos.x < xmargin_end) { caret.visible = true; - if (draw_caret) { + if (draw_caret || drag_caret_force_displayed) { if (caret_type == CaretType::CARET_TYPE_BLOCK || overtype_mode) { //Block or underline caret, draw trailing carets at full height. int h = font->get_height(font_size); @@ -1391,7 +1392,7 @@ void TextEdit::_notification(int p_what) { DisplayServer::get_singleton()->virtual_keyboard_hide(); } - if (deselect_on_focus_loss_enabled) { + if (deselect_on_focus_loss_enabled && !selection.drag_attempt) { deselect(); } } break; @@ -1411,6 +1412,30 @@ void TextEdit::_notification(int p_what) { update(); } } break; + case Control::NOTIFICATION_DRAG_BEGIN: { + selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE; + drag_action = true; + dragging_minimap = false; + dragging_selection = false; + can_drag_minimap = false; + click_select_held->stop(); + } break; + case Control::NOTIFICATION_DRAG_END: { + if (is_drag_successful()) { + if (selection.drag_attempt) { + selection.drag_attempt = false; + if (is_editable() && !Input::get_singleton()->is_key_pressed(Key::CTRL)) { + delete_selection(); + } else if (deselect_on_focus_loss_enabled) { + deselect(); + } + } + } else { + selection.drag_attempt = false; + } + drag_action = false; + drag_caret_force_displayed = false; + } break; } } @@ -1495,6 +1520,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { set_caret_line(row, false, false); set_caret_column(col); + selection.drag_attempt = false; if (mb->is_shift_pressed() && (caret.column != prev_col || caret.line != prev_line)) { if (!selection.active) { @@ -1538,6 +1564,9 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { update(); } + } else if (is_mouse_over_selection()) { + selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE; + selection.drag_attempt = true; } else { selection.active = false; selection.selecting_mode = SelectionMode::SELECTION_MODE_POINTER; @@ -1551,6 +1580,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { if (!mb->is_double_click() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < triple_click_timeout && mb->get_position().distance_to(last_dblclk_pos) < triple_click_tolerance) { // Triple-click select line. selection.selecting_mode = SelectionMode::SELECTION_MODE_LINE; + selection.drag_attempt = false; _update_selection_mode_line(); last_dblclk = 0; } else if (mb->is_double_click() && text[caret.line].length()) { @@ -1594,17 +1624,23 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } _generate_context_menu(); - menu->set_position(get_screen_transform().xform(mpos)); + menu->set_position(get_screen_position() + mpos); menu->reset_size(); menu->popup(); grab_focus(); } } else { if (mb->get_button_index() == MouseButton::LEFT) { + if (selection.drag_attempt && is_mouse_over_selection()) { + selection.active = false; + } dragging_minimap = false; dragging_selection = false; can_drag_minimap = false; click_select_held->stop(); + if (!drag_action) { + selection.drag_attempt = false; + } if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CLIPBOARD_PRIMARY)) { DisplayServer::get_singleton()->clipboard_set_primary(get_selected_text()); } @@ -1689,6 +1725,14 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { hovered_gutter = current_hovered_gutter; update(); } + + if (drag_action && can_drop_data(mpos, get_viewport()->gui_get_drag_data())) { + drag_caret_force_displayed = true; + Point2i pos = get_line_column_at_pos(get_local_mouse_pos()); + set_caret_line(pos.y, false); + set_caret_column(pos.x); + dragging_selection = true; + } } if (draw_minimap && !dragging_selection) { @@ -1827,7 +1871,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { if (context_menu_enabled) { _generate_context_menu(); adjust_viewport_to_caret(); - menu->set_position(get_screen_transform().xform(get_caret_draw_pos())); + menu->set_position(get_screen_position() + get_caret_draw_pos()); menu->reset_size(); menu->popup(); menu->grab_focus(); @@ -2406,6 +2450,75 @@ bool TextEdit::is_text_field() const { return true; } +Variant TextEdit::get_drag_data(const Point2 &p_point) { + if (selection.active && selection.drag_attempt) { + String t = get_selected_text(); + Label *l = memnew(Label); + l->set_text(t); + set_drag_preview(l); + return t; + } + + return Variant(); +} + +bool TextEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const { + bool drop_override = Control::can_drop_data(p_point, p_data); // In case user wants to drop custom data. + if (drop_override) { + return drop_override; + } + + return is_editable() && p_data.get_type() == Variant::STRING; +} + +void TextEdit::drop_data(const Point2 &p_point, const Variant &p_data) { + Control::drop_data(p_point, p_data); + + if (p_data.get_type() == Variant::STRING && is_editable()) { + Point2i pos = get_line_column_at_pos(get_local_mouse_pos()); + int caret_row_tmp = pos.y; + int caret_column_tmp = pos.x; + if (selection.drag_attempt) { + selection.drag_attempt = false; + if (!is_mouse_over_selection(!Input::get_singleton()->is_key_pressed(Key::CTRL))) { + begin_complex_operation(); + if (!Input::get_singleton()->is_key_pressed(Key::CTRL)) { + if (caret_row_tmp > selection.to_line) { + caret_row_tmp = caret_row_tmp - (selection.to_line - selection.from_line); + } else if (caret_row_tmp == selection.to_line && caret_column_tmp >= selection.to_column) { + caret_column_tmp = caret_column_tmp - (selection.to_column - selection.from_column); + } + delete_selection(); + } else { + deselect(); + } + + set_caret_line(caret_row_tmp, true, false); + set_caret_column(caret_column_tmp); + insert_text_at_caret(p_data); + end_complex_operation(); + } + } else if (is_mouse_over_selection()) { + caret_row_tmp = selection.from_line; + caret_column_tmp = selection.from_column; + set_caret_line(caret_row_tmp, true, false); + set_caret_column(caret_column_tmp); + insert_text_at_caret(p_data); + grab_focus(); + } else { + deselect(); + set_caret_line(caret_row_tmp, true, false); + set_caret_column(caret_column_tmp); + insert_text_at_caret(p_data); + grab_focus(); + } + + if (caret_row_tmp != caret.line || caret_column_tmp != caret.column) { + select(caret_row_tmp, caret_column_tmp, caret.line, caret.column); + } + } +} + Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const { Point2i pos = get_line_column_at_pos(p_pos); int row = pos.y; @@ -3580,6 +3693,21 @@ bool TextEdit::is_dragging_cursor() const { return dragging_selection || dragging_minimap; } +bool TextEdit::is_mouse_over_selection(bool p_edges) const { + if (!has_selection()) { + return false; + } + Point2i pos = get_line_column_at_pos(get_local_mouse_pos()); + int row = pos.y; + int col = pos.x; + if (p_edges) { + if ((row == selection.from_line && col == selection.from_column) || (row == selection.to_line && col == selection.to_column)) { + return true; + } + } + return (row >= selection.from_line && row <= selection.to_line && (row > selection.from_line || col > selection.from_column) && (row < selection.to_line || col < selection.to_column)); +} + /* Caret */ void TextEdit::set_caret_type(CaretType p_type) { caret_type = p_type; @@ -4776,6 +4904,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_minimap_line_at_pos", "position"), &TextEdit::get_minimap_line_at_pos); ClassDB::bind_method(D_METHOD("is_dragging_cursor"), &TextEdit::is_dragging_cursor); + ClassDB::bind_method(D_METHOD("is_mouse_over_selection", "edges"), &TextEdit::is_mouse_over_selection); /* Caret. */ BIND_ENUM_CONSTANT(CARET_TYPE_LINE); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 42b21cbe9c..a1b2ed59f5 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -375,6 +375,9 @@ private: bool caret_mid_grapheme_enabled = false; + bool drag_action = false; + bool drag_caret_force_displayed = false; + void _emit_caret_changed(); void _reset_caret_blink_timer(); @@ -400,6 +403,7 @@ private: int to_column = 0; bool shiftclick_left = false; + bool drag_attempt = false; } selection; bool selecting_enabled = true; @@ -611,6 +615,9 @@ public: virtual Size2 get_minimum_size() const override; virtual bool is_text_field() const override; virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override; + virtual Variant get_drag_data(const Point2 &p_point) override; + virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override; + virtual void drop_data(const Point2 &p_point, const Variant &p_data) override; virtual String get_tooltip(const Point2 &p_pos) const override; void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata); @@ -731,6 +738,7 @@ public: int get_minimap_line_at_pos(const Point2i &p_pos) const; bool is_dragging_cursor() const; + bool is_mouse_over_selection(bool p_edges = true) const; /* Caret */ void set_caret_type(CaretType p_type); diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 8659ea06a2..3f0d907a7e 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -289,19 +289,19 @@ void TextureButton::_bind_methods() { void TextureButton::set_normal_texture(const Ref<Texture2D> &p_normal) { normal = p_normal; update(); - minimum_size_changed(); + update_minimum_size(); } void TextureButton::set_pressed_texture(const Ref<Texture2D> &p_pressed) { pressed = p_pressed; update(); - minimum_size_changed(); + update_minimum_size(); } void TextureButton::set_hover_texture(const Ref<Texture2D> &p_hover) { hover = p_hover; update(); - minimum_size_changed(); + update_minimum_size(); } void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) { @@ -312,7 +312,7 @@ void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) { void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) { click_mask = p_click_mask; update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TextureButton::get_normal_texture() const { @@ -349,7 +349,7 @@ bool TextureButton::get_expand() const { void TextureButton::set_expand(bool p_expand) { expand = p_expand; - minimum_size_changed(); + update_minimum_size(); update(); } diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp index facbe06d4d..6a926a0364 100644 --- a/scene/gui/texture_progress_bar.cpp +++ b/scene/gui/texture_progress_bar.cpp @@ -35,7 +35,7 @@ void TextureProgressBar::set_under_texture(const Ref<Texture2D> &p_texture) { under = p_texture; update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TextureProgressBar::get_under_texture() const { @@ -46,7 +46,7 @@ void TextureProgressBar::set_over_texture(const Ref<Texture2D> &p_texture) { over = p_texture; update(); if (under.is_null()) { - minimum_size_changed(); + update_minimum_size(); } } @@ -58,7 +58,7 @@ void TextureProgressBar::set_stretch_margin(Side p_side, int p_size) { ERR_FAIL_INDEX((int)p_side, 4); stretch_margin[p_side] = p_size; update(); - minimum_size_changed(); + update_minimum_size(); } int TextureProgressBar::get_stretch_margin(Side p_side) const { @@ -69,7 +69,7 @@ int TextureProgressBar::get_stretch_margin(Side p_side) const { void TextureProgressBar::set_nine_patch_stretch(bool p_stretch) { nine_patch_stretch = p_stretch; update(); - minimum_size_changed(); + update_minimum_size(); } bool TextureProgressBar::get_nine_patch_stretch() const { @@ -93,7 +93,7 @@ Size2 TextureProgressBar::get_minimum_size() const { void TextureProgressBar::set_progress_texture(const Ref<Texture2D> &p_texture) { progress = p_texture; update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TextureProgressBar::get_progress_texture() const { @@ -501,6 +501,7 @@ void TextureProgressBar::_notification(int p_what) { } p *= get_relative_center(); + p += progress_offset; p = p.floor(); draw_line(p - Point2(8, 0), p + Point2(8, 0), Color(0.9, 0.5, 0.5), 2); draw_line(p - Point2(0, 8), p + Point2(0, 8), Color(0.9, 0.5, 0.5), 2); diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index 1cba88e06f..85c15cdae7 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -152,7 +152,7 @@ void TextureRect::_bind_methods() { void TextureRect::_texture_changed() { if (texture.is_valid()) { update(); - minimum_size_changed(); + update_minimum_size(); } } @@ -172,7 +172,7 @@ void TextureRect::set_texture(const Ref<Texture2D> &p_tex) { } update(); - minimum_size_changed(); + update_minimum_size(); } Ref<Texture2D> TextureRect::get_texture() const { @@ -182,7 +182,7 @@ Ref<Texture2D> TextureRect::get_texture() const { void TextureRect::set_expand(bool p_expand) { expand = p_expand; update(); - minimum_size_changed(); + update_minimum_size(); } bool TextureRect::has_expand() const { diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 89caaaafd0..050ba9f519 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -2532,7 +2532,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int } popup_menu->set_size(Size2(col_width, 0)); - popup_menu->set_position(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h) - cache.offset); + popup_menu->set_position(get_screen_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h) - cache.offset); popup_menu->popup(); popup_edited_item = p_item; popup_edited_item_col = col; @@ -3441,7 +3441,7 @@ bool Tree::edit_selected() { } popup_menu->set_size(Size2(rect.size.width, 0)); - popup_menu->set_position(get_global_position() + rect.position + Point2i(0, rect.size.height)); + popup_menu->set_position(get_screen_position() + rect.position + Point2i(0, rect.size.height)); popup_menu->popup(); popup_edited_item = s; popup_edited_item_col = col; @@ -4370,7 +4370,7 @@ void Tree::scroll_to_item(TreeItem *p_item) { void Tree::set_h_scroll_enabled(bool p_enable) { h_scroll_enabled = p_enable; - minimum_size_changed(); + update_minimum_size(); } bool Tree::is_h_scroll_enabled() const { @@ -4379,7 +4379,7 @@ bool Tree::is_h_scroll_enabled() const { void Tree::set_v_scroll_enabled(bool p_enable) { v_scroll_enabled = p_enable; - minimum_size_changed(); + update_minimum_size(); } bool Tree::is_v_scroll_enabled() const { @@ -4830,6 +4830,7 @@ void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_allow_reselect"), &Tree::get_allow_reselect); ADD_PROPERTY(PropertyInfo(Variant::INT, "columns"), "set_columns", "get_columns"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "column_titles_visible"), "set_column_titles_visible", "are_column_titles_visible"); 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"); diff --git a/scene/gui/video_player.cpp b/scene/gui/video_stream_player.cpp index 989aabc549..a11d56a2ed 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_stream_player.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* video_player.cpp */ +/* video_stream_player.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "video_player.h" +#include "video_stream_player.h" #include "core/os/os.h" #include "scene/scene_string_names.h" #include "servers/audio_server.h" -int VideoPlayer::sp_get_channel_count() const { +int VideoStreamPlayer::sp_get_channel_count() const { if (playback.is_null()) { return 0; } @@ -42,7 +42,7 @@ int VideoPlayer::sp_get_channel_count() const { return playback->get_channels(); } -bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) { +bool VideoStreamPlayer::mix(AudioFrame *p_buffer, int p_frames) { // Check the amount resampler can really handle. // If it cannot, wait "wait_resampler_phase_limit" times. // This mechanism contributes to smoother pause/unpause operation. @@ -56,11 +56,11 @@ bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) { } // Called from main thread (e.g. VideoStreamPlaybackTheora::update). -int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) { +int VideoStreamPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) { ERR_FAIL_NULL_V(p_udata, 0); ERR_FAIL_NULL_V(p_data, 0); - VideoPlayer *vp = (VideoPlayer *)p_udata; + VideoStreamPlayer *vp = (VideoStreamPlayer *)p_udata; int todo = MIN(vp->resampler.get_writer_space(), p_frames); @@ -75,13 +75,13 @@ int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_f return todo; } -void VideoPlayer::_mix_audios(void *p_self) { +void VideoStreamPlayer::_mix_audios(void *p_self) { ERR_FAIL_NULL(p_self); - reinterpret_cast<VideoPlayer *>(p_self)->_mix_audio(); + reinterpret_cast<VideoStreamPlayer *>(p_self)->_mix_audio(); } // Called from audio thread -void VideoPlayer::_mix_audio() { +void VideoStreamPlayer::_mix_audio() { if (!stream.is_valid()) { return; } @@ -126,7 +126,7 @@ void VideoPlayer::_mix_audio() { } } -void VideoPlayer::_notification(int p_notification) { +void VideoStreamPlayer::_notification(int p_notification) { switch (p_notification) { case NOTIFICATION_ENTER_TREE: { AudioServer::get_singleton()->add_mix_callback(_mix_audios, this); @@ -180,7 +180,7 @@ void VideoPlayer::_notification(int p_notification) { }; }; -Size2 VideoPlayer::get_minimum_size() const { +Size2 VideoStreamPlayer::get_minimum_size() const { if (!expand && !texture.is_null()) { return texture->get_size(); } else { @@ -188,17 +188,17 @@ Size2 VideoPlayer::get_minimum_size() const { } } -void VideoPlayer::set_expand(bool p_expand) { +void VideoStreamPlayer::set_expand(bool p_expand) { expand = p_expand; update(); - minimum_size_changed(); + update_minimum_size(); } -bool VideoPlayer::has_expand() const { +bool VideoStreamPlayer::has_expand() const { return expand; } -void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) { +void VideoStreamPlayer::set_stream(const Ref<VideoStream> &p_stream) { stop(); AudioServer::get_singleton()->lock(); @@ -241,15 +241,15 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) { update(); if (!expand) { - minimum_size_changed(); + update_minimum_size(); } }; -Ref<VideoStream> VideoPlayer::get_stream() const { +Ref<VideoStream> VideoStreamPlayer::get_stream() const { return stream; }; -void VideoPlayer::play() { +void VideoStreamPlayer::play() { ERR_FAIL_COND(!is_inside_tree()); if (playback.is_null()) { return; @@ -262,7 +262,7 @@ void VideoPlayer::play() { last_audio_time = 0; }; -void VideoPlayer::stop() { +void VideoStreamPlayer::stop() { if (!is_inside_tree()) { return; } @@ -277,7 +277,7 @@ void VideoPlayer::stop() { last_audio_time = 0; }; -bool VideoPlayer::is_playing() const { +bool VideoStreamPlayer::is_playing() const { if (playback.is_null()) { return false; } @@ -285,7 +285,7 @@ bool VideoPlayer::is_playing() const { return playback->is_playing(); }; -void VideoPlayer::set_paused(bool p_paused) { +void VideoStreamPlayer::set_paused(bool p_paused) { paused = p_paused; if (playback.is_valid()) { playback->set_paused(p_paused); @@ -294,35 +294,35 @@ void VideoPlayer::set_paused(bool p_paused) { last_audio_time = 0; }; -bool VideoPlayer::is_paused() const { +bool VideoStreamPlayer::is_paused() const { return paused; } -void VideoPlayer::set_buffering_msec(int p_msec) { +void VideoStreamPlayer::set_buffering_msec(int p_msec) { buffering_ms = p_msec; } -int VideoPlayer::get_buffering_msec() const { +int VideoStreamPlayer::get_buffering_msec() const { return buffering_ms; } -void VideoPlayer::set_audio_track(int p_track) { +void VideoStreamPlayer::set_audio_track(int p_track) { audio_track = p_track; } -int VideoPlayer::get_audio_track() const { +int VideoStreamPlayer::get_audio_track() const { return audio_track; } -void VideoPlayer::set_volume(float p_vol) { +void VideoStreamPlayer::set_volume(float p_vol) { volume = p_vol; }; -float VideoPlayer::get_volume() const { +float VideoStreamPlayer::get_volume() const { return volume; }; -void VideoPlayer::set_volume_db(float p_db) { +void VideoStreamPlayer::set_volume_db(float p_db) { if (p_db < -79) { set_volume(0); } else { @@ -330,7 +330,7 @@ void VideoPlayer::set_volume_db(float p_db) { } }; -float VideoPlayer::get_volume_db() const { +float VideoStreamPlayer::get_volume_db() const { if (volume == 0) { return -80; } else { @@ -338,27 +338,27 @@ float VideoPlayer::get_volume_db() const { } }; -String VideoPlayer::get_stream_name() const { +String VideoStreamPlayer::get_stream_name() const { if (stream.is_null()) { return "<No Stream>"; } return stream->get_name(); }; -float VideoPlayer::get_stream_position() const { +float VideoStreamPlayer::get_stream_position() const { if (playback.is_null()) { return 0; } return playback->get_playback_position(); }; -void VideoPlayer::set_stream_position(float p_position) { +void VideoStreamPlayer::set_stream_position(float p_position) { if (playback.is_valid()) { playback->seek(p_position); } } -Ref<Texture2D> VideoPlayer::get_video_texture() const { +Ref<Texture2D> VideoStreamPlayer::get_video_texture() const { if (playback.is_valid()) { return playback->get_texture(); } @@ -366,22 +366,22 @@ Ref<Texture2D> VideoPlayer::get_video_texture() const { return Ref<Texture2D>(); } -void VideoPlayer::set_autoplay(bool p_enable) { +void VideoStreamPlayer::set_autoplay(bool p_enable) { autoplay = p_enable; }; -bool VideoPlayer::has_autoplay() const { +bool VideoStreamPlayer::has_autoplay() const { return autoplay; }; -void VideoPlayer::set_bus(const StringName &p_bus) { +void VideoStreamPlayer::set_bus(const StringName &p_bus) { //if audio is active, must lock this AudioServer::get_singleton()->lock(); bus = p_bus; AudioServer::get_singleton()->unlock(); } -StringName VideoPlayer::get_bus() const { +StringName VideoStreamPlayer::get_bus() const { for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { if (AudioServer::get_singleton()->get_bus_name(i) == bus) { return bus; @@ -390,7 +390,7 @@ StringName VideoPlayer::get_bus() const { return "Master"; } -void VideoPlayer::_validate_property(PropertyInfo &p_property) const { +void VideoStreamPlayer::_validate_property(PropertyInfo &p_property) const { if (p_property.name == "bus") { String options; for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { @@ -405,45 +405,45 @@ void VideoPlayer::_validate_property(PropertyInfo &p_property) const { } } -void VideoPlayer::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoPlayer::set_stream); - ClassDB::bind_method(D_METHOD("get_stream"), &VideoPlayer::get_stream); +void VideoStreamPlayer::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoStreamPlayer::set_stream); + ClassDB::bind_method(D_METHOD("get_stream"), &VideoStreamPlayer::get_stream); - ClassDB::bind_method(D_METHOD("play"), &VideoPlayer::play); - ClassDB::bind_method(D_METHOD("stop"), &VideoPlayer::stop); + ClassDB::bind_method(D_METHOD("play"), &VideoStreamPlayer::play); + ClassDB::bind_method(D_METHOD("stop"), &VideoStreamPlayer::stop); - ClassDB::bind_method(D_METHOD("is_playing"), &VideoPlayer::is_playing); + ClassDB::bind_method(D_METHOD("is_playing"), &VideoStreamPlayer::is_playing); - ClassDB::bind_method(D_METHOD("set_paused", "paused"), &VideoPlayer::set_paused); - ClassDB::bind_method(D_METHOD("is_paused"), &VideoPlayer::is_paused); + ClassDB::bind_method(D_METHOD("set_paused", "paused"), &VideoStreamPlayer::set_paused); + ClassDB::bind_method(D_METHOD("is_paused"), &VideoStreamPlayer::is_paused); - ClassDB::bind_method(D_METHOD("set_volume", "volume"), &VideoPlayer::set_volume); - ClassDB::bind_method(D_METHOD("get_volume"), &VideoPlayer::get_volume); + ClassDB::bind_method(D_METHOD("set_volume", "volume"), &VideoStreamPlayer::set_volume); + ClassDB::bind_method(D_METHOD("get_volume"), &VideoStreamPlayer::get_volume); - ClassDB::bind_method(D_METHOD("set_volume_db", "db"), &VideoPlayer::set_volume_db); - ClassDB::bind_method(D_METHOD("get_volume_db"), &VideoPlayer::get_volume_db); + ClassDB::bind_method(D_METHOD("set_volume_db", "db"), &VideoStreamPlayer::set_volume_db); + ClassDB::bind_method(D_METHOD("get_volume_db"), &VideoStreamPlayer::get_volume_db); - ClassDB::bind_method(D_METHOD("set_audio_track", "track"), &VideoPlayer::set_audio_track); - ClassDB::bind_method(D_METHOD("get_audio_track"), &VideoPlayer::get_audio_track); + ClassDB::bind_method(D_METHOD("set_audio_track", "track"), &VideoStreamPlayer::set_audio_track); + ClassDB::bind_method(D_METHOD("get_audio_track"), &VideoStreamPlayer::get_audio_track); - ClassDB::bind_method(D_METHOD("get_stream_name"), &VideoPlayer::get_stream_name); + ClassDB::bind_method(D_METHOD("get_stream_name"), &VideoStreamPlayer::get_stream_name); - ClassDB::bind_method(D_METHOD("set_stream_position", "position"), &VideoPlayer::set_stream_position); - ClassDB::bind_method(D_METHOD("get_stream_position"), &VideoPlayer::get_stream_position); + ClassDB::bind_method(D_METHOD("set_stream_position", "position"), &VideoStreamPlayer::set_stream_position); + ClassDB::bind_method(D_METHOD("get_stream_position"), &VideoStreamPlayer::get_stream_position); - ClassDB::bind_method(D_METHOD("set_autoplay", "enabled"), &VideoPlayer::set_autoplay); - ClassDB::bind_method(D_METHOD("has_autoplay"), &VideoPlayer::has_autoplay); + ClassDB::bind_method(D_METHOD("set_autoplay", "enabled"), &VideoStreamPlayer::set_autoplay); + ClassDB::bind_method(D_METHOD("has_autoplay"), &VideoStreamPlayer::has_autoplay); - ClassDB::bind_method(D_METHOD("set_expand", "enable"), &VideoPlayer::set_expand); - ClassDB::bind_method(D_METHOD("has_expand"), &VideoPlayer::has_expand); + ClassDB::bind_method(D_METHOD("set_expand", "enable"), &VideoStreamPlayer::set_expand); + ClassDB::bind_method(D_METHOD("has_expand"), &VideoStreamPlayer::has_expand); - ClassDB::bind_method(D_METHOD("set_buffering_msec", "msec"), &VideoPlayer::set_buffering_msec); - ClassDB::bind_method(D_METHOD("get_buffering_msec"), &VideoPlayer::get_buffering_msec); + ClassDB::bind_method(D_METHOD("set_buffering_msec", "msec"), &VideoStreamPlayer::set_buffering_msec); + ClassDB::bind_method(D_METHOD("get_buffering_msec"), &VideoStreamPlayer::get_buffering_msec); - ClassDB::bind_method(D_METHOD("set_bus", "bus"), &VideoPlayer::set_bus); - ClassDB::bind_method(D_METHOD("get_bus"), &VideoPlayer::get_bus); + ClassDB::bind_method(D_METHOD("set_bus", "bus"), &VideoStreamPlayer::set_bus); + ClassDB::bind_method(D_METHOD("get_bus"), &VideoStreamPlayer::get_bus); - ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoPlayer::get_video_texture); + ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoStreamPlayer::get_video_texture); ADD_SIGNAL(MethodInfo("finished")); @@ -461,9 +461,9 @@ void VideoPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); } -VideoPlayer::VideoPlayer() {} +VideoStreamPlayer::VideoStreamPlayer() {} -VideoPlayer::~VideoPlayer() { +VideoStreamPlayer::~VideoStreamPlayer() { // if (stream_rid.is_valid()) // AudioServer::get_singleton()->free(stream_rid); resampler.clear(); //Not necessary here, but make in consistent with other "stream_player" classes diff --git a/scene/gui/video_player.h b/scene/gui/video_stream_player.h index 0edad296a1..ad4a3dd9e9 100644 --- a/scene/gui/video_player.h +++ b/scene/gui/video_stream_player.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* video_player.h */ +/* video_stream_player.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,16 +28,16 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VIDEO_PLAYER_H -#define VIDEO_PLAYER_H +#ifndef VIDEO_STREAM_PLAYER_H +#define VIDEO_STREAM_PLAYER_H #include "scene/gui/control.h" #include "scene/resources/video_stream.h" #include "servers/audio/audio_rb_resampler.h" #include "servers/audio_server.h" -class VideoPlayer : public Control { - GDCLASS(VideoPlayer, Control); +class VideoStreamPlayer : public Control { + GDCLASS(VideoStreamPlayer, Control); struct Output { AudioFrame vol; @@ -119,8 +119,8 @@ public: void set_bus(const StringName &p_bus); StringName get_bus() const; - VideoPlayer(); - ~VideoPlayer(); + VideoStreamPlayer(); + ~VideoStreamPlayer(); }; -#endif // VIDEO_PLAYER_H +#endif // VIDEO_STREAM_PLAYER_H diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 22e3c3bf24..0fd3a963ae 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -275,9 +275,6 @@ void CanvasItem::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { ERR_FAIL_COND(!is_inside_tree()); - _update_texture_filter_changed(false); - _update_texture_repeat_changed(false); - first_draw = true; Node *parent = get_parent(); if (parent) { @@ -306,6 +303,10 @@ void CanvasItem::_notification(int p_what) { } } _enter_canvas(); + + _update_texture_filter_changed(false); + _update_texture_repeat_changed(false); + if (!block_transform_notify && !xform_change.in_list()) { get_tree()->xform_change_list.add(&xform_change); } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index f9e96a0784..af4032a77d 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -396,14 +396,15 @@ void Viewport::_notification(int p_what) { #ifndef _3D_DISABLED PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count()); contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create(); - RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true); + RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, false); RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0); RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid()); contact_3d_debug_instance = RenderingServer::get_singleton()->instance_create(); RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh); RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario()); - //RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true); + RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); #endif // _3D_DISABLED + set_physics_process_internal(true); } } break; @@ -1182,7 +1183,7 @@ void Viewport::_gui_show_tooltip() { Control *tooltip_owner = nullptr; String tooltip_text = _gui_get_tooltip( gui.tooltip_control, - gui.tooltip_control->get_global_transform().xform_inv(gui.last_mouse_pos), + gui.tooltip_control->get_screen_transform().xform_inv(gui.last_mouse_pos), &tooltip_owner); tooltip_text = tooltip_text.strip_edges(); if (tooltip_text.is_empty()) { @@ -1707,13 +1708,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (mm->get_button_mask() == MouseButton::NONE) { // Nothing pressed. - bool can_tooltip = true; - bool is_tooltip_shown = false; if (gui.tooltip_popup) { - if (can_tooltip && gui.tooltip_control) { - String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_global_transform().xform_inv(mpos)); + if (gui.tooltip_control) { + String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_screen_transform().xform_inv(mpos)); if (tooltip.length() == 0) { _gui_cancel_tooltip(); @@ -1737,7 +1736,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } - if (can_tooltip && !is_tooltip_shown) { + if (!is_tooltip_shown && over->can_process()) { if (gui.tooltip_timer.is_valid()) { gui.tooltip_timer->release_connections(); gui.tooltip_timer = Ref<SceneTreeTimer>(); @@ -1870,14 +1869,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Transform2D localizer = gui.drag_mouse_over->get_global_transform_with_canvas().affine_inverse(); gui.drag_mouse_over_pos = localizer.xform(viewport_pos); - if ((mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { - bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true); + bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true); - if (!can_drop) { - ds_cursor_shape = DisplayServer::CURSOR_FORBIDDEN; - } else { - ds_cursor_shape = DisplayServer::CURSOR_CAN_DROP; - } + if (!can_drop) { + ds_cursor_shape = DisplayServer::CURSOR_FORBIDDEN; + } else { + ds_cursor_shape = DisplayServer::CURSOR_CAN_DROP; } } @@ -2045,6 +2042,7 @@ void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control * if (p_control) { _gui_set_drag_preview(p_base, p_control); } + _propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN); } void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) { diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 056ace5e4e..b8442e7f70 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -123,7 +123,7 @@ #include "scene/gui/texture_progress_bar.h" #include "scene/gui/texture_rect.h" #include "scene/gui/tree.h" -#include "scene/gui/video_player.h" +#include "scene/gui/video_stream_player.h" #include "scene/main/canvas_item.h" #include "scene/main/canvas_layer.h" #include "scene/main/http_request.h" @@ -232,7 +232,6 @@ #include "scene/3d/path_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/3d/position_3d.h" -#include "scene/3d/proximity_group_3d.h" #include "scene/3d/ray_cast_3d.h" #include "scene/3d/reflection_probe.h" #include "scene/3d/remote_transform_3d.h" @@ -361,7 +360,7 @@ void register_scene_types() { GDREGISTER_CLASS(ItemList); GDREGISTER_CLASS(LineEdit); - GDREGISTER_CLASS(VideoPlayer); + GDREGISTER_CLASS(VideoStreamPlayer); #ifndef ADVANCED_GUI_DISABLED GDREGISTER_CLASS(FileDialog); @@ -511,7 +510,6 @@ void register_scene_types() { GDREGISTER_CLASS(VehicleBody3D); GDREGISTER_CLASS(VehicleWheel3D); GDREGISTER_CLASS(Area3D); - GDREGISTER_CLASS(ProximityGroup3D); GDREGISTER_CLASS(CollisionShape3D); GDREGISTER_CLASS(CollisionPolygon3D); GDREGISTER_CLASS(RayCast3D); @@ -933,6 +931,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("KinematicBody2D", "CharacterBody2D"); ClassDB::add_compatibility_class("KinematicCollision", "KinematicCollision3D"); ClassDB::add_compatibility_class("Light", "Light3D"); + ClassDB::add_compatibility_class("Light2D", "PointLight2D"); ClassDB::add_compatibility_class("LineShape2D", "WorldBoundaryShape2D"); ClassDB::add_compatibility_class("Listener", "AudioListener3D"); ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D"); @@ -964,7 +963,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("PinJoint", "PinJoint3D"); ClassDB::add_compatibility_class("PlaneShape", "WorldBoundaryShape3D"); ClassDB::add_compatibility_class("ProceduralSky", "Sky"); - ClassDB::add_compatibility_class("ProximityGroup", "ProximityGroup3D"); ClassDB::add_compatibility_class("RayCast", "RayCast3D"); ClassDB::add_compatibility_class("RayShape", "SeparationRayShape3D"); ClassDB::add_compatibility_class("RayShape2D", "SeparationRayShape2D"); @@ -986,13 +984,17 @@ void register_scene_types() { ClassDB::add_compatibility_class("SpringArm", "SpringArm3D"); ClassDB::add_compatibility_class("Sprite", "Sprite2D"); ClassDB::add_compatibility_class("StaticBody", "StaticBody3D"); + ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); ClassDB::add_compatibility_class("TextureProgress", "TextureProgressBar"); ClassDB::add_compatibility_class("VehicleBody", "VehicleBody3D"); ClassDB::add_compatibility_class("VehicleWheel", "VehicleWheel3D"); + ClassDB::add_compatibility_class("VideoPlayer", "VideoStreamPlayer"); ClassDB::add_compatibility_class("ViewportContainer", "SubViewportContainer"); ClassDB::add_compatibility_class("Viewport", "SubViewport"); ClassDB::add_compatibility_class("VisibilityEnabler", "VisibleOnScreenEnabler3D"); ClassDB::add_compatibility_class("VisibilityNotifier", "VisibleOnScreenNotifier3D"); + ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D"); + ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D"); ClassDB::add_compatibility_class("VisualServer", "RenderingServer"); ClassDB::add_compatibility_class("VisualShaderNodeScalarConstant", "VisualShaderNodeFloatConstant"); ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); @@ -1010,11 +1012,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch"); ClassDB::add_compatibility_class("VisualShaderNodeScalarTransformMult", "VisualShaderNodeTransformOp"); ClassDB::add_compatibility_class("World", "World3D"); - ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); - ClassDB::add_compatibility_class("Light2D", "PointLight2D"); - ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D"); - ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D"); - #endif /* DISABLE_DEPRECATED */ OS::get_singleton()->yield(); // may take time to init @@ -1031,6 +1028,16 @@ void register_scene_types() { GLOBAL_DEF_BASIC(vformat("layer_names/3d_navigation/layer_%d", i + 1), ""); } + if (RenderingServer::get_singleton()) { + ColorPicker::init_shaders(); // RenderingServer needs to exist for this to succeed. + } + + SceneDebugger::initialize(); + + NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE); +} + +void initialize_theme() { bool default_theme_hidpi = GLOBAL_DEF("gui/theme/use_hidpi", false); ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/use_hidpi", PropertyInfo(Variant::BOOL, "gui/theme/use_hidpi", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); String theme_path = GLOBAL_DEF_RST("gui/theme/custom", ""); @@ -1049,7 +1056,6 @@ void register_scene_types() { // Always make the default theme to avoid invalid default font/icon/style in the given theme. if (RenderingServer::get_singleton()) { make_default_theme(default_theme_hidpi, font); - ColorPicker::init_shaders(); // RenderingServer needs to exist for this to succeed. } if (theme_path != String()) { @@ -1063,9 +1069,6 @@ void register_scene_types() { ERR_PRINT("Error loading custom theme '" + theme_path + "'"); } } - SceneDebugger::initialize(); - - NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE); } void unregister_scene_types() { diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h index 1ff542eef8..32ab165fb3 100644 --- a/scene/register_scene_types.h +++ b/scene/register_scene_types.h @@ -34,4 +34,6 @@ void register_scene_types(); void unregister_scene_types(); +void initialize_theme(); + #endif diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index b87639de6a..bf3efd7599 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -33,15 +33,15 @@ #include "core/core_string_names.h" template <class T> -static _FORCE_INLINE_ T _bezier_interp(real_t t, T start, T control_1, T control_2, T end) { +static _FORCE_INLINE_ T _bezier_interp(real_t p_t, T p_start, T p_control_1, T p_control_2, T p_end) { /* Formula from Wikipedia article on Bezier curves. */ - real_t omt = (1.0 - t); + real_t omt = (1.0 - p_t); real_t omt2 = omt * omt; real_t omt3 = omt2 * omt; - real_t t2 = t * t; - real_t t3 = t2 * t; + real_t t2 = p_t * p_t; + real_t t3 = t2 * p_t; - return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3; + return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3; } const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed"; @@ -49,46 +49,46 @@ const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed"; Curve::Curve() { } -int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, TangentMode left_mode, TangentMode right_mode) { +int Curve::add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_tangent, TangentMode p_left_mode, TangentMode p_right_mode) { // Add a point and preserve order // Curve bounds is in 0..1 - if (p_pos.x > MAX_X) { - p_pos.x = MAX_X; - } else if (p_pos.x < MIN_X) { - p_pos.x = MIN_X; + if (p_position.x > MAX_X) { + p_position.x = MAX_X; + } else if (p_position.x < MIN_X) { + p_position.x = MIN_X; } int ret = -1; if (_points.size() == 0) { - _points.push_back(Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); + _points.push_back(Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode)); ret = 0; } else if (_points.size() == 1) { // TODO Is the `else` able to handle this block already? - real_t diff = p_pos.x - _points[0].pos.x; + real_t diff = p_position.x - _points[0].position.x; if (diff > 0) { - _points.push_back(Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); + _points.push_back(Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode)); ret = 1; } else { - _points.insert(0, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); + _points.insert(0, Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode)); ret = 0; } } else { - int i = get_index(p_pos.x); + int i = get_index(p_position.x); - if (i == 0 && p_pos.x < _points[0].pos.x) { + if (i == 0 && p_position.x < _points[0].position.x) { // Insert before anything else - _points.insert(0, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); + _points.insert(0, Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode)); ret = 0; } else { // Insert between i and i+1 ++i; - _points.insert(i, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); + _points.insert(i, Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode)); ret = i; } } @@ -100,7 +100,7 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T return ret; } -int Curve::get_index(real_t offset) const { +int Curve::get_index(real_t p_offset) const { // Lower-bound float binary search int imin = 0; @@ -109,13 +109,13 @@ int Curve::get_index(real_t offset) const { while (imax - imin > 1) { int m = (imin + imax) / 2; - real_t a = _points[m].pos.x; - real_t b = _points[m + 1].pos.x; + real_t a = _points[m].position.x; + real_t b = _points[m + 1].position.x; - if (a < offset && b < offset) { + if (a < p_offset && b < p_offset) { imin = m; - } else if (a > offset) { + } else if (a > p_offset) { imax = m; } else { @@ -124,7 +124,7 @@ int Curve::get_index(real_t offset) const { } // Will happen if the offset is out of bounds - if (offset > _points[imax].pos.x) { + if (p_offset > _points[imax].position.x) { return imax; } return imin; @@ -134,7 +134,7 @@ void Curve::clean_dupes() { bool dirty = false; for (int i = 1; i < _points.size(); ++i) { - real_t diff = _points[i - 1].pos.x - _points[i].pos.x; + real_t diff = _points[i - 1].position.x - _points[i].position.x; if (diff <= CMP_EPSILON) { _points.remove_at(i); --i; @@ -147,62 +147,62 @@ void Curve::clean_dupes() { } } -void Curve::set_point_left_tangent(int i, real_t tangent) { - ERR_FAIL_INDEX(i, _points.size()); - _points.write[i].left_tangent = tangent; - _points.write[i].left_mode = TANGENT_FREE; +void Curve::set_point_left_tangent(int p_index, real_t p_tangent) { + ERR_FAIL_INDEX(p_index, _points.size()); + _points.write[p_index].left_tangent = p_tangent; + _points.write[p_index].left_mode = TANGENT_FREE; mark_dirty(); } -void Curve::set_point_right_tangent(int i, real_t tangent) { - ERR_FAIL_INDEX(i, _points.size()); - _points.write[i].right_tangent = tangent; - _points.write[i].right_mode = TANGENT_FREE; +void Curve::set_point_right_tangent(int p_index, real_t p_tangent) { + ERR_FAIL_INDEX(p_index, _points.size()); + _points.write[p_index].right_tangent = p_tangent; + _points.write[p_index].right_mode = TANGENT_FREE; mark_dirty(); } -void Curve::set_point_left_mode(int i, TangentMode p_mode) { - ERR_FAIL_INDEX(i, _points.size()); - _points.write[i].left_mode = p_mode; - if (i > 0) { +void Curve::set_point_left_mode(int p_index, TangentMode p_mode) { + ERR_FAIL_INDEX(p_index, _points.size()); + _points.write[p_index].left_mode = p_mode; + if (p_index > 0) { if (p_mode == TANGENT_LINEAR) { - Vector2 v = (_points[i - 1].pos - _points[i].pos).normalized(); - _points.write[i].left_tangent = v.y / v.x; + Vector2 v = (_points[p_index - 1].position - _points[p_index].position).normalized(); + _points.write[p_index].left_tangent = v.y / v.x; } } mark_dirty(); } -void Curve::set_point_right_mode(int i, TangentMode p_mode) { - ERR_FAIL_INDEX(i, _points.size()); - _points.write[i].right_mode = p_mode; - if (i + 1 < _points.size()) { +void Curve::set_point_right_mode(int p_index, TangentMode p_mode) { + ERR_FAIL_INDEX(p_index, _points.size()); + _points.write[p_index].right_mode = p_mode; + if (p_index + 1 < _points.size()) { if (p_mode == TANGENT_LINEAR) { - Vector2 v = (_points[i + 1].pos - _points[i].pos).normalized(); - _points.write[i].right_tangent = v.y / v.x; + Vector2 v = (_points[p_index + 1].position - _points[p_index].position).normalized(); + _points.write[p_index].right_tangent = v.y / v.x; } } mark_dirty(); } -real_t Curve::get_point_left_tangent(int i) const { - ERR_FAIL_INDEX_V(i, _points.size(), 0); - return _points[i].left_tangent; +real_t Curve::get_point_left_tangent(int p_index) const { + ERR_FAIL_INDEX_V(p_index, _points.size(), 0); + return _points[p_index].left_tangent; } -real_t Curve::get_point_right_tangent(int i) const { - ERR_FAIL_INDEX_V(i, _points.size(), 0); - return _points[i].right_tangent; +real_t Curve::get_point_right_tangent(int p_index) const { + ERR_FAIL_INDEX_V(p_index, _points.size(), 0); + return _points[p_index].right_tangent; } -Curve::TangentMode Curve::get_point_left_mode(int i) const { - ERR_FAIL_INDEX_V(i, _points.size(), TANGENT_FREE); - return _points[i].left_mode; +Curve::TangentMode Curve::get_point_left_mode(int p_index) const { + ERR_FAIL_INDEX_V(p_index, _points.size(), TANGENT_FREE); + return _points[p_index].left_mode; } -Curve::TangentMode Curve::get_point_right_mode(int i) const { - ERR_FAIL_INDEX_V(i, _points.size(), TANGENT_FREE); - return _points[i].right_mode; +Curve::TangentMode Curve::get_point_right_mode(int p_index) const { + ERR_FAIL_INDEX_V(p_index, _points.size(), TANGENT_FREE); + return _points[p_index].right_mode; } void Curve::remove_point(int p_index) { @@ -216,18 +216,18 @@ void Curve::clear_points() { mark_dirty(); } -void Curve::set_point_value(int p_index, real_t pos) { +void Curve::set_point_value(int p_index, real_t p_position) { ERR_FAIL_INDEX(p_index, _points.size()); - _points.write[p_index].pos.y = pos; + _points.write[p_index].position.y = p_position; update_auto_tangents(p_index); mark_dirty(); } -int Curve::set_point_offset(int p_index, float offset) { +int Curve::set_point_offset(int p_index, real_t p_offset) { ERR_FAIL_INDEX_V(p_index, _points.size(), -1); Point p = _points[p_index]; remove_point(p_index); - int i = add_point(Vector2(offset, p.pos.y)); + int i = add_point(Vector2(p_offset, p.position.y)); _points.write[i].left_tangent = p.left_tangent; _points.write[i].right_tangent = p.right_tangent; _points.write[i].left_mode = p.left_mode; @@ -241,7 +241,7 @@ int Curve::set_point_offset(int p_index, float offset) { Vector2 Curve::get_point_position(int p_index) const { ERR_FAIL_INDEX_V(p_index, _points.size(), Vector2(0, 0)); - return _points[p_index].pos; + return _points[p_index].position; } Curve::Point Curve::get_point(int p_index) const { @@ -249,35 +249,35 @@ Curve::Point Curve::get_point(int p_index) const { return _points[p_index]; } -void Curve::update_auto_tangents(int i) { - Point &p = _points.write[i]; +void Curve::update_auto_tangents(int p_index) { + Point &p = _points.write[p_index]; - if (i > 0) { + if (p_index > 0) { if (p.left_mode == TANGENT_LINEAR) { - Vector2 v = (_points[i - 1].pos - p.pos).normalized(); + Vector2 v = (_points[p_index - 1].position - p.position).normalized(); p.left_tangent = v.y / v.x; } - if (_points[i - 1].right_mode == TANGENT_LINEAR) { - Vector2 v = (_points[i - 1].pos - p.pos).normalized(); - _points.write[i - 1].right_tangent = v.y / v.x; + if (_points[p_index - 1].right_mode == TANGENT_LINEAR) { + Vector2 v = (_points[p_index - 1].position - p.position).normalized(); + _points.write[p_index - 1].right_tangent = v.y / v.x; } } - if (i + 1 < _points.size()) { + if (p_index + 1 < _points.size()) { if (p.right_mode == TANGENT_LINEAR) { - Vector2 v = (_points[i + 1].pos - p.pos).normalized(); + Vector2 v = (_points[p_index + 1].position - p.position).normalized(); p.right_tangent = v.y / v.x; } - if (_points[i + 1].left_mode == TANGENT_LINEAR) { - Vector2 v = (_points[i + 1].pos - p.pos).normalized(); - _points.write[i + 1].left_tangent = v.y / v.x; + if (_points[p_index + 1].left_mode == TANGENT_LINEAR) { + Vector2 v = (_points[p_index + 1].position - p.position).normalized(); + _points.write[p_index + 1].left_tangent = v.y / v.x; } } } #define MIN_Y_RANGE 0.01 -void Curve::set_min_value(float p_min) { +void Curve::set_min_value(real_t p_min) { if (_minmax_set_once & 0b11 && p_min > _max_value - MIN_Y_RANGE) { _min_value = _max_value - MIN_Y_RANGE; } else { @@ -289,7 +289,7 @@ void Curve::set_min_value(float p_min) { emit_signal(SNAME(SIGNAL_RANGE_CHANGED)); } -void Curve::set_max_value(float p_max) { +void Curve::set_max_value(real_t p_max) { if (_minmax_set_once & 0b11 && p_max < _min_value + MIN_Y_RANGE) { _max_value = _min_value + MIN_Y_RANGE; } else { @@ -299,32 +299,32 @@ void Curve::set_max_value(float p_max) { emit_signal(SNAME(SIGNAL_RANGE_CHANGED)); } -real_t Curve::interpolate(real_t offset) const { +real_t Curve::interpolate(real_t p_offset) const { if (_points.size() == 0) { return 0; } if (_points.size() == 1) { - return _points[0].pos.y; + return _points[0].position.y; } - int i = get_index(offset); + int i = get_index(p_offset); if (i == _points.size() - 1) { - return _points[i].pos.y; + return _points[i].position.y; } - real_t local = offset - _points[i].pos.x; + real_t local = p_offset - _points[i].position.x; if (i == 0 && local <= 0) { - return _points[0].pos.y; + return _points[0].position.y; } return interpolate_local_nocheck(i, local); } -real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const { - const Point a = _points[index]; - const Point b = _points[index + 1]; +real_t Curve::interpolate_local_nocheck(int p_index, real_t p_local_offset) const { + const Point a = _points[p_index]; + const Point b = _points[p_index + 1]; /* Cubic bezier * @@ -341,16 +341,16 @@ real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const { */ // Control points are chosen at equal distances - real_t d = b.pos.x - a.pos.x; - if (Math::abs(d) <= CMP_EPSILON) { - return b.pos.y; + real_t d = b.position.x - a.position.x; + if (Math::is_zero_approx(d)) { + return b.position.y; } - local_offset /= d; + p_local_offset /= d; d /= 3.0; - real_t yac = a.pos.y + d * a.right_tangent; - real_t ybc = b.pos.y - d * b.left_tangent; + real_t yac = a.position.y + d * a.right_tangent; + real_t ybc = b.position.y - d * b.left_tangent; - real_t y = _bezier_interp(local_offset, a.pos.y, yac, ybc, b.pos.y); + real_t y = _bezier_interp(p_local_offset, a.position.y, yac, ybc, b.position.y); return y; } @@ -369,7 +369,7 @@ Array Curve::get_data() const { const Point p = _points[j]; int i = j * ELEMS; - output[i] = p.pos; + output[i] = p.position; output[i + 1] = p.left_tangent; output[i + 2] = p.right_tangent; output[i + 3] = p.left_mode; @@ -379,39 +379,39 @@ Array Curve::get_data() const { return output; } -void Curve::set_data(Array input) { +void Curve::set_data(const Array p_input) { const unsigned int ELEMS = 5; - ERR_FAIL_COND(input.size() % ELEMS != 0); + ERR_FAIL_COND(p_input.size() % ELEMS != 0); _points.clear(); // Validate input - for (int i = 0; i < input.size(); i += ELEMS) { - ERR_FAIL_COND(input[i].get_type() != Variant::VECTOR2); - ERR_FAIL_COND(!input[i + 1].is_num()); - ERR_FAIL_COND(input[i + 2].get_type() != Variant::FLOAT); + for (int i = 0; i < p_input.size(); i += ELEMS) { + ERR_FAIL_COND(p_input[i].get_type() != Variant::VECTOR2); + ERR_FAIL_COND(!p_input[i + 1].is_num()); + ERR_FAIL_COND(p_input[i + 2].get_type() != Variant::FLOAT); - ERR_FAIL_COND(input[i + 3].get_type() != Variant::INT); - int left_mode = input[i + 3]; + ERR_FAIL_COND(p_input[i + 3].get_type() != Variant::INT); + int left_mode = p_input[i + 3]; ERR_FAIL_COND(left_mode < 0 || left_mode >= TANGENT_MODE_COUNT); - ERR_FAIL_COND(input[i + 4].get_type() != Variant::INT); - int right_mode = input[i + 4]; + ERR_FAIL_COND(p_input[i + 4].get_type() != Variant::INT); + int right_mode = p_input[i + 4]; ERR_FAIL_COND(right_mode < 0 || right_mode >= TANGENT_MODE_COUNT); } - _points.resize(input.size() / ELEMS); + _points.resize(p_input.size() / ELEMS); for (int j = 0; j < _points.size(); ++j) { Point &p = _points.write[j]; int i = j * ELEMS; - p.pos = input[i]; - p.left_tangent = input[i + 1]; - p.right_tangent = input[i + 2]; + p.position = p_input[i]; + p.left_tangent = p_input[i + 1]; + p.right_tangent = p_input[i + 2]; // TODO For some reason the compiler won't convert from Variant to enum - int left_mode = input[i + 3]; - int right_mode = input[i + 4]; + int left_mode = p_input[i + 3]; + int right_mode = p_input[i + 4]; p.left_mode = (TangentMode)left_mode; p.right_mode = (TangentMode)right_mode; } @@ -431,8 +431,8 @@ void Curve::bake() { } if (_points.size() != 0) { - _baked_cache.write[0] = _points[0].pos.y; - _baked_cache.write[_baked_cache.size() - 1] = _points[_points.size() - 1].pos.y; + _baked_cache.write[0] = _points[0].position.y; + _baked_cache.write[_baked_cache.size() - 1] = _points[_points.size() - 1].position.y; } _baked_cache_dirty = false; @@ -445,7 +445,7 @@ void Curve::set_bake_resolution(int p_resolution) { _baked_cache_dirty = true; } -real_t Curve::interpolate_baked(real_t offset) const { +real_t Curve::interpolate_baked(real_t p_offset) const { if (_baked_cache_dirty) { // Last-second bake if not done already const_cast<Curve *>(this)->bake(); @@ -456,13 +456,13 @@ real_t Curve::interpolate_baked(real_t offset) const { if (_points.size() == 0) { return 0; } - return _points[0].pos.y; + return _points[0].position.y; } else if (_baked_cache.size() == 1) { return _baked_cache[0]; } // Get interpolation index - real_t fi = offset * _baked_cache.size(); + real_t fi = p_offset * _baked_cache.size(); int i = Math::floor(fi); if (i < 0) { i = 0; @@ -481,7 +481,7 @@ real_t Curve::interpolate_baked(real_t offset) const { } } -void Curve::ensure_default_setup(float p_min, float p_max) { +void Curve::ensure_default_setup(real_t p_min, real_t p_max) { if (_points.size() == 0 && _min_value == 0 && _max_value == 1) { add_point(Vector2(0, 1)); add_point(Vector2(1, 1)); @@ -535,9 +535,9 @@ int Curve2D::get_point_count() const { return points.size(); } -void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) { +void Curve2D::add_point(const Vector2 &p_position, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) { Point n; - n.pos = p_pos; + n.position = p_position; n.in = p_in; n.out = p_out; if (p_atpos >= 0 && p_atpos < points.size()) { @@ -550,17 +550,17 @@ void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2 emit_signal(CoreStringNames::get_singleton()->changed); } -void Curve2D::set_point_position(int p_index, const Vector2 &p_pos) { +void Curve2D::set_point_position(int p_index, const Vector2 &p_position) { ERR_FAIL_INDEX(p_index, points.size()); - points.write[p_index].pos = p_pos; + points.write[p_index].position = p_position; baked_cache_dirty = true; emit_signal(CoreStringNames::get_singleton()->changed); } Vector2 Curve2D::get_point_position(int p_index) const { ERR_FAIL_INDEX_V(p_index, points.size(), Vector2()); - return points[p_index].pos; + return points[p_index].position; } void Curve2D::set_point_in(int p_index, const Vector2 &p_in) { @@ -604,19 +604,19 @@ void Curve2D::clear_points() { } } -Vector2 Curve2D::interpolate(int p_index, float p_offset) const { +Vector2 Curve2D::interpolate(int p_index, const real_t p_offset) const { int pc = points.size(); ERR_FAIL_COND_V(pc == 0, Vector2()); if (p_index >= pc - 1) { - return points[pc - 1].pos; + return points[pc - 1].position; } else if (p_index < 0) { - return points[0].pos; + return points[0].position; } - Vector2 p0 = points[p_index].pos; + Vector2 p0 = points[p_index].position; Vector2 p1 = p0 + points[p_index].out; - Vector2 p3 = points[p_index + 1].pos; + Vector2 p3 = points[p_index + 1].position; Vector2 p2 = p3 + points[p_index + 1].in; return _bezier_interp(p_offset, p0, p1, p2, p3); @@ -632,15 +632,15 @@ Vector2 Curve2D::interpolatef(real_t p_findex) const { return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0)); } -void Curve2D::_bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const { - float mp = p_begin + (p_end - p_begin) * 0.5; +void Curve2D::_bake_segment2d(Map<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const { + real_t mp = p_begin + (p_end - p_begin) * 0.5; Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b); Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b); Vector2 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b); Vector2 na = (mid - beg).normalized(); Vector2 nb = (end - mid).normalized(); - float dp = na.dot(nb); + real_t dp = na.dot(nb); if (dp < Math::cos(Math::deg2rad(p_tol))) { r_bake[mp] = mid; @@ -668,47 +668,47 @@ void Curve2D::_bake() const { if (points.size() == 1) { baked_point_cache.resize(1); - baked_point_cache.set(0, points[0].pos); + baked_point_cache.set(0, points[0].position); baked_dist_cache.resize(1); baked_dist_cache.set(0, 0.0); return; } - Vector2 pos = points[0].pos; - float dist = 0.0; + Vector2 position = points[0].position; + real_t dist = 0.0; List<Vector2> pointlist; - List<float> distlist; + List<real_t> distlist; - pointlist.push_back(pos); //start always from origin + pointlist.push_back(position); //start always from origin distlist.push_back(0.0); for (int i = 0; i < points.size() - 1; i++) { - float step = 0.1; // at least 10 substeps ought to be enough? - float p = 0.0; + real_t step = 0.1; // at least 10 substeps ought to be enough? + real_t p = 0.0; while (p < 1.0) { - float np = p + step; + real_t np = p + step; if (np > 1.0) { np = 1.0; } - Vector2 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos); - float d = pos.distance_to(npp); + Vector2 npp = _bezier_interp(np, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position); + real_t d = position.distance_to(npp); if (d > bake_interval) { // OK! between P and NP there _has_ to be Something, let's go searching! int iterations = 10; //lots of detail! - float low = p; - float hi = np; - float mid = low + (hi - low) * 0.5; + real_t low = p; + real_t hi = np; + real_t mid = low + (hi - low) * 0.5; for (int j = 0; j < iterations; j++) { - npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos); - d = pos.distance_to(npp); + npp = _bezier_interp(mid, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position); + d = position.distance_to(npp); if (bake_interval < d) { hi = mid; @@ -718,11 +718,11 @@ void Curve2D::_bake() const { mid = low + (hi - low) * 0.5; } - pos = npp; + position = npp; p = mid; dist += d; - pointlist.push_back(pos); + pointlist.push_back(position); distlist.push_back(dist); } else { p = np; @@ -730,9 +730,9 @@ void Curve2D::_bake() const { } } - Vector2 lastpos = points[points.size() - 1].pos; + Vector2 lastpos = points[points.size() - 1].position; - float rem = pos.distance_to(lastpos); + real_t rem = position.distance_to(lastpos); dist += rem; baked_max_ofs = dist; pointlist.push_back(lastpos); @@ -742,7 +742,7 @@ void Curve2D::_bake() const { baked_dist_cache.resize(distlist.size()); Vector2 *w = baked_point_cache.ptrw(); - float *wd = baked_dist_cache.ptrw(); + real_t *wd = baked_dist_cache.ptrw(); for (int i = 0; i < pointlist.size(); i++) { w[i] = pointlist[i]; @@ -750,7 +750,7 @@ void Curve2D::_bake() const { } } -float Curve2D::get_baked_length() const { +real_t Curve2D::get_baked_length() const { if (baked_cache_dirty) { _bake(); } @@ -758,7 +758,7 @@ float Curve2D::get_baked_length() const { return baked_max_ofs; } -Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { +Vector2 Curve2D::interpolate_baked(real_t p_offset, bool p_cubic) const { if (baked_cache_dirty) { _bake(); } @@ -784,7 +784,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { int start = 0, end = bpc, idx = (end + start) / 2; // binary search to find baked points while (start < idx) { - float offset = baked_dist_cache[idx]; + real_t offset = baked_dist_cache[idx]; if (p_offset <= offset) { end = idx; } else { @@ -793,13 +793,13 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { idx = (end + start) / 2; } - float offset_begin = baked_dist_cache[idx]; - float offset_end = baked_dist_cache[idx + 1]; + real_t offset_begin = baked_dist_cache[idx]; + real_t offset_end = baked_dist_cache[idx + 1]; - float idx_interval = offset_end - offset_begin; + real_t idx_interval = offset_end - offset_begin; ERR_FAIL_COND_V_MSG(p_offset < offset_begin || p_offset > offset_end, Vector2(), "failed to find baked segment"); - float frac = (p_offset - offset_begin) / idx_interval; + real_t frac = (p_offset - offset_begin) / idx_interval; if (p_cubic) { Vector2 pre = idx > 0 ? r[idx - 1] : r[idx]; @@ -818,13 +818,13 @@ PackedVector2Array Curve2D::get_baked_points() const { return baked_point_cache; } -void Curve2D::set_bake_interval(float p_tolerance) { +void Curve2D::set_bake_interval(real_t p_tolerance) { bake_interval = p_tolerance; baked_cache_dirty = true; emit_signal(CoreStringNames::get_singleton()->changed); } -float Curve2D::get_bake_interval() const { +real_t Curve2D::get_bake_interval() const { return bake_interval; } @@ -846,16 +846,16 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const { const Vector2 *r = baked_point_cache.ptr(); Vector2 nearest; - float nearest_dist = -1.0f; + real_t nearest_dist = -1.0f; for (int i = 0; i < pc - 1; i++) { Vector2 origin = r[i]; Vector2 direction = (r[i + 1] - origin) / bake_interval; - float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); + real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); Vector2 proj = origin + direction * d; - float dist = proj.distance_squared_to(p_to_point); + real_t dist = proj.distance_squared_to(p_to_point); if (nearest_dist < 0.0f || dist < nearest_dist) { nearest = proj; @@ -866,7 +866,7 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const { return nearest; } -float Curve2D::get_closest_offset(const Vector2 &p_to_point) const { +real_t Curve2D::get_closest_offset(const Vector2 &p_to_point) const { // Brute force method if (baked_cache_dirty) { @@ -883,18 +883,18 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const { const Vector2 *r = baked_point_cache.ptr(); - float nearest = 0.0f; - float nearest_dist = -1.0f; - float offset = 0.0f; + real_t nearest = 0.0f; + real_t nearest_dist = -1.0f; + real_t offset = 0.0f; for (int i = 0; i < pc - 1; i++) { Vector2 origin = r[i]; Vector2 direction = (r[i + 1] - origin) / bake_interval; - float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); + real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); Vector2 proj = origin + direction * d; - float dist = proj.distance_squared_to(p_to_point); + real_t dist = proj.distance_squared_to(p_to_point); if (nearest_dist < 0.0f || dist < nearest_dist) { nearest = offset + d; @@ -917,7 +917,7 @@ Dictionary Curve2D::_get_data() const { for (int i = 0; i < points.size(); i++) { w[i * 3 + 0] = points[i].in; w[i * 3 + 1] = points[i].out; - w[i * 3 + 2] = points[i].pos; + w[i * 3 + 2] = points[i].position; } dc["points"] = d; @@ -937,42 +937,42 @@ void Curve2D::_set_data(const Dictionary &p_data) { for (int i = 0; i < points.size(); i++) { points.write[i].in = r[i * 3 + 0]; points.write[i].out = r[i * 3 + 1]; - points.write[i].pos = r[i * 3 + 2]; + points.write[i].position = r[i * 3 + 2]; } baked_cache_dirty = true; } -PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const { +PackedVector2Array Curve2D::tessellate(int p_max_stages, real_t p_tolerance) const { PackedVector2Array tess; if (points.size() == 0) { return tess; } - Vector<Map<float, Vector2>> midpoints; + Vector<Map<real_t, Vector2>> midpoints; midpoints.resize(points.size() - 1); int pc = 1; for (int i = 0; i < points.size() - 1; i++) { - _bake_segment2d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance); + _bake_segment2d(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_tolerance); pc++; pc += midpoints[i].size(); } tess.resize(pc); Vector2 *bpw = tess.ptrw(); - bpw[0] = points[0].pos; + bpw[0] = points[0].position; int pidx = 0; for (int i = 0; i < points.size() - 1; i++) { - for (const KeyValue<float, Vector2> &E : midpoints[i]) { + for (const KeyValue<real_t, Vector2> &E : midpoints[i]) { pidx++; bpw[pidx] = E.value; } pidx++; - bpw[pidx] = points[i + 1].pos; + bpw[pidx] = points[i + 1].position; } return tess; @@ -1026,9 +1026,9 @@ int Curve3D::get_point_count() const { return points.size(); } -void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) { +void Curve3D::add_point(const Vector3 &p_position, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) { Point n; - n.pos = p_pos; + n.position = p_position; n.in = p_in; n.out = p_out; if (p_atpos >= 0 && p_atpos < points.size()) { @@ -1041,20 +1041,20 @@ void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3 emit_signal(CoreStringNames::get_singleton()->changed); } -void Curve3D::set_point_position(int p_index, const Vector3 &p_pos) { +void Curve3D::set_point_position(int p_index, const Vector3 &p_position) { ERR_FAIL_INDEX(p_index, points.size()); - points.write[p_index].pos = p_pos; + points.write[p_index].position = p_position; baked_cache_dirty = true; emit_signal(CoreStringNames::get_singleton()->changed); } Vector3 Curve3D::get_point_position(int p_index) const { ERR_FAIL_INDEX_V(p_index, points.size(), Vector3()); - return points[p_index].pos; + return points[p_index].position; } -void Curve3D::set_point_tilt(int p_index, float p_tilt) { +void Curve3D::set_point_tilt(int p_index, real_t p_tilt) { ERR_FAIL_INDEX(p_index, points.size()); points.write[p_index].tilt = p_tilt; @@ -1062,7 +1062,7 @@ void Curve3D::set_point_tilt(int p_index, float p_tilt) { emit_signal(CoreStringNames::get_singleton()->changed); } -float Curve3D::get_point_tilt(int p_index) const { +real_t Curve3D::get_point_tilt(int p_index) const { ERR_FAIL_INDEX_V(p_index, points.size(), 0); return points[p_index].tilt; } @@ -1108,19 +1108,19 @@ void Curve3D::clear_points() { } } -Vector3 Curve3D::interpolate(int p_index, float p_offset) const { +Vector3 Curve3D::interpolate(int p_index, real_t p_offset) const { int pc = points.size(); ERR_FAIL_COND_V(pc == 0, Vector3()); if (p_index >= pc - 1) { - return points[pc - 1].pos; + return points[pc - 1].position; } else if (p_index < 0) { - return points[0].pos; + return points[0].position; } - Vector3 p0 = points[p_index].pos; + Vector3 p0 = points[p_index].position; Vector3 p1 = p0 + points[p_index].out; - Vector3 p3 = points[p_index + 1].pos; + Vector3 p3 = points[p_index + 1].position; Vector3 p2 = p3 + points[p_index + 1].in; return _bezier_interp(p_offset, p0, p1, p2, p3); @@ -1136,15 +1136,15 @@ Vector3 Curve3D::interpolatef(real_t p_findex) const { return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0)); } -void Curve3D::_bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const { - float mp = p_begin + (p_end - p_begin) * 0.5; +void Curve3D::_bake_segment3d(Map<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const { + real_t mp = p_begin + (p_end - p_begin) * 0.5; Vector3 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b); Vector3 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b); Vector3 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b); Vector3 na = (mid - beg).normalized(); Vector3 nb = (end - mid).normalized(); - float dp = na.dot(nb); + real_t dp = na.dot(nb); if (dp < Math::cos(Math::deg2rad(p_tol))) { r_bake[mp] = mid; @@ -1173,7 +1173,7 @@ void Curve3D::_bake() const { if (points.size() == 1) { baked_point_cache.resize(1); - baked_point_cache.set(0, points[0].pos); + baked_point_cache.set(0, points[0].position); baked_tilt_cache.resize(1); baked_tilt_cache.set(0, points[0].tilt); baked_dist_cache.resize(1); @@ -1189,39 +1189,39 @@ void Curve3D::_bake() const { return; } - Vector3 pos = points[0].pos; - float dist = 0.0; + Vector3 position = points[0].position; + real_t dist = 0.0; List<Plane> pointlist; - List<float> distlist; + List<real_t> distlist; - pointlist.push_back(Plane(pos, points[0].tilt)); + pointlist.push_back(Plane(position, points[0].tilt)); distlist.push_back(0.0); for (int i = 0; i < points.size() - 1; i++) { - float step = 0.1; // at least 10 substeps ought to be enough? - float p = 0.0; + real_t step = 0.1; // at least 10 substeps ought to be enough? + real_t p = 0.0; while (p < 1.0) { - float np = p + step; + real_t np = p + step; if (np > 1.0) { np = 1.0; } - Vector3 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos); - float d = pos.distance_to(npp); + Vector3 npp = _bezier_interp(np, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position); + real_t d = position.distance_to(npp); if (d > bake_interval) { // OK! between P and NP there _has_ to be Something, let's go searching! int iterations = 10; //lots of detail! - float low = p; - float hi = np; - float mid = low + (hi - low) * 0.5; + real_t low = p; + real_t hi = np; + real_t mid = low + (hi - low) * 0.5; for (int j = 0; j < iterations; j++) { - npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos); - d = pos.distance_to(npp); + npp = _bezier_interp(mid, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position); + d = position.distance_to(npp); if (bake_interval < d) { hi = mid; @@ -1231,10 +1231,10 @@ void Curve3D::_bake() const { mid = low + (hi - low) * 0.5; } - pos = npp; + position = npp; p = mid; Plane post; - post.normal = pos; + post.normal = position; post.d = Math::lerp(points[i].tilt, points[i + 1].tilt, mid); dist += d; @@ -1246,10 +1246,10 @@ void Curve3D::_bake() const { } } - Vector3 lastpos = points[points.size() - 1].pos; - float lastilt = points[points.size() - 1].tilt; + Vector3 lastpos = points[points.size() - 1].position; + real_t lastilt = points[points.size() - 1].tilt; - float rem = pos.distance_to(lastpos); + real_t rem = position.distance_to(lastpos); dist += rem; baked_max_ofs = dist; pointlist.push_back(Plane(lastpos, lastilt)); @@ -1266,7 +1266,7 @@ void Curve3D::_bake() const { Vector3 *up_write = baked_up_vector_cache.ptrw(); baked_dist_cache.resize(pointlist.size()); - float *wd = baked_dist_cache.ptrw(); + real_t *wd = baked_dist_cache.ptrw(); Vector3 sideways; Vector3 up; @@ -1288,7 +1288,7 @@ void Curve3D::_bake() const { forward = idx > 0 ? (w[idx] - w[idx - 1]).normalized() : prev_forward; - float y_dot = prev_up.dot(forward); + real_t y_dot = prev_up.dot(forward); if (y_dot > (1.0f - CMP_EPSILON)) { sideways = prev_sideways; @@ -1315,7 +1315,7 @@ void Curve3D::_bake() const { } } -float Curve3D::get_baked_length() const { +real_t Curve3D::get_baked_length() const { if (baked_cache_dirty) { _bake(); } @@ -1323,7 +1323,7 @@ float Curve3D::get_baked_length() const { return baked_max_ofs; } -Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { +Vector3 Curve3D::interpolate_baked(real_t p_offset, bool p_cubic) const { if (baked_cache_dirty) { _bake(); } @@ -1349,7 +1349,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { int start = 0, end = bpc, idx = (end + start) / 2; // binary search to find baked points while (start < idx) { - float offset = baked_dist_cache[idx]; + real_t offset = baked_dist_cache[idx]; if (p_offset <= offset) { end = idx; } else { @@ -1358,13 +1358,13 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { idx = (end + start) / 2; } - float offset_begin = baked_dist_cache[idx]; - float offset_end = baked_dist_cache[idx + 1]; + real_t offset_begin = baked_dist_cache[idx]; + real_t offset_end = baked_dist_cache[idx + 1]; - float idx_interval = offset_end - offset_begin; + real_t idx_interval = offset_end - offset_begin; ERR_FAIL_COND_V_MSG(p_offset < offset_begin || p_offset > offset_end, Vector3(), "failed to find baked segment"); - float frac = (p_offset - offset_begin) / idx_interval; + real_t frac = (p_offset - offset_begin) / idx_interval; if (p_cubic) { Vector3 pre = idx > 0 ? r[idx - 1] : r[idx]; @@ -1375,7 +1375,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { } } -float Curve3D::interpolate_baked_tilt(float p_offset) const { +real_t Curve3D::interpolate_baked_tilt(real_t p_offset) const { if (baked_cache_dirty) { _bake(); } @@ -1399,7 +1399,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const { } int idx = Math::floor((double)p_offset / (double)bake_interval); - float frac = Math::fmod(p_offset, bake_interval); + real_t frac = Math::fmod(p_offset, bake_interval); if (idx >= bpc - 1) { return r[bpc - 1]; @@ -1414,7 +1414,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const { return Math::lerp(r[idx], r[idx + 1], (real_t)frac); } -Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) const { +Vector3 Curve3D::interpolate_baked_up_vector(real_t p_offset, bool p_apply_tilt) const { if (baked_cache_dirty) { _bake(); } @@ -1432,10 +1432,10 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) const Vector3 *rp = baked_point_cache.ptr(); const real_t *rt = baked_tilt_cache.ptr(); - float offset = CLAMP(p_offset, 0.0f, baked_max_ofs); + real_t offset = CLAMP(p_offset, 0.0f, baked_max_ofs); int idx = Math::floor((double)offset / (double)bake_interval); - float frac = Math::fmod(offset, bake_interval) / bake_interval; + real_t frac = Math::fmod(offset, bake_interval) / bake_interval; if (idx == count - 1) { return p_apply_tilt ? r[idx].rotated((rp[idx] - rp[idx - 1]).normalized(), rt[idx]) : r[idx]; @@ -1503,16 +1503,16 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const { const Vector3 *r = baked_point_cache.ptr(); Vector3 nearest; - float nearest_dist = -1.0f; + real_t nearest_dist = -1.0f; for (int i = 0; i < pc - 1; i++) { Vector3 origin = r[i]; Vector3 direction = (r[i + 1] - origin) / bake_interval; - float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); + real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); Vector3 proj = origin + direction * d; - float dist = proj.distance_squared_to(p_to_point); + real_t dist = proj.distance_squared_to(p_to_point); if (nearest_dist < 0.0f || dist < nearest_dist) { nearest = proj; @@ -1523,7 +1523,7 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const { return nearest; } -float Curve3D::get_closest_offset(const Vector3 &p_to_point) const { +real_t Curve3D::get_closest_offset(const Vector3 &p_to_point) const { // Brute force method if (baked_cache_dirty) { @@ -1540,18 +1540,18 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const { const Vector3 *r = baked_point_cache.ptr(); - float nearest = 0.0f; - float nearest_dist = -1.0f; - float offset = 0.0f; + real_t nearest = 0.0f; + real_t nearest_dist = -1.0f; + real_t offset = 0.0f; for (int i = 0; i < pc - 1; i++) { Vector3 origin = r[i]; Vector3 direction = (r[i + 1] - origin) / bake_interval; - float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); + real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); Vector3 proj = origin + direction * d; - float dist = proj.distance_squared_to(p_to_point); + real_t dist = proj.distance_squared_to(p_to_point); if (nearest_dist < 0.0f || dist < nearest_dist) { nearest = offset + d; @@ -1564,13 +1564,13 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const { return nearest; } -void Curve3D::set_bake_interval(float p_tolerance) { +void Curve3D::set_bake_interval(real_t p_tolerance) { bake_interval = p_tolerance; baked_cache_dirty = true; emit_signal(CoreStringNames::get_singleton()->changed); } -float Curve3D::get_bake_interval() const { +real_t Curve3D::get_bake_interval() const { return bake_interval; } @@ -1597,7 +1597,7 @@ Dictionary Curve3D::_get_data() const { for (int i = 0; i < points.size(); i++) { w[i * 3 + 0] = points[i].in; w[i * 3 + 1] = points[i].out; - w[i * 3 + 2] = points[i].pos; + w[i * 3 + 2] = points[i].position; wt[i] = points[i].tilt; } @@ -1622,43 +1622,43 @@ void Curve3D::_set_data(const Dictionary &p_data) { for (int i = 0; i < points.size(); i++) { points.write[i].in = r[i * 3 + 0]; points.write[i].out = r[i * 3 + 1]; - points.write[i].pos = r[i * 3 + 2]; + points.write[i].position = r[i * 3 + 2]; points.write[i].tilt = rt[i]; } baked_cache_dirty = true; } -PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const { +PackedVector3Array Curve3D::tessellate(int p_max_stages, real_t p_tolerance) const { PackedVector3Array tess; if (points.size() == 0) { return tess; } - Vector<Map<float, Vector3>> midpoints; + Vector<Map<real_t, Vector3>> midpoints; midpoints.resize(points.size() - 1); int pc = 1; for (int i = 0; i < points.size() - 1; i++) { - _bake_segment3d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance); + _bake_segment3d(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_tolerance); pc++; pc += midpoints[i].size(); } tess.resize(pc); Vector3 *bpw = tess.ptrw(); - bpw[0] = points[0].pos; + bpw[0] = points[0].position; int pidx = 0; for (int i = 0; i < points.size() - 1; i++) { - for (const KeyValue<float, Vector3> &E : midpoints[i]) { + for (const KeyValue<real_t, Vector3> &E : midpoints[i]) { pidx++; bpw[pidx] = E.value; } pidx++; - bpw[pidx] = points[i + 1].pos; + bpw[pidx] = points[i + 1].position; } return tess; diff --git a/scene/resources/curve.h b/scene/resources/curve.h index 5808fd6508..16facda85a 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -50,7 +50,7 @@ public: }; struct Point { - Vector2 pos; + Vector2 position; real_t left_tangent = 0.0; real_t right_tangent = 0.0; TangentMode left_mode = TANGENT_FREE; @@ -59,12 +59,12 @@ public: Point() { } - Point(Vector2 p_pos, + Point(const Vector2 &p_position, real_t p_left = 0.0, real_t p_right = 0.0, TangentMode p_left_mode = TANGENT_FREE, TangentMode p_right_mode = TANGENT_FREE) { - pos = p_pos; + position = p_position; left_tangent = p_left; right_tangent = p_right; left_mode = p_left_mode; @@ -76,7 +76,7 @@ public: int get_point_count() const { return _points.size(); } - int add_point(Vector2 p_pos, + int add_point(Vector2 p_position, real_t left_tangent = 0, real_t right_tangent = 0, TangentMode left_mode = TANGENT_FREE, @@ -85,34 +85,34 @@ public: void remove_point(int p_index); void clear_points(); - int get_index(real_t offset) const; + int get_index(real_t p_offset) const; - void set_point_value(int p_index, real_t pos); - int set_point_offset(int p_index, float offset); + void set_point_value(int p_index, real_t p_position); + int set_point_offset(int p_index, real_t p_offset); Vector2 get_point_position(int p_index) const; Point get_point(int p_index) const; - float get_min_value() const { return _min_value; } - void set_min_value(float p_min); + real_t get_min_value() const { return _min_value; } + void set_min_value(real_t p_min); - float get_max_value() const { return _max_value; } - void set_max_value(float p_max); + real_t get_max_value() const { return _max_value; } + void set_max_value(real_t p_max); - real_t interpolate(real_t offset) const; - real_t interpolate_local_nocheck(int index, real_t local_offset) const; + real_t interpolate(real_t p_offset) const; + real_t interpolate_local_nocheck(int p_index, real_t p_local_offset) const; void clean_dupes(); - void set_point_left_tangent(int i, real_t tangent); - void set_point_right_tangent(int i, real_t tangent); - void set_point_left_mode(int i, TangentMode p_mode); - void set_point_right_mode(int i, TangentMode p_mode); + void set_point_left_tangent(int p_index, real_t p_tangent); + void set_point_right_tangent(int p_index, real_t p_tangent); + void set_point_left_mode(int p_index, TangentMode p_mode); + void set_point_right_mode(int p_index, TangentMode p_mode); - real_t get_point_left_tangent(int i) const; - real_t get_point_right_tangent(int i) const; - TangentMode get_point_left_mode(int i) const; - TangentMode get_point_right_mode(int i) const; + real_t get_point_left_tangent(int p_index) const; + real_t get_point_right_tangent(int p_index) const; + TangentMode get_point_left_mode(int p_index) const; + TangentMode get_point_right_mode(int p_index) const; void update_auto_tangents(int i); @@ -122,9 +122,9 @@ public: void bake(); int get_bake_resolution() const { return _bake_resolution; } void set_bake_resolution(int p_resolution); - real_t interpolate_baked(real_t offset) const; + real_t interpolate_baked(real_t p_offset) const; - void ensure_default_setup(float p_min, float p_max); + void ensure_default_setup(real_t p_min, real_t p_max); protected: static void _bind_methods(); @@ -136,8 +136,8 @@ private: bool _baked_cache_dirty = false; Vector<real_t> _baked_cache; int _bake_resolution = 100; - float _min_value = 0.0; - float _max_value = 1.0; + real_t _min_value = 0.0; + real_t _max_value = 1.0; int _minmax_set_once = 0b00; // Encodes whether min and max have been set a first time, first bit for min and second for max. }; @@ -149,26 +149,26 @@ class Curve2D : public Resource { struct Point { Vector2 in; Vector2 out; - Vector2 pos; + Vector2 position; }; Vector<Point> points; struct BakedPoint { - float ofs = 0.0; + real_t ofs = 0.0; Vector2 point; }; mutable bool baked_cache_dirty = false; mutable PackedVector2Array baked_point_cache; - mutable PackedFloat32Array baked_dist_cache; - mutable float baked_max_ofs = 0.0; + mutable Vector<real_t> baked_dist_cache; + mutable real_t baked_max_ofs = 0.0; void _bake() const; - float bake_interval = 5.0; + real_t bake_interval = 5.0; - void _bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const; + void _bake_segment2d(Map<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const; Dictionary _get_data() const; void _set_data(const Dictionary &p_data); @@ -177,8 +177,8 @@ protected: public: int get_point_count() const; - void add_point(const Vector2 &p_pos, const Vector2 &p_in = Vector2(), const Vector2 &p_out = Vector2(), int p_atpos = -1); - void set_point_position(int p_index, const Vector2 &p_pos); + void add_point(const Vector2 &p_position, const Vector2 &p_in = Vector2(), const Vector2 &p_out = Vector2(), int p_atpos = -1); + void set_point_position(int p_index, const Vector2 &p_position); Vector2 get_point_position(int p_index) const; void set_point_in(int p_index, const Vector2 &p_in); Vector2 get_point_in(int p_index) const; @@ -187,19 +187,19 @@ public: void remove_point(int p_index); void clear_points(); - Vector2 interpolate(int p_index, float p_offset) const; + Vector2 interpolate(int p_index, real_t p_offset) const; Vector2 interpolatef(real_t p_findex) const; - void set_bake_interval(float p_tolerance); - float get_bake_interval() const; + void set_bake_interval(real_t p_tolerance); + real_t get_bake_interval() const; - float get_baked_length() const; - Vector2 interpolate_baked(float p_offset, bool p_cubic = false) const; + real_t get_baked_length() const; + Vector2 interpolate_baked(real_t p_offset, bool p_cubic = false) const; PackedVector2Array get_baked_points() const; //useful for going through Vector2 get_closest_point(const Vector2 &p_to_point) const; - float get_closest_offset(const Vector2 &p_to_point) const; + real_t get_closest_offset(const Vector2 &p_to_point) const; - PackedVector2Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display + PackedVector2Array tessellate(int p_max_stages = 5, real_t p_tolerance = 4) const; //useful for display Curve2D(); }; @@ -210,14 +210,14 @@ class Curve3D : public Resource { struct Point { Vector3 in; Vector3 out; - Vector3 pos; - float tilt = 0.0; + Vector3 position; + real_t tilt = 0.0; }; Vector<Point> points; struct BakedPoint { - float ofs = 0.0; + real_t ofs = 0.0; Vector3 point; }; @@ -225,15 +225,15 @@ class Curve3D : public Resource { mutable PackedVector3Array baked_point_cache; mutable Vector<real_t> baked_tilt_cache; mutable PackedVector3Array baked_up_vector_cache; - mutable PackedFloat32Array baked_dist_cache; - mutable float baked_max_ofs = 0.0; + mutable Vector<real_t> baked_dist_cache; + mutable real_t baked_max_ofs = 0.0; void _bake() const; - float bake_interval = 0.2; + real_t bake_interval = 0.2; bool up_vector_enabled = true; - void _bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const; + void _bake_segment3d(Map<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const; Dictionary _get_data() const; void _set_data(const Dictionary &p_data); @@ -242,11 +242,11 @@ protected: public: int get_point_count() const; - void add_point(const Vector3 &p_pos, const Vector3 &p_in = Vector3(), const Vector3 &p_out = Vector3(), int p_atpos = -1); - void set_point_position(int p_index, const Vector3 &p_pos); + void add_point(const Vector3 &p_position, const Vector3 &p_in = Vector3(), const Vector3 &p_out = Vector3(), int p_atpos = -1); + void set_point_position(int p_index, const Vector3 &p_position); Vector3 get_point_position(int p_index) const; - void set_point_tilt(int p_index, float p_tilt); - float get_point_tilt(int p_index) const; + void set_point_tilt(int p_index, real_t p_tilt); + real_t get_point_tilt(int p_index) const; void set_point_in(int p_index, const Vector3 &p_in); Vector3 get_point_in(int p_index) const; void set_point_out(int p_index, const Vector3 &p_out); @@ -254,25 +254,25 @@ public: void remove_point(int p_index); void clear_points(); - Vector3 interpolate(int p_index, float p_offset) const; + Vector3 interpolate(int p_index, real_t p_offset) const; Vector3 interpolatef(real_t p_findex) const; - void set_bake_interval(float p_tolerance); - float get_bake_interval() const; + void set_bake_interval(real_t p_tolerance); + real_t get_bake_interval() const; void set_up_vector_enabled(bool p_enable); bool is_up_vector_enabled() const; - float get_baked_length() const; - Vector3 interpolate_baked(float p_offset, bool p_cubic = false) const; - float interpolate_baked_tilt(float p_offset) const; - Vector3 interpolate_baked_up_vector(float p_offset, bool p_apply_tilt = false) const; + real_t get_baked_length() const; + Vector3 interpolate_baked(real_t p_offset, bool p_cubic = false) const; + real_t interpolate_baked_tilt(real_t p_offset) const; + Vector3 interpolate_baked_up_vector(real_t p_offset, bool p_apply_tilt = false) const; PackedVector3Array get_baked_points() const; //useful for going through Vector<real_t> get_baked_tilts() const; //useful for going through PackedVector3Array get_baked_up_vectors() const; Vector3 get_closest_point(const Vector3 &p_to_point) const; - float get_closest_offset(const Vector3 &p_to_point) const; + real_t get_closest_offset(const Vector3 &p_to_point) const; - PackedVector3Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display + PackedVector3Array tessellate(int p_max_stages = 5, real_t p_tolerance = 4) const; //useful for display Curve3D(); }; diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp index fe7124de9e..4f9a055bfb 100644 --- a/scene/resources/immediate_mesh.cpp +++ b/scene/resources/immediate_mesh.cpp @@ -144,6 +144,7 @@ void ImmediateMesh::surface_add_vertex_2d(const Vector2 &p_vertex) { active_surface_data.vertex_2d = true; } + void ImmediateMesh::surface_end() { ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it."); ERR_FAIL_COND_MSG(!vertices.size(), "No vertices were added, surface can't be created."); @@ -185,7 +186,7 @@ void ImmediateMesh::surface_end() { vtx[2] = vertices[i].z; } if (i == 0) { - aabb.position = vertices[i]; + aabb = AABB(vertices[i], SMALL_VEC3); // Must have a bit of size. } else { aabb.expand_to(vertices[i]); } diff --git a/scene/resources/immediate_mesh.h b/scene/resources/immediate_mesh.h index 6673ee6f3d..92bf91441d 100644 --- a/scene/resources/immediate_mesh.h +++ b/scene/resources/immediate_mesh.h @@ -75,6 +75,8 @@ class ImmediateMesh : public Mesh { Vector<uint8_t> surface_vertex_create_cache; Vector<uint8_t> surface_attribute_create_cache; + const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON); + protected: static void _bind_methods(); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 8399b14a56..98bda4ad1b 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -1658,13 +1658,28 @@ bool BaseMaterial3D::get_feature(Feature p_feature) const { void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) { ERR_FAIL_INDEX(p_param, TEXTURE_MAX); + + if (get_texture(TEXTURE_ROUGHNESS).is_null() && p_texture.is_valid() && p_param == TEXTURE_ROUGHNESS) { + // If no roughness texture is currently set, automatically set the recommended value + // for roughness when using a roughness map. + set_roughness(1.0); + } + + if (get_texture(TEXTURE_METALLIC).is_null() && p_texture.is_valid() && p_param == TEXTURE_METALLIC) { + // If no metallic texture is currently set, automatically set the recommended value + // for metallic when using a metallic map. + set_metallic(1.0); + } + textures[p_param] = p_texture; RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid); + if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) { RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size, Vector2i(p_texture->get_width(), p_texture->get_height())); } + notify_property_list_changed(); _queue_shader_change(); } @@ -2884,7 +2899,7 @@ bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value) idx++; } - print_line("remapped parameter not found: " + String(p_name)); + WARN_PRINT("Godot 3.x SpatialMaterial remapped parameter not found: " + String(p_name)); return true; } diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 51b4e1fbd8..e14d6be235 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -994,9 +994,9 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { } //clear unused flags - print_line("format pre: " + itos(old_format)); + print_verbose("Mesh format pre-conversion: " + itos(old_format)); - print_line("format post: " + itos(new_format)); + print_verbose("Mesh format post-conversion: " + itos(new_format)); ERR_FAIL_COND_V(!d.has("aabb"), false); AABB aabb = d["aabb"]; diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index e77f5a0be7..5ceb90d511 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -584,7 +584,7 @@ void ParticlesMaterial::_update_shader() { code += " float base_angle = (tex_angle) * mix(initial_angle_min, initial_angle_max, rand_from_seed(alt_seed));\n"; code += " base_angle += CUSTOM.y * LIFETIME * (tex_angular_velocity) * mix(angular_velocity_min,angular_velocity_max, rand_from_seed(alt_seed));\n"; code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle - code += " CUSTOM.z = (tex_anim_offset) * mix(anim_offset_min, anim_offset_max, rand_from_seed(alt_seed)) + CUSTOM.y * tex_anim_speed * mix(anim_speed_min, anim_speed_max, rand_from_seed(alt_seed));\n"; // angle + code += " CUSTOM.z = (tex_anim_offset) * mix(anim_offset_min, anim_offset_max, rand_from_seed(alt_seed)) + tv * tex_anim_speed * mix(anim_speed_min, anim_speed_max, rand_from_seed(alt_seed));\n"; // angle // apply color // apply hue rotation diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 951870fe34..e6870971d4 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -1647,6 +1647,21 @@ String VisualShaderNodeIntOp::generate_code(Shader::Mode p_mode, VisualShader::T case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_BITWISE_AND: + code += p_input_vars[0] + " & " + p_input_vars[1] + ";\n"; + break; + case OP_BITWISE_OR: + code += p_input_vars[0] + " | " + p_input_vars[1] + ";\n"; + break; + case OP_BITWISE_XOR: + code += p_input_vars[0] + " ^ " + p_input_vars[1] + ";\n"; + break; + case OP_BITWISE_LEFT_SHIFT: + code += p_input_vars[0] + " << " + p_input_vars[1] + ";\n"; + break; + case OP_BITWISE_RIGHT_SHIFT: + code += p_input_vars[0] + " >> " + p_input_vars[1] + ";\n"; + break; default: break; } @@ -1677,7 +1692,7 @@ void VisualShaderNodeIntOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min,Bitwise AND,Bitwise OR,Bitwise XOR,Bitwise Left Shift,Bitwise Right Shift"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1686,6 +1701,11 @@ void VisualShaderNodeIntOp::_bind_methods() { BIND_ENUM_CONSTANT(OP_MOD); BIND_ENUM_CONSTANT(OP_MAX); BIND_ENUM_CONSTANT(OP_MIN); + BIND_ENUM_CONSTANT(OP_BITWISE_AND); + BIND_ENUM_CONSTANT(OP_BITWISE_OR); + BIND_ENUM_CONSTANT(OP_BITWISE_XOR); + BIND_ENUM_CONSTANT(OP_BITWISE_LEFT_SHIFT); + BIND_ENUM_CONSTANT(OP_BITWISE_RIGHT_SHIFT); BIND_ENUM_CONSTANT(OP_ENUM_SIZE); } @@ -2333,7 +2353,8 @@ String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader: static const char *functions[FUNC_MAX] = { "abs($)", "-($)", - "sign($)" + "sign($)", + "~($)" }; return " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n"; @@ -2362,11 +2383,12 @@ void VisualShaderNodeIntFunc::_bind_methods() { ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function); ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function); - ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign"), "set_function", "get_function"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign,Bitwise NOT"), "set_function", "get_function"); BIND_ENUM_CONSTANT(FUNC_ABS); BIND_ENUM_CONSTANT(FUNC_NEGATE); BIND_ENUM_CONSTANT(FUNC_SIGN); + BIND_ENUM_CONSTANT(FUNC_BITWISE_NOT); BIND_ENUM_CONSTANT(FUNC_MAX); } diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 2c952300fe..2f3400404c 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -579,6 +579,11 @@ public: OP_MOD, OP_MAX, OP_MIN, + OP_BITWISE_AND, + OP_BITWISE_OR, + OP_BITWISE_XOR, + OP_BITWISE_LEFT_SHIFT, + OP_BITWISE_RIGHT_SHIFT, OP_ENUM_SIZE, }; @@ -882,6 +887,7 @@ public: FUNC_ABS, FUNC_NEGATE, FUNC_SIGN, + FUNC_BITWISE_NOT, FUNC_MAX, }; diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp index 1a829968e3..a7c20b2cb9 100644 --- a/scene/resources/visual_shader_particle_nodes.cpp +++ b/scene/resources/visual_shader_particle_nodes.cpp @@ -318,26 +318,24 @@ String VisualShaderNodeParticleMeshEmitter::get_input_port_name(int p_port) cons String VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code; - if (mesh.is_valid()) { - if (is_output_port_connected(0)) { // position - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n"; - } + if (is_output_port_connected(0)) { // position + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n"; + } - if (is_output_port_connected(1)) { // normal - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n"; - } + if (is_output_port_connected(1)) { // normal + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n"; + } - if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n"; - } + if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n"; + } - if (is_output_port_connected(4)) { // uv - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n"; - } + if (is_output_port_connected(4)) { // uv + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n"; + } - if (is_output_port_connected(5)) { // uv2 - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n"; - } + if (is_output_port_connected(5)) { // uv2 + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n"; } return code; @@ -503,67 +501,97 @@ void VisualShaderNodeParticleMeshEmitter::_update_textures() { Vector<Vector2> uvs; Vector<Vector2> uvs2; + const int surface_count = mesh->get_surface_count(); + if (use_all_surfaces) { - for (int i = 0; i < max_surface_index; i++) { + for (int i = 0; i < surface_count; i++) { + const Array surface_arrays = mesh->surface_get_arrays(i); + const int surface_arrays_size = surface_arrays.size(); + // position - Array vertex_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_VERTEX]; - for (int j = 0; j < vertex_array.size(); j++) { - vertices.push_back((Vector3)vertex_array[j]); + if (surface_arrays_size > Mesh::ARRAY_VERTEX) { + Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX]; + for (int j = 0; j < vertex_array.size(); j++) { + vertices.push_back((Vector3)vertex_array[j]); + } } // normal - Array normal_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_NORMAL]; - for (int j = 0; j < normal_array.size(); j++) { - normals.push_back((Vector3)normal_array[j]); + if (surface_arrays_size > Mesh::ARRAY_NORMAL) { + Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL]; + for (int j = 0; j < normal_array.size(); j++) { + normals.push_back((Vector3)normal_array[j]); + } } // color - Array color_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_COLOR]; - for (int j = 0; j < color_array.size(); j++) { - colors.push_back((Color)color_array[j]); + if (surface_arrays_size > Mesh::ARRAY_COLOR) { + Array color_array = surface_arrays[Mesh::ARRAY_COLOR]; + for (int j = 0; j < color_array.size(); j++) { + colors.push_back((Color)color_array[j]); + } } // uv - Array uv_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV]; - for (int j = 0; j < uv_array.size(); j++) { - uvs.push_back((Vector2)uv_array[j]); + if (surface_arrays_size > Mesh::ARRAY_TEX_UV) { + Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV]; + for (int j = 0; j < uv_array.size(); j++) { + uvs.push_back((Vector2)uv_array[j]); + } } // uv2 - Array uv2_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV2]; - for (int j = 0; j < uv2_array.size(); j++) { - uvs2.push_back((Vector2)uv2_array[j]); + if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) { + Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2]; + for (int j = 0; j < uv2_array.size(); j++) { + uvs2.push_back((Vector2)uv2_array[j]); + } } } } else { - // position - Array vertex_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_VERTEX]; - for (int i = 0; i < vertex_array.size(); i++) { - vertices.push_back((Vector3)vertex_array[i]); - } + if (surface_index >= 0 && surface_index < surface_count) { + const Array surface_arrays = mesh->surface_get_arrays(surface_index); + const int surface_arrays_size = surface_arrays.size(); - // normal - Array normal_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_NORMAL]; - for (int i = 0; i < normal_array.size(); i++) { - normals.push_back((Vector3)normal_array[i]); - } + // position + if (surface_arrays_size > Mesh::ARRAY_VERTEX) { + Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX]; + for (int i = 0; i < vertex_array.size(); i++) { + vertices.push_back((Vector3)vertex_array[i]); + } + } - // color - Array color_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_COLOR]; - for (int i = 0; i < color_array.size(); i++) { - colors.push_back((Color)color_array[i]); - } + // normal + if (surface_arrays_size > Mesh::ARRAY_NORMAL) { + Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL]; + for (int i = 0; i < normal_array.size(); i++) { + normals.push_back((Vector3)normal_array[i]); + } + } - // uv - Array uv_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV]; - for (int j = 0; j < uv_array.size(); j++) { - uvs.push_back((Vector2)uv_array[j]); - } + // color + if (surface_arrays_size > Mesh::ARRAY_COLOR) { + Array color_array = surface_arrays[Mesh::ARRAY_COLOR]; + for (int i = 0; i < color_array.size(); i++) { + colors.push_back((Color)color_array[i]); + } + } + + // uv + if (surface_arrays_size > Mesh::ARRAY_TEX_UV) { + Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV]; + for (int j = 0; j < uv_array.size(); j++) { + uvs.push_back((Vector2)uv_array[j]); + } + } - // uv2 - Array uv2_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV2]; - for (int j = 0; j < uv2_array.size(); j++) { - uvs2.push_back((Vector2)uv2_array[j]); + // uv2 + if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) { + Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2]; + for (int j = 0; j < uv2_array.size(); j++) { + uvs2.push_back((Vector2)uv2_array[j]); + } + } } } @@ -579,12 +607,6 @@ void VisualShaderNodeParticleMeshEmitter::set_mesh(Ref<Mesh> p_mesh) { return; } - if (p_mesh.is_valid()) { - max_surface_index = p_mesh->get_surface_count(); - } else { - max_surface_index = 0; - } - if (mesh.is_valid()) { Callable callable = callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures); @@ -623,7 +645,16 @@ bool VisualShaderNodeParticleMeshEmitter::is_use_all_surfaces() const { } void VisualShaderNodeParticleMeshEmitter::set_surface_index(int p_surface_index) { - if (p_surface_index == surface_index || p_surface_index < 0 || p_surface_index >= max_surface_index) { + if (mesh.is_valid()) { + if (mesh->get_surface_count() > 0) { + p_surface_index = CLAMP(p_surface_index, 0, mesh->get_surface_count() - 1); + } else { + p_surface_index = 0; + } + } else if (p_surface_index < 0) { + p_surface_index = 0; + } + if (surface_index == p_surface_index) { return; } surface_index = p_surface_index; diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h index 79459432f1..ae7ea69225 100644 --- a/scene/resources/visual_shader_particle_nodes.h +++ b/scene/resources/visual_shader_particle_nodes.h @@ -111,7 +111,6 @@ class VisualShaderNodeParticleMeshEmitter : public VisualShaderNodeParticleEmitt Ref<Mesh> mesh; bool use_all_surfaces = true; int surface_index = 0; - int max_surface_index = 0; Ref<ImageTexture> position_texture; Ref<ImageTexture> normal_texture; diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 186764e69e..a5ed27cb7b 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -61,6 +61,7 @@ SceneStringNames::SceneStringNames() { animation_finished = StaticCString::create("animation_finished"); animation_changed = StaticCString::create("animation_changed"); animation_started = StaticCString::create("animation_started"); + RESET = StaticCString::create("RESET"); pose_updated = StaticCString::create("pose_updated"); bone_pose_changed = StaticCString::create("bone_pose_changed"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 67007c85e0..b1ace1748c 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -97,6 +97,7 @@ public: StringName animation_finished; StringName animation_changed; StringName animation_started; + StringName RESET; StringName pose_updated; StringName bone_pose_changed; |