Prevent preview error for the instance parameter in visual shader
This commit is contained in:
parent
1ed549e64b
commit
c0a3129210
|
@ -128,7 +128,7 @@ void VisualShaderGraphPlugin::set_connections(const List<VisualShader::Connectio
|
||||||
connections = p_connections;
|
connections = p_connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p_node_id, int p_port_id) {
|
void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p_node_id, int p_port_id, bool p_is_valid) {
|
||||||
if (visual_shader->get_shader_type() == p_type && links.has(p_node_id) && links[p_node_id].output_ports.has(p_port_id)) {
|
if (visual_shader->get_shader_type() == p_type && links.has(p_node_id) && links[p_node_id].output_ports.has(p_port_id)) {
|
||||||
Link &link = links[p_node_id];
|
Link &link = links[p_node_id];
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p
|
||||||
vbox->add_child(offset);
|
vbox->add_child(offset);
|
||||||
|
|
||||||
VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview);
|
VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview);
|
||||||
port_preview->setup(visual_shader, visual_shader->get_shader_type(), p_node_id, p_port_id);
|
port_preview->setup(visual_shader, visual_shader->get_shader_type(), p_node_id, p_port_id, p_is_valid);
|
||||||
port_preview->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
|
port_preview->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
|
||||||
vbox->add_child(port_preview);
|
vbox->add_child(port_preview);
|
||||||
link.preview_visible = true;
|
link.preview_visible = true;
|
||||||
|
@ -351,6 +351,29 @@ void VisualShaderGraphPlugin::update_theme() {
|
||||||
vector_expanded_color[3] = editor->get_theme_color(SNAME("axis_w_color"), SNAME("Editor")); // alpha
|
vector_expanded_color[3] = editor->get_theme_color(SNAME("axis_w_color"), SNAME("Editor")); // alpha
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VisualShaderGraphPlugin::is_node_has_parameter_instances_relatively(VisualShader::Type p_type, int p_node) const {
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
Ref<VisualShaderNodeParameter> parameter_node = Object::cast_to<VisualShaderNodeParameter>(visual_shader->get_node_unchecked(p_type, p_node).ptr());
|
||||||
|
if (parameter_node.is_valid()) {
|
||||||
|
if (parameter_node->get_qualifier() == VisualShaderNodeParameter::QUAL_INSTANCE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalVector<int> prev_connected_nodes;
|
||||||
|
visual_shader->get_prev_connected_nodes(p_type, p_node, prev_connected_nodes);
|
||||||
|
|
||||||
|
for (const int &E : prev_connected_nodes) {
|
||||||
|
result = is_node_has_parameter_instances_relatively(p_type, E);
|
||||||
|
if (result) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool p_just_update) {
|
void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool p_just_update) {
|
||||||
if (!visual_shader.is_valid() || p_type != visual_shader->get_shader_type()) {
|
if (!visual_shader.is_valid() || p_type != visual_shader->get_shader_type()) {
|
||||||
return;
|
return;
|
||||||
|
@ -969,8 +992,10 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_relative_parameter_instances = false;
|
||||||
if (vsnode->get_output_port_for_preview() >= 0) {
|
if (vsnode->get_output_port_for_preview() >= 0) {
|
||||||
show_port_preview(p_type, p_id, vsnode->get_output_port_for_preview());
|
has_relative_parameter_instances = is_node_has_parameter_instances_relatively(p_type, p_id);
|
||||||
|
show_port_preview(p_type, p_id, vsnode->get_output_port_for_preview(), !has_relative_parameter_instances);
|
||||||
} else {
|
} else {
|
||||||
offset = memnew(Control);
|
offset = memnew(Control);
|
||||||
offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE));
|
offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE));
|
||||||
|
@ -978,6 +1003,9 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
String error = vsnode->get_warning(mode, p_type);
|
String error = vsnode->get_warning(mode, p_type);
|
||||||
|
if (has_relative_parameter_instances) {
|
||||||
|
error += "\n" + TTR("The 2D preview cannot correctly show the result retrieved from instance parameter.");
|
||||||
|
}
|
||||||
if (!error.is_empty()) {
|
if (!error.is_empty()) {
|
||||||
Label *error_label = memnew(Label);
|
Label *error_label = memnew(Label);
|
||||||
error_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("error_color"), SNAME("Editor")));
|
error_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("error_color"), SNAME("Editor")));
|
||||||
|
@ -4970,6 +4998,29 @@ void VisualShaderEditor::_update_preview() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VisualShaderEditor::_update_next_previews(int p_node_id) {
|
||||||
|
VisualShader::Type type = get_current_shader_type();
|
||||||
|
|
||||||
|
LocalVector<int> nodes;
|
||||||
|
_get_next_nodes_recursively(type, p_node_id, nodes);
|
||||||
|
|
||||||
|
for (int node_id : nodes) {
|
||||||
|
if (graph_plugin->is_preview_visible(node_id)) {
|
||||||
|
graph_plugin->update_node_deferred(type, node_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisualShaderEditor::_get_next_nodes_recursively(VisualShader::Type p_type, int p_node_id, LocalVector<int> &r_nodes) const {
|
||||||
|
LocalVector<int> next_connections;
|
||||||
|
visual_shader->get_next_connected_nodes(p_type, p_node_id, next_connections);
|
||||||
|
|
||||||
|
for (int node_id : next_connections) {
|
||||||
|
r_nodes.push_back(node_id);
|
||||||
|
_get_next_nodes_recursively(p_type, node_id, r_nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VisualShaderEditor::_visibility_changed() {
|
void VisualShaderEditor::_visibility_changed() {
|
||||||
if (!is_visible()) {
|
if (!is_visible()) {
|
||||||
if (preview_window->is_visible()) {
|
if (preview_window->is_visible()) {
|
||||||
|
@ -5002,6 +5053,7 @@ void VisualShaderEditor::_bind_methods() {
|
||||||
ClassDB::bind_method("_update_options_menu_deferred", &VisualShaderEditor::_update_options_menu_deferred);
|
ClassDB::bind_method("_update_options_menu_deferred", &VisualShaderEditor::_update_options_menu_deferred);
|
||||||
ClassDB::bind_method("_rebuild_shader_deferred", &VisualShaderEditor::_rebuild_shader_deferred);
|
ClassDB::bind_method("_rebuild_shader_deferred", &VisualShaderEditor::_rebuild_shader_deferred);
|
||||||
ClassDB::bind_method("_resources_removed", &VisualShaderEditor::_resources_removed);
|
ClassDB::bind_method("_resources_removed", &VisualShaderEditor::_resources_removed);
|
||||||
|
ClassDB::bind_method("_update_next_previews", &VisualShaderEditor::_update_next_previews);
|
||||||
|
|
||||||
ClassDB::bind_method("_is_available", &VisualShaderEditor::_is_available);
|
ClassDB::bind_method("_is_available", &VisualShaderEditor::_is_available);
|
||||||
}
|
}
|
||||||
|
@ -6292,6 +6344,8 @@ public:
|
||||||
if (p_property != "constant") {
|
if (p_property != "constant") {
|
||||||
VisualShaderGraphPlugin *graph_plugin = editor->get_graph_plugin();
|
VisualShaderGraphPlugin *graph_plugin = editor->get_graph_plugin();
|
||||||
if (graph_plugin) {
|
if (graph_plugin) {
|
||||||
|
undo_redo->add_do_method(editor, "_update_next_previews", node_id);
|
||||||
|
undo_redo->add_undo_method(editor, "_update_next_previews", node_id);
|
||||||
undo_redo->add_do_method(graph_plugin, "update_node_deferred", shader_type, node_id);
|
undo_redo->add_do_method(graph_plugin, "update_node_deferred", shader_type, node_id);
|
||||||
undo_redo->add_undo_method(graph_plugin, "update_node_deferred", shader_type, node_id);
|
undo_redo->add_undo_method(graph_plugin, "update_node_deferred", shader_type, node_id);
|
||||||
}
|
}
|
||||||
|
@ -6586,7 +6640,7 @@ bool EditorInspectorVisualShaderModePlugin::parse_property(Object *p_object, con
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
|
|
||||||
void VisualShaderNodePortPreview::_shader_changed() {
|
void VisualShaderNodePortPreview::_shader_changed() {
|
||||||
if (shader.is_null()) {
|
if (!is_valid || shader.is_null()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6633,12 +6687,13 @@ void VisualShaderNodePortPreview::_shader_changed() {
|
||||||
set_material(mat);
|
set_material(mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualShaderNodePortPreview::setup(const Ref<VisualShader> &p_shader, VisualShader::Type p_type, int p_node, int p_port) {
|
void VisualShaderNodePortPreview::setup(const Ref<VisualShader> &p_shader, VisualShader::Type p_type, int p_node, int p_port, bool p_is_valid) {
|
||||||
shader = p_shader;
|
shader = p_shader;
|
||||||
shader->connect("changed", callable_mp(this, &VisualShaderNodePortPreview::_shader_changed));
|
shader->connect("changed", callable_mp(this, &VisualShaderNodePortPreview::_shader_changed), CONNECT_DEFERRED);
|
||||||
type = p_type;
|
type = p_type;
|
||||||
port = p_port;
|
port = p_port;
|
||||||
node = p_node;
|
node = p_node;
|
||||||
|
is_valid = p_is_valid;
|
||||||
queue_redraw();
|
queue_redraw();
|
||||||
_shader_changed();
|
_shader_changed();
|
||||||
}
|
}
|
||||||
|
@ -6665,14 +6720,24 @@ void VisualShaderNodePortPreview::_notification(int p_what) {
|
||||||
Vector2(0, 1)
|
Vector2(0, 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector<Color> colors = {
|
if (is_valid) {
|
||||||
Color(1, 1, 1, 1),
|
Vector<Color> colors = {
|
||||||
Color(1, 1, 1, 1),
|
Color(1, 1, 1, 1),
|
||||||
Color(1, 1, 1, 1),
|
Color(1, 1, 1, 1),
|
||||||
Color(1, 1, 1, 1)
|
Color(1, 1, 1, 1),
|
||||||
};
|
Color(1, 1, 1, 1)
|
||||||
|
};
|
||||||
|
draw_primitive(points, colors, uvs);
|
||||||
|
} else {
|
||||||
|
Vector<Color> colors = {
|
||||||
|
Color(0, 0, 0, 1),
|
||||||
|
Color(0, 0, 0, 1),
|
||||||
|
Color(0, 0, 0, 1),
|
||||||
|
Color(0, 0, 0, 1)
|
||||||
|
};
|
||||||
|
draw_primitive(points, colors, uvs);
|
||||||
|
}
|
||||||
|
|
||||||
draw_primitive(points, colors, uvs);
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ public:
|
||||||
void remove_node(VisualShader::Type p_type, int p_id, bool p_just_update);
|
void remove_node(VisualShader::Type p_type, int p_id, bool p_just_update);
|
||||||
void connect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
|
void connect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
|
||||||
void disconnect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
|
void disconnect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
|
||||||
void show_port_preview(VisualShader::Type p_type, int p_node_id, int p_port_id);
|
void show_port_preview(VisualShader::Type p_type, int p_node_id, int p_port_id, bool p_is_valid);
|
||||||
void set_node_position(VisualShader::Type p_type, int p_id, const Vector2 &p_position);
|
void set_node_position(VisualShader::Type p_type, int p_id, const Vector2 &p_position);
|
||||||
void refresh_node_ports(VisualShader::Type p_type, int p_node);
|
void refresh_node_ports(VisualShader::Type p_type, int p_node);
|
||||||
void set_input_port_default_value(VisualShader::Type p_type, int p_node_id, int p_port_id, Variant p_value);
|
void set_input_port_default_value(VisualShader::Type p_type, int p_node_id, int p_port_id, Variant p_value);
|
||||||
|
@ -133,6 +133,7 @@ public:
|
||||||
Ref<Script> get_node_script(int p_node_id) const;
|
Ref<Script> get_node_script(int p_node_id) const;
|
||||||
void update_node_size(int p_node_id);
|
void update_node_size(int p_node_id);
|
||||||
void update_theme();
|
void update_theme();
|
||||||
|
bool is_node_has_parameter_instances_relatively(VisualShader::Type p_type, int p_node) const;
|
||||||
VisualShader::Type get_shader_type() const;
|
VisualShader::Type get_shader_type() const;
|
||||||
|
|
||||||
VisualShaderGraphPlugin();
|
VisualShaderGraphPlugin();
|
||||||
|
@ -354,6 +355,8 @@ class VisualShaderEditor : public VBoxContainer {
|
||||||
void _preview_close_requested();
|
void _preview_close_requested();
|
||||||
void _preview_size_changed();
|
void _preview_size_changed();
|
||||||
void _update_preview();
|
void _update_preview();
|
||||||
|
void _update_next_previews(int p_node_id);
|
||||||
|
void _get_next_nodes_recursively(VisualShader::Type p_type, int p_node_id, LocalVector<int> &r_nodes) const;
|
||||||
String _get_description(int p_idx);
|
String _get_description(int p_idx);
|
||||||
|
|
||||||
struct DragOp {
|
struct DragOp {
|
||||||
|
@ -570,6 +573,7 @@ class VisualShaderNodePortPreview : public Control {
|
||||||
VisualShader::Type type = VisualShader::Type::TYPE_MAX;
|
VisualShader::Type type = VisualShader::Type::TYPE_MAX;
|
||||||
int node = 0;
|
int node = 0;
|
||||||
int port = 0;
|
int port = 0;
|
||||||
|
bool is_valid = false;
|
||||||
void _shader_changed(); //must regen
|
void _shader_changed(); //must regen
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
@ -577,7 +581,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual Size2 get_minimum_size() const override;
|
virtual Size2 get_minimum_size() const override;
|
||||||
void setup(const Ref<VisualShader> &p_shader, VisualShader::Type p_type, int p_node, int p_port);
|
void setup(const Ref<VisualShader> &p_shader, VisualShader::Type p_type, int p_node, int p_port, bool p_is_valid);
|
||||||
};
|
};
|
||||||
|
|
||||||
class VisualShaderConversionPlugin : public EditorResourceConversionPlugin {
|
class VisualShaderConversionPlugin : public EditorResourceConversionPlugin {
|
||||||
|
|
|
@ -815,6 +815,8 @@ void VisualShader::remove_node(Type p_type, int p_id) {
|
||||||
if (E->get().from_node == p_id) {
|
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].prev_connected_nodes.erase(p_id);
|
||||||
g->nodes[E->get().to_node].node->set_input_port_connected(E->get().to_port, false);
|
g->nodes[E->get().to_node].node->set_input_port_connected(E->get().to_port, false);
|
||||||
|
} else if (E->get().to_node == p_id) {
|
||||||
|
g->nodes[E->get().from_node].next_connected_nodes.erase(p_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
E = N;
|
E = N;
|
||||||
|
@ -981,6 +983,7 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from
|
||||||
c.to_node = p_to_node;
|
c.to_node = p_to_node;
|
||||||
c.to_port = p_to_port;
|
c.to_port = p_to_port;
|
||||||
g->connections.push_back(c);
|
g->connections.push_back(c);
|
||||||
|
g->nodes[p_from_node].next_connected_nodes.push_back(p_to_node);
|
||||||
g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
|
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_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);
|
g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true);
|
||||||
|
@ -1014,6 +1017,7 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
|
||||||
c.to_node = p_to_node;
|
c.to_node = p_to_node;
|
||||||
c.to_port = p_to_port;
|
c.to_port = p_to_port;
|
||||||
g->connections.push_back(c);
|
g->connections.push_back(c);
|
||||||
|
g->nodes[p_from_node].next_connected_nodes.push_back(p_to_node);
|
||||||
g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
|
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_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);
|
g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true);
|
||||||
|
@ -1029,6 +1033,7 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por
|
||||||
for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
|
for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
|
||||||
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) {
|
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->connections.erase(E);
|
||||||
|
g->nodes[p_from_node].next_connected_nodes.erase(p_to_node);
|
||||||
g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node);
|
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_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);
|
g->nodes[p_to_node].node->set_input_port_connected(p_to_port, false);
|
||||||
|
|
|
@ -122,7 +122,8 @@ private:
|
||||||
struct Node {
|
struct Node {
|
||||||
Ref<VisualShaderNode> node;
|
Ref<VisualShaderNode> node;
|
||||||
Vector2 position;
|
Vector2 position;
|
||||||
List<int> prev_connected_nodes;
|
LocalVector<int> prev_connected_nodes;
|
||||||
|
LocalVector<int> next_connected_nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Graph {
|
struct Graph {
|
||||||
|
@ -199,6 +200,16 @@ public: // internal methods
|
||||||
Vector2 get_node_position(Type p_type, int p_id) const;
|
Vector2 get_node_position(Type p_type, int p_id) const;
|
||||||
Ref<VisualShaderNode> get_node(Type p_type, int p_id) const;
|
Ref<VisualShaderNode> get_node(Type p_type, int p_id) const;
|
||||||
|
|
||||||
|
_FORCE_INLINE_ Ref<VisualShaderNode> get_node_unchecked(Type p_type, int p_id) const {
|
||||||
|
return graph[p_type].nodes[p_id].node;
|
||||||
|
}
|
||||||
|
_FORCE_INLINE_ void get_next_connected_nodes(Type p_type, int p_id, LocalVector<int> &r_list) const {
|
||||||
|
r_list = graph[p_type].nodes[p_id].next_connected_nodes;
|
||||||
|
}
|
||||||
|
_FORCE_INLINE_ void get_prev_connected_nodes(Type p_type, int p_id, LocalVector<int> &r_list) const {
|
||||||
|
r_list = graph[p_type].nodes[p_id].prev_connected_nodes;
|
||||||
|
}
|
||||||
|
|
||||||
Vector<int> get_node_list(Type p_type) const;
|
Vector<int> get_node_list(Type p_type) const;
|
||||||
int get_valid_node_id(Type p_type) const;
|
int get_valid_node_id(Type p_type) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue