summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/3d/node_3d.cpp4
-rw-r--r--scene/gui/box_container.cpp11
-rw-r--r--scene/gui/file_dialog.cpp2
-rw-r--r--scene/gui/line_edit.cpp47
-rw-r--r--scene/gui/line_edit.h4
-rw-r--r--scene/gui/scroll_bar.cpp2
-rw-r--r--scene/gui/text_edit.cpp2
-rw-r--r--scene/main/canvas_item.cpp2
-rw-r--r--scene/main/node.cpp14
-rw-r--r--scene/main/scene_tree.cpp14
-rw-r--r--scene/main/scene_tree.h1
-rw-r--r--scene/main/viewport.cpp8
-rw-r--r--scene/main/window.cpp1
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/animation.cpp2
-rw-r--r--scene/resources/visual_shader.cpp94
-rw-r--r--scene/resources/visual_shader.h10
-rw-r--r--scene/resources/visual_shader_nodes.cpp21
-rw-r--r--scene/resources/visual_shader_nodes.h3
19 files changed, 173 insertions, 71 deletions
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 73f17060df..bd9e4f5bde 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -174,7 +174,7 @@ void Node3D::_notification(int p_what) {
ERR_FAIL_COND(!data.viewport);
if (get_script_instance()) {
- get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, nullptr, 0);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_enter_world);
}
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) {
@@ -202,7 +202,7 @@ void Node3D::_notification(int p_what) {
#endif
if (get_script_instance()) {
- get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world, nullptr, 0);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_exit_world);
}
data.viewport = nullptr;
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index 191110a669..f130726837 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -104,6 +104,7 @@ void BoxContainer::_resort() {
has_stretched = true;
bool refit_successful = true; //assume refit-test will go well
+ float error = 0; // Keep track of accumulated error in pixels
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
@@ -119,8 +120,9 @@ void BoxContainer::_resort() {
if (msc.will_stretch) { //wants to stretch
//let's see if it can really stretch
-
- int final_pixel_size = stretch_avail * c->get_stretch_ratio() / stretch_ratio_total;
+ float final_pixel_size = stretch_avail * c->get_stretch_ratio() / stretch_ratio_total;
+ // Add leftover fractional pixels to error accumulator
+ error += final_pixel_size - (int)final_pixel_size;
if (final_pixel_size < msc.min_size) {
//if available stretching area is too small for widget,
//then remove it from stretching area
@@ -132,6 +134,11 @@ void BoxContainer::_resort() {
break;
} else {
msc.final_size = final_pixel_size;
+ // Dump accumulated error if one pixel or more
+ if (error >= 1) {
+ msc.final_size += 1;
+ error -= 1;
+ }
}
}
}
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 21eb3d558c..4aea2928f4 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -272,7 +272,7 @@ void FileDialog::_action_pressed() {
}
if (dir_access->file_exists(f)) {
- confirm_save->set_text(RTR("File Exists, Overwrite?"));
+ confirm_save->set_text(RTR("File exists, overwrite?"));
confirm_save->popup_centered(Size2(200, 80));
} else {
emit_signal("file_selected", f);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 3a0fbeaac3..5afc1f438e 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -120,9 +120,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
if (selection.enabled) {
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, selection.begin, selection.end);
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end);
} else {
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, cursor_pos);
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos);
}
}
}
@@ -313,6 +313,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
}
+ return;
} break;
case KEY_BACKSPACE: {
@@ -699,7 +700,7 @@ void LineEdit::_notification(int p_what) {
update();
} break;
case NOTIFICATION_DRAW: {
- if ((!has_focus() && !menu->has_focus()) || !window_has_focus) {
+ if ((!has_focus() && !menu->has_focus() && !caret_force_displayed) || !window_has_focus) {
draw_caret = false;
}
@@ -925,10 +926,14 @@ void LineEdit::_notification(int p_what) {
}
} break;
case NOTIFICATION_FOCUS_ENTER: {
- if (caret_blink_enabled) {
- caret_blink_timer->start();
- } else {
- draw_caret = true;
+ if (!caret_force_displayed) {
+ if (caret_blink_enabled) {
+ if (caret_blink_timer->is_stopped()) {
+ caret_blink_timer->start();
+ }
+ } else {
+ draw_caret = true;
+ }
}
if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) {
@@ -939,15 +944,15 @@ void LineEdit::_notification(int p_what) {
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
if (selection.enabled) {
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, selection.begin, selection.end);
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end);
} else {
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, cursor_pos);
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos);
}
}
} break;
case NOTIFICATION_FOCUS_EXIT: {
- if (caret_blink_enabled) {
+ if (caret_blink_enabled && !caret_force_displayed) {
caret_blink_timer->stop();
}
@@ -1167,9 +1172,11 @@ bool LineEdit::cursor_get_blink_enabled() const {
void LineEdit::cursor_set_blink_enabled(const bool p_enabled) {
caret_blink_enabled = p_enabled;
- if (has_focus()) {
+ if (has_focus() || caret_force_displayed) {
if (p_enabled) {
- caret_blink_timer->start();
+ if (caret_blink_timer->is_stopped()) {
+ caret_blink_timer->start();
+ }
} else {
caret_blink_timer->stop();
}
@@ -1178,6 +1185,16 @@ void LineEdit::cursor_set_blink_enabled(const bool p_enabled) {
draw_caret = true;
}
+bool LineEdit::cursor_get_force_displayed() const {
+ return caret_force_displayed;
+}
+
+void LineEdit::cursor_set_force_displayed(const bool p_enabled) {
+ caret_force_displayed = p_enabled;
+ cursor_set_blink_enabled(caret_blink_enabled);
+ update();
+}
+
float LineEdit::cursor_get_blink_speed() const {
return caret_blink_timer->get_wait_time();
}
@@ -1200,7 +1217,7 @@ void LineEdit::_reset_caret_blink_timer() {
void LineEdit::_toggle_draw_caret() {
draw_caret = !draw_caret;
- if (is_visible_in_tree() && has_focus() && window_has_focus) {
+ if (is_visible_in_tree() && ((has_focus() && window_has_focus) || caret_force_displayed)) {
update();
}
}
@@ -1804,6 +1821,8 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_expand_to_text_length"), &LineEdit::get_expand_to_text_length);
ClassDB::bind_method(D_METHOD("cursor_set_blink_enabled", "enabled"), &LineEdit::cursor_set_blink_enabled);
ClassDB::bind_method(D_METHOD("cursor_get_blink_enabled"), &LineEdit::cursor_get_blink_enabled);
+ ClassDB::bind_method(D_METHOD("cursor_set_force_displayed", "enabled"), &LineEdit::cursor_set_force_displayed);
+ ClassDB::bind_method(D_METHOD("cursor_get_force_displayed"), &LineEdit::cursor_get_force_displayed);
ClassDB::bind_method(D_METHOD("cursor_set_blink_speed", "blink_speed"), &LineEdit::cursor_set_blink_speed);
ClassDB::bind_method(D_METHOD("cursor_get_blink_speed"), &LineEdit::cursor_get_blink_speed);
ClassDB::bind_method(D_METHOD("set_max_length", "chars"), &LineEdit::set_max_length);
@@ -1870,6 +1889,7 @@ void LineEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "cursor_set_blink_enabled", "cursor_get_blink_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed");
ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_position"), "set_cursor_position", "get_cursor_position");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_force_displayed"), "cursor_set_force_displayed", "cursor_get_force_displayed");
}
LineEdit::LineEdit() {
@@ -1899,6 +1919,7 @@ LineEdit::LineEdit() {
draw_caret = true;
caret_blink_enabled = false;
+ caret_force_displayed = false;
caret_blink_timer = memnew(Timer);
add_child(caret_blink_timer);
caret_blink_timer->set_wait_time(0.65);
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 2ed63e7d50..d6cc1f1f11 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -136,6 +136,7 @@ private:
void update_placeholder_width();
bool caret_blink_enabled;
+ bool caret_force_displayed;
bool draw_caret;
bool window_has_focus;
@@ -203,6 +204,9 @@ public:
float cursor_get_blink_speed() const;
void cursor_set_blink_speed(const float p_speed);
+ bool cursor_get_force_displayed() const;
+ void cursor_set_force_displayed(const bool p_enabled);
+
void copy_text();
void cut_text();
void paste_text();
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 4db6ca2949..0e9ef71892 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -522,7 +522,7 @@ void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
drag_node_accum = Vector2();
last_drag_node_accum = Vector2();
drag_node_from = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0);
- drag_node_touching = !DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id()));
+ drag_node_touching = DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id()));
drag_node_touching_deaccel = false;
time_since_motion = 0;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 07ebdb6523..39ac10a46e 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1632,7 +1632,7 @@ void TextEdit::_notification(int p_what) {
}
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) {
- DisplayServer::get_singleton()->virtual_keyboard_show(get_text(), get_global_rect());
+ DisplayServer::get_singleton()->virtual_keyboard_show(get_text(), get_global_rect(), true);
}
} break;
case NOTIFICATION_FOCUS_EXIT: {
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index d1bf038b8d..d6d1134cc9 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -434,7 +434,7 @@ void CanvasItem::_update_callback() {
notification(NOTIFICATION_DRAW);
emit_signal(SceneStringNames::get_singleton()->draw);
if (get_script_instance()) {
- get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_draw, nullptr, 0);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_draw);
}
current_item_drawn = nullptr;
drawing = false;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 88f9730f78..4dcfcd9d96 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -55,15 +55,13 @@ void Node::_notification(int p_notification) {
case NOTIFICATION_PROCESS: {
if (get_script_instance()) {
Variant time = get_process_delta_time();
- const Variant *ptr[1] = { &time };
- get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_process, ptr, 1);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_process, time);
}
} break;
case NOTIFICATION_PHYSICS_PROCESS: {
if (get_script_instance()) {
Variant time = get_physics_process_delta_time();
- const Variant *ptr[1] = { &time };
- get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_physics_process, ptr, 1);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_physics_process, time);
}
} break;
@@ -146,7 +144,7 @@ void Node::_notification(int p_notification) {
set_physics_process(true);
}
- get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_ready, nullptr, 0);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_ready);
}
} break;
@@ -216,7 +214,7 @@ void Node::_propagate_enter_tree() {
notification(NOTIFICATION_ENTER_TREE);
if (get_script_instance()) {
- get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_enter_tree, nullptr, 0);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_enter_tree);
}
emit_signal(SceneStringNames::get_singleton()->tree_entered);
@@ -264,7 +262,7 @@ void Node::_propagate_exit_tree() {
data.blocked--;
if (get_script_instance()) {
- get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_tree, nullptr, 0);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_exit_tree);
}
emit_signal(SceneStringNames::get_singleton()->tree_exiting);
@@ -1060,7 +1058,7 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
bool unique = true;
- if (p_child->data.name == StringName() || p_child->data.name.operator String()[0] == '@') {
+ if (p_child->data.name == StringName()) {
//new unique name must be assigned
unique = false;
} else {
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index d6159e089b..75b3d7a73d 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -250,11 +250,7 @@ void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_grou
}
if (p_call_flags & GROUP_CALL_REALTIME) {
- if (p_call_flags & GROUP_CALL_MULTILEVEL) {
- nodes[i]->call_multilevel(p_function, VARIANT_ARG_PASS);
- } else {
- nodes[i]->call(p_function, VARIANT_ARG_PASS);
- }
+ nodes[i]->call(p_function, VARIANT_ARG_PASS);
} else {
MessageQueue::get_singleton()->push_call(nodes[i], p_function, VARIANT_ARG_PASS);
}
@@ -267,11 +263,7 @@ void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_grou
}
if (p_call_flags & GROUP_CALL_REALTIME) {
- if (p_call_flags & GROUP_CALL_MULTILEVEL) {
- nodes[i]->call_multilevel(p_function, VARIANT_ARG_PASS);
- } else {
- nodes[i]->call(p_function, VARIANT_ARG_PASS);
- }
+ nodes[i]->call(p_function, VARIANT_ARG_PASS);
} else {
MessageQueue::get_singleton()->push_call(nodes[i], p_function, VARIANT_ARG_PASS);
}
@@ -883,7 +875,7 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
continue;
}
- n->call_multilevel(p_method, (const Variant **)v, 1);
+ n->call(p_method, (const Variant **)v, 1);
//ERR_FAIL_COND(node_count != g.nodes.size());
}
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 41dc49bc64..0f74f2e973 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -223,7 +223,6 @@ public:
GROUP_CALL_REVERSE = 1,
GROUP_CALL_REALTIME = 2,
GROUP_CALL_UNIQUE = 4,
- GROUP_CALL_MULTILEVEL = 8,
};
_FORCE_INLINE_ Window *get_root() const { return root; }
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 1c259b7d32..16d0325881 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1607,7 +1607,7 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
}
if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) {
- control->call_multilevel(SceneStringNames::get_singleton()->_gui_input, ev);
+ control->call(SceneStringNames::get_singleton()->_gui_input, ev);
}
if (!control->is_inside_tree() || control->is_set_as_toplevel()) {
@@ -2306,7 +2306,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (gui.key_focus) {
gui.key_event_accepted = false;
if (gui.key_focus->can_process()) {
- gui.key_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, p_event);
+ gui.key_focus->call(SceneStringNames::get_singleton()->_gui_input, p_event);
if (gui.key_focus) { //maybe lost it
gui.key_focus->emit_signal(SceneStringNames::get_singleton()->gui_input, p_event);
}
@@ -2516,7 +2516,7 @@ void Viewport::_drop_mouse_focus() {
mb->set_global_position(c->get_local_mouse_position());
mb->set_button_index(i + 1);
mb->set_pressed(false);
- c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb);
+ c->call(SceneStringNames::get_singleton()->_gui_input, mb);
}
}
}
@@ -2581,7 +2581,7 @@ void Viewport::_post_gui_grab_click_focus() {
mb->set_position(click);
mb->set_button_index(i + 1);
mb->set_pressed(false);
- gui.mouse_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb);
+ gui.mouse_focus->call(SceneStringNames::get_singleton()->_gui_input, mb);
}
}
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 81f33d74fe..8c985242f1 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -247,6 +247,7 @@ void Window::_make_window() {
}
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
+ DisplayServer::get_singleton()->show_window(window_id);
}
void Window::_update_from_window() {
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 3cbc64c075..db80dbe814 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -372,7 +372,7 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
- AcceptDialog::set_swap_cancel_ok(GLOBAL_DEF("gui/common/swap_cancel_ok", bool(DisplayServer::get_singleton()->get_swap_cancel_ok())));
+ AcceptDialog::set_swap_cancel_ok(GLOBAL_DEF_NOVAL("gui/common/swap_cancel_ok", bool(DisplayServer::get_singleton()->get_swap_cancel_ok())));
#endif
/* REGISTER 3D */
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 479d97aadc..b8edd70712 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -752,7 +752,9 @@ int Animation::_insert(float p_time, T &p_keys, const V &p_value) {
while (true) {
// Condition for replacement.
if (idx > 0 && Math::is_equal_approx(p_keys[idx - 1].time, p_time)) {
+ float transition = p_keys[idx - 1].transition;
p_keys.write[idx - 1] = p_value;
+ p_keys.write[idx - 1].transition = transition;
return idx - 1;
// Condition for insert.
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 8236f9a9e3..0b8e435c19 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -63,6 +63,36 @@ bool VisualShaderNode::is_port_separator(int p_index) const {
return false;
}
+bool VisualShaderNode::is_output_port_connected(int p_port) const {
+ if (connected_output_ports.has(p_port)) {
+ return connected_output_ports[p_port];
+ }
+ return false;
+}
+
+void VisualShaderNode::set_output_port_connected(int p_port, bool p_connected) {
+ connected_output_ports[p_port] = p_connected;
+}
+
+bool VisualShaderNode::is_input_port_connected(int p_port) const {
+ if (connected_input_ports.has(p_port)) {
+ return connected_input_ports[p_port];
+ }
+ return false;
+}
+
+void VisualShaderNode::set_input_port_connected(int p_port, bool p_connected) {
+ connected_input_ports[p_port] = p_connected;
+}
+
+bool VisualShaderNode::is_generate_input_var(int p_port) const {
+ return true;
+}
+
+bool VisualShaderNode::is_code_generated() const {
+ return true;
+}
+
Vector<VisualShader::DefaultTextureParam> VisualShaderNode::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
return Vector<VisualShader::DefaultTextureParam>();
}
@@ -429,6 +459,7 @@ void VisualShader::remove_node(Type p_type, int p_id) {
g->connections.erase(E);
if (E->get().from_node == p_id) {
g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id);
+ g->nodes[E->get().to_node].node->set_input_port_connected(E->get().to_port, false);
}
}
E = N;
@@ -526,6 +557,8 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from
c.to_port = p_to_port;
g->connections.push_back(c);
g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
+ g->nodes[p_from_node].node->set_output_port_connected(p_from_port, true);
+ g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true);
_queue_update();
}
@@ -557,6 +590,8 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
c.to_port = p_to_port;
g->connections.push_back(c);
g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
+ g->nodes[p_from_node].node->set_output_port_connected(p_from_port, true);
+ g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true);
_queue_update();
return OK;
@@ -570,6 +605,8 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
g->connections.erase(E);
g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node);
+ g->nodes[p_from_node].node->set_output_port_connected(p_from_port, false);
+ g->nodes[p_to_node].node->set_input_port_connected(p_to_port, false);
_queue_update();
return;
}
@@ -1105,6 +1142,35 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
// then this node
+ Vector<VisualShader::DefaultTextureParam> params = vsnode->get_default_texture_parameters(type, node);
+ for (int i = 0; i < params.size(); i++) {
+ def_tex_params.push_back(params[i]);
+ }
+
+ Ref<VisualShaderNodeInput> input = vsnode;
+ bool skip_global = input.is_valid() && for_preview;
+
+ if (!skip_global) {
+ global_code += vsnode->generate_global(get_mode(), type, node);
+
+ String class_name = vsnode->get_class_name();
+ if (class_name == "VisualShaderNodeCustom") {
+ class_name = vsnode->get_script_instance()->get_script()->get_path();
+ }
+ if (!r_classes.has(class_name)) {
+ global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node);
+ for (int i = 0; i < TYPE_MAX; i++) {
+ global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node);
+ }
+ r_classes.insert(class_name);
+ }
+ }
+
+ if (!vsnode->is_code_generated()) { // just generate globals and ignore locals
+ processed.insert(node);
+ return OK;
+ }
+
code += "// " + vsnode->get_caption() + ":" + itos(node) + "\n";
Vector<String> input_vars;
@@ -1163,6 +1229,10 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
inputs[i] = "int(" + src_var + ")";
}
} else {
+ if (!vsnode->is_generate_input_var(i)) {
+ continue;
+ }
+
Variant defval = vsnode->get_input_port_default_value(i);
if (defval.get_type() == Variant::FLOAT) {
float val = defval;
@@ -1255,30 +1325,6 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
}
}
- Vector<VisualShader::DefaultTextureParam> params = vsnode->get_default_texture_parameters(type, node);
- for (int i = 0; i < params.size(); i++) {
- def_tex_params.push_back(params[i]);
- }
-
- Ref<VisualShaderNodeInput> input = vsnode;
- bool skip_global = input.is_valid() && for_preview;
-
- if (!skip_global) {
- global_code += vsnode->generate_global(get_mode(), type, node);
-
- String class_name = vsnode->get_class_name();
- if (class_name == "VisualShaderNodeCustom") {
- class_name = vsnode->get_script_instance()->get_script()->get_path();
- }
- if (!r_classes.has(class_name)) {
- global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node);
- for (int i = 0; i < TYPE_MAX; i++) {
- global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node);
- }
- r_classes.insert(class_name);
- }
- }
-
code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview);
code += "\n"; //
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index dbb8d1d28c..6d3fda1744 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -182,6 +182,8 @@ class VisualShaderNode : public Resource {
int port_preview;
Map<int, Variant> default_input_values;
+ Map<int, bool> connected_input_ports;
+ Map<int, bool> connected_output_ports;
protected:
bool simple_decl;
@@ -222,6 +224,14 @@ public:
virtual bool is_port_separator(int p_index) const;
+ bool is_output_port_connected(int p_port) const;
+ void set_output_port_connected(int p_port, bool p_connected);
+ bool is_input_port_connected(int p_port) const;
+ void set_input_port_connected(int p_port, bool p_connected);
+ virtual bool is_generate_input_var(int p_port) const;
+
+ virtual bool is_code_generated() const;
+
virtual Vector<StringName> get_editable_properties() const;
virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const;
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 88f5287831..0caa3cecd8 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -3915,6 +3915,10 @@ String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, Visu
return code;
}
+bool VisualShaderNodeTextureUniform::is_code_generated() const {
+ return is_output_port_connected(0) || is_output_port_connected(1); // rgb or alpha
+}
+
String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String id = get_uniform_name();
String code = "\t{\n";
@@ -4453,6 +4457,13 @@ String VisualShaderNodeFresnel::get_output_port_name(int p_port) const {
return "result";
}
+bool VisualShaderNodeFresnel::is_generate_input_var(int p_port) const {
+ if (p_port == 2) {
+ return false;
+ }
+ return true;
+}
+
String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String normal;
String view;
@@ -4467,7 +4478,15 @@ String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader:
view = p_input_vars[1];
}
- return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n";
+ if (is_input_port_connected(2)) {
+ return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n";
+ } else {
+ if (get_input_port_default_value(2)) {
+ return "\t" + p_output_vars[0] + " = pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n";
+ } else {
+ return "\t" + p_output_vars[0] + " = pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n";
+ }
+ }
}
String VisualShaderNodeFresnel::get_input_port_default_hint(int p_port) const {
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 13a132c60e..6c6e7b7580 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1715,6 +1715,8 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual bool is_code_generated() const override;
+
Vector<StringName> get_editable_properties() const override;
void set_texture_type(TextureType p_type);
@@ -1875,6 +1877,7 @@ public:
virtual String get_output_port_name(int p_port) const override;
virtual String get_input_port_default_hint(int p_port) const override;
+ virtual bool is_generate_input_var(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeFresnel();