summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/audio_stream_player_2d.cpp2
-rw-r--r--scene/2d/cpu_particles_2d.cpp4
-rw-r--r--scene/2d/navigation_agent_2d.cpp32
-rw-r--r--scene/2d/navigation_link_2d.cpp38
-rw-r--r--scene/2d/navigation_link_2d.h6
-rw-r--r--scene/2d/skeleton_2d.cpp13
-rw-r--r--scene/2d/skeleton_2d.h3
-rw-r--r--scene/2d/touch_screen_button.cpp4
-rw-r--r--scene/3d/audio_stream_player_3d.cpp2
-rw-r--r--scene/3d/cpu_particles_3d.cpp4
-rw-r--r--scene/3d/navigation_agent_3d.cpp34
-rw-r--r--scene/3d/navigation_agent_3d.h6
-rw-r--r--scene/3d/navigation_link_3d.cpp38
-rw-r--r--scene/3d/navigation_link_3d.h6
-rw-r--r--scene/3d/voxelizer.cpp32
-rw-r--r--scene/audio/audio_stream_player.cpp2
-rw-r--r--scene/gui/aspect_ratio_container.cpp12
-rw-r--r--scene/gui/code_edit.cpp2
-rw-r--r--scene/gui/color_picker.cpp113
-rw-r--r--scene/gui/color_picker.h12
-rw-r--r--scene/gui/file_dialog.cpp10
-rw-r--r--scene/gui/file_dialog.h1
-rw-r--r--scene/gui/item_list.cpp14
-rw-r--r--scene/gui/label.cpp16
-rw-r--r--scene/gui/popup_menu.cpp6
-rw-r--r--scene/gui/rich_text_label.cpp6
-rw-r--r--scene/gui/text_edit.cpp5
-rw-r--r--scene/main/canvas_item.cpp6
-rw-r--r--scene/main/viewport.cpp4
-rw-r--r--scene/main/window.cpp28
-rw-r--r--scene/main/window.h2
-rw-r--r--scene/resources/material.cpp15
-rw-r--r--scene/resources/texture.cpp68
-rw-r--r--scene/resources/texture.h23
-rw-r--r--scene/resources/tile_set.cpp48
-rw-r--r--scene/resources/visual_shader_nodes.cpp7
36 files changed, 365 insertions, 259 deletions
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index 902fba38bf..c175edb6cb 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -234,7 +234,7 @@ float AudioStreamPlayer2D::get_volume_db() const {
}
void AudioStreamPlayer2D::set_pitch_scale(float p_pitch_scale) {
- ERR_FAIL_COND(p_pitch_scale <= 0.0);
+ ERR_FAIL_COND(!(p_pitch_scale > 0.0));
pitch_scale = p_pitch_scale;
for (Ref<AudioStreamPlayback> &playback : stream_playbacks) {
AudioServer::get_singleton()->set_playback_pitch_scale(playback, p_pitch_scale);
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index afd4763d74..04c7555306 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -1402,8 +1402,8 @@ void CPUParticles2D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL);
ADD_GROUP("Damping", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_min", "get_param_min", PARAM_DAMPING);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_max", "get_param_max", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_DAMPING);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING);
ADD_GROUP("Angle", "");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE);
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 52a1213a49..bfe2f6252e 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -31,6 +31,7 @@
#include "navigation_agent_2d.h"
#include "core/math/geometry_2d.h"
+#include "scene/2d/navigation_link_2d.h"
#include "scene/resources/world_2d.h"
#include "servers/navigation_server_2d.h"
@@ -94,19 +95,19 @@ void NavigationAgent2D::_bind_methods() {
ADD_GROUP("Pathfinding", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_position", "get_target_position");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,suffix:px"), "set_path_desired_distance", "get_path_desired_distance");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,suffix:px"), "set_target_desired_distance", "get_target_desired_distance");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,1000,1,suffix:px"), "set_path_max_distance", "get_path_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,or_greater,suffix:px"), "set_path_desired_distance", "get_path_desired_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,or_greater,suffix:px"), "set_target_desired_distance", "get_target_desired_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,1000,1,or_greater,suffix:px"), "set_path_max_distance", "get_path_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
ADD_GROUP("Avoidance", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01,suffix:px"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,100000,0.01,suffix:px"), "set_neighbor_distance", "get_neighbor_distance");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10,0.01,suffix:s"), "set_time_horizon", "get_time_horizon");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:px/s"), "set_max_speed", "get_max_speed");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01,or_greater,suffix:px"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,100000,0.01,or_greater,suffix:px"), "set_neighbor_distance", "get_neighbor_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,or_greater,1"), "set_max_neighbors", "get_max_neighbors");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10,0.01,or_greater,suffix:s"), "set_time_horizon", "get_time_horizon");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,or_greater,suffix:px/s"), "set_max_speed", "get_max_speed");
ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationAgent2D::set_debug_enabled);
ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationAgent2D::get_debug_enabled);
@@ -623,6 +624,21 @@ void NavigationAgent2D::update_navigation() {
}
details[SNAME("owner")] = owner;
+
+ if (waypoint_type == NavigationPathQueryResult2D::PATH_SEGMENT_TYPE_LINK) {
+ const NavigationLink2D *navlink = Object::cast_to<NavigationLink2D>(owner);
+ if (navlink) {
+ Vector2 link_global_start_position = navlink->get_global_start_position();
+ Vector2 link_global_end_position = navlink->get_global_end_position();
+ if (waypoint.distance_to(link_global_start_position) < waypoint.distance_to(link_global_end_position)) {
+ details[SNAME("link_entry_position")] = link_global_start_position;
+ details[SNAME("link_exit_position")] = link_global_end_position;
+ } else {
+ details[SNAME("link_entry_position")] = link_global_end_position;
+ details[SNAME("link_exit_position")] = link_global_start_position;
+ }
+ }
+ }
}
// Emit a signal for the waypoint
diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp
index 26dca40176..8adb7c6305 100644
--- a/scene/2d/navigation_link_2d.cpp
+++ b/scene/2d/navigation_link_2d.cpp
@@ -54,6 +54,12 @@ void NavigationLink2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink2D::set_end_position);
ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink2D::get_end_position);
+ ClassDB::bind_method(D_METHOD("set_global_start_position", "position"), &NavigationLink2D::set_global_start_position);
+ ClassDB::bind_method(D_METHOD("get_global_start_position"), &NavigationLink2D::get_global_start_position);
+
+ ClassDB::bind_method(D_METHOD("set_global_end_position", "position"), &NavigationLink2D::set_global_end_position);
+ ClassDB::bind_method(D_METHOD("get_global_end_position"), &NavigationLink2D::get_global_end_position);
+
ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink2D::set_enter_cost);
ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink2D::get_enter_cost);
@@ -271,6 +277,38 @@ void NavigationLink2D::set_end_position(Vector2 p_position) {
#endif // DEBUG_ENABLED
}
+void NavigationLink2D::set_global_start_position(Vector2 p_position) {
+ if (is_inside_tree()) {
+ set_start_position(to_local(p_position));
+ } else {
+ set_start_position(p_position);
+ }
+}
+
+Vector2 NavigationLink2D::get_global_start_position() const {
+ if (is_inside_tree()) {
+ return to_global(start_position);
+ } else {
+ return start_position;
+ }
+}
+
+void NavigationLink2D::set_global_end_position(Vector2 p_position) {
+ if (is_inside_tree()) {
+ set_end_position(to_local(p_position));
+ } else {
+ set_end_position(p_position);
+ }
+}
+
+Vector2 NavigationLink2D::get_global_end_position() const {
+ if (is_inside_tree()) {
+ return to_global(end_position);
+ } else {
+ return end_position;
+ }
+}
+
void NavigationLink2D::set_enter_cost(real_t p_enter_cost) {
ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive.");
if (Math::is_equal_approx(enter_cost, p_enter_cost)) {
diff --git a/scene/2d/navigation_link_2d.h b/scene/2d/navigation_link_2d.h
index 5bf2a72358..8a24d611c9 100644
--- a/scene/2d/navigation_link_2d.h
+++ b/scene/2d/navigation_link_2d.h
@@ -78,6 +78,12 @@ public:
void set_end_position(Vector2 p_position);
Vector2 get_end_position() const { return end_position; }
+ void set_global_start_position(Vector2 p_position);
+ Vector2 get_global_start_position() const;
+
+ void set_global_end_position(Vector2 p_position);
+ Vector2 get_global_end_position() const;
+
void set_enter_cost(real_t p_enter_cost);
real_t get_enter_cost() const { return enter_cost; }
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index 96711bbe72..4fdc7b3584 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -378,9 +378,6 @@ void Bone2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_skeleton_rest"), &Bone2D::get_skeleton_rest);
ClassDB::bind_method(D_METHOD("get_index_in_skeleton"), &Bone2D::get_index_in_skeleton);
- ClassDB::bind_method(D_METHOD("set_default_length", "default_length"), &Bone2D::set_default_length);
- ClassDB::bind_method(D_METHOD("get_default_length"), &Bone2D::get_default_length);
-
ClassDB::bind_method(D_METHOD("set_autocalculate_length_and_angle", "auto_calculate"), &Bone2D::set_autocalculate_length_and_angle);
ClassDB::bind_method(D_METHOD("get_autocalculate_length_and_angle"), &Bone2D::get_autocalculate_length_and_angle);
ClassDB::bind_method(D_METHOD("set_length", "length"), &Bone2D::set_length);
@@ -416,16 +413,6 @@ void Bone2D::apply_rest() {
set_transform(rest);
}
-void Bone2D::set_default_length(real_t p_length) {
- WARN_DEPRECATED_MSG("set_default_length is deprecated. Please use set_length instead!");
- set_length(p_length);
-}
-
-real_t Bone2D::get_default_length() const {
- WARN_DEPRECATED_MSG("get_default_length is deprecated. Please use get_length instead!");
- return get_length();
-}
-
int Bone2D::get_index_in_skeleton() const {
ERR_FAIL_COND_V(!skeleton, -1);
skeleton->_update_bone_setup();
diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h
index 149ab64306..6a36a31552 100644
--- a/scene/2d/skeleton_2d.h
+++ b/scene/2d/skeleton_2d.h
@@ -80,9 +80,6 @@ public:
PackedStringArray get_configuration_warnings() const override;
- void set_default_length(real_t p_length);
- real_t get_default_length() const;
-
void set_autocalculate_length_and_angle(bool p_autocalculate);
bool get_autocalculate_length_and_angle() const;
void set_length(real_t p_length);
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 54ed96f585..1c2903fe22 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -194,10 +194,6 @@ void TouchScreenButton::input(const Ref<InputEvent> &p_event) {
return;
}
- if (p_event->get_device() != 0) {
- return;
- }
-
const InputEventScreenTouch *st = Object::cast_to<InputEventScreenTouch>(*p_event);
if (passby_press) {
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 77bf15125e..ac626d0d2a 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -559,7 +559,7 @@ float AudioStreamPlayer3D::get_max_db() const {
}
void AudioStreamPlayer3D::set_pitch_scale(float p_pitch_scale) {
- ERR_FAIL_COND(p_pitch_scale <= 0.0);
+ ERR_FAIL_COND(!(p_pitch_scale > 0.0));
pitch_scale = p_pitch_scale;
}
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index b9a161e476..c88eb033de 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -1588,8 +1588,8 @@ void CPUParticles3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL);
ADD_GROUP("Damping", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_min", "get_param_min", PARAM_DAMPING);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_max", "get_param_max", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_DAMPING);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING);
ADD_GROUP("Angle", "");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_less,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE);
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 16f357194e..396e4b72af 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -30,6 +30,7 @@
#include "navigation_agent_3d.h"
+#include "scene/3d/navigation_link_3d.h"
#include "servers/navigation_server_3d.h"
void NavigationAgent3D::_bind_methods() {
@@ -98,20 +99,20 @@ void NavigationAgent3D::_bind_methods() {
ADD_GROUP("Pathfinding", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_position", "get_target_position");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_path_desired_distance", "get_path_desired_distance");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_target_desired_distance", "get_target_desired_distance");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,suffix:m"), "set_agent_height_offset", "get_agent_height_offset");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1,suffix:m"), "set_path_max_distance", "get_path_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,or_greater,suffix:m"), "set_path_desired_distance", "get_path_desired_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,or_greater,suffix:m"), "set_target_desired_distance", "get_target_desired_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,or_greater,suffix:m"), "set_agent_height_offset", "get_agent_height_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1,or_greater,suffix:m"), "set_path_max_distance", "get_path_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
ADD_GROUP("Avoidance", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:m"), "set_neighbor_distance", "get_neighbor_distance");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.01,100,0.01,suffix:s"), "set_time_horizon", "get_time_horizon");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:m/s"), "set_max_speed", "get_max_speed");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,100,0.01,or_greater,suffix:m"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,10000,0.01,or_greater,suffix:m"), "set_neighbor_distance", "get_neighbor_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1,or_greater"), "set_max_neighbors", "get_max_neighbors");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.01,10,0.01,or_greater,suffix:s"), "set_time_horizon", "get_time_horizon");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,1000,0.01,or_greater,suffix:m/s"), "set_max_speed", "get_max_speed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y");
ADD_SIGNAL(MethodInfo("path_changed"));
@@ -649,6 +650,21 @@ void NavigationAgent3D::update_navigation() {
}
details[SNAME("owner")] = owner;
+
+ if (waypoint_type == NavigationPathQueryResult3D::PATH_SEGMENT_TYPE_LINK) {
+ const NavigationLink3D *navlink = Object::cast_to<NavigationLink3D>(owner);
+ if (navlink) {
+ Vector3 link_global_start_position = navlink->get_global_start_position();
+ Vector3 link_global_end_position = navlink->get_global_end_position();
+ if (waypoint.distance_to(link_global_start_position) < waypoint.distance_to(link_global_end_position)) {
+ details[SNAME("link_entry_position")] = link_global_start_position;
+ details[SNAME("link_exit_position")] = link_global_end_position;
+ } else {
+ details[SNAME("link_entry_position")] = link_global_end_position;
+ details[SNAME("link_exit_position")] = link_global_start_position;
+ }
+ }
+ }
}
// Emit a signal for the waypoint
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index 072ca1d3e8..cde826ed5c 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -52,14 +52,14 @@ class NavigationAgent3D : public Node {
real_t path_desired_distance = 1.0;
real_t target_desired_distance = 1.0;
- real_t radius = 1.0;
+ real_t radius = 0.5;
real_t navigation_height_offset = 0.0;
bool ignore_y = true;
real_t neighbor_distance = 50.0;
int max_neighbors = 10;
- real_t time_horizon = 5.0;
+ real_t time_horizon = 1.0;
real_t max_speed = 10.0;
- real_t path_max_distance = 3.0;
+ real_t path_max_distance = 5.0;
Vector3 target_position;
bool target_position_submitted = false;
diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation_link_3d.cpp
index f47fcfaf51..9c4b8e7905 100644
--- a/scene/3d/navigation_link_3d.cpp
+++ b/scene/3d/navigation_link_3d.cpp
@@ -163,6 +163,12 @@ void NavigationLink3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink3D::set_end_position);
ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink3D::get_end_position);
+ ClassDB::bind_method(D_METHOD("set_global_start_position", "position"), &NavigationLink3D::set_global_start_position);
+ ClassDB::bind_method(D_METHOD("get_global_start_position"), &NavigationLink3D::get_global_start_position);
+
+ ClassDB::bind_method(D_METHOD("set_global_end_position", "position"), &NavigationLink3D::set_global_end_position);
+ ClassDB::bind_method(D_METHOD("get_global_end_position"), &NavigationLink3D::get_global_end_position);
+
ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink3D::set_enter_cost);
ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink3D::get_enter_cost);
@@ -386,6 +392,38 @@ void NavigationLink3D::set_end_position(Vector3 p_position) {
update_configuration_warnings();
}
+void NavigationLink3D::set_global_start_position(Vector3 p_position) {
+ if (is_inside_tree()) {
+ set_start_position(to_local(p_position));
+ } else {
+ set_start_position(p_position);
+ }
+}
+
+Vector3 NavigationLink3D::get_global_start_position() const {
+ if (is_inside_tree()) {
+ return to_global(start_position);
+ } else {
+ return start_position;
+ }
+}
+
+void NavigationLink3D::set_global_end_position(Vector3 p_position) {
+ if (is_inside_tree()) {
+ set_end_position(to_local(p_position));
+ } else {
+ set_end_position(p_position);
+ }
+}
+
+Vector3 NavigationLink3D::get_global_end_position() const {
+ if (is_inside_tree()) {
+ return to_global(end_position);
+ } else {
+ return end_position;
+ }
+}
+
void NavigationLink3D::set_enter_cost(real_t p_enter_cost) {
ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive.");
if (Math::is_equal_approx(enter_cost, p_enter_cost)) {
diff --git a/scene/3d/navigation_link_3d.h b/scene/3d/navigation_link_3d.h
index 5c9ec36189..991f45c85d 100644
--- a/scene/3d/navigation_link_3d.h
+++ b/scene/3d/navigation_link_3d.h
@@ -83,6 +83,12 @@ public:
void set_end_position(Vector3 p_position);
Vector3 get_end_position() const { return end_position; }
+ void set_global_start_position(Vector3 p_position);
+ Vector3 get_global_start_position() const;
+
+ void set_global_end_position(Vector3 p_position);
+ Vector3 get_global_end_position() const;
+
void set_enter_cost(real_t p_enter_cost);
real_t get_enter_cost() const { return enter_cost; }
diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp
index d169999de4..42b0748698 100644
--- a/scene/3d/voxelizer.cpp
+++ b/scene/3d/voxelizer.cpp
@@ -346,25 +346,29 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
} else {
mc.albedo = _get_bake_texture(img_albedo, Color(1, 1, 1), mat->get_albedo()); // no albedo texture, color is additive
}
+ if (mat->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
+ Ref<Texture2D> emission_tex = mat->get_texture(BaseMaterial3D::TEXTURE_EMISSION);
- Ref<Texture2D> emission_tex = mat->get_texture(BaseMaterial3D::TEXTURE_EMISSION);
-
- Color emission_col = mat->get_emission();
- float emission_energy = mat->get_emission_energy_multiplier() * exposure_normalization;
- if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) {
- emission_energy *= mat->get_emission_intensity();
- }
+ Color emission_col = mat->get_emission();
+ float emission_energy = mat->get_emission_energy_multiplier() * exposure_normalization;
+ if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) {
+ emission_energy *= mat->get_emission_intensity();
+ }
- Ref<Image> img_emission;
+ Ref<Image> img_emission;
- if (emission_tex.is_valid()) {
- img_emission = emission_tex->get_image();
- }
+ if (emission_tex.is_valid()) {
+ img_emission = emission_tex->get_image();
+ }
- if (mat->get_emission_operator() == BaseMaterial3D::EMISSION_OP_ADD) {
- mc.emission = _get_bake_texture(img_emission, Color(1, 1, 1) * emission_energy, emission_col * emission_energy);
+ if (mat->get_emission_operator() == BaseMaterial3D::EMISSION_OP_ADD) {
+ mc.emission = _get_bake_texture(img_emission, Color(1, 1, 1) * emission_energy, emission_col * emission_energy);
+ } else {
+ mc.emission = _get_bake_texture(img_emission, emission_col * emission_energy, Color(0, 0, 0));
+ }
} else {
- mc.emission = _get_bake_texture(img_emission, emission_col * emission_energy, Color(0, 0, 0));
+ Ref<Image> empty;
+ mc.emission = _get_bake_texture(empty, Color(0, 0, 0), Color(0, 0, 0));
}
} else {
diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp
index 7533a56b59..6c37d6f81d 100644
--- a/scene/audio/audio_stream_player.cpp
+++ b/scene/audio/audio_stream_player.cpp
@@ -111,7 +111,7 @@ float AudioStreamPlayer::get_volume_db() const {
}
void AudioStreamPlayer::set_pitch_scale(float p_pitch_scale) {
- ERR_FAIL_COND(p_pitch_scale <= 0.0);
+ ERR_FAIL_COND(!(p_pitch_scale > 0.0));
pitch_scale = p_pitch_scale;
for (Ref<AudioStreamPlayback> &playback : stream_playbacks) {
diff --git a/scene/gui/aspect_ratio_container.cpp b/scene/gui/aspect_ratio_container.cpp
index 802189c374..94240ccead 100644
--- a/scene/gui/aspect_ratio_container.cpp
+++ b/scene/gui/aspect_ratio_container.cpp
@@ -30,6 +30,8 @@
#include "aspect_ratio_container.h"
+#include "scene/gui/texture_rect.h"
+
Size2 AspectRatioContainer::get_minimum_size() const {
Size2 ms;
for (int i = 0; i < get_child_count(); i++) {
@@ -113,6 +115,16 @@ void AspectRatioContainer::_notification(int p_what) {
if (c->is_set_as_top_level()) {
continue;
}
+
+ // Temporary fix for editor crash.
+ TextureRect *trect = Object::cast_to<TextureRect>(c);
+ if (trect) {
+ if (trect->get_expand_mode() == TextureRect::EXPAND_FIT_WIDTH_PROPORTIONAL || trect->get_expand_mode() == TextureRect::EXPAND_FIT_HEIGHT_PROPORTIONAL) {
+ WARN_PRINT_ONCE("Proportional TextureRect is currently not supported inside AspectRatioContainer");
+ continue;
+ }
+ }
+
Size2 child_minsize = c->get_combined_minimum_size();
Size2 child_size = Size2(ratio, 1.0);
float scale_factor = 1.0;
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index e2f7ec860c..ee39327d4d 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -896,6 +896,7 @@ void CodeEdit::indent_lines() {
set_caret_column(get_caret_column(c) + selection_offset, false, c);
}
end_complex_operation();
+ queue_redraw();
}
void CodeEdit::unindent_lines() {
@@ -973,6 +974,7 @@ void CodeEdit::unindent_lines() {
set_caret_column(initial_cursor_column - removed_characters, false, c);
}
end_complex_operation();
+ queue_redraw();
}
int CodeEdit::_calculate_spaces_till_next_left_indent(int p_column) const {
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 0b0698188c..48e3759981 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -31,10 +31,12 @@
#include "color_picker.h"
#include "core/input/input.h"
+#include "core/io/image.h"
#include "core/math/color.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "scene/gui/color_mode.h"
+#include "servers/display_server.h"
#include "thirdparty/misc/ok_color.h"
#include "thirdparty/misc/ok_color_shader.h"
@@ -90,8 +92,8 @@ void ColorPicker::_notification(int p_what) {
} break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
- if (screen != nullptr && screen->is_visible()) {
- screen->hide();
+ if (picker_window != nullptr && picker_window->is_visible()) {
+ picker_window->hide();
}
} break;
}
@@ -1372,30 +1374,26 @@ void ColorPicker::_recent_preset_pressed(const bool p_pressed, ColorPresetButton
emit_signal(SNAME("color_changed"), p_preset->get_preset_color());
}
-void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
+void ColorPicker::_picker_texture_input(const Ref<InputEvent> &p_event) {
if (!is_inside_tree()) {
return;
}
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid() && bev->get_button_index() == MouseButton::LEFT && !bev->is_pressed()) {
+ set_pick_color(picker_color);
emit_signal(SNAME("color_changed"), color);
- screen->hide();
+ picker_window->hide();
}
Ref<InputEventMouseMotion> mev = p_event;
if (mev.is_valid()) {
- Viewport *r = get_tree()->get_root();
- if (!r->get_visible_rect().has_point(mev->get_global_position())) {
- return;
- }
-
- Ref<Image> img = r->get_texture()->get_image();
+ Ref<Image> img = picker_texture_rect->get_texture()->get_image();
if (img.is_valid() && !img->is_empty()) {
- Vector2 ofs = mev->get_global_position();
- Color c = img->get_pixel(ofs.x, ofs.y);
-
- set_pick_color(c);
+ Vector2 ofs = mev->get_position();
+ picker_color = img->get_pixel(ofs.x, ofs.y);
+ picker_preview_style_box->set_bg_color(picker_color);
+ picker_preview_label->set_self_modulate(picker_color.get_luminance() < 0.5 ? Color(1.0f, 1.0f, 1.0f) : Color(0.0f, 0.0f, 0.0f));
}
}
}
@@ -1409,27 +1407,79 @@ void ColorPicker::_add_preset_pressed() {
emit_signal(SNAME("preset_added"), color);
}
-void ColorPicker::_screen_pick_pressed() {
+void ColorPicker::_pick_button_pressed() {
if (!is_inside_tree()) {
return;
}
- Viewport *r = get_tree()->get_root();
- if (!screen) {
- screen = memnew(Control);
- r->add_child(screen);
- screen->set_as_top_level(true);
- screen->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
- screen->set_default_cursor_shape(CURSOR_POINTING_HAND);
- screen->connect("gui_input", callable_mp(this, &ColorPicker::_screen_input));
- // It immediately toggles off in the first press otherwise.
- screen->call_deferred(SNAME("connect"), "hidden", Callable(btn_pick, "set_pressed").bind(false));
+ if (!picker_window) {
+ picker_window = memnew(Popup);
+ picker_window->hide();
+ picker_window->set_transient(true);
+ add_child(picker_window);
+
+ picker_texture_rect = memnew(TextureRect);
+ picker_texture_rect->set_anchors_preset(Control::PRESET_FULL_RECT);
+ picker_window->add_child(picker_texture_rect);
+ picker_texture_rect->set_default_cursor_shape(CURSOR_POINTING_HAND);
+ picker_texture_rect->connect(SNAME("gui_input"), callable_mp(this, &ColorPicker::_picker_texture_input));
+
+ picker_preview = memnew(Panel);
+ picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP);
+ picker_preview->set_mouse_filter(MOUSE_FILTER_IGNORE);
+ picker_window->add_child(picker_preview);
+
+ picker_preview_label = memnew(Label);
+ picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP);
+ picker_preview_label->set_text("Color Picking active");
+ picker_preview->add_child(picker_preview_label);
+
+ picker_preview_style_box = (Ref<StyleBoxFlat>)memnew(StyleBoxFlat);
+ picker_preview_style_box->set_bg_color(Color(1.0, 1.0, 1.0));
+ picker_preview->add_theme_style_override("panel", picker_preview_style_box);
+ }
+
+ Rect2i screen_rect;
+ if (picker_window->is_embedded()) {
+ screen_rect = picker_window->get_embedder()->get_visible_rect();
+ picker_window->set_position(Point2i());
+ picker_texture_rect->set_texture(ImageTexture::create_from_image(picker_window->get_embedder()->get_texture()->get_image()));
} else {
- screen->show();
+ screen_rect = picker_window->get_parent_rect();
+ picker_window->set_position(screen_rect.position);
+
+ Ref<Image> target_image = Image::create_empty(screen_rect.size.x, screen_rect.size.y, false, Image::FORMAT_RGB8);
+ DisplayServer *ds = DisplayServer::get_singleton();
+
+ // Add the Texture of each Window to the Image.
+ Vector<DisplayServer::WindowID> wl = ds->get_window_list();
+ // FIXME: sort windows by visibility.
+ for (int index = 0; index < wl.size(); index++) {
+ DisplayServer::WindowID wid = wl[index];
+ if (wid == DisplayServer::INVALID_WINDOW_ID) {
+ continue;
+ }
+
+ ObjectID woid = DisplayServer::get_singleton()->window_get_attached_instance_id(wid);
+ if (woid == ObjectID()) {
+ continue;
+ }
+
+ Window *w = Object::cast_to<Window>(ObjectDB::get_instance(woid));
+ Ref<Image> img = w->get_texture()->get_image();
+ if (!img.is_valid() || img->is_empty()) {
+ continue;
+ }
+ img->convert(Image::FORMAT_RGB8);
+ target_image->blit_rect(img, Rect2i(Point2i(0, 0), img->get_size()), w->get_position());
+ }
+
+ picker_texture_rect->set_texture(ImageTexture::create_from_image(target_image));
}
- screen->move_to_front();
- // TODO: show modal no longer works, needs to be converted to a popup.
- //screen->show_modal();
+
+ picker_window->set_size(screen_rect.size);
+ picker_preview->set_size(screen_rect.size / 10.0); // 10% of size in each axis.
+ picker_window->popup();
}
void ColorPicker::_html_focus_exit() {
@@ -1595,9 +1645,8 @@ ColorPicker::ColorPicker() {
btn_pick = memnew(Button);
sample_hbc->add_child(btn_pick);
- btn_pick->set_toggle_mode(true);
- btn_pick->set_tooltip_text(RTR("Pick a color from the editor window."));
- btn_pick->connect("pressed", callable_mp(this, &ColorPicker::_screen_pick_pressed));
+ btn_pick->set_tooltip_text(RTR("Pick a color from the application window."));
+ btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed));
sample = memnew(TextureRect);
sample_hbc->add_child(sample);
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index f7578612cd..d02c3278e6 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -40,6 +40,7 @@
#include "scene/gui/line_edit.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/option_button.h"
+#include "scene/gui/panel.h"
#include "scene/gui/popup.h"
#include "scene/gui/separator.h"
#include "scene/gui/slider.h"
@@ -111,7 +112,12 @@ private:
Vector<ColorMode *> modes;
- Control *screen = nullptr;
+ Popup *picker_window = nullptr;
+ TextureRect *picker_texture_rect = nullptr;
+ Panel *picker_preview = nullptr;
+ Label *picker_preview_label = nullptr;
+ Ref<StyleBoxFlat> picker_preview_style_box;
+ Color picker_color;
Control *uv_edit = nullptr;
Control *w_edit = nullptr;
AspectRatioContainer *wheel_edit = nullptr;
@@ -211,10 +217,10 @@ private:
void _line_edit_input(const Ref<InputEvent> &p_event);
void _preset_input(const Ref<InputEvent> &p_event, const Color &p_color);
void _recent_preset_pressed(const bool pressed, ColorPresetButton *p_preset);
- void _screen_input(const Ref<InputEvent> &p_event);
+ void _picker_texture_input(const Ref<InputEvent> &p_event);
void _text_changed(const String &p_new_text);
void _add_preset_pressed();
- void _screen_pick_pressed();
+ void _pick_button_pressed();
void _html_focus_exit();
inline int _get_preset_size();
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 5dd8cde342..02abddaa43 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -35,7 +35,6 @@
#include "scene/gui/label.h"
FileDialog::GetIconFunc FileDialog::get_icon_func = nullptr;
-FileDialog::GetIconFunc FileDialog::get_large_icon_func = nullptr;
FileDialog::RegisterFunc FileDialog::register_func = nullptr;
FileDialog::RegisterFunc FileDialog::unregister_func = nullptr;
@@ -347,14 +346,15 @@ void FileDialog::_action_pressed() {
}
}
- if (!valid) {
+ String file_name = file_text.strip_edges().get_file();
+ if (!valid || file_name.is_empty()) {
exterr->popup_centered(Size2(250, 80));
return;
}
if (dir_access->file_exists(f)) {
- confirm_save->set_text(RTR("File exists, overwrite?"));
- confirm_save->popup_centered(Size2(200, 80));
+ confirm_save->set_text(vformat(RTR("File \"%s\" already exists.\nDo you want to overwrite it?"), f));
+ confirm_save->popup_centered(Size2(250, 80));
} else {
emit_signal(SNAME("file_selected"), f);
hide();
@@ -1136,7 +1136,7 @@ FileDialog::FileDialog() {
add_child(mkdirerr, false, INTERNAL_MODE_FRONT);
exterr = memnew(AcceptDialog);
- exterr->set_text(RTR("Must use a valid extension."));
+ exterr->set_text(RTR("Invalid extension, or empty filename."));
add_child(exterr, false, INTERNAL_MODE_FRONT);
update_filters();
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index d85cdcac90..7f80caf01d 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -60,7 +60,6 @@ public:
typedef void (*RegisterFunc)(FileDialog *);
static GetIconFunc get_icon_func;
- static GetIconFunc get_large_icon_func;
static RegisterFunc register_func;
static RegisterFunc unregister_func;
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 25a27d5e1a..d367a8d281 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -801,8 +801,9 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
search_string = ""; //any mousepress cancels
for (int i = 4; i > 0; i--) {
- if (current - current_columns * i >= 0 && CAN_SELECT(current - current_columns * i)) {
- set_current(current - current_columns * i);
+ int index = current - current_columns * i;
+ if (index >= 0 && index < items.size() && CAN_SELECT(index)) {
+ set_current(index);
ensure_current_is_visible();
if (select_mode == SELECT_SINGLE) {
emit_signal(SNAME("item_selected"), current);
@@ -815,8 +816,9 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
search_string = ""; //any mousepress cancels
for (int i = 4; i > 0; i--) {
- if (current + current_columns * i < items.size() && CAN_SELECT(current + current_columns * i)) {
- set_current(current + current_columns * i);
+ int index = current + current_columns * i;
+ if (index >= 0 && index < items.size() && CAN_SELECT(index)) {
+ set_current(index);
ensure_current_is_visible();
if (select_mode == SELECT_SINGLE) {
emit_signal(SNAME("item_selected"), current);
@@ -832,7 +834,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
if (current % current_columns != 0) {
int current_row = current / current_columns;
int next = current - 1;
- while (!CAN_SELECT(next)) {
+ while (next >= 0 && !CAN_SELECT(next)) {
next = next - 1;
}
if (next < 0 || !IS_SAME_ROW(next, current_row)) {
@@ -852,7 +854,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
if (current % current_columns != (current_columns - 1) && current + 1 < items.size()) {
int current_row = current / current_columns;
int next = current + 1;
- while (!CAN_SELECT(next)) {
+ while (next < items.size() && !CAN_SELECT(next)) {
next = next + 1;
}
if (items.size() <= next || !IS_SAME_ROW(next, current_row)) {
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 45218773fe..b861d7af01 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -139,11 +139,14 @@ bool Label::_shape() {
can_process_lines = true;
lines_dirty = false;
} else {
- // With autowrap on, we won't compute the minimum size until width is stable (two shape requests in a
- // row with the same width.) This avoids situations in which the initial width is very narrow and the label
- // would break text into many very short lines, causing a very tall label that can leave a deformed container.
-
- can_process_lines = get_size().width == stable_width || autowrap_mode == TextServer::AUTOWRAP_OFF;
+ // With autowrap on or off with trimming enabled, we won't compute the minimum size until width is stable
+ // (two shape requests in a row with the same width.) This avoids situations in which the initial width is
+ // very narrow and the label would break text into many very short lines, causing a very tall label that can
+ // leave a deformed container. In the remaining case (namely, autowrap off and no trimming), the label is
+ // free to dictate its own width, something that will be taken advtantage of.
+ bool can_dictate_width = autowrap_mode == TextServer::AUTOWRAP_OFF && overrun_behavior == TextServer::OVERRUN_NO_TRIMMING;
+ bool is_width_stable = get_size().width == stable_width;
+ can_process_lines = can_dictate_width || is_width_stable;
stable_width = get_size().width;
if (can_process_lines) {
@@ -171,14 +174,13 @@ bool Label::_shape() {
}
}
- if (autowrap_mode == TextServer::AUTOWRAP_OFF) {
+ if (can_dictate_width) {
for (int i = 0; i < lines_rid.size(); i++) {
if (minsize.width < TS->shaped_text_get_size(lines_rid[i]).x) {
minsize.width = TS->shaped_text_get_size(lines_rid[i]).x;
}
}
- // With autowrap off, by now we already know the width the label will take.
width = (minsize.width - style->get_minimum_size().width);
}
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 1a6adca121..cf73729c0a 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -1715,12 +1715,12 @@ void PopupMenu::activate_item(int p_item) {
need_hide = false;
}
+ emit_signal(SNAME("id_pressed"), id);
+ emit_signal(SNAME("index_pressed"), p_item);
+
if (need_hide) {
hide();
}
-
- emit_signal(SNAME("id_pressed"), id);
- emit_signal(SNAME("index_pressed"), p_item);
}
void PopupMenu::remove_item(int p_idx) {
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 2c1c44322a..973b02b3a3 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1179,7 +1179,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
dot_ul_started = false;
float y_off = TS->shaped_text_get_underline_position(rid);
float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale;
- draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2);
+ draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, MAX(2.0, underline_width * 2));
}
if (_find_strikethrough(it)) {
if (!st_started) {
@@ -1341,7 +1341,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
dot_ul_started = false;
float y_off = TS->shaped_text_get_underline_position(rid);
float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale;
- draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2);
+ draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, MAX(2.0, underline_width * 2));
}
if (st_started) {
st_started = false;
@@ -1363,7 +1363,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
dot_ul_started = false;
float y_off = TS->shaped_text_get_underline_position(rid);
float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale;
- draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2);
+ draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, MAX(2.0, underline_width * 2));
}
if (st_started) {
st_started = false;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index d785280701..ebca8296a0 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2681,6 +2681,7 @@ void TextEdit::_do_backspace(bool p_word, bool p_all_to_left) {
set_caret_line(get_caret_line(caret_idx), false, true, 0, caret_idx);
set_caret_column(column, caret_idx == 0, caret_idx);
+ adjust_carets_after_edit(caret_idx, get_caret_line(caret_idx), column, get_caret_line(caret_idx), from_column);
// Now we can clean up the overlapping caret.
if (overlapping_caret_index != -1) {
@@ -4362,7 +4363,9 @@ int TextEdit::get_minimap_line_at_pos(const Point2i &p_pos) const {
if (first_vis_line > 0 && minimap_line >= 0) {
minimap_line -= get_next_visible_line_index_offset_from(first_vis_line, 0, -num_lines_before).x;
minimap_line -= (minimap_line > 0 && smooth_scroll_enabled ? 1 : 0);
- } else {
+ }
+
+ if (minimap_line < 0) {
minimap_line = 0;
}
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index e5dcdd2afd..b36353158b 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -513,14 +513,16 @@ bool CanvasItem::is_y_sort_enabled() const {
void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
+ ERR_FAIL_COND(p_dash <= 0.0);
float length = (p_to - p_from).length();
- if (length < p_dash) {
+ Vector2 step = p_dash * (p_to - p_from).normalized();
+
+ if (length < p_dash || step == Vector2()) {
RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
return;
}
- Vector2 step = p_dash * (p_to - p_from).normalized();
int steps = (p_aligned) ? Math::ceil(length / p_dash) : Math::floor(length / p_dash);
if (steps % 2 == 0) {
steps--;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 126b1d54fc..244e0d5b93 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1330,7 +1330,7 @@ void Viewport::_gui_show_tooltip() {
Window *window = gui.tooltip_popup->get_parent_visible_window();
Rect2i vr;
if (gui.tooltip_popup->is_embedded()) {
- vr = gui.tooltip_popup->_get_embedder()->get_visible_rect();
+ vr = gui.tooltip_popup->get_embedder()->get_visible_rect();
} else {
vr = window->get_usable_parent_rect();
}
@@ -1851,7 +1851,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Window *w = Object::cast_to<Window>(this);
if (w) {
if (w->is_embedded()) {
- embedder = w->_get_embedder();
+ embedder = w->get_embedder();
viewport_pos = get_final_transform().xform(mpos) + w->get_position(); // To parent coords.
}
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index b79a9ba444..59e3d307c6 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -485,7 +485,7 @@ void Window::set_ime_position(const Point2i &p_pos) {
bool Window::is_embedded() const {
ERR_FAIL_COND_V(!is_inside_tree(), false);
- return _get_embedder() != nullptr;
+ return get_embedder() != nullptr;
}
bool Window::is_in_edited_scene_root() const {
@@ -710,7 +710,7 @@ void Window::set_visible(bool p_visible) {
// Stop any queued resizing, as the window will be resized right now.
updating_child_controls = false;
- Viewport *embedder_vp = _get_embedder();
+ Viewport *embedder_vp = get_embedder();
if (!embedder_vp) {
if (!p_visible && window_id != DisplayServer::INVALID_WINDOW_ID) {
@@ -1053,7 +1053,7 @@ void Window::_update_window_callbacks() {
DisplayServer::get_singleton()->window_set_drop_files_callback(callable_mp(this, &Window::_window_drop_files), window_id);
}
-Viewport *Window::_get_embedder() const {
+Viewport *Window::get_embedder() const {
Viewport *vp = get_parent_viewport();
while (vp) {
@@ -1088,7 +1088,7 @@ void Window::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
bool embedded = false;
{
- embedder = _get_embedder();
+ embedder = get_embedder();
if (embedder) {
embedded = true;
if (!visible) {
@@ -1431,7 +1431,7 @@ void Window::popup_centered_clamped(const Size2i &p_size, float p_fallback_ratio
Rect2 parent_rect;
if (is_embedded()) {
- parent_rect = _get_embedder()->get_visible_rect();
+ parent_rect = get_embedder()->get_visible_rect();
} else {
DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id();
int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id);
@@ -1462,7 +1462,7 @@ void Window::popup_centered(const Size2i &p_minsize) {
Rect2 parent_rect;
if (is_embedded()) {
- parent_rect = _get_embedder()->get_visible_rect();
+ parent_rect = get_embedder()->get_visible_rect();
} else {
DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id();
int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id);
@@ -1488,7 +1488,7 @@ void Window::popup_centered_ratio(float p_ratio) {
Rect2 parent_rect;
if (is_embedded()) {
- parent_rect = _get_embedder()->get_visible_rect();
+ parent_rect = get_embedder()->get_visible_rect();
} else {
DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id();
int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id);
@@ -1509,7 +1509,7 @@ void Window::popup_centered_ratio(float p_ratio) {
void Window::popup(const Rect2i &p_screen_rect) {
emit_signal(SNAME("about_to_popup"));
- if (!_get_embedder() && get_flag(FLAG_POPUP)) {
+ if (!get_embedder() && get_flag(FLAG_POPUP)) {
// Send a focus-out notification when opening a Window Manager Popup.
SceneTree *scene_tree = get_tree();
if (scene_tree) {
@@ -1545,7 +1545,7 @@ void Window::popup(const Rect2i &p_screen_rect) {
Rect2i parent_rect;
if (is_embedded()) {
- parent_rect = _get_embedder()->get_visible_rect();
+ parent_rect = get_embedder()->get_visible_rect();
} else {
int screen_id = DisplayServer::get_singleton()->window_get_current_screen(get_window_id());
parent_rect = DisplayServer::get_singleton()->screen_get_usable_rect(screen_id);
@@ -1587,7 +1587,7 @@ Rect2i Window::get_usable_parent_rect() const {
ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
Rect2i parent_rect;
if (is_embedded()) {
- parent_rect = _get_embedder()->get_visible_rect();
+ parent_rect = get_embedder()->get_visible_rect();
} else {
const Window *w = is_visible() ? this : get_parent_visible_window();
//find a parent that can contain us
@@ -2154,9 +2154,9 @@ Transform2D Window::get_final_transform() const {
Transform2D Window::get_screen_transform_internal(bool p_absolute_position) const {
Transform2D embedder_transform;
- if (_get_embedder()) {
+ if (get_embedder()) {
embedder_transform.translate_local(get_position());
- embedder_transform = _get_embedder()->get_screen_transform_internal(p_absolute_position) * embedder_transform;
+ embedder_transform = get_embedder()->get_screen_transform_internal(p_absolute_position) * embedder_transform;
} else if (p_absolute_position) {
embedder_transform.translate_local(get_position());
}
@@ -2170,8 +2170,8 @@ Transform2D Window::get_popup_base_transform() const {
Transform2D popup_base_transform;
popup_base_transform.set_origin(get_position());
popup_base_transform *= get_final_transform();
- if (_get_embedder()) {
- return _get_embedder()->get_popup_base_transform() * popup_base_transform;
+ if (get_embedder()) {
+ return get_embedder()->get_popup_base_transform() * popup_base_transform;
}
return popup_base_transform;
}
diff --git a/scene/main/window.h b/scene/main/window.h
index 5359c37e9a..40b629ed11 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -192,7 +192,6 @@ private:
Ref<Shortcut> debugger_stop_shortcut;
protected:
- Viewport *_get_embedder() const;
virtual Rect2i _popup_adjust_rect() const { return Rect2i(); }
virtual void _update_theme_item_cache();
@@ -278,6 +277,7 @@ public:
void set_ime_position(const Point2i &p_pos);
bool is_embedded() const;
+ Viewport *get_embedder() const;
void set_content_scale_size(const Size2i &p_size);
Size2i get_content_scale_size() const;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 7e84814ab3..2627898f5f 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -369,7 +369,15 @@ void ShaderMaterial::set_shader_parameter(const StringName &p_param, const Varia
param_cache.erase(p_param);
RS::get_singleton()->material_set_param(_get_material(), p_param, Variant());
} else {
- param_cache[p_param] = p_value;
+ Variant *v = param_cache.getptr(p_param);
+ if (!v) {
+ // Never assigned, also update the remap cache.
+ remap_cache["shader_parameter/" + p_param.operator String()] = p_param;
+ param_cache.insert(p_param, p_value);
+ } else {
+ *v = p_value;
+ }
+
if (p_value.get_type() == Variant::OBJECT) {
RID tex_rid = p_value;
if (tex_rid == RID()) {
@@ -955,11 +963,14 @@ void BaseMaterial3D::_update_shader() {
} break;
case BILLBOARD_PARTICLES: {
//make billboard
- code += " mat4 mat_world = mat4(normalize(INV_VIEW_MATRIX[0]) * length(MODEL_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]) * length(MODEL_MATRIX[0]),normalize(INV_VIEW_MATRIX[2]) * length(MODEL_MATRIX[2]), MODEL_MATRIX[3]);\n";
+ code += " mat4 mat_world = mat4(normalize(INV_VIEW_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]) ,normalize(INV_VIEW_MATRIX[2]), MODEL_MATRIX[3]);\n";
//rotate by rotation
code += " mat_world = mat_world * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
//set modelview
code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat_world;\n";
+ if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
+ code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
+ }
//set modelview normal
code += " MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);\n";
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 7e3156d2ff..05be40c446 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -2566,73 +2566,6 @@ void GradientTexture2D::_bind_methods() {
//////////////////////////////////////
-void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) {
- ERR_FAIL_COND(p_texture == this);
-
- base = p_texture;
- if (base.is_valid()) {
- ERR_FAIL_NULL(RenderingServer::get_singleton());
- if (proxy_ph.is_valid()) {
- RS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
- RS::get_singleton()->free(proxy_ph);
- proxy_ph = RID();
- } else if (proxy.is_valid()) {
- RS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
- } else {
- proxy = RS::get_singleton()->texture_proxy_create(base->get_rid());
- }
- }
-}
-
-Ref<Texture2D> ProxyTexture::get_base() const {
- return base;
-}
-
-int ProxyTexture::get_width() const {
- if (base.is_valid()) {
- return base->get_width();
- }
- return 1;
-}
-
-int ProxyTexture::get_height() const {
- if (base.is_valid()) {
- return base->get_height();
- }
- return 1;
-}
-
-RID ProxyTexture::get_rid() const {
- if (proxy.is_null()) {
- proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
- proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
- }
- return proxy;
-}
-
-bool ProxyTexture::has_alpha() const {
- if (base.is_valid()) {
- return base->has_alpha();
- }
- return false;
-}
-
-ProxyTexture::ProxyTexture() {
- //proxy = RS::get_singleton()->texture_create();
-}
-
-ProxyTexture::~ProxyTexture() {
- ERR_FAIL_NULL(RenderingServer::get_singleton());
- if (proxy_ph.is_valid()) {
- RS::get_singleton()->free(proxy_ph);
- }
- if (proxy.is_valid()) {
- RS::get_singleton()->free(proxy);
- }
-}
-
-//////////////////////////////////////////////
-
void AnimatedTexture::_update_proxy() {
RWLockRead r(rw_lock);
@@ -2704,6 +2637,7 @@ void AnimatedTexture::set_current_frame(int p_frame) {
RWLockWrite r(rw_lock);
current_frame = p_frame;
+ time = 0;
}
int AnimatedTexture::get_current_frame() const {
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 7f74ae6941..7c4d479da8 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -892,29 +892,6 @@ public:
VARIANT_ENUM_CAST(GradientTexture2D::Fill);
VARIANT_ENUM_CAST(GradientTexture2D::Repeat);
-class ProxyTexture : public Texture2D {
-private:
- mutable RID proxy_ph;
- mutable RID proxy;
- Ref<Texture2D> base;
-
-protected:
- static void _bind_methods();
-
-public:
- void set_base(const Ref<Texture2D> &p_texture);
- Ref<Texture2D> get_base() const;
-
- virtual int get_width() const override;
- virtual int get_height() const override;
- virtual RID get_rid() const override;
-
- virtual bool has_alpha() const override;
-
- ProxyTexture();
- ~ProxyTexture();
-};
-
class AnimatedTexture : public Texture2D {
GDCLASS(AnimatedTexture, Texture2D);
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index fee0a4a910..d4b2be355e 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -3308,7 +3308,7 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
PropertyInfo property_info;
// Rendering.
- p_list->push_back(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Rendering", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < occlusion_layers.size(); i++) {
p_list->push_back(PropertyInfo(Variant::INT, vformat("occlusion_layer_%d/light_mask", i), PROPERTY_HINT_LAYERS_2D_RENDER));
@@ -3321,7 +3321,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
}
// Physics.
- p_list->push_back(PropertyInfo(Variant::NIL, "Physics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Physics", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < physics_layers.size(); i++) {
p_list->push_back(PropertyInfo(Variant::INT, vformat("physics_layer_%d/collision_layer", i), PROPERTY_HINT_LAYERS_2D_PHYSICS));
@@ -3341,7 +3341,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
}
// Terrains.
- p_list->push_back(PropertyInfo(Variant::NIL, "Terrains", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Terrains", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int terrain_set_index = 0; terrain_set_index < terrain_sets.size(); terrain_set_index++) {
p_list->push_back(PropertyInfo(Variant::INT, vformat("terrain_set_%d/mode", terrain_set_index), PROPERTY_HINT_ENUM, "Match Corners and Sides,Match Corners,Match Sides"));
p_list->push_back(PropertyInfo(Variant::NIL, vformat("terrain_set_%d/terrains", terrain_set_index), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, vformat("terrain_set_%d/terrain_", terrain_set_index)));
@@ -3352,7 +3352,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
}
// Navigation.
- p_list->push_back(PropertyInfo(Variant::NIL, "Navigation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Navigation", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < navigation_layers.size(); i++) {
p_list->push_back(PropertyInfo(Variant::INT, vformat("navigation_layer_%d/layers", i), PROPERTY_HINT_LAYERS_2D_NAVIGATION));
}
@@ -3362,7 +3362,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 1; i < Variant::VARIANT_MAX; i++) {
argt += "," + Variant::get_type_name(Variant::Type(i));
}
- p_list->push_back(PropertyInfo(Variant::NIL, "Custom data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Custom Data", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < custom_data_layers.size(); i++) {
p_list->push_back(PropertyInfo(Variant::STRING, vformat("custom_data_layer_%d/name", i)));
p_list->push_back(PropertyInfo(Variant::INT, vformat("custom_data_layer_%d/type", i), PROPERTY_HINT_ENUM, argt));
@@ -3376,10 +3376,10 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
// Tile Proxies.
// Note: proxies need to be set after sources are set.
- p_list->push_back(PropertyInfo(Variant::NIL, "Tile Proxies", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
- p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/source_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/coords_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
- p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/alternative_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Tile Proxies", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/source_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/coords_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/alternative_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
// Patterns.
for (unsigned int pattern_index = 0; pattern_index < patterns.size(); pattern_index++) {
@@ -4887,9 +4887,9 @@ bool TileSetScenesCollectionSource::_get(const StringName &p_name, Variant &r_re
void TileSetScenesCollectionSource::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < scenes_ids.size(); i++) {
- p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("scenes/%d/scene", scenes_ids[i]), PROPERTY_HINT_RESOURCE_TYPE, "TileSetScenesCollectionSource"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("%s/%d/%s", PNAME("scenes"), scenes_ids[i], PNAME("scene")), PROPERTY_HINT_RESOURCE_TYPE, "TileSetScenesCollectionSource"));
- PropertyInfo property_info = PropertyInfo(Variant::BOOL, vformat("scenes/%d/display_placeholder", scenes_ids[i]));
+ PropertyInfo property_info = PropertyInfo(Variant::BOOL, vformat("%s/%d/%s", PNAME("scenes"), scenes_ids[i], PNAME("display_placeholder")));
if (scenes[scenes_ids[i]].display_placeholder == false) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
@@ -5692,10 +5692,10 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const {
// Add the groups manually.
if (tile_set) {
// Occlusion layers.
- p_list->push_back(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Rendering", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < occluders.size(); i++) {
// occlusion_layer_%d/polygon
- property_info = PropertyInfo(Variant::OBJECT, vformat("occlusion_layer_%d/polygon", i), PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_DEFAULT);
+ property_info = PropertyInfo(Variant::OBJECT, vformat("occlusion_layer_%d/%s", i, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_DEFAULT);
if (!occluders[i].is_valid()) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
@@ -5703,29 +5703,29 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const {
}
// Physics layers.
- p_list->push_back(PropertyInfo(Variant::NIL, "Physics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Physics", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < physics.size(); i++) {
- p_list->push_back(PropertyInfo(Variant::VECTOR2, vformat("physics_layer_%d/linear_velocity", i), PROPERTY_HINT_NONE));
- p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/angular_velocity", i), PROPERTY_HINT_NONE));
- p_list->push_back(PropertyInfo(Variant::INT, vformat("physics_layer_%d/polygons_count", i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, vformat("physics_layer_%d/%s", i, PNAME("linear_velocity")), PROPERTY_HINT_NONE));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/%s", i, PNAME("angular_velocity")), PROPERTY_HINT_NONE));
+ p_list->push_back(PropertyInfo(Variant::INT, vformat("physics_layer_%d/%s", i, PNAME("polygons_count")), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
for (int j = 0; j < physics[i].polygons.size(); j++) {
// physics_layer_%d/points
- property_info = PropertyInfo(Variant::ARRAY, vformat("physics_layer_%d/polygon_%d/points", i, j), PROPERTY_HINT_ARRAY_TYPE, "Vector2", PROPERTY_USAGE_DEFAULT);
+ property_info = PropertyInfo(Variant::ARRAY, vformat("physics_layer_%d/polygon_%d/%s", i, j, PNAME("points")), PROPERTY_HINT_ARRAY_TYPE, "Vector2", PROPERTY_USAGE_DEFAULT);
if (physics[i].polygons[j].polygon.is_empty()) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
p_list->push_back(property_info);
// physics_layer_%d/polygon_%d/one_way
- property_info = PropertyInfo(Variant::BOOL, vformat("physics_layer_%d/polygon_%d/one_way", i, j));
+ property_info = PropertyInfo(Variant::BOOL, vformat("physics_layer_%d/polygon_%d/%s", i, j, PNAME("one_way")));
if (physics[i].polygons[j].one_way == false) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
p_list->push_back(property_info);
// physics_layer_%d/polygon_%d/one_way_margin
- property_info = PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/polygon_%d/one_way_margin", i, j));
+ property_info = PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/polygon_%d/%s", i, j, PNAME("one_way_margin")));
if (physics[i].polygons[j].one_way_margin == 1.0) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
@@ -5735,7 +5735,7 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const {
// Terrain data
if (terrain_set >= 0) {
- p_list->push_back(PropertyInfo(Variant::NIL, "Terrains", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Terrains", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
if (is_valid_terrain_peering_bit(bit)) {
@@ -5749,9 +5749,9 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const {
}
// Navigation layers.
- p_list->push_back(PropertyInfo(Variant::NIL, "Navigation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Navigation", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < navigation.size(); i++) {
- property_info = PropertyInfo(Variant::OBJECT, vformat("navigation_layer_%d/polygon", i), PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon", PROPERTY_USAGE_DEFAULT);
+ property_info = PropertyInfo(Variant::OBJECT, vformat("navigation_layer_%d/%s", i, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon", PROPERTY_USAGE_DEFAULT);
if (!navigation[i].is_valid()) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
@@ -5759,7 +5759,7 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const {
}
// Custom data layers.
- p_list->push_back(PropertyInfo(Variant::NIL, "Custom data", PROPERTY_HINT_NONE, "custom_data_", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Custom Data", "custom_data_"), PROPERTY_HINT_NONE, "custom_data_", PROPERTY_USAGE_GROUP));
for (int i = 0; i < custom_data.size(); i++) {
Variant default_val;
Callable::CallError error;
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 7550f598f8..9f5a64597a 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -7606,8 +7606,11 @@ String VisualShaderNodeBillboard::generate_code(Shader::Mode p_mode, VisualShade
break;
case BILLBOARD_TYPE_PARTICLES:
code += " {\n";
- code += " mat4 __wm = mat4(normalize(INV_VIEW_MATRIX[0]) * length(MODEL_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]) * length(MODEL_MATRIX[0]), normalize(INV_VIEW_MATRIX[2]) * length(MODEL_MATRIX[2]), MODEL_MATRIX[3]);\n";
+ code += " mat4 __wm = mat4(normalize(INV_VIEW_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]), normalize(INV_VIEW_MATRIX[2]), MODEL_MATRIX[3]);\n";
code += " __wm = __wm * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
+ if (keep_scale) {
+ code += " __wm = __wm * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
+ }
code += " " + p_output_vars[0] + " = VIEW_MATRIX * __wm;\n";
code += " }\n";
break;
@@ -7650,7 +7653,7 @@ bool VisualShaderNodeBillboard::is_keep_scale_enabled() const {
Vector<StringName> VisualShaderNodeBillboard::get_editable_properties() const {
Vector<StringName> props;
props.push_back("billboard_type");
- if (billboard_type == BILLBOARD_TYPE_ENABLED || billboard_type == BILLBOARD_TYPE_FIXED_Y) {
+ if (billboard_type == BILLBOARD_TYPE_ENABLED || billboard_type == BILLBOARD_TYPE_FIXED_Y || billboard_type == BILLBOARD_TYPE_PARTICLES) {
props.push_back("keep_scale");
}
return props;