summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/cpu_particles_2d.cpp2
-rw-r--r--scene/2d/gpu_particles_2d.cpp2
-rw-r--r--scene/3d/cpu_particles_3d.h2
-rw-r--r--scene/3d/gpu_particles_3d.cpp2
-rw-r--r--scene/gui/button.cpp93
-rw-r--r--scene/gui/button.h4
-rw-r--r--scene/gui/color_picker.cpp69
-rw-r--r--scene/gui/color_picker.h3
-rw-r--r--scene/gui/graph_node.cpp1
-rw-r--r--scene/gui/option_button.cpp59
-rw-r--r--scene/gui/option_button.h7
-rw-r--r--scene/gui/scroll_container.cpp87
-rw-r--r--scene/gui/scroll_container.h4
-rw-r--r--scene/main/node.cpp15
-rw-r--r--scene/main/node.h18
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/environment.cpp8
-rw-r--r--scene/resources/label_settings.h8
-rw-r--r--scene/resources/particles_material.cpp34
-rw-r--r--scene/resources/particles_material.h12
-rw-r--r--scene/resources/visual_shader.cpp8
-rw-r--r--scene/resources/visual_shader_nodes.cpp7
-rw-r--r--scene/resources/visual_shader_nodes.h1
23 files changed, 266 insertions, 182 deletions
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 4155d0797f..26204a3b1a 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -1470,7 +1470,7 @@ CPUParticles2D::CPUParticles2D() {
set_emitting(true);
set_amount(8);
- set_use_local_coordinates(true);
+ set_use_local_coordinates(false);
set_param_min(PARAM_INITIAL_LINEAR_VELOCITY, 0);
set_param_min(PARAM_ANGULAR_VELOCITY, 0);
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index a869cf2525..075421a26d 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -660,7 +660,7 @@ GPUParticles2D::GPUParticles2D() {
set_explosiveness_ratio(0);
set_randomness_ratio(0);
set_visibility_rect(Rect2(Vector2(-100, -100), Vector2(200, 200)));
- set_use_local_coordinates(true);
+ set_use_local_coordinates(false);
set_draw_order(DRAW_ORDER_LIFETIME);
set_speed_scale(1);
set_fixed_fps(30);
diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h
index 4cb693f494..e26c301038 100644
--- a/scene/3d/cpu_particles_3d.h
+++ b/scene/3d/cpu_particles_3d.h
@@ -138,7 +138,7 @@ private:
real_t randomness_ratio = 0.0;
double lifetime_randomness = 0.0;
double speed_scale = 1.0;
- bool local_coords = true;
+ bool local_coords = false;
int fixed_fps = 0;
bool fractional_delta = true;
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index 01aff32954..2ee126e161 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -631,7 +631,7 @@ GPUParticles3D::GPUParticles3D() {
set_randomness_ratio(0);
set_trail_length(0.3);
set_visibility_aabb(AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8)));
- set_use_local_coordinates(true);
+ set_use_local_coordinates(false);
set_draw_passes(1);
set_draw_order(DRAW_ORDER_INDEX);
set_speed_scale(1);
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index a67f850a86..9bcb061526 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -34,39 +34,14 @@
#include "servers/rendering_server.h"
Size2 Button::get_minimum_size() const {
- Size2 minsize = text_buf->get_size();
- if (clip_text || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) {
- minsize.width = 0;
- }
-
- if (!expand_icon) {
- Ref<Texture2D> _icon;
- if (icon.is_null() && has_theme_icon(SNAME("icon"))) {
- _icon = Control::get_theme_icon(SNAME("icon"));
- } else {
- _icon = icon;
- }
-
- if (!_icon.is_null()) {
- minsize.height = MAX(minsize.height, _icon->get_height());
-
- if (icon_alignment != HORIZONTAL_ALIGNMENT_CENTER) {
- minsize.width += _icon->get_width();
- if (!xl_text.is_empty()) {
- minsize.width += get_theme_constant(SNAME("h_separation"));
- }
- } else {
- minsize.width = MAX(minsize.width, _icon->get_width());
- }
- }
- }
- if (!xl_text.is_empty()) {
- Ref<Font> font = get_theme_font(SNAME("font"));
- float font_height = font->get_height(get_theme_font_size(SNAME("font_size")));
- minsize.height = MAX(font_height, minsize.height);
+ Ref<Texture2D> _icon;
+ if (icon.is_null() && has_theme_icon(SNAME("icon"))) {
+ _icon = Control::get_theme_icon(SNAME("icon"));
+ } else {
+ _icon = icon;
}
- return get_theme_stylebox(SNAME("normal"))->get_minimum_size() + minsize;
+ return get_minimum_size_for_text_and_icon("", _icon);
}
void Button::_set_internal_margin(Side p_side, float p_value) {
@@ -352,18 +327,62 @@ void Button::_notification(int p_what) {
}
}
-void Button::_shape() {
+Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Texture2D> p_icon) const {
+ Ref<TextParagraph> paragraph;
+ if (p_text.is_empty()) {
+ paragraph = text_buf;
+ } else {
+ paragraph.instantiate();
+ const_cast<Button *>(this)->_shape(paragraph, p_text);
+ }
+
+ Size2 minsize = paragraph->get_size();
+ if (clip_text || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) {
+ minsize.width = 0;
+ }
+
+ if (!expand_icon && !p_icon.is_null()) {
+ minsize.height = MAX(minsize.height, p_icon->get_height());
+
+ if (icon_alignment != HORIZONTAL_ALIGNMENT_CENTER) {
+ minsize.width += p_icon->get_width();
+ if (!xl_text.is_empty() || !p_text.is_empty()) {
+ minsize.width += get_theme_constant(SNAME("hseparation"));
+ }
+ } else {
+ minsize.width = MAX(minsize.width, p_icon->get_width());
+ }
+ }
+
+ if (!xl_text.is_empty() || !p_text.is_empty()) {
+ Ref<Font> font = get_theme_font(SNAME("font"));
+ float font_height = font->get_height(get_theme_font_size(SNAME("font_size")));
+ minsize.height = MAX(font_height, minsize.height);
+ }
+
+ return get_theme_stylebox(SNAME("normal"))->get_minimum_size() + minsize;
+}
+
+void Button::_shape(Ref<TextParagraph> p_paragraph, String p_text) {
+ if (p_paragraph.is_null()) {
+ p_paragraph = text_buf;
+ }
+
+ if (p_text.is_empty()) {
+ p_text = xl_text;
+ }
+
Ref<Font> font = get_theme_font(SNAME("font"));
int font_size = get_theme_font_size(SNAME("font_size"));
- text_buf->clear();
+ p_paragraph->clear();
if (text_direction == Control::TEXT_DIRECTION_INHERITED) {
- text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
+ p_paragraph->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
} else {
- text_buf->set_direction((TextServer::Direction)text_direction);
+ p_paragraph->set_direction((TextServer::Direction)text_direction);
}
- text_buf->add_string(xl_text, font, font_size, language);
- text_buf->set_text_overrun_behavior(overrun_behavior);
+ p_paragraph->add_string(p_text, font, font_size, language);
+ p_paragraph->set_text_overrun_behavior(overrun_behavior);
}
void Button::set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior) {
diff --git a/scene/gui/button.h b/scene/gui/button.h
index 9d8d457f7c..23b5c78166 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -54,7 +54,7 @@ private:
HorizontalAlignment icon_alignment = HORIZONTAL_ALIGNMENT_LEFT;
float _internal_margin[4] = {};
- void _shape();
+ void _shape(Ref<TextParagraph> p_paragraph = Ref<TextParagraph>(), String p_text = "");
protected:
void _set_internal_margin(Side p_side, float p_value);
@@ -64,6 +64,8 @@ protected:
public:
virtual Size2 get_minimum_size() const override;
+ Size2 get_minimum_size_for_text_and_icon(const String &p_text, Ref<Texture2D> p_icon) const;
+
void set_text(const String &p_text);
String get_text() const;
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index dc186b2209..8f63d76347 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -264,15 +264,7 @@ void ColorPicker::_update_controls() {
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
color = p_color;
if (color != last_color) {
- if (_get_actual_shape() == SHAPE_OKHSL_CIRCLE) {
- h = color.get_ok_hsl_h();
- s = color.get_ok_hsl_s();
- v = color.get_ok_hsl_l();
- } else {
- h = color.get_h();
- s = color.get_s();
- v = color.get_v();
- }
+ _copy_color_to_hsv();
last_color = color;
}
@@ -386,6 +378,26 @@ Vector<float> ColorPicker::get_active_slider_values() {
return values;
}
+void ColorPicker::_copy_color_to_hsv() {
+ if (_get_actual_shape() == SHAPE_OKHSL_CIRCLE) {
+ h = color.get_ok_hsl_h();
+ s = color.get_ok_hsl_s();
+ v = color.get_ok_hsl_l();
+ } else {
+ h = color.get_h();
+ s = color.get_s();
+ v = color.get_v();
+ }
+}
+
+void ColorPicker::_copy_hsv_to_color() {
+ if (_get_actual_shape() == SHAPE_OKHSL_CIRCLE) {
+ color.set_ok_hsl(h, s, v, color.a);
+ } else {
+ color.set_hsv(h, s, v, color.a);
+ }
+}
+
ColorPicker::PickerShapeType ColorPicker::_get_actual_shape() const {
return modes[current_mode]->get_shape_override() != SHAPE_MAX ? modes[current_mode]->get_shape_override() : current_shape;
}
@@ -499,6 +511,8 @@ void ColorPicker::set_picker_shape(PickerShapeType p_shape) {
ERR_FAIL_INDEX(p_shape, SHAPE_MAX);
current_shape = p_shape;
+ _copy_color_to_hsv();
+
_update_controls();
_update_color();
}
@@ -640,8 +654,7 @@ void ColorPicker::_sample_input(const Ref<InputEvent> &p_event) {
const Rect2 rect_old = Rect2(Point2(), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95));
if (rect_old.has_point(mb->get_position())) {
// Revert to the old color when left-clicking the old color sample.
- color = old_color;
- _update_color();
+ set_pick_color(old_color);
emit_signal(SNAME("color_changed"), color);
}
}
@@ -887,17 +900,14 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
v = 1.0 - (y - c->get_position().y - corner_y) / real_size.y;
}
}
+
changing_color = true;
- if (current_picker == SHAPE_OKHSL_CIRCLE) {
- color.set_ok_hsl(h, s, v, color.a);
- } else {
- color.set_hsv(h, s, v, color.a);
- }
+ _copy_hsv_to_color();
last_color = color;
-
set_pick_color(color);
_update_color();
+
if (!deferred_mode_enabled) {
emit_signal(SNAME("color_changed"), color);
}
@@ -940,14 +950,12 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
v = 1.0 - (y - corner_y) / real_size.y;
}
}
- if (current_picker != SHAPE_OKHSL_CIRCLE) {
- color.set_hsv(h, s, v, color.a);
- } else {
- color.set_ok_hsl(h, s, v, color.a);
- }
+
+ _copy_hsv_to_color();
last_color = color;
set_pick_color(color);
_update_color();
+
if (!deferred_mode_enabled) {
emit_signal(SNAME("color_changed"), color);
}
@@ -970,14 +978,12 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
} else {
changing_color = false;
}
- if (actual_shape != SHAPE_OKHSL_CIRCLE) {
- color.set_hsv(h, s, v, color.a);
- } else {
- color.set_ok_hsl(h, s, v, color.a);
- }
+
+ _copy_hsv_to_color();
last_color = color;
set_pick_color(color);
_update_color();
+
if (!deferred_mode_enabled) {
emit_signal(SNAME("color_changed"), color);
} else if (!bev->is_pressed() && bev->get_button_index() == MouseButton::LEFT) {
@@ -998,15 +1004,11 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
h = y / w_edit->get_size().height;
}
- if (actual_shape == SHAPE_OKHSL_CIRCLE) {
- color.set_ok_hsl(h, s, v, color.a);
- } else {
- color.set_hsv(h, s, v, color.a);
- }
-
+ _copy_hsv_to_color();
last_color = color;
set_pick_color(color);
_update_color();
+
if (!deferred_mode_enabled) {
emit_signal(SNAME("color_changed"), color);
}
@@ -1019,7 +1021,6 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event, const Color &p_c
if (bev.is_valid()) {
if (bev->is_pressed() && bev->get_button_index() == MouseButton::LEFT) {
set_pick_color(p_color);
- _update_color();
emit_signal(SNAME("color_changed"), p_color);
} else if (bev->is_pressed() && bev->get_button_index() == MouseButton::RIGHT && presets_enabled) {
erase_preset(p_color);
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 8e65ee1861..05b760b109 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -156,6 +156,9 @@ private:
float v = 0.0;
Color last_color;
+ void _copy_color_to_hsv();
+ void _copy_hsv_to_color();
+
PickerShapeType _get_actual_shape() const;
void create_slider(GridContainer *gc, int idx);
void _reset_theme();
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 92016ca42e..c5054525a7 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -1051,6 +1051,7 @@ void GraphNode::_bind_methods() {
ADD_GROUP("BiDi", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
+ ADD_GROUP("", "");
ADD_SIGNAL(MethodInfo("position_offset_changed"));
ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx")));
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index a10ec1db06..c58513df17 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -35,7 +35,12 @@
static const int NONE_SELECTED = -1;
Size2 OptionButton::get_minimum_size() const {
- Size2 minsize = Button::get_minimum_size();
+ Size2 minsize;
+ if (fit_to_longest_item) {
+ minsize = _cached_size;
+ } else {
+ minsize = Button::get_minimum_size();
+ }
if (has_theme_icon(SNAME("arrow"))) {
const Size2 padding = get_theme_stylebox(SNAME("normal"))->get_minimum_size();
@@ -107,6 +112,7 @@ void OptionButton::_notification(int p_what) {
_set_internal_margin(SIDE_RIGHT, Control::get_theme_icon(SNAME("arrow"))->get_width());
}
}
+ _refresh_size_cache();
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
@@ -135,6 +141,10 @@ bool OptionButton::_set(const StringName &p_name, const Variant &p_value) {
_select(idx, false);
}
+ if (property == "text" || property == "icon") {
+ _queue_refresh_cache();
+ }
+
return valid;
}
return false;
@@ -208,6 +218,7 @@ void OptionButton::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_l
if (first_selectable) {
select(get_item_count() - 1);
}
+ _queue_refresh_cache();
}
void OptionButton::add_item(const String &p_label, int p_id) {
@@ -216,6 +227,7 @@ void OptionButton::add_item(const String &p_label, int p_id) {
if (first_selectable) {
select(get_item_count() - 1);
}
+ _queue_refresh_cache();
}
void OptionButton::set_item_text(int p_idx, const String &p_text) {
@@ -224,6 +236,7 @@ void OptionButton::set_item_text(int p_idx, const String &p_text) {
if (current == p_idx) {
set_text(p_text);
}
+ _queue_refresh_cache();
}
void OptionButton::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
@@ -232,6 +245,7 @@ void OptionButton::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
if (current == p_idx) {
set_icon(p_icon);
}
+ _queue_refresh_cache();
}
void OptionButton::set_item_id(int p_idx, int p_id) {
@@ -301,6 +315,7 @@ void OptionButton::set_item_count(int p_count) {
}
}
+ _refresh_size_cache();
notify_property_list_changed();
}
@@ -333,6 +348,19 @@ int OptionButton::get_item_count() const {
return popup->get_item_count();
}
+void OptionButton::set_fit_to_longest_item(bool p_fit) {
+ if (p_fit == fit_to_longest_item) {
+ return;
+ }
+ fit_to_longest_item = p_fit;
+
+ _refresh_size_cache();
+}
+
+bool OptionButton::is_fit_to_longest_item() const {
+ return fit_to_longest_item;
+}
+
void OptionButton::add_separator(const String &p_text) {
popup->add_separator(p_text);
}
@@ -341,6 +369,7 @@ void OptionButton::clear() {
popup->clear();
set_text("");
current = NONE_SELECTED;
+ _refresh_size_cache();
}
void OptionButton::_select(int p_which, bool p_emit) {
@@ -380,6 +409,29 @@ void OptionButton::_select_int(int p_which) {
_select(p_which, false);
}
+void OptionButton::_refresh_size_cache() {
+ cache_refresh_pending = false;
+
+ if (!fit_to_longest_item) {
+ return;
+ }
+
+ _cached_size = Vector2();
+ for (int i = 0; i < get_item_count(); i++) {
+ _cached_size = _cached_size.max(get_minimum_size_for_text_and_icon(get_item_text(i), get_item_icon(i)));
+ }
+ update_minimum_size();
+}
+
+void OptionButton::_queue_refresh_cache() {
+ if (cache_refresh_pending) {
+ return;
+ }
+ cache_refresh_pending = true;
+
+ callable_mp(this, &OptionButton::_refresh_size_cache).call_deferredp(nullptr, 0);
+}
+
void OptionButton::select(int p_idx) {
_select(p_idx, false);
}
@@ -405,6 +457,7 @@ void OptionButton::remove_item(int p_idx) {
if (current == p_idx) {
_select(NONE_SELECTED);
}
+ _queue_refresh_cache();
}
PopupMenu *OptionButton::get_popup() const {
@@ -453,10 +506,13 @@ void OptionButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_count"), &OptionButton::get_item_count);
ClassDB::bind_method(D_METHOD("has_selectable_items"), &OptionButton::has_selectable_items);
ClassDB::bind_method(D_METHOD("get_selectable_item", "from_last"), &OptionButton::get_selectable_item, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("set_fit_to_longest_item", "fit"), &OptionButton::set_fit_to_longest_item);
+ ClassDB::bind_method(D_METHOD("is_fit_to_longest_item"), &OptionButton::is_fit_to_longest_item);
// "selected" property must come after "item_count", otherwise GH-10213 occurs.
ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "popup/item_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "selected"), "_select_int", "get_selected");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fit_to_longest_item"), "set_fit_to_longest_item", "is_fit_to_longest_item");
ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "index")));
ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "index")));
}
@@ -482,6 +538,7 @@ OptionButton::OptionButton(const String &p_text) :
popup->connect("index_pressed", callable_mp(this, &OptionButton::_selected));
popup->connect("id_focused", callable_mp(this, &OptionButton::_focused));
popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed).bind(false));
+ _refresh_size_cache();
}
OptionButton::~OptionButton() {
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 5665296699..49b5eee910 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -39,11 +39,16 @@ class OptionButton : public Button {
PopupMenu *popup = nullptr;
int current = -1;
+ bool fit_to_longest_item = true;
+ Vector2 _cached_size;
+ bool cache_refresh_pending = false;
void _focused(int p_which);
void _selected(int p_which);
void _select(int p_which, bool p_emit = false);
void _select_int(int p_which);
+ void _refresh_size_cache();
+ void _queue_refresh_cache();
virtual void pressed() override;
@@ -85,6 +90,8 @@ public:
void set_item_count(int p_count);
int get_item_count() const;
+ void set_fit_to_longest_item(bool p_fit);
+ bool is_fit_to_longest_item() const;
void add_separator(const String &p_text = "");
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 9efab27e3a..8fd547813d 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -37,7 +37,10 @@
Size2 ScrollContainer::get_minimum_size() const {
Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg"));
Size2 min_size;
- Size2 content_min_size;
+
+ // Calculated in this function, as it needs to traverse all child controls once to calculate;
+ // and needs to be calculated before being used by update_scrollbars().
+ largest_child_min_size = Size2();
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
@@ -50,25 +53,27 @@ Size2 ScrollContainer::get_minimum_size() const {
if (c == h_scroll || c == v_scroll) {
continue;
}
- Size2 minsize = c->get_combined_minimum_size();
- content_min_size.x = MAX(content_min_size.x, minsize.x);
- content_min_size.y = MAX(content_min_size.y, minsize.y);
+ Size2 child_min_size = c->get_combined_minimum_size();
+
+ largest_child_min_size.x = MAX(largest_child_min_size.x, child_min_size.x);
+ largest_child_min_size.y = MAX(largest_child_min_size.y, child_min_size.y);
}
if (horizontal_scroll_mode == SCROLL_MODE_DISABLED) {
- min_size.x = MAX(min_size.x, content_min_size.x);
+ min_size.x = MAX(min_size.x, largest_child_min_size.x);
}
if (vertical_scroll_mode == SCROLL_MODE_DISABLED) {
- min_size.y = MAX(min_size.y, content_min_size.y);
+ min_size.y = MAX(min_size.y, largest_child_min_size.y);
}
- bool h_scroll_show = horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && content_min_size.x > min_size.x);
- bool v_scroll_show = vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && content_min_size.y > min_size.y);
- if (h_scroll_show) {
+ bool h_scroll_show = horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.x > min_size.x);
+ bool v_scroll_show = vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.y > min_size.y);
+
+ if (h_scroll_show && h_scroll->get_parent() == this) {
min_size.y += h_scroll->get_minimum_size().y;
}
- if (v_scroll_show) {
+ if (v_scroll_show && v_scroll->get_parent() == this) {
min_size.x += v_scroll->get_minimum_size().x;
}
@@ -261,8 +266,8 @@ void ScrollContainer::ensure_control_visible(Control *p_control) {
set_v_scroll(get_v_scroll() + (diff.y - global_rect.position.y));
}
-void ScrollContainer::_update_dimensions() {
- child_max_size = Size2(0, 0);
+void ScrollContainer::_reposition_children() {
+ update_scrollbars();
Size2 size = get_size();
Point2 ofs;
@@ -291,25 +296,13 @@ void ScrollContainer::_update_dimensions() {
continue;
}
Size2 minsize = c->get_combined_minimum_size();
- child_max_size.x = MAX(child_max_size.x, minsize.x);
- child_max_size.y = MAX(child_max_size.y, minsize.y);
Rect2 r = Rect2(-Size2(get_h_scroll(), get_v_scroll()), minsize);
- if (horizontal_scroll_mode == SCROLL_MODE_DISABLED || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
- r.position.x = 0;
- if (c->get_h_size_flags() & SIZE_EXPAND) {
- r.size.width = MAX(size.width, minsize.width);
- } else {
- r.size.width = minsize.width;
- }
+ if (c->get_h_size_flags() & SIZE_EXPAND) {
+ r.size.width = MAX(size.width, minsize.width);
}
- if (vertical_scroll_mode == SCROLL_MODE_DISABLED || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) {
- r.position.y = 0;
- if (c->get_v_size_flags() & SIZE_EXPAND) {
- r.size.height = MAX(size.height, minsize.height);
- } else {
- r.size.height = minsize.height;
- }
+ if (c->get_v_size_flags() & SIZE_EXPAND) {
+ r.size.height = MAX(size.height, minsize.height);
}
r.position += ofs;
if (rtl && v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) {
@@ -319,7 +312,6 @@ void ScrollContainer::_update_dimensions() {
fit_child_in_rect(c, r);
}
- update_scrollbars();
update();
}
@@ -337,18 +329,16 @@ void ScrollContainer::_notification(int p_what) {
Viewport *viewport = get_viewport();
ERR_FAIL_COND(!viewport);
viewport->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_gui_focus_changed));
- _update_dimensions();
+ _reposition_children();
} break;
case NOTIFICATION_SORT_CHILDREN: {
- _update_dimensions();
+ _reposition_children();
} break;
case NOTIFICATION_DRAW: {
Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg"));
draw_style_box(sb, Rect2(Vector2(), get_size()));
-
- update_scrollbars();
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -426,36 +416,25 @@ void ScrollContainer::update_scrollbars() {
Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg"));
size -= sb->get_minimum_size();
- Size2 hmin;
- Size2 vmin;
- if (horizontal_scroll_mode != SCROLL_MODE_DISABLED) {
- hmin = h_scroll->get_combined_minimum_size();
- }
- if (vertical_scroll_mode != SCROLL_MODE_DISABLED) {
- vmin = v_scroll->get_combined_minimum_size();
- }
-
- Size2 min = child_max_size;
+ Size2 hmin = h_scroll->get_combined_minimum_size();
+ Size2 vmin = v_scroll->get_combined_minimum_size();
- bool hide_scroll_h = horizontal_scroll_mode != SCROLL_MODE_SHOW_ALWAYS && (horizontal_scroll_mode == SCROLL_MODE_DISABLED || horizontal_scroll_mode == SCROLL_MODE_SHOW_NEVER || (horizontal_scroll_mode == SCROLL_MODE_AUTO && min.width <= size.width));
- bool hide_scroll_v = vertical_scroll_mode != SCROLL_MODE_SHOW_ALWAYS && (vertical_scroll_mode == SCROLL_MODE_DISABLED || vertical_scroll_mode == SCROLL_MODE_SHOW_NEVER || (vertical_scroll_mode == SCROLL_MODE_AUTO && min.height <= size.height));
+ h_scroll->set_visible(horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.width > size.width));
+ v_scroll->set_visible(vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && largest_child_min_size.height > size.height));
- h_scroll->set_max(min.width);
- h_scroll->set_page(size.width - (hide_scroll_v ? 0 : vmin.width));
- h_scroll->set_visible(!hide_scroll_h);
+ h_scroll->set_max(largest_child_min_size.width);
+ h_scroll->set_page((v_scroll->is_visible() && v_scroll->get_parent() == this) ? size.width - vmin.width : size.width);
- v_scroll->set_max(min.height);
- v_scroll->set_page(size.height - (hide_scroll_h ? 0 : hmin.height));
- v_scroll->set_visible(!hide_scroll_v);
+ v_scroll->set_max(largest_child_min_size.height);
+ v_scroll->set_page((h_scroll->is_visible() && h_scroll->get_parent() == this) ? size.height - hmin.height : size.height);
// Avoid scrollbar overlapping.
- h_scroll->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, hide_scroll_v ? 0 : -vmin.width);
- v_scroll->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, hide_scroll_h ? 0 : -hmin.height);
+ h_scroll->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, (v_scroll->is_visible() && v_scroll->get_parent() == this) ? -vmin.width : 0);
+ v_scroll->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, (h_scroll->is_visible() && h_scroll->get_parent() == this) ? -hmin.height : 0);
}
void ScrollContainer::_scroll_moved(float) {
queue_sort();
- update();
};
void ScrollContainer::set_h_scroll(int p_pos) {
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index 7c8690538d..bfa74cfd0f 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -50,7 +50,7 @@ private:
HScrollBar *h_scroll = nullptr;
VScrollBar *v_scroll = nullptr;
- Size2 child_max_size;
+ mutable Size2 largest_child_min_size; // The largest one among the min sizes of all available child controls.
void update_scrollbars();
@@ -75,7 +75,7 @@ protected:
Size2 get_minimum_size() const override;
void _gui_focus_changed(Control *p_control);
- void _update_dimensions();
+ void _reposition_children();
void _notification(int p_what);
void _scroll_moved(float);
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 6617bd1726..ea9788de27 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -653,21 +653,6 @@ Error Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallE
return err;
}
-template <typename... VarArgs>
-Error Node::rpc(const StringName &p_method, VarArgs... p_args) {
- return rpc_id(0, p_method, p_args...);
-}
-
-template <typename... VarArgs>
-Error Node::rpc_id(int p_peer_id, const StringName &p_method, VarArgs... p_args) {
- Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
- const Variant *argptrs[sizeof...(p_args) + 1];
- for (uint32_t i = 0; i < sizeof...(p_args); i++) {
- argptrs[i] = &args[i];
- }
- return rpcp(p_peer_id, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
-}
-
Error Node::rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) {
ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED);
return get_multiplayer()->rpcp(this, p_peer_id, p_method, p_arg, p_argcount);
diff --git a/scene/main/node.h b/scene/main/node.h
index 0645c68eb9..ccd1d561d2 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -512,4 +512,22 @@ VARIANT_ENUM_CAST(Node::DuplicateFlags);
typedef HashSet<Node *, Node::Comparator> NodeSet;
+// Template definitions must be in the header so they are always fully initialized before their usage.
+// See this StackOverflow question for more information: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file
+
+template <typename... VarArgs>
+Error Node::rpc(const StringName &p_method, VarArgs... p_args) {
+ return rpc_id(0, p_method, p_args...);
+}
+
+template <typename... VarArgs>
+Error Node::rpc_id(int p_peer_id, const StringName &p_method, VarArgs... p_args) {
+ Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
+ const Variant *argptrs[sizeof...(p_args) + 1];
+ for (uint32_t i = 0; i < sizeof...(p_args); i++) {
+ argptrs[i] = &args[i];
+ }
+ return rpcp(p_peer_id, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
+}
+
#endif // NODE_H
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 0878a9f78f..d7fcd500b2 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -523,9 +523,7 @@ void register_scene_types() {
GDREGISTER_CLASS(GPUParticlesAttractorVectorField3D);
GDREGISTER_CLASS(CPUParticles3D);
GDREGISTER_CLASS(Position3D);
-
GDREGISTER_CLASS(RootMotionView);
- ClassDB::set_class_enabled("RootMotionView", false); // disabled by default, enabled by editor
OS::get_singleton()->yield(); // may take time to init
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index a8d4903dad..95b0f9e6c0 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -1249,8 +1249,8 @@ void Environment::_bind_methods() {
ADD_GROUP("SSR", "ssr_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssr_enabled"), "set_ssr_enabled", "is_ssr_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "ssr_max_steps", PROPERTY_HINT_RANGE, "1,512,1"), "set_ssr_max_steps", "get_ssr_max_steps");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_in", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_ssr_fade_in", "get_ssr_fade_in");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_out", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_ssr_fade_out", "get_ssr_fade_out");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_depth_tolerance", PROPERTY_HINT_RANGE, "0.01,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance");
// SSAO
@@ -1277,7 +1277,7 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.01,16,0.01,or_greater"), "set_ssao_radius", "get_ssao_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_ssao_intensity", "get_ssao_intensity");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_power", PROPERTY_HINT_EXP_EASING), "set_ssao_power", "get_ssao_power");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_power", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_ssao_power", "get_ssao_power");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_detail", PROPERTY_HINT_RANGE, "0,5,0.01"), "set_ssao_detail", "get_ssao_detail");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_horizon", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ssao_horizon", "get_ssao_horizon");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_sharpness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ssao_sharpness", "get_ssao_sharpness");
@@ -1462,7 +1462,7 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_RANGE, "0.0,16,0.01,exp"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_anisotropy", PROPERTY_HINT_RANGE, "-0.9,0.9,0.01"), "set_volumetric_fog_anisotropy", "get_volumetric_fog_anisotropy");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_ambient_inject", PROPERTY_HINT_RANGE, "0.0,16,0.01,exp"), "set_volumetric_fog_ambient_inject", "get_volumetric_fog_ambient_inject");
ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled");
diff --git a/scene/resources/label_settings.h b/scene/resources/label_settings.h
index d2644a7484..062d499d50 100644
--- a/scene/resources/label_settings.h
+++ b/scene/resources/label_settings.h
@@ -39,17 +39,17 @@
class LabelSettings : public Resource {
GDCLASS(LabelSettings, Resource);
- real_t line_spacing = 0;
+ real_t line_spacing = 3;
Ref<Font> font;
int font_size = Font::DEFAULT_FONT_SIZE;
- Color font_color = Color(0.875, 0.875, 0.875);
+ Color font_color = Color(1, 1, 1);
int outline_size = 0;
Color outline_color = Color(1, 1, 1);
- int shadow_size = 0;
- Color shadow_color = Color(1, 1, 1);
+ int shadow_size = 1;
+ Color shadow_color = Color(0, 0, 0, 0);
Vector2 shadow_offset = Vector2(1, 1);
void _font_changed();
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index 4b2fdbed5b..4b2e029f47 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -98,7 +98,7 @@ void ParticlesMaterial::init_shaders() {
shader_names->emission_ring_radius = "emission_ring_radius";
shader_names->emission_ring_inner_radius = "emission_ring_inner_radius";
- shader_names->turbulence_active = "turbulence_active";
+ shader_names->turbulence_enabled = "turbulence_enabled";
shader_names->turbulence_noise_strength = "turbulence_noise_strength";
shader_names->turbulence_noise_scale = "turbulence_noise_scale";
shader_names->turbulence_noise_speed = "turbulence_noise_speed";
@@ -292,7 +292,7 @@ void ParticlesMaterial::_update_shader() {
code += "uniform float collision_bounce;\n";
}
- if (turbulence_active) {
+ if (turbulence_enabled) {
code += "uniform float turbulence_noise_strength;\n";
code += "uniform float turbulence_noise_scale;\n";
code += "uniform float turbulence_influence_min;\n";
@@ -546,7 +546,7 @@ void ParticlesMaterial::_update_shader() {
}
code += " if (RESTART_VELOCITY) VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n";
// Apply noise/turbulence: initial displacement.
- if (turbulence_active) {
+ if (turbulence_enabled) {
if (get_turbulence_noise_speed_random() >= 0.0) {
code += " vec3 time_noise = noise_3d( vec3(TIME) * turbulence_noise_speed_random ) * -turbulence_noise_speed;\n";
} else {
@@ -680,7 +680,7 @@ void ParticlesMaterial::_update_shader() {
}
// Apply noise/turbulence.
- if (turbulence_active) {
+ if (turbulence_enabled) {
code += " // apply turbulence\n";
if (tex_parameters[PARAM_TURB_INFLUENCE_OVER_LIFE].is_valid()) {
code += " float turbulence_influence = textureLod(turbulence_influence_over_life, vec2(tv, 0.0), 0.0).r;\n";
@@ -837,7 +837,7 @@ void ParticlesMaterial::_update_shader() {
code += " } else {\n";
code += " VELOCITY = vec3(0.0);\n";
// If turbulence is enabled, set the noise direction to up so the turbulence color is "neutral"
- if (turbulence_active) {
+ if (turbulence_enabled) {
code += " noise_direction = vec3(1.0, 0.0, 0.0);\n";
}
code += " }\n";
@@ -1311,15 +1311,15 @@ real_t ParticlesMaterial::get_emission_ring_inner_radius() const {
return emission_ring_inner_radius;
}
-void ParticlesMaterial::set_turbulence_active(const bool p_turbulence_active) {
- turbulence_active = p_turbulence_active;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_active, turbulence_active);
+void ParticlesMaterial::set_turbulence_enabled(const bool p_turbulence_enabled) {
+ turbulence_enabled = p_turbulence_enabled;
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_enabled, turbulence_enabled);
_queue_shader_change();
notify_property_list_changed();
}
-bool ParticlesMaterial::get_turbulence_active() const {
- return turbulence_active;
+bool ParticlesMaterial::get_turbulence_enabled() const {
+ return turbulence_enabled;
}
void ParticlesMaterial::set_turbulence_noise_strength(float p_turbulence_noise_strength) {
@@ -1423,7 +1423,7 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
property.usage = PROPERTY_USAGE_NONE;
}
- if (!turbulence_active) {
+ if (!turbulence_enabled) {
if (property.name == "turbulence_noise_strength" ||
property.name == "turbulence_noise_scale" ||
property.name == "turbulence_noise_speed" ||
@@ -1433,7 +1433,7 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
property.name == "turbulence_influence_max" ||
property.name == "turbulence_initial_displacement_min" ||
property.name == "turbulence_initial_displacement_max") {
- property.usage = PROPERTY_USAGE_NONE;
+ property.usage = PROPERTY_USAGE_NO_EDITOR;
}
}
}
@@ -1587,8 +1587,8 @@ void ParticlesMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_emission_ring_inner_radius", "inner_radius"), &ParticlesMaterial::set_emission_ring_inner_radius);
ClassDB::bind_method(D_METHOD("get_emission_ring_inner_radius"), &ParticlesMaterial::get_emission_ring_inner_radius);
- ClassDB::bind_method(D_METHOD("get_turbulence_active"), &ParticlesMaterial::get_turbulence_active);
- ClassDB::bind_method(D_METHOD("set_turbulence_active", "turbulence_active"), &ParticlesMaterial::set_turbulence_active);
+ ClassDB::bind_method(D_METHOD("get_turbulence_enabled"), &ParticlesMaterial::get_turbulence_enabled);
+ ClassDB::bind_method(D_METHOD("set_turbulence_enabled", "turbulence_enabled"), &ParticlesMaterial::set_turbulence_enabled);
ClassDB::bind_method(D_METHOD("get_turbulence_noise_strength"), &ParticlesMaterial::get_turbulence_noise_strength);
ClassDB::bind_method(D_METHOD("set_turbulence_noise_strength", "turbulence_noise_strength"), &ParticlesMaterial::set_turbulence_noise_strength);
@@ -1650,7 +1650,7 @@ void ParticlesMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_height"), "set_emission_ring_height", "get_emission_ring_height");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_radius"), "set_emission_ring_radius", "get_emission_ring_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_inner_radius"), "set_emission_ring_inner_radius", "get_emission_ring_inner_radius");
- ADD_GROUP("ParticleFlags", "particle_flag_");
+ ADD_GROUP("Particle Flags", "particle_flag_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_rotate_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ROTATE_Y);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_disable_z"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_DISABLE_Z);
@@ -1706,7 +1706,7 @@ void ParticlesMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_HUE_VARIATION);
ADD_GROUP("Turbulence", "turbulence_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "turbulence_active"), "set_turbulence_active", "get_turbulence_active");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "turbulence_enabled"), "set_turbulence_enabled", "get_turbulence_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_strength", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_turbulence_noise_strength", "get_turbulence_noise_strength");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_scale", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_turbulence_noise_scale", "get_turbulence_noise_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "turbulence_noise_speed"), "set_turbulence_noise_speed", "get_turbulence_noise_speed");
@@ -1815,7 +1815,7 @@ ParticlesMaterial::ParticlesMaterial() :
set_emission_ring_radius(1);
set_emission_ring_inner_radius(0);
- set_turbulence_active(false);
+ set_turbulence_enabled(false);
set_turbulence_noise_speed(Vector3(0.5, 0.5, 0.5));
set_turbulence_noise_strength(1);
set_turbulence_noise_scale(9);
diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h
index 18ab60a431..7fb46d6ac5 100644
--- a/scene/resources/particles_material.h
+++ b/scene/resources/particles_material.h
@@ -108,7 +108,7 @@ private:
uint32_t attractor_enabled : 1;
uint32_t collision_enabled : 1;
uint32_t collision_scale : 1;
- uint32_t turbulence_active : 1;
+ uint32_t turbulence_enabled : 1;
};
uint64_t key = 0;
@@ -156,7 +156,7 @@ private:
mk.collision_enabled = collision_enabled;
mk.attractor_enabled = attractor_interaction_enabled;
mk.collision_scale = collision_scale;
- mk.turbulence_active = turbulence_active;
+ mk.turbulence_enabled = turbulence_enabled;
return mk;
}
@@ -221,7 +221,7 @@ private:
StringName emission_ring_radius;
StringName emission_ring_inner_radius;
- StringName turbulence_active;
+ StringName turbulence_enabled;
StringName turbulence_noise_strength;
StringName turbulence_noise_scale;
StringName turbulence_noise_speed;
@@ -282,7 +282,7 @@ private:
bool anim_loop = false;
- bool turbulence_active;
+ bool turbulence_enabled;
Vector3 turbulence_noise_speed;
Ref<Texture2D> turbulence_color_ramp;
float turbulence_noise_strength = 0.0f;
@@ -364,13 +364,13 @@ public:
real_t get_emission_ring_inner_radius() const;
int get_emission_point_count() const;
- void set_turbulence_active(bool p_turbulence_active);
+ void set_turbulence_enabled(bool p_turbulence_enabled);
void set_turbulence_noise_strength(float p_turbulence_noise_strength);
void set_turbulence_noise_scale(float p_turbulence_noise_scale);
void set_turbulence_noise_speed_random(float p_turbulence_noise_speed_random);
void set_turbulence_noise_speed(const Vector3 &p_turbulence_noise_speed);
- bool get_turbulence_active() const;
+ bool get_turbulence_enabled() const;
float get_turbulence_noise_strength() const;
float get_turbulence_noise_scale() const;
float get_turbulence_noise_speed_random() const;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 5e0627a7d9..a67716d52b 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -2647,6 +2647,10 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_world", "NODE_POSITION_WORLD" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_position_world", "CAMERA_POSITION_WORLD" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_direction_world", "CAMERA_DIRECTION_WORLD" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_view", "NODE_POSITION_VIEW" },
// Node3D, Fragment
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_4D, "fragcoord", "FRAGCOORD" },
@@ -2675,6 +2679,10 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_world", "NODE_POSITION_WORLD" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_position_world", "CAMERA_POSITION_WORLD" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_direction_world", "CAMERA_DIRECTION_WORLD" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_view", "NODE_POSITION_VIEW" },
// Node3D, Light
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_4D, "fragcoord", "FRAGCOORD" },
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index b8667f07fe..5cc2073ca5 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -5581,12 +5581,16 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty
case VisualShaderNodeTextureUniform::TYPE_DATA:
if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) {
type_code = "hint_default_black";
+ } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) {
+ type_code = "hint_default_transparent";
}
break;
case VisualShaderNodeTextureUniform::TYPE_COLOR:
type_code = "source_color";
if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) {
type_code += ", hint_default_black";
+ } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) {
+ type_code += ", hint_default_transparent";
}
break;
case VisualShaderNodeTextureUniform::TYPE_NORMAL_MAP:
@@ -5812,7 +5816,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureUniform::get_texture_repeat);
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black"), "set_color_default", "get_color_default");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black,Transparent"), "set_color_default", "get_color_default");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Default,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Default,Enabled,Disabled"), "set_texture_repeat", "get_texture_repeat");
@@ -5824,6 +5828,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() {
BIND_ENUM_CONSTANT(COLOR_DEFAULT_WHITE);
BIND_ENUM_CONSTANT(COLOR_DEFAULT_BLACK);
+ BIND_ENUM_CONSTANT(COLOR_DEFAULT_TRANSPARENT);
BIND_ENUM_CONSTANT(COLOR_DEFAULT_MAX);
BIND_ENUM_CONSTANT(FILTER_DEFAULT);
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 1eb7b7240f..f770156d14 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -2131,6 +2131,7 @@ public:
enum ColorDefault {
COLOR_DEFAULT_WHITE,
COLOR_DEFAULT_BLACK,
+ COLOR_DEFAULT_TRANSPARENT,
COLOR_DEFAULT_MAX,
};