diff options
Diffstat (limited to 'editor')
49 files changed, 1709 insertions, 1020 deletions
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index e8fd97fa1a..61ec8abacf 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -446,14 +446,14 @@ void CreateDialog::_notification(int p_what) { } } -void CreateDialog::select_type(const String &p_type) { +void CreateDialog::select_type(const String &p_type, bool p_center_on_item) { if (!search_options_types.has(p_type)) { return; } TreeItem *to_select = search_options_types[p_type]; to_select->select(0); - search_options->scroll_to_item(to_select); + search_options->scroll_to_item(to_select, p_center_on_item); if (EditorHelp::get_doc_data()->class_list.has(p_type) && !DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description).is_empty()) { // Display both class name and description, since the help bit may be displayed @@ -503,24 +503,14 @@ Variant CreateDialog::instance_selected() { } else { obj = ClassDB::instantiate(selected->get_text(0)); } - - // Check if any Object-type property should be instantiated. - List<PropertyInfo> pinfo; - ((Object *)obj)->get_property_list(&pinfo); - - for (const PropertyInfo &pi : pinfo) { - if (pi.type == Variant::OBJECT && pi.usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) { - Object *prop = ClassDB::instantiate(pi.class_name); - ((Object *)obj)->set(pi.name, prop); - } - } + EditorNode::get_editor_data().instantiate_object_properties(obj); return obj; } void CreateDialog::_item_selected() { String name = get_selected_type(); - select_type(name); + select_type(name, false); } void CreateDialog::_hide_requested() { diff --git a/editor/create_dialog.h b/editor/create_dialog.h index f905160df3..a82c4db191 100644 --- a/editor/create_dialog.h +++ b/editor/create_dialog.h @@ -79,7 +79,7 @@ class CreateDialog : public ConfirmationDialog { void _sbox_input(const Ref<InputEvent> &p_ie); void _text_changed(const String &p_newtext); - void select_type(const String &p_type); + void select_type(const String &p_type, bool p_center_on_item = true); void _item_selected(); void _hide_requested(); diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 4b6a11f388..8702e773f8 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -683,7 +683,7 @@ EditorDebuggerNode::CameraOverride EditorDebuggerNode::get_camera_override() { void EditorDebuggerNode::add_debugger_plugin(const Ref<Script> &p_script) { ERR_FAIL_COND_MSG(debugger_plugins.has(p_script), "Debugger plugin already exists."); ERR_FAIL_COND_MSG(p_script.is_null(), "Debugger plugin script is null"); - ERR_FAIL_COND_MSG(String(p_script->get_instance_base_type()) == "", "Debugger plugin script has error."); + ERR_FAIL_COND_MSG(p_script->get_instance_base_type() == StringName(), "Debugger plugin script has error."); ERR_FAIL_COND_MSG(String(p_script->get_instance_base_type()) != "EditorDebuggerPlugin", "Base type of debugger plugin is not 'EditorDebuggerPlugin'."); ERR_FAIL_COND_MSG(!p_script->is_tool(), "Debugger plugin script is not in tool mode."); debugger_plugins.insert(p_script); diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index cf5d8ca4ff..28e8edb26e 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -36,7 +36,6 @@ #include "core/io/marshalls.h" #include "core/string/ustring.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "editor/debugger/debug_adapter/debug_adapter_protocol.h" #include "editor/debugger/editor_network_profiler.h" #include "editor/debugger/editor_performance_profiler.h" @@ -1549,19 +1548,10 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { const int line_number = file_line_number[1].to_int(); // Construct a GitHub repository URL and open it in the user's default web browser. - if (String(VERSION_HASH).length() >= 1) { - // Git commit hash information available; use it for greater accuracy, including for development versions. - OS::get_singleton()->shell_open(vformat("https://github.com/godotengine/godot/blob/%s/%s#L%d", - VERSION_HASH, - file, - line_number)); - } else { - // Git commit hash information unavailable; fall back to tagged releases. - OS::get_singleton()->shell_open(vformat("https://github.com/godotengine/godot/blob/%s-stable/%s#L%d", - VERSION_NUMBER, - file, - line_number)); - } + // If the commit hash is available, use it for greater accuracy. Otherwise fall back to tagged release. + String git_ref = String(VERSION_HASH).is_empty() ? String(VERSION_NUMBER) + "-stable" : String(VERSION_HASH); + OS::get_singleton()->shell_open(vformat("https://github.com/godotengine/godot/blob/%s/%s#L%d", + git_ref, file, line_number)); } break; case ACTION_DELETE_BREAKPOINT: { const TreeItem *selected = breakpoints_tree->get_selected(); diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 54377971c6..4309f55a2b 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -29,13 +29,12 @@ /*************************************************************************/ #include "editor_about.h" -#include "editor_node.h" #include "core/authors.gen.h" #include "core/donors.gen.h" #include "core/license.gen.h" #include "core/version.h" -#include "core/version_hash.gen.h" +#include "editor_node.h" // The metadata key used to store and retrieve the version text to copy to the clipboard. static const String META_TEXT_TO_COPY = "text_to_copy"; diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index d74a6e12b2..6d31141be7 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -362,21 +362,21 @@ Node *EditorAutoloadSettings::_create_autoload(const String &p_path) { RES res = ResourceLoader::load(p_path); ERR_FAIL_COND_V_MSG(res.is_null(), nullptr, "Can't autoload: " + p_path + "."); Node *n = nullptr; - if (res->is_class("PackedScene")) { - Ref<PackedScene> ps = res; - n = ps->instantiate(); - } else if (res->is_class("Script")) { - Ref<Script> s = res; - StringName ibt = s->get_instance_base_type(); + Ref<PackedScene> scn = res; + Ref<Script> script = res; + if (scn.is_valid()) { + n = scn->instantiate(); + } else if (script.is_valid()) { + StringName ibt = script->get_instance_base_type(); bool valid_type = ClassDB::is_parent_class(ibt, "Node"); ERR_FAIL_COND_V_MSG(!valid_type, nullptr, "Script does not inherit a Node: " + p_path + "."); Object *obj = ClassDB::instantiate(ibt); - ERR_FAIL_COND_V_MSG(obj == nullptr, nullptr, "Cannot instance script for AutoLoad, expected 'Node' inheritance, got: " + String(ibt) + "."); + ERR_FAIL_COND_V_MSG(!obj, nullptr, "Cannot instance script for AutoLoad, expected 'Node' inheritance, got: " + String(ibt) + "."); n = Object::cast_to<Node>(obj); - n->set_script(s); + n->set_script(script); } ERR_FAIL_COND_V_MSG(!n, nullptr, "Path in AutoLoad not a node or script: " + p_path + "."); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 7a0a4abbff..625330ef37 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -520,6 +520,21 @@ void EditorData::remove_custom_type(const String &p_type) { } } +void EditorData::instantiate_object_properties(Object *p_object) { + ERR_FAIL_NULL(p_object); + // Check if any Object-type property should be instantiated. + List<PropertyInfo> pinfo; + p_object->get_property_list(&pinfo); + + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + PropertyInfo pi = E->get(); + if (pi.type == Variant::OBJECT && pi.usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) { + Object *prop = ClassDB::instantiate(pi.class_name); + p_object->set(pi.name, prop); + } + } +} + int EditorData::add_edited_scene(int p_at_pos) { if (p_at_pos < 0) { p_at_pos = edited_scene.size(); @@ -894,21 +909,12 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i return false; } - Ref<Script> script = script_class_load_script(p_class); - if (script.is_null()) { - return false; - } - - String base = script_class_get_base(p_class); - Ref<Script> base_script = script->get_base_script(); - - while (p_inherits != base) { + String base = p_class; + while (base != p_inherits) { if (ClassDB::class_exists(base)) { return ClassDB::is_parent_class(base, p_inherits); } else if (ScriptServer::is_global_class(base)) { - base = script_class_get_base(base); - } else if (base_script.is_valid()) { - return ClassDB::is_parent_class(base_script->get_instance_base_type(), p_inherits); + base = ScriptServer::get_global_class_base(base); } else { return false; } diff --git a/editor/editor_data.h b/editor/editor_data.h index ccf641ff26..e485d47bf6 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -182,6 +182,8 @@ public: void remove_custom_type(const String &p_type); const Map<String, Vector<CustomType>> &get_custom_types() const { return custom_types; } + void instantiate_object_properties(Object *p_object); + int add_edited_scene(int p_at_pos); void move_edited_scene_index(int p_idx, int p_to_idx); void remove_scene(int p_idx); diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 1d73bdfa6e..2fc29c46af 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -592,7 +592,15 @@ void EditorFeatureProfileManager::_class_list_item_selected() { List<PropertyInfo> props; ClassDB::get_property_list(class_name, &props, true); - if (props.size() > 0) { + bool has_editor_props = false; + for (const PropertyInfo &E : props) { + if (E.usage & PROPERTY_USAGE_EDITOR) { + has_editor_props = true; + break; + } + } + + if (has_editor_props) { TreeItem *properties = property_list->create_item(root); properties->set_text(0, TTR("Class Properties:")); diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index 36d3ac9e66..29bf22a478 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -610,11 +610,6 @@ TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, cons text = p_text; } else { icon = ui_service->get_theme_icon(p_icon, SNAME("EditorIcons")); - /*// In flat mode, show the class icon. -if (ui_service->has_icon(p_class_name, "EditorIcons")) -icon = ui_service->get_icon(p_class_name, "EditorIcons"); -else if (ClassDB::is_parent_class(p_class_name, "Object")) -icon = ui_service->get_icon("Object", "EditorIcons");*/ text = p_class_name + "." + p_text; } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 29d1752578..cbfd6ae6de 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2425,7 +2425,7 @@ void EditorInspector::update_tree() { if (!ClassDB::class_exists(type) && !ScriptServer::is_global_class(type) && p.hint_string.length() && FileAccess::exists(p.hint_string)) { // If we have a category inside a script, search for the first script with a valid icon. Ref<Script> script = ResourceLoader::load(p.hint_string, "Script"); - String base_type; + StringName base_type; if (script.is_valid()) { base_type = script->get_instance_base_type(); } @@ -3020,7 +3020,7 @@ void EditorInspector::_update_inspector_bg() { n = n->get_parent(); } count_subinspectors = MIN(15, count_subinspectors); - add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), "Editor")); + add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), SNAME("Editor"))); } else { add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); } @@ -3479,10 +3479,14 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li String path = s->get_path(); String name = EditorNode::get_editor_data().script_class_get_name(path); if (name.is_empty()) { - if (!s->is_built_in()) { - name = path.get_file(); + if (s->is_built_in()) { + if (s->get_name().is_empty()) { + name = TTR("Built-in script"); + } else { + name = vformat("%s (%s)", s->get_name(), TTR("Built-in")); + } } else { - name = TTR("Built-in script"); + name = path.get_file(); } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index bf7e463559..4b2f1c5104 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -47,7 +47,6 @@ #include "core/string/print_string.h" #include "core/string/translation.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "main/main.h" #include "scene/3d/importer_mesh_instance_3d.h" #include "scene/gui/center_container.h" @@ -128,10 +127,10 @@ #include "editor/plugins/animation_tree_editor_plugin.h" #include "editor/plugins/asset_library_editor_plugin.h" #include "editor/plugins/audio_stream_editor_plugin.h" +#include "editor/plugins/audio_stream_randomizer_editor_plugin.h" #include "editor/plugins/camera_3d_editor_plugin.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/collision_polygon_2d_editor_plugin.h" -#include "editor/plugins/collision_polygon_3d_editor_plugin.h" #include "editor/plugins/collision_shape_2d_editor_plugin.h" #include "editor/plugins/cpu_particles_2d_editor_plugin.h" #include "editor/plugins/cpu_particles_3d_editor_plugin.h" @@ -162,6 +161,7 @@ #include "editor/plugins/path_3d_editor_plugin.h" #include "editor/plugins/physical_bone_3d_editor_plugin.h" #include "editor/plugins/polygon_2d_editor_plugin.h" +#include "editor/plugins/polygon_3d_editor_plugin.h" #include "editor/plugins/replication_editor_plugin.h" #include "editor/plugins/resource_preloader_editor_plugin.h" #include "editor/plugins/root_motion_editor_plugin.h" @@ -745,7 +745,6 @@ void EditorNode::_notification(int p_what) { bottom_panel_raise->set_icon(gui_base->get_theme_icon(SNAME("ExpandBottomDock"), SNAME("EditorIcons"))); - // clear_button->set_icon(gui_base->get_icon("Close", "EditorIcons")); don't have access to that node. needs to become a class property if (gui_base->is_layout_rtl()) { dock_tab_move_left->set_icon(theme->get_icon(SNAME("Forward"), SNAME("EditorIcons"))); dock_tab_move_right->set_icon(theme->get_icon(SNAME("Back"), SNAME("EditorIcons"))); @@ -2280,7 +2279,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { if (main_plugin) { // special case if use of external editor is true Resource *current_res = Object::cast_to<Resource>(current_obj); - if (main_plugin->get_name() == "Script" && current_obj->get_class_name() != StringName("VisualScript") && current_res && !current_res->is_built_in() && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { + if (main_plugin->get_name() == "Script" && current_obj->is_class("VisualScript") && current_res && !current_res->is_built_in() && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { if (!changing_scene) { main_plugin->edit(current_obj); } @@ -3293,8 +3292,8 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, return; } - // Errors in the script cause the base_type to be an empty string. - if (String(script->get_instance_base_type()) == "") { + // Errors in the script cause the base_type to be an empty StringName. + if (script->get_instance_base_type() == StringName()) { show_warning(vformat(TTR("Unable to load addon script from path: '%s'. This might be due to a code error in that script.\nDisabling the addon at '%s' to prevent further errors."), script_path, p_addon)); _remove_plugin_from_enabled(p_addon); return; @@ -3937,7 +3936,7 @@ StringName EditorNode::get_object_custom_type_name(const Object *p_object) const ERR_FAIL_COND_V(!p_object, StringName()); Ref<Script> script = p_object->get_script(); - if (script.is_null() && p_object->is_class("Script")) { + if (script.is_null() && Object::cast_to<Script>(p_object)) { script = p_object; } @@ -4148,13 +4147,12 @@ Ref<Texture2D> EditorNode::_file_dialog_get_icon(const String &p_path) { void EditorNode::_build_icon_type_cache() { List<StringName> tl; - StringName ei = "EditorIcons"; - theme_base->get_theme()->get_icon_list(ei, &tl); + theme_base->get_theme()->get_icon_list(SNAME("EditorIcons"), &tl); for (const StringName &E : tl) { if (!ClassDB::class_exists(E)) { continue; } - icon_type_cache[E] = theme_base->get_theme()->get_icon(E, ei); + icon_type_cache[E] = theme_base->get_theme()->get_icon(E, SNAME("EditorIcons")); } } @@ -4236,8 +4234,9 @@ void EditorNode::_dock_make_float() { Control *dock = dock_slot[dock_popup_selected]->get_current_tab_control(); ERR_FAIL_COND(!dock); - const Size2i borders = Size2i(4, 4) * EDSCALE; - Size2 dock_size = dock->get_size() + borders * 2; // remember size + Size2 borders = Size2(4, 4) * EDSCALE; + // Remember size and position before removing it from the main window. + Size2 dock_size = dock->get_size() + borders * 2; Point2 dock_screen_pos = dock->get_global_position() + get_tree()->get_root()->get_position() - borders; int dock_index = dock->get_index(); @@ -4246,7 +4245,7 @@ void EditorNode::_dock_make_float() { Window *window = memnew(Window); window->set_title(dock->get_name()); Panel *p = memnew(Panel); - p->set_mode(Panel::MODE_FOREGROUND); + p->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("PanelForeground"), SNAME("EditorStyles"))); p->set_anchors_and_offsets_preset(Control::PRESET_WIDE); window->add_child(p); MarginContainer *margin = memnew(MarginContainer); @@ -5677,6 +5676,7 @@ void EditorNode::_feature_profile_changed() { void EditorNode::_bind_methods() { GLOBAL_DEF("editor/scene/scene_naming", SCENE_NAME_CASING_SNAKE_CASE); ProjectSettings::get_singleton()->set_custom_property_info("editor/scene/scene_naming", PropertyInfo(Variant::INT, "editor/scene/scene_naming", PROPERTY_HINT_ENUM, "Auto,PascalCase,snake_case")); + ClassDB::bind_method("edit_current", &EditorNode::edit_current); ClassDB::bind_method("_editor_select", &EditorNode::_editor_select); ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed); ClassDB::bind_method("edit_node", &EditorNode::edit_node); @@ -6969,6 +6969,7 @@ EditorNode::EditorNode() { // more visually meaningful to have this later raise_bottom_panel_item(AnimationPlayerEditor::get_singleton()); + add_editor_plugin(memnew(ReplicationEditorPlugin(this))); add_editor_plugin(VersionControlEditorPlugin::get_singleton()); add_editor_plugin(memnew(ShaderEditorPlugin(this))); @@ -7012,6 +7013,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(TextureLayeredEditorPlugin(this))); add_editor_plugin(memnew(Texture3DEditorPlugin(this))); add_editor_plugin(memnew(AudioStreamEditorPlugin(this))); + add_editor_plugin(memnew(AudioStreamRandomizerEditorPlugin(this))); add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor))); add_editor_plugin(memnew(Skeleton3DEditorPlugin(this))); add_editor_plugin(memnew(SkeletonIK3DEditorPlugin(this))); @@ -7022,7 +7024,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(InputEventEditorPlugin(this))); add_editor_plugin(memnew(SubViewportPreviewEditorPlugin(this))); add_editor_plugin(memnew(TextControlEditorPlugin(this))); - add_editor_plugin(memnew(ReplicationEditorPlugin(this))); for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) { add_editor_plugin(EditorPlugins::create(i, this)); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index a1c031aa1b..fe44486d0d 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -717,9 +717,9 @@ void EditorPlugin::remove_translation_parser_plugin(const Ref<EditorTranslationP EditorTranslationParser::get_singleton()->remove_parser(p_parser, EditorTranslationParser::CUSTOM); } -void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin> &p_importer) { +void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin> &p_importer, bool p_first_priority) { ERR_FAIL_COND(!p_importer.is_valid()); - ResourceFormatImporter::get_singleton()->add_importer(p_importer); + ResourceFormatImporter::get_singleton()->add_importer(p_importer, p_first_priority); EditorFileSystem::get_singleton()->call_deferred(SNAME("scan")); } @@ -759,9 +759,9 @@ void EditorPlugin::remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_p EditorInspector::remove_inspector_plugin(p_plugin); } -void EditorPlugin::add_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer) { +void EditorPlugin::add_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer, bool p_first_priority) { ERR_FAIL_COND(!p_importer.is_valid()); - ResourceImporterScene::get_singleton()->add_importer(p_importer); + ResourceImporterScene::get_singleton()->add_importer(p_importer, p_first_priority); } void EditorPlugin::remove_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer) { @@ -769,9 +769,10 @@ void EditorPlugin::remove_scene_format_importer_plugin(const Ref<EditorSceneForm ResourceImporterScene::get_singleton()->remove_importer(p_importer); } -void EditorPlugin::add_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { - ResourceImporterScene::get_singleton()->add_post_importer_plugin(p_plugin); +void EditorPlugin::add_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority) { + ResourceImporterScene::get_singleton()->add_post_importer_plugin(p_plugin, p_first_priority); } + void EditorPlugin::remove_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { ResourceImporterScene::get_singleton()->remove_post_importer_plugin(p_plugin); } @@ -881,11 +882,11 @@ void EditorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("queue_save_layout"), &EditorPlugin::queue_save_layout); ClassDB::bind_method(D_METHOD("add_translation_parser_plugin", "parser"), &EditorPlugin::add_translation_parser_plugin); ClassDB::bind_method(D_METHOD("remove_translation_parser_plugin", "parser"), &EditorPlugin::remove_translation_parser_plugin); - ClassDB::bind_method(D_METHOD("add_import_plugin", "importer"), &EditorPlugin::add_import_plugin); + ClassDB::bind_method(D_METHOD("add_import_plugin", "importer", "first_priority"), &EditorPlugin::add_import_plugin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("remove_import_plugin", "importer"), &EditorPlugin::remove_import_plugin); - ClassDB::bind_method(D_METHOD("add_scene_format_importer_plugin", "scene_format_importer"), &EditorPlugin::add_scene_format_importer_plugin); + ClassDB::bind_method(D_METHOD("add_scene_format_importer_plugin", "scene_format_importer", "first_priority"), &EditorPlugin::add_scene_format_importer_plugin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("remove_scene_format_importer_plugin", "scene_format_importer"), &EditorPlugin::remove_scene_format_importer_plugin); - ClassDB::bind_method(D_METHOD("add_scene_post_import_plugin", "scene_import_plugin"), &EditorPlugin::add_scene_post_import_plugin); + ClassDB::bind_method(D_METHOD("add_scene_post_import_plugin", "scene_import_plugin", "first_priority"), &EditorPlugin::add_scene_post_import_plugin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("remove_scene_post_import_plugin", "scene_import_plugin"), &EditorPlugin::remove_scene_post_import_plugin); ClassDB::bind_method(D_METHOD("add_export_plugin", "plugin"), &EditorPlugin::add_export_plugin); ClassDB::bind_method(D_METHOD("remove_export_plugin", "plugin"), &EditorPlugin::remove_export_plugin); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 06517190f6..f23c5f40f6 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -278,7 +278,7 @@ public: void add_translation_parser_plugin(const Ref<EditorTranslationParserPlugin> &p_parser); void remove_translation_parser_plugin(const Ref<EditorTranslationParserPlugin> &p_parser); - void add_import_plugin(const Ref<EditorImportPlugin> &p_importer); + void add_import_plugin(const Ref<EditorImportPlugin> &p_importer, bool p_first_priority = false); void remove_import_plugin(const Ref<EditorImportPlugin> &p_importer); void add_export_plugin(const Ref<EditorExportPlugin> &p_exporter); @@ -290,10 +290,10 @@ public: void add_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); void remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); - void add_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer); + void add_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer, bool p_first_priority = false); void remove_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer); - void add_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_importer); + void add_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_importer, bool p_first_priority = false); void remove_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_importer); void add_autoload_singleton(const String &p_name, const String &p_path); diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index cfed86d1ae..c28c7db2cb 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -658,7 +658,7 @@ void EditorPropertyArray::_reorder_button_up() { Variant array = object->get_array(); Variant value_to_move = array.get(reorder_from_index); - array.call("remove", reorder_from_index); + array.call("remove_at", reorder_from_index); array.call("insert", reorder_to_index, value_to_move); emit_changed(get_edited_property(), array, "", false); diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 716643f812..398a096550 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -77,16 +77,16 @@ void EditorResourcePicker::_update_resource_preview(const String &p_path, const return; } - String type = edited_resource->get_class_name(); - if (ClassDB::is_parent_class(type, "Script")) { - assign_button->set_text(edited_resource->get_path().get_file()); + Ref<Script> script = edited_resource; + if (script.is_valid()) { + assign_button->set_text(script->get_path().get_file()); return; } if (p_preview.is_valid()) { preview_rect->set_offset(SIDE_LEFT, assign_button->get_icon()->get_width() + assign_button->get_theme_stylebox(SNAME("normal"))->get_default_margin(SIDE_LEFT) + get_theme_constant(SNAME("hseparation"), SNAME("Button"))); - if (type == "GradientTexture1D") { + if (Ref<GradientTexture1D>(edited_resource).is_valid()) { preview_rect->set_stretch_mode(TextureRect::STRETCH_SCALE); assign_button->set_custom_minimum_size(Size2(1, 1)); } else { @@ -377,6 +377,8 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { Resource *resp = Object::cast_to<Resource>(obj); ERR_BREAK(!resp); + EditorNode::get_editor_data().instantiate_object_properties(obj); + edited_resource = RES(resp); emit_signal(SNAME("resource_changed"), edited_resource); _update_resource(); @@ -640,7 +642,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ for (Set<String>::Element *E = allowed_types.front(); E; E = E->next()) { String at = E->get().strip_edges(); - if (at == "BaseMaterial3D" && ClassDB::is_parent_class(dropped_resource->get_class(), "Texture2D")) { + if (at == "BaseMaterial3D" && Ref<Texture2D>(dropped_resource).is_valid()) { // Use existing resource if possible and only replace its data. Ref<StandardMaterial3D> mat = edited_resource; if (!mat.is_valid()) { @@ -651,7 +653,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ break; } - if (at == "ShaderMaterial" && ClassDB::is_parent_class(dropped_resource->get_class(), "Shader")) { + if (at == "ShaderMaterial" && Ref<Shader>(dropped_resource).is_valid()) { Ref<ShaderMaterial> mat = edited_resource; if (!mat.is_valid()) { mat.instantiate(); @@ -661,7 +663,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ break; } - if (at == "Font" && ClassDB::is_parent_class(dropped_resource->get_class(), "FontData")) { + if (at == "Font" && Ref<FontData>(dropped_resource).is_valid()) { Ref<Font> font = edited_resource; if (!font.is_valid()) { font.instantiate(); @@ -671,7 +673,7 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ break; } - if (at == "Texture2D" && ClassDB::is_parent_class(dropped_resource->get_class(), "Image")) { + if (at == "Texture2D" && Ref<Image>(dropped_resource).is_valid()) { Ref<ImageTexture> texture = edited_resource; if (!texture.is_valid()) { texture.instantiate(); diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index 1cb95226ec..fc37590337 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -272,15 +272,15 @@ void EditorSettingsDialog::_create_shortcut_treeitem(TreeItem *p_parent, const S shortcut_item->set_text(1, sc_text); if (sc_text == "None") { // Fade out unassigned shortcut labels for easier visual grepping. - shortcut_item->set_custom_color(1, shortcuts->get_theme_color("font_color", "Label") * Color(1, 1, 1, 0.5)); + shortcut_item->set_custom_color(1, shortcuts->get_theme_color(SNAME("font_color"), SNAME("Label")) * Color(1, 1, 1, 0.5)); } if (p_allow_revert) { - shortcut_item->add_button(1, shortcuts->get_theme_icon("Reload", "EditorIcons"), SHORTCUT_REVERT); + shortcut_item->add_button(1, shortcuts->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")), SHORTCUT_REVERT); } - shortcut_item->add_button(1, shortcuts->get_theme_icon("Add", "EditorIcons"), SHORTCUT_ADD); - shortcut_item->add_button(1, shortcuts->get_theme_icon("Close", "EditorIcons"), SHORTCUT_ERASE); + shortcut_item->add_button(1, shortcuts->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), SHORTCUT_ADD); + shortcut_item->add_button(1, shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), SHORTCUT_ERASE); shortcut_item->set_meta("is_action", p_is_action); shortcut_item->set_meta("type", "shortcut"); @@ -299,11 +299,11 @@ void EditorSettingsDialog::_create_shortcut_treeitem(TreeItem *p_parent, const S event_item->set_text(0, shortcut_item->get_child_count() == 1 ? "Primary" : ""); event_item->set_text(1, ie->as_text()); - event_item->add_button(1, shortcuts->get_theme_icon("Edit", "EditorIcons"), SHORTCUT_EDIT); - event_item->add_button(1, shortcuts->get_theme_icon("Close", "EditorIcons"), SHORTCUT_ERASE); + event_item->add_button(1, shortcuts->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), SHORTCUT_EDIT); + event_item->add_button(1, shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), SHORTCUT_ERASE); - event_item->set_custom_bg_color(0, shortcuts->get_theme_color("dark_color_3", "Editor")); - event_item->set_custom_bg_color(1, shortcuts->get_theme_color("dark_color_3", "Editor")); + event_item->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("dark_color_3"), SNAME("Editor"))); + event_item->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("dark_color_3"), SNAME("Editor"))); event_item->set_meta("is_action", p_is_action); event_item->set_meta("type", "event"); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 2a5fefda20..1e373239a6 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -1279,7 +1279,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Panel theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4, corner_width)); - theme->set_stylebox("panel_fg", "Panel", style_default); + theme->set_stylebox("PanelForeground", "EditorStyles", style_default); // Label theme->set_stylebox("normal", "Label", style_empty); diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index 6c9e4ab0fc..24227b3a6b 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -113,22 +113,22 @@ void EditorToaster::_notification(int p_what) { disable_notifications_button->set_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons"))); // Styleboxes background. - info_panel_style_background->set_bg_color(get_theme_color("base_color", "Editor")); + info_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor"))); - warning_panel_style_background->set_bg_color(get_theme_color("base_color", "Editor")); - warning_panel_style_background->set_border_color(get_theme_color("warning_color", "Editor")); + warning_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor"))); + warning_panel_style_background->set_border_color(get_theme_color(SNAME("warning_color"), SNAME("Editor"))); - error_panel_style_background->set_bg_color(get_theme_color("base_color", "Editor")); - error_panel_style_background->set_border_color(get_theme_color("error_color", "Editor")); + error_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor"))); + error_panel_style_background->set_border_color(get_theme_color(SNAME("error_color"), SNAME("Editor"))); // Styleboxes progress. - info_panel_style_progress->set_bg_color(get_theme_color("base_color", "Editor").lightened(0.03)); + info_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03)); - warning_panel_style_progress->set_bg_color(get_theme_color("base_color", "Editor").lightened(0.03)); - warning_panel_style_progress->set_border_color(get_theme_color("warning_color", "Editor")); + warning_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03)); + warning_panel_style_progress->set_border_color(get_theme_color(SNAME("warning_color"), SNAME("Editor"))); - error_panel_style_progress->set_bg_color(get_theme_color("base_color", "Editor").lightened(0.03)); - error_panel_style_progress->set_border_color(get_theme_color("error_color", "Editor")); + error_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03)); + error_panel_style_progress->set_border_color(get_theme_color(SNAME("error_color"), SNAME("Editor"))); main_button->update(); disable_notifications_button->update(); @@ -256,13 +256,13 @@ void EditorToaster::_draw_button() { real_t button_radius = main_button->get_size().x / 8; switch (highest_severity) { case SEVERITY_INFO: - color = get_theme_color("accent_color", "Editor"); + color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); break; case SEVERITY_WARNING: - color = get_theme_color("warning_color", "Editor"); + color = get_theme_color(SNAME("warning_color"), SNAME("Editor")); break; case SEVERITY_ERROR: - color = get_theme_color("error_color", "Editor"); + color = get_theme_color(SNAME("error_color"), SNAME("Editor")); break; default: break; @@ -360,7 +360,7 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ if (p_time > 0.0) { Button *close_button = memnew(Button); close_button->set_flat(true); - close_button->set_icon(get_theme_icon("Close", "EditorIcons")); + close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); close_button->connect("pressed", callable_bind(callable_mp(this, &EditorToaster::close), panel)); close_button->connect("theme_changed", callable_bind(callable_mp(this, &EditorToaster::_close_button_theme_changed), close_button)); hbox_container->add_child(close_button); @@ -442,7 +442,7 @@ void EditorToaster::close(Control *p_control) { void EditorToaster::_close_button_theme_changed(Control *p_close_button) { Button *close_button = Object::cast_to<Button>(p_close_button); if (close_button) { - close_button->set_icon(get_theme_icon("Close", "EditorIcons")); + close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); } } diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index a038da4c18..c91351022f 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -338,30 +338,28 @@ void FileSystemDock::_notification(int p_what) { EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &FileSystemDock::_fs_changed)); EditorResourcePreview::get_singleton()->connect("preview_invalidated", callable_mp(this, &FileSystemDock::_preview_invalidated)); - String ei = "EditorIcons"; - - button_reload->set_icon(get_theme_icon(SNAME("Reload"), ei)); - button_toggle_display_mode->set_icon(get_theme_icon(SNAME("Panels2"), ei)); + button_reload->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); + button_toggle_display_mode->set_icon(get_theme_icon(SNAME("Panels2"), SNAME("EditorIcons"))); button_file_list_display_mode->connect("pressed", callable_mp(this, &FileSystemDock::_toggle_file_display)); files->connect("item_activated", callable_mp(this, &FileSystemDock::_file_list_activate_file)); button_hist_next->connect("pressed", callable_mp(this, &FileSystemDock::_fw_history)); button_hist_prev->connect("pressed", callable_mp(this, &FileSystemDock::_bw_history)); - tree_search_box->set_right_icon(get_theme_icon(SNAME("Search"), ei)); + tree_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); tree_search_box->set_clear_button_enabled(true); - tree_button_sort->set_icon(get_theme_icon(SNAME("Sort"), ei)); + tree_button_sort->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons"))); - file_list_search_box->set_right_icon(get_theme_icon(SNAME("Search"), ei)); + file_list_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); file_list_search_box->set_clear_button_enabled(true); - file_list_button_sort->set_icon(get_theme_icon(SNAME("Sort"), ei)); + file_list_button_sort->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons"))); if (is_layout_rtl()) { - button_hist_next->set_icon(get_theme_icon(SNAME("Back"), ei)); - button_hist_prev->set_icon(get_theme_icon(SNAME("Forward"), ei)); + button_hist_next->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); + button_hist_prev->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); } else { - button_hist_next->set_icon(get_theme_icon(SNAME("Forward"), ei)); - button_hist_prev->set_icon(get_theme_icon(SNAME("Back"), ei)); + button_hist_next->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); + button_hist_prev->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); } file_list_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_file_list_rmb_option)); tree_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_tree_rmb_option)); @@ -412,15 +410,14 @@ void FileSystemDock::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { // Update icons. - String ei = "EditorIcons"; - button_reload->set_icon(get_theme_icon(SNAME("Reload"), ei)); - button_toggle_display_mode->set_icon(get_theme_icon(SNAME("Panels2"), ei)); + button_reload->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); + button_toggle_display_mode->set_icon(get_theme_icon(SNAME("Panels2"), SNAME("EditorIcons"))); if (is_layout_rtl()) { - button_hist_next->set_icon(get_theme_icon(SNAME("Back"), ei)); - button_hist_prev->set_icon(get_theme_icon(SNAME("Forward"), ei)); + button_hist_next->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); + button_hist_prev->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); } else { - button_hist_next->set_icon(get_theme_icon(SNAME("Forward"), ei)); - button_hist_prev->set_icon(get_theme_icon(SNAME("Back"), ei)); + button_hist_next->set_icon(get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); + button_hist_prev->set_icon(get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); } if (file_list_display_mode == FILE_LIST_DISPLAY_LIST) { button_file_list_display_mode->set_icon(get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"))); @@ -428,13 +425,13 @@ void FileSystemDock::_notification(int p_what) { button_file_list_display_mode->set_icon(get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"))); } - tree_search_box->set_right_icon(get_theme_icon(SNAME("Search"), ei)); + tree_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); tree_search_box->set_clear_button_enabled(true); - tree_button_sort->set_icon(get_theme_icon(SNAME("Sort"), ei)); + tree_button_sort->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons"))); - file_list_search_box->set_right_icon(get_theme_icon(SNAME("Search"), ei)); + file_list_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); file_list_search_box->set_clear_button_enabled(true); - file_list_button_sort->set_icon(get_theme_icon(SNAME("Sort"), ei)); + file_list_button_sort->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons"))); // Update always show folders. bool new_always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); @@ -718,7 +715,6 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { String directory = path; String file = ""; - String ei = "EditorIcons"; int thumbnail_size = EditorSettings::get_singleton()->get("docks/filesystem/thumbnail_size"); thumbnail_size *= EDSCALE; Ref<Texture2D> folder_thumbnail; @@ -736,13 +732,13 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size)); if (thumbnail_size < 64) { - folder_thumbnail = get_theme_icon(SNAME("FolderMediumThumb"), ei); - file_thumbnail = get_theme_icon(SNAME("FileMediumThumb"), ei); - file_thumbnail_broken = get_theme_icon(SNAME("FileDeadMediumThumb"), ei); + folder_thumbnail = get_theme_icon(SNAME("FolderMediumThumb"), SNAME("EditorIcons")); + file_thumbnail = get_theme_icon(SNAME("FileMediumThumb"), SNAME("EditorIcons")); + file_thumbnail_broken = get_theme_icon(SNAME("FileDeadMediumThumb"), SNAME("EditorIcons")); } else { - folder_thumbnail = get_theme_icon(SNAME("FolderBigThumb"), ei); - file_thumbnail = get_theme_icon(SNAME("FileBigThumb"), ei); - file_thumbnail_broken = get_theme_icon(SNAME("FileDeadBigThumb"), ei); + folder_thumbnail = get_theme_icon(SNAME("FolderBigThumb"), SNAME("EditorIcons")); + file_thumbnail = get_theme_icon(SNAME("FileBigThumb"), SNAME("EditorIcons")); + file_thumbnail_broken = get_theme_icon(SNAME("FileDeadBigThumb"), SNAME("EditorIcons")); } } else { // No thumbnails. @@ -871,7 +867,6 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { // Fills the ItemList control node from the FileInfos. String main_scene = ProjectSettings::get_singleton()->get("application/run/main_scene"); - String oi = "Object"; for (FileInfo &E : file_list) { FileInfo *finfo = &(E); String fname = finfo->name; @@ -885,10 +880,10 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { // Select the icons. if (!finfo->import_broken) { - type_icon = (has_theme_icon(ftype, ei)) ? get_theme_icon(ftype, ei) : get_theme_icon(oi, ei); + type_icon = (has_theme_icon(ftype, SNAME("EditorIcons"))) ? get_theme_icon(ftype, SNAME("EditorIcons")) : get_theme_icon(SNAME("Object"), SNAME("EditorIcons")); big_icon = file_thumbnail; } else { - type_icon = get_theme_icon(SNAME("ImportFail"), ei); + type_icon = get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons")); big_icon = file_thumbnail_broken; tooltip += "\n" + TTR("Status: Import of file failed. Please fix file and reimport manually."); } @@ -1230,6 +1225,30 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin if (err != OK) { EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import\n"); } + + // Remove uid from .import file to avoid conflict. + Ref<ConfigFile> cfg; + cfg.instantiate(); + cfg->load(new_path + ".import"); + cfg->erase_section_key("remap", "uid"); + cfg->save(new_path + ".import"); + } else if (p_item.is_file && (old_path.get_extension() == "tscn" || old_path.get_extension() == "tres")) { + // FIXME: Quick hack to fix text resources. This should be fixed properly. + FileAccessRef file = FileAccess::open(old_path, FileAccess::READ, &err); + if (err == OK) { + PackedStringArray lines = file->get_as_utf8_string().split("\n"); + String line = lines[0]; + + if (line.contains("uid")) { + line = line.substr(0, line.find(" uid")) + "]"; + lines.write[0] = line; + + FileAccessRef file2 = FileAccess::open(new_path, FileAccess::WRITE, &err); + if (err == OK) { + file2->store_string(String("\n").join(lines)); + } + } + } } } else { EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + "\n"); diff --git a/editor/import/dynamicfont_import_settings.cpp b/editor/import/dynamicfont_import_settings.cpp index 81b98c1d45..244352fbb2 100644 --- a/editor/import/dynamicfont_import_settings.cpp +++ b/editor/import/dynamicfont_import_settings.cpp @@ -495,7 +495,7 @@ void DynamicFontImportSettings::_variation_add() { vars_item->set_text(0, TTR("New configuration")); vars_item->set_editable(0, true); - vars_item->add_button(1, vars_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); + vars_item->add_button(1, vars_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75)); Ref<DynamicFontImportSettingsData> import_variation_data; @@ -643,8 +643,8 @@ void DynamicFontImportSettings::_glyph_selected() { TreeItem *item = glyph_table->get_selected(); ERR_FAIL_NULL(item); - Color scol = glyph_table->get_theme_color("box_selection_fill_color", "Editor"); - Color fcol = glyph_table->get_theme_color("font_selected_color", "Editor"); + Color scol = glyph_table->get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor")); + Color fcol = glyph_table->get_theme_color(SNAME("font_selected_color"), SNAME("Editor")); scol.a = 1.f; int32_t c = item->get_metadata(glyph_table->get_selected_column()); @@ -705,8 +705,8 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { TreeItem *root = glyph_table->create_item(); ERR_FAIL_NULL(root); - Color scol = glyph_table->get_theme_color("box_selection_fill_color", "Editor"); - Color fcol = glyph_table->get_theme_color("font_selected_color", "Editor"); + Color scol = glyph_table->get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor")); + Color fcol = glyph_table->get_theme_color(SNAME("font_selected_color"), SNAME("Editor")); scol.a = 1.f; TreeItem *item = nullptr; @@ -719,12 +719,12 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { item->set_text(0, _pad_zeros(String::num_int64(c, 16))); item->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT); item->set_selectable(0, false); - item->set_custom_bg_color(0, glyph_table->get_theme_color("dark_color_3", "Editor")); + item->set_custom_bg_color(0, glyph_table->get_theme_color(SNAME("dark_color_3"), SNAME("Editor"))); } if (font_main->has_char(c)) { item->set_text(col + 1, String::chr(c)); item->set_custom_color(col + 1, Color(1, 1, 1)); - if (selected_chars.has(c) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, c)))) { + if (selected_chars.has(c) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, c)))) { item->set_custom_color(col + 1, fcol); item->set_custom_bg_color(col + 1, scol); } else { @@ -732,13 +732,13 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { item->clear_custom_bg_color(col + 1); } } else { - item->set_custom_bg_color(col + 1, glyph_table->get_theme_color("dark_color_2", "Editor")); + item->set_custom_bg_color(col + 1, glyph_table->get_theme_color(SNAME("dark_color_2"), SNAME("Editor"))); } item->set_metadata(col + 1, c); item->set_text_alignment(col + 1, HORIZONTAL_ALIGNMENT_CENTER); item->set_selectable(col + 1, true); item->set_custom_font(col + 1, font_main); - item->set_custom_font_size(col + 1, get_theme_font_size("font_size") * 2); + item->set_custom_font_size(col + 1, get_theme_font_size(SNAME("font_size")) * 2); col++; if (col == 16) { @@ -752,8 +752,8 @@ bool DynamicFontImportSettings::_char_update(int32_t p_char) { if (selected_chars.has(p_char)) { selected_chars.erase(p_char); return false; - } else if (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, p_char))) { - selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, p_char)); + } else if (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, p_char))) { + selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, p_char)); return false; } else { selected_chars.insert(p_char); @@ -767,7 +767,7 @@ void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) { for (int32_t i = p_start; i <= p_end; i++) { if (font_main->has_char(i)) { if (font_main->get_data(0).is_valid()) { - all_selected = all_selected && (selected_chars.has(i) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, i)))); + all_selected = all_selected && (selected_chars.has(i) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, i)))); } else { all_selected = all_selected && selected_chars.has(i); } @@ -780,7 +780,7 @@ void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) { } else { selected_chars.erase(i); if (font_main->get_data(0).is_valid()) { - selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, i)); + selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, i)); } } } @@ -809,7 +809,7 @@ void DynamicFontImportSettings::_lang_add_item(const String &p_locale) { lang_item->set_checked(0, false); lang_item->set_text(1, p_locale); lang_item->set_editable(1, true); - lang_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); lang_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); } @@ -841,7 +841,7 @@ void DynamicFontImportSettings::_ot_add_item(int p_option) { ot_item->set_editable(0, false); ot_item->set_text(1, "1"); ot_item->set_editable(1, true); - ot_item->add_button(2, ot_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + ot_item->add_button(2, ot_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); } @@ -868,7 +868,7 @@ void DynamicFontImportSettings::_script_add_item(int p_option) { script_item->set_checked(0, false); script_item->set_text(1, script_codes[p_option]); script_item->set_editable(1, true); - script_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); script_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); } @@ -895,10 +895,10 @@ void DynamicFontImportSettings::_notification(int p_what) { if (p_what == NOTIFICATION_READY) { connect("confirmed", callable_mp(this, &DynamicFontImportSettings::_re_import)); } else if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - add_lang->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); - add_script->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); - add_var->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); - add_ot->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_lang->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + add_script->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + add_var->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + add_ot->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } } @@ -1043,7 +1043,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { inspector_vars->edit(nullptr); inspector_general->edit(nullptr); - int gww = get_theme_font("font")->get_string_size("00000", get_theme_font_size("font_size")).x + 50; + int gww = get_theme_font(SNAME("font"))->get_string_size("00000", get_theme_font_size(SNAME("font_size"))).x + 50; glyph_table->set_column_custom_minimum_width(0, gww); glyph_table->clear(); @@ -1146,7 +1146,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { vars_item->set_text(0, TTR("Configuration") + " " + itos(i)); vars_item->set_editable(0, true); - vars_item->add_button(1, vars_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); + vars_item->add_button(1, vars_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75)); Ref<DynamicFontImportSettingsData> import_variation_data_custom; @@ -1184,7 +1184,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { lang_item->set_checked(0, true); lang_item->set_text(1, _langs[i]); lang_item->set_editable(1, true); - lang_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); } } else if (key == "support_overrides/language_disabled") { PackedStringArray _langs = config->get_value("params", key); @@ -1197,7 +1197,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { lang_item->set_checked(0, false); lang_item->set_text(1, _langs[i]); lang_item->set_editable(1, true); - lang_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); } } else if (key == "support_overrides/script_enabled") { PackedStringArray _scripts = config->get_value("params", key); @@ -1210,7 +1210,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { script_item->set_checked(0, true); script_item->set_text(1, _scripts[i]); script_item->set_editable(1, true); - script_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); } } else if (key == "support_overrides/script_disabled") { PackedStringArray _scripts = config->get_value("params", key); @@ -1223,7 +1223,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { script_item->set_checked(0, false); script_item->set_text(1, _scripts[i]); script_item->set_editable(1, true); - script_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); } } else if (key == "opentype_feature_overrides") { Dictionary features = config->get_value("params", key); @@ -1239,7 +1239,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { ot_item->set_editable(0, false); ot_item->set_text(1, itos(value)); ot_item->set_editable(1, true); - ot_item->add_button(2, ot_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + ot_item->add_button(2, ot_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); } } else { @@ -1356,7 +1356,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { menu_ot->add_child(menu_ot_cu); menu_ot_cu->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item)); - Color warn_color = (EditorNode::get_singleton()) ? EditorNode::get_singleton()->get_gui_base()->get_theme_color("warning_color", "Editor") : Color(1, 1, 0); + Color warn_color = (EditorNode::get_singleton()) ? EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")) : Color(1, 1, 0); // Root layout @@ -1438,7 +1438,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { add_var = memnew(Button); page2_hb_vars->add_child(add_var); add_var->set_tooltip(TTR("Add configuration")); - add_var->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_var->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_var->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_variation_add)); vars_list = memnew(Tree); @@ -1545,8 +1545,8 @@ DynamicFontImportSettings::DynamicFontImportSettings() { for (int i = 0; i < 16; i++) { glyph_table->set_column_title(i + 1, String::num_int64(i, 16)); } - glyph_table->add_theme_style_override("selected", glyph_table->get_theme_stylebox("bg")); - glyph_table->add_theme_style_override("selected_focus", glyph_table->get_theme_stylebox("bg")); + glyph_table->add_theme_style_override("selected", glyph_table->get_theme_stylebox(SNAME("bg"))); + glyph_table->add_theme_style_override("selected_focus", glyph_table->get_theme_stylebox(SNAME("bg"))); glyph_table->add_theme_constant_override("hseparation", 0); glyph_table->set_h_size_flags(Control::SIZE_EXPAND_FILL); glyph_table->set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -1590,7 +1590,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { add_lang = memnew(Button); hb_lang->add_child(add_lang); add_lang->set_tooltip(TTR("Add language override")); - add_lang->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_lang->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_lang->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_lang_add)); lang_list = memnew(Tree); @@ -1618,7 +1618,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { add_script = memnew(Button); hb_script->add_child(add_script); add_script->set_tooltip(TTR("Add script override")); - add_script->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_script->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_script->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_script_add)); script_list = memnew(Tree); @@ -1646,7 +1646,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { add_ot = memnew(Button); hb_ot->add_child(add_ot); add_ot->set_tooltip(TTR("Add feature override")); - add_ot->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_ot->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_ot->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add)); ot_list = memnew(Tree); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 5d356604f4..3eb12353b5 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -39,6 +39,7 @@ #include "scene/3d/importer_mesh_instance_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/navigation_region_3d.h" +#include "scene/3d/occluder_instance_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/3d/vehicle_body_3d.h" #include "scene/animation/animation_player.h" @@ -371,10 +372,10 @@ static void _pre_gen_shape_list(Ref<ImporterMesh> &mesh, Vector<Ref<Shape3D>> &r } } -Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, List<Pair<NodePath, Node *>> &r_node_renames) { +Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &r_collision_map, Pair<PackedVector3Array, PackedInt32Array> *r_occluder_arrays, List<Pair<NodePath, Node *>> &r_node_renames) { // Children first. for (int i = 0; i < p_node->get_child_count(); i++) { - Node *r = _pre_fix_node(p_node->get_child(i), p_root, collision_map, r_node_renames); + Node *r = _pre_fix_node(p_node->get_child(i), p_root, r_collision_map, r_occluder_arrays, r_node_renames); if (!r) { i--; // Was erased. } @@ -498,14 +499,14 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I if (mesh.is_valid()) { Vector<Ref<Shape3D>> shapes; - if (collision_map.has(mesh)) { - shapes = collision_map[mesh]; + if (r_collision_map.has(mesh)) { + shapes = r_collision_map[mesh]; } else if (_teststr(name, "colonly")) { _pre_gen_shape_list(mesh, shapes, false); - collision_map[mesh] = shapes; + r_collision_map[mesh] = shapes; } else if (_teststr(name, "convcolonly")) { _pre_gen_shape_list(mesh, shapes, true); - collision_map[mesh] = shapes; + r_collision_map[mesh] = shapes; } if (shapes.size()) { @@ -560,8 +561,8 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I if (mesh.is_valid()) { Vector<Ref<Shape3D>> shapes; - if (collision_map.has(mesh)) { - shapes = collision_map[mesh]; + if (r_collision_map.has(mesh)) { + shapes = r_collision_map[mesh]; } else { _pre_gen_shape_list(mesh, shapes, true); } @@ -586,14 +587,14 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I if (mesh.is_valid()) { Vector<Ref<Shape3D>> shapes; String fixed_name; - if (collision_map.has(mesh)) { - shapes = collision_map[mesh]; + if (r_collision_map.has(mesh)) { + shapes = r_collision_map[mesh]; } else if (_teststr(name, "col")) { _pre_gen_shape_list(mesh, shapes, false); - collision_map[mesh] = shapes; + r_collision_map[mesh] = shapes; } else if (_teststr(name, "convcol")) { _pre_gen_shape_list(mesh, shapes, true); - collision_map[mesh] = shapes; + r_collision_map[mesh] = shapes; } if (_teststr(name, "col")) { @@ -635,7 +636,31 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I p_node->replace_by(nmi); memdelete(p_node); p_node = nmi; + } else if (_teststr(name, "occ") || _teststr(name, "occonly")) { + if (isroot) { + return p_node; + } + ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node); + if (mi) { + Ref<ImporterMesh> mesh = mi->get_mesh(); + if (mesh.is_valid()) { + if (r_occluder_arrays) { + OccluderInstance3D::bake_single_node(mi, 0.0f, r_occluder_arrays->first, r_occluder_arrays->second); + } + if (_teststr(name, "occ")) { + String fixed_name = _fixstr(name, "occ"); + if (!fixed_name.is_empty()) { + if (mi->get_parent() && !mi->get_parent()->has_node(fixed_name)) { + mi->set_name(fixed_name); + } + } + } else { + memdelete(p_node); + p_node = nullptr; + } + } + } } else if (Object::cast_to<ImporterMeshInstance3D>(p_node)) { //last attempt, maybe collision inside the mesh data @@ -644,16 +669,21 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I Ref<ImporterMesh> mesh = mi->get_mesh(); if (!mesh.is_null()) { Vector<Ref<Shape3D>> shapes; - if (collision_map.has(mesh)) { - shapes = collision_map[mesh]; + if (r_collision_map.has(mesh)) { + shapes = r_collision_map[mesh]; } else if (_teststr(mesh->get_name(), "col")) { _pre_gen_shape_list(mesh, shapes, false); - collision_map[mesh] = shapes; + r_collision_map[mesh] = shapes; mesh->set_name(_fixstr(mesh->get_name(), "col")); } else if (_teststr(mesh->get_name(), "convcol")) { _pre_gen_shape_list(mesh, shapes, true); - collision_map[mesh] = shapes; + r_collision_map[mesh] = shapes; mesh->set_name(_fixstr(mesh->get_name(), "convcol")); + } else if (_teststr(mesh->get_name(), "occ")) { + if (r_occluder_arrays) { + OccluderInstance3D::bake_single_node(mi, 0.0f, r_occluder_arrays->first, r_occluder_arrays->second); + } + mesh->set_name(_fixstr(mesh->get_name(), "occ")); } if (shapes.size()) { @@ -677,10 +707,10 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I return p_node; } -Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) { +Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) { // children first for (int i = 0; i < p_node->get_child_count(); i++) { - Node *r = _post_fix_node(p_node->get_child(i), p_root, collision_map, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps); + Node *r = _post_fix_node(p_node->get_child(i), p_root, collision_map, r_occluder_arrays, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps); if (!r) { i--; //was erased } @@ -883,6 +913,32 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< } } + if (Object::cast_to<ImporterMeshInstance3D>(p_node)) { + ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node); + + Ref<ImporterMesh> m = mi->get_mesh(); + + if (m.is_valid()) { + if (node_settings.has("generate/occluder")) { + int occluder_mode = node_settings["generate/occluder"]; + + if (occluder_mode != OCCLUDER_DISABLED) { + float simplification_dist = 0.0f; + if (node_settings.has("occluder/simplification_distance")) { + simplification_dist = node_settings["occluder/simplification_distance"]; + } + + OccluderInstance3D::bake_single_node(mi, simplification_dist, r_occluder_arrays.first, r_occluder_arrays.second); + + if (occluder_mode == OCCLUDER_OCCLUDER_ONLY) { + memdelete(p_node); + p_node = nullptr; + } + } + } + } + } + if (Object::cast_to<AnimationPlayer>(p_node)) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); @@ -1255,6 +1311,9 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "primitive/radius", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1.0)); r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3())); r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3())); + + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/occluder", PROPERTY_HINT_ENUM, "Disabled,Mesh + Occluder,Occluder Only", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "occluder/simplification_distance", PROPERTY_HINT_RANGE, "0.0,2.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0.1f)); } break; case INTERNAL_IMPORT_CATEGORY_MESH: { r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false)); @@ -1376,6 +1435,11 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor (physics_shape == SHAPE_TYPE_CYLINDER || physics_shape == SHAPE_TYPE_CAPSULE); } + + if (p_option == "occluder/simplification_distance") { + // Show only if occluder generation is enabled + return p_options.has("generate/occluder") && p_options["generate/occluder"].operator signed int() != OCCLUDER_DISABLED; + } } break; case INTERNAL_IMPORT_CATEGORY_MESH: { if (p_option == "save_to_file/path" || p_option == "save_to_file/make_streamable") { @@ -1869,7 +1933,7 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file) { Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map; List<Pair<NodePath, Node *>> node_renames; - _pre_fix_node(scene, scene, collision_map, node_renames); + _pre_fix_node(scene, scene, collision_map, nullptr, node_renames); return scene; } @@ -1944,15 +2008,16 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p Set<Ref<ImporterMesh>> scanned_meshes; Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map; + Pair<PackedVector3Array, PackedInt32Array> occluder_arrays; List<Pair<NodePath, Node *>> node_renames; - _pre_fix_node(scene, scene, collision_map, node_renames); + _pre_fix_node(scene, scene, collision_map, &occluder_arrays, node_renames); for (int i = 0; i < post_importer_plugins.size(); i++) { post_importer_plugins.write[i]->pre_process(scene, p_options); } - _post_fix_node(scene, scene, collision_map, scanned_meshes, node_data, material_data, animation_data, fps); + _post_fix_node(scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps); String root_type = p_options["nodes/root_type"]; root_type = root_type.split(" ")[0]; // full root_type is "ClassName (filename.gd)" for a script global class. @@ -1989,6 +2054,15 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p scene->set_name(p_save_path.get_file().get_basename()); } + if (!occluder_arrays.first.is_empty() && !occluder_arrays.second.is_empty()) { + Ref<ArrayOccluder3D> occ = memnew(ArrayOccluder3D); + occ->set_arrays(occluder_arrays.first, occluder_arrays.second); + OccluderInstance3D *occluder_instance = memnew(OccluderInstance3D); + occluder_instance->set_occluder(occ); + scene->add_child(occluder_instance, true); + occluder_instance->set_owner(scene); + } + bool gen_lods = bool(p_options["meshes/generate_lods"]); bool create_shadow_meshes = bool(p_options["meshes/create_shadow_meshes"]); int light_bake_mode = p_options["meshes/light_baking"]; @@ -2088,18 +2162,26 @@ ResourceImporterScene::ResourceImporterScene() { singleton = this; } -void ResourceImporterScene::add_importer(Ref<EditorSceneFormatImporter> p_importer) { +void ResourceImporterScene::add_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority) { ERR_FAIL_COND(p_importer.is_null()); - importers.insert(0, p_importer); + if (p_first_priority) { + importers.insert(0, p_importer); + } else { + importers.push_back(p_importer); + } } void ResourceImporterScene::remove_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { post_importer_plugins.erase(p_plugin); } -void ResourceImporterScene::add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { +void ResourceImporterScene::add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority) { ERR_FAIL_COND(p_plugin.is_null()); - post_importer_plugins.insert(0, p_plugin); + if (p_first_priority) { + post_importer_plugins.insert(0, p_plugin); + } else { + post_importer_plugins.push_back(p_plugin); + } } void ResourceImporterScene::remove_importer(Ref<EditorSceneFormatImporter> p_importer) { diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index a3aeac4022..a819be682d 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -178,6 +178,12 @@ class ResourceImporterScene : public ResourceImporter { NAVMESH_NAVMESH_ONLY, }; + enum OccluderMode { + OCCLUDER_DISABLED, + OCCLUDER_MESH_AND_OCCLUDER, + OCCLUDER_OCCLUDER_ONLY, + }; + enum MeshOverride { MESH_OVERRIDE_DEFAULT, MESH_OVERRIDE_ENABLE, @@ -224,12 +230,12 @@ class ResourceImporterScene : public ResourceImporter { public: static ResourceImporterScene *get_singleton() { return singleton; } - void add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin); + void add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority = false); void remove_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin); const Vector<Ref<EditorSceneFormatImporter>> &get_importers() const { return importers; } - void add_importer(Ref<EditorSceneFormatImporter> p_importer); + void add_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority = false); void remove_importer(Ref<EditorSceneFormatImporter> p_importer); virtual String get_importer_name() const override; @@ -261,8 +267,8 @@ public: // Import scenes *after* everything else (such as textures). virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; } - Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, List<Pair<NodePath, Node *>> &r_node_renames); - Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps); + Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &r_collision_map, Pair<PackedVector3Array, PackedInt32Array> *r_occluder_arrays, List<Pair<NodePath, Node *>> &r_node_renames); + Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps); Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks); void _create_clips(AnimationPlayer *anim, const Array &p_clips, bool p_bake_all); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index b000ff8eee..40d6bc48e7 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -300,7 +300,7 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) { base_name = add_options[p_idx].name; } else { ERR_FAIL_COND(add_options[p_idx].script.is_null()); - String base_type = add_options[p_idx].script->get_instance_base_type(); + StringName base_type = add_options[p_idx].script->get_instance_base_type(); AnimationNode *an = Object::cast_to<AnimationNode>(ClassDB::instantiate(base_type)); ERR_FAIL_COND(!an); anode = Ref<AnimationNode>(an); diff --git a/editor/plugins/audio_stream_randomizer_editor_plugin.cpp b/editor/plugins/audio_stream_randomizer_editor_plugin.cpp new file mode 100644 index 0000000000..fea3c29967 --- /dev/null +++ b/editor/plugins/audio_stream_randomizer_editor_plugin.cpp @@ -0,0 +1,119 @@ +/*************************************************************************/ +/* audio_stream_randomizer_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "audio_stream_randomizer_editor_plugin.h" + +void AudioStreamRandomizerEditorPlugin::edit(Object *p_object) { +} + +bool AudioStreamRandomizerEditorPlugin::handles(Object *p_object) const { + return false; +} + +void AudioStreamRandomizerEditorPlugin::make_visible(bool p_visible) { +} + +void AudioStreamRandomizerEditorPlugin::_move_stream_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) { + UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo); + ERR_FAIL_COND(!undo_redo); + + AudioStreamRandomizer *randomizer = Object::cast_to<AudioStreamRandomizer>(p_edited); + if (!randomizer) { + return; + } + + // Compute the array indices to save. + int begin = 0; + int end; + if (p_array_prefix == "stream_") { + end = randomizer->get_streams_count(); + } else { + ERR_FAIL_MSG("Invalid array prefix for AudioStreamRandomizer."); + } + if (p_from_index < 0) { + // Adding new. + if (p_to_pos >= 0) { + begin = p_to_pos; + } else { + end = 0; // Nothing to save when adding at the end. + } + } else if (p_to_pos < 0) { + // Removing. + begin = p_from_index; + } else { + // Moving. + begin = MIN(p_from_index, p_to_pos); + end = MIN(MAX(p_from_index, p_to_pos) + 1, end); + } + +#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property)); + // Save layers' properties. + if (p_from_index < 0) { + undo_redo->add_undo_method(randomizer, "remove_stream", p_to_pos < 0 ? randomizer->get_streams_count() : p_to_pos); + } else if (p_to_pos < 0) { + undo_redo->add_undo_method(randomizer, "add_stream", p_from_index); + } + + List<PropertyInfo> properties; + randomizer->get_property_list(&properties); + for (PropertyInfo pi : properties) { + if (pi.name.begins_with(p_array_prefix)) { + String str = pi.name.trim_prefix(p_array_prefix); + int to_char_index = 0; + while (to_char_index < str.length()) { + if (str[to_char_index] < '0' || str[to_char_index] > '9') { + break; + } + to_char_index++; + } + if (to_char_index > 0) { + int array_index = str.left(to_char_index).to_int(); + if (array_index >= begin && array_index < end) { + ADD_UNDO(randomizer, pi.name); + } + } + } + } +#undef ADD_UNDO + + if (p_from_index < 0) { + undo_redo->add_do_method(randomizer, "add_stream", p_to_pos); + } else if (p_to_pos < 0) { + undo_redo->add_do_method(randomizer, "remove_stream", p_from_index); + } else { + undo_redo->add_do_method(randomizer, "move_stream", p_from_index, p_to_pos); + } +} + +AudioStreamRandomizerEditorPlugin::AudioStreamRandomizerEditorPlugin(EditorNode *p_node) { + EditorNode::get_singleton()->get_editor_data().add_move_array_element_function(SNAME("AudioStreamRandomizer"), callable_mp(this, &AudioStreamRandomizerEditorPlugin::_move_stream_array_element)); +} + +AudioStreamRandomizerEditorPlugin::~AudioStreamRandomizerEditorPlugin() {} diff --git a/editor/plugins/audio_stream_randomizer_editor_plugin.h b/editor/plugins/audio_stream_randomizer_editor_plugin.h new file mode 100644 index 0000000000..490af7e2c2 --- /dev/null +++ b/editor/plugins/audio_stream_randomizer_editor_plugin.h @@ -0,0 +1,57 @@ +/*************************************************************************/ +/* audio_stream_randomizer_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef AUDIO_STREAM_RANDOMIZER_EDITOR_PLUGIN_H +#define AUDIO_STREAM_RANDOMIZER_EDITOR_PLUGIN_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "servers/audio/audio_stream.h" + +class AudioStreamRandomizerEditorPlugin : public EditorPlugin { + GDCLASS(AudioStreamRandomizerEditorPlugin, EditorPlugin); + + EditorNode *editor; + +private: + void _move_stream_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos); + +public: + virtual String get_name() const override { return "AudioStreamRandomizer"; } + bool has_main_screen() const override { return false; } + virtual void edit(Object *p_object) override; + virtual bool handles(Object *p_object) const override; + virtual void make_visible(bool p_visible) override; + + AudioStreamRandomizerEditorPlugin(EditorNode *p_node); + ~AudioStreamRandomizerEditorPlugin(); +}; + +#endif // AUDIO_STREAM_RANDOMIZER_EDITOR_PLUGIN_H diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index d496804bf2..aa8ad55ff3 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -5797,22 +5797,17 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name)); } - String node_class = child->get_class(); - if (node_class == "Polygon2D") { - editor_data->get_undo_redo().add_do_property(child, "texture/texture", texture); - } else if (node_class == "TouchScreenButton") { - editor_data->get_undo_redo().add_do_property(child, "normal", texture); - } else if (node_class == "TextureButton") { - editor_data->get_undo_redo().add_do_property(child, "texture_button", texture); + if (Object::cast_to<TouchScreenButton>(child) || Object::cast_to<TextureButton>(child)) { + editor_data->get_undo_redo().add_do_property(child, "texture_normal", texture); } else { editor_data->get_undo_redo().add_do_property(child, "texture", texture); } // make visible for certain node type - if (ClassDB::is_parent_class(node_class, "Control")) { + if (Object::cast_to<Control>(child)) { Size2 texture_size = texture->get_size(); editor_data->get_undo_redo().add_do_property(child, "rect_size", texture_size); - } else if (node_class == "Polygon2D") { + } else if (Object::cast_to<Polygon2D>(child)) { Size2 texture_size = texture->get_size(); Vector<Vector2> list = { Vector2(0, 0), @@ -5940,29 +5935,32 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian if (String(d["type"]) == "files") { Vector<String> files = d["files"]; bool can_instantiate = false; - for (int i = 0; i < files.size(); i++) { // check if dragged files contain resource or scene can be created at least once - RES res = ResourceLoader::load(files[i]); - if (res.is_null()) { - continue; - } - String type = res->get_class(); - if (type == "PackedScene") { - Ref<PackedScene> sdata = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); - Node *instantiated_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); - if (!instantiated_scene) { + + List<String> scene_extensions; + ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions); + List<String> texture_extensions; + ResourceLoader::get_recognized_extensions_for_type("Texture2D", &texture_extensions); + + for (int i = 0; i < files.size(); i++) { + // Check if dragged files with texture or scene extension can be created at least once. + if (texture_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) { + RES res = ResourceLoader::load(files[i]); + if (res.is_null()) { continue; } - memdelete(instantiated_scene); - } else if (ClassDB::is_parent_class(type, "Texture2D")) { - Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(*res)); - if (!texture.is_valid()) { + Ref<PackedScene> scn = res; + if (scn.is_valid()) { + Node *instantiated_scene = scn->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instantiated_scene) { + continue; + } + memdelete(instantiated_scene); + } else { continue; } - } else { - continue; + can_instantiate = true; + break; } - can_instantiate = true; - break; } if (can_instantiate) { if (!preview_node->get_parent()) { // create preview only once @@ -6069,10 +6067,21 @@ Node *CanvasItemEditorViewport::_make_texture_node_type(String texture_node_type } void CanvasItemEditorViewport::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + List<BaseButton *> btn_list; + button_group->get_buttons(&btn_list); + + for (int i = 0; i < btn_list.size(); i++) { + CheckBox *check = Object::cast_to<CheckBox>(btn_list[i]); + check->set_icon(get_theme_icon(check->get_text(), SNAME("EditorIcons"))); + } + + label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + } + switch (p_what) { case NOTIFICATION_ENTER_TREE: { connect("mouse_exited", callable_mp(this, &CanvasItemEditorViewport::_on_mouse_exit)); - label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); } break; case NOTIFICATION_EXIT_TREE: { disconnect("mouse_exited", callable_mp(this, &CanvasItemEditorViewport::_on_mouse_exit)); @@ -6123,7 +6132,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte btn_group = memnew(VBoxContainer); vbc->add_child(btn_group); - btn_group->set_h_size_flags(0); + btn_group->set_h_size_flags(SIZE_EXPAND_FILL); button_group.instantiate(); for (int i = 0; i < texture_node_types.size(); i++) { diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 7e0019faac..d23b52014e 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -188,7 +188,7 @@ bool EditorImagePreviewPlugin::generate_small_preview_automatically() const { } //////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////// + bool EditorBitmapPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "BitMap"); } @@ -308,7 +308,7 @@ void EditorMaterialPreviewPlugin::_preview_done() { } bool EditorMaterialPreviewPlugin::handles(const String &p_type) const { - return ClassDB::is_parent_class(p_type, "Material"); //any material + return ClassDB::is_parent_class(p_type, "Material"); // Any material. } bool EditorMaterialPreviewPlugin::generate_small_preview_automatically() const { @@ -699,7 +699,7 @@ void EditorMeshPreviewPlugin::_preview_done() { } bool EditorMeshPreviewPlugin::handles(const String &p_type) const { - return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh + return ClassDB::is_parent_class(p_type, "Mesh"); // Any mesh. } Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 88d2aee667..b4b1cf05ac 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -1889,6 +1889,7 @@ void MeshInstance3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { OccluderInstance3DGizmoPlugin::OccluderInstance3DGizmoPlugin() { create_material("line_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/occluder", Color(0.8, 0.5, 1))); + create_handle_material("handles"); } bool OccluderInstance3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { @@ -1903,6 +1904,189 @@ int OccluderInstance3DGizmoPlugin::get_priority() const { return -1; } +String OccluderInstance3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { + const OccluderInstance3D *cs = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); + + Ref<Occluder3D> o = cs->get_occluder(); + if (o.is_null()) { + return ""; + } + + if (Object::cast_to<SphereOccluder3D>(*o)) { + return "Radius"; + } + + if (Object::cast_to<BoxOccluder3D>(*o) || Object::cast_to<QuadOccluder3D>(*o)) { + return "Size"; + } + + return ""; +} + +Variant OccluderInstance3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { + OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); + + Ref<Occluder3D> o = oi->get_occluder(); + if (o.is_null()) { + return Variant(); + } + + if (Object::cast_to<SphereOccluder3D>(*o)) { + Ref<SphereOccluder3D> so = o; + return so->get_radius(); + } + + if (Object::cast_to<BoxOccluder3D>(*o)) { + Ref<BoxOccluder3D> bo = o; + return bo->get_size(); + } + + if (Object::cast_to<QuadOccluder3D>(*o)) { + Ref<QuadOccluder3D> qo = o; + return qo->get_size(); + } + + return Variant(); +} + +void OccluderInstance3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { + OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); + + Ref<Occluder3D> o = oi->get_occluder(); + if (o.is_null()) { + return; + } + + Transform3D gt = oi->get_global_transform(); + Transform3D gi = gt.affine_inverse(); + + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); + + Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; + + bool snap_enabled = Node3DEditor::get_singleton()->is_snap_enabled(); + float snap = Node3DEditor::get_singleton()->get_translate_snap(); + + if (Object::cast_to<SphereOccluder3D>(*o)) { + Ref<SphereOccluder3D> so = o; + Vector3 ra, rb; + Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb); + float d = ra.x; + if (snap_enabled) { + d = Math::snapped(d, snap); + } + + if (d < 0.001) { + d = 0.001; + } + + so->set_radius(d); + } + + if (Object::cast_to<BoxOccluder3D>(*o)) { + Vector3 axis; + axis[p_id] = 1.0; + Ref<BoxOccluder3D> bo = o; + Vector3 ra, rb; + Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); + float d = ra[p_id]; + if (snap_enabled) { + d = Math::snapped(d, snap); + } + + if (d < 0.001) { + d = 0.001; + } + + Vector3 he = bo->get_size(); + he[p_id] = d * 2; + bo->set_size(he); + } + + if (Object::cast_to<QuadOccluder3D>(*o)) { + Ref<QuadOccluder3D> qo = o; + Plane p = Plane(Vector3(0.0f, 0.0f, 1.0f), 0.0f); + Vector3 intersection; + if (!p.intersects_segment(sg[0], sg[1], &intersection)) { + return; + } + + if (p_id == 2) { + Vector2 s = Vector2(intersection.x, intersection.y) * 2.0f; + if (snap_enabled) { + s = s.snapped(Vector2(snap, snap)); + } + s = s.max(Vector2(0.001, 0.001)); + qo->set_size(s); + } else { + float d = intersection[p_id]; + if (snap_enabled) { + d = Math::snapped(d, snap); + } + + if (d < 0.001) { + d = 0.001; + } + + Vector2 he = qo->get_size(); + he[p_id] = d * 2.0f; + qo->set_size(he); + } + } +} + +void OccluderInstance3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { + OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); + + Ref<Occluder3D> o = oi->get_occluder(); + if (o.is_null()) { + return; + } + + if (Object::cast_to<SphereOccluder3D>(*o)) { + Ref<SphereOccluder3D> so = o; + if (p_cancel) { + so->set_radius(p_restore); + return; + } + + UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Sphere Shape Radius")); + ur->add_do_method(so.ptr(), "set_radius", so->get_radius()); + ur->add_undo_method(so.ptr(), "set_radius", p_restore); + ur->commit_action(); + } + + if (Object::cast_to<BoxOccluder3D>(*o)) { + Ref<BoxOccluder3D> bo = o; + if (p_cancel) { + bo->set_size(p_restore); + return; + } + + UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Box Shape Size")); + ur->add_do_method(bo.ptr(), "set_size", bo->get_size()); + ur->add_undo_method(bo.ptr(), "set_size", p_restore); + ur->commit_action(); + } + + if (Object::cast_to<QuadOccluder3D>(*o)) { + Ref<QuadOccluder3D> qo = o; + if (p_cancel) { + qo->set_size(p_restore); + return; + } + + UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Box Shape Size")); + ur->add_do_method(qo.ptr(), "set_size", qo->get_size()); + ur->add_undo_method(qo.ptr(), "set_size", p_restore); + ur->commit_action(); + } +} + void OccluderInstance3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { OccluderInstance3D *occluder_instance = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); @@ -1920,6 +2104,35 @@ void OccluderInstance3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_lines(lines, material); p_gizmo->add_collision_segments(lines); } + + Ref<Material> handles_material = get_material("handles"); + if (Object::cast_to<SphereOccluder3D>(*o)) { + Ref<SphereOccluder3D> so = o; + float r = so->get_radius(); + Vector<Vector3> handles = { Vector3(r, 0, 0) }; + p_gizmo->add_handles(handles, handles_material); + } + + if (Object::cast_to<BoxOccluder3D>(*o)) { + Ref<BoxOccluder3D> bo = o; + + Vector<Vector3> handles; + for (int i = 0; i < 3; i++) { + Vector3 ax; + ax[i] = bo->get_size()[i] / 2; + handles.push_back(ax); + } + + p_gizmo->add_handles(handles, handles_material); + } + + if (Object::cast_to<QuadOccluder3D>(*o)) { + Ref<QuadOccluder3D> qo = o; + Vector2 size = qo->get_size(); + Vector3 s = Vector3(size.x, size.y, 0.0f) / 2.0f; + Vector<Vector3> handles = { Vector3(s.x, 0.0f, 0.0f), Vector3(0.0f, s.y, 0.0f), Vector3(s.x, s.y, 0.0f) }; + p_gizmo->add_handles(handles, handles_material); + } } ///// diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h index 66b3f02fcf..fa55651d26 100644 --- a/editor/plugins/node_3d_editor_gizmos.h +++ b/editor/plugins/node_3d_editor_gizmos.h @@ -300,6 +300,11 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override; + void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override; + void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override; + OccluderInstance3DGizmoPlugin(); }; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 0c0188e8d1..e35af6dd64 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -384,6 +384,28 @@ int Node3DEditorViewport::get_selected_count() const { return count; } +void Node3DEditorViewport::cancel_transform() { + _edit.mode = TRANSFORM_NONE; + + List<Node *> &selection = editor_selection->get_selected_node_list(); + + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + Node3D *sp = Object::cast_to<Node3D>(E->get()); + if (!sp) { + continue; + } + + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); + if (!se) { + continue; + } + + sp->set_global_transform(se->original); + } + surface->update(); + set_message(TTR("Transform Aborted."), 3); +} + float Node3DEditorViewport::get_znear() const { return CLAMP(spatial_editor->get_znear(), MIN_Z, MAX_Z); } @@ -865,6 +887,7 @@ void Node3DEditorViewport::_update_name() { } void Node3DEditorViewport::_compute_edit(const Point2 &p_point) { + _edit.original_local = spatial_editor->are_local_coords_enabled(); _edit.click_ray = _get_ray(p_point); _edit.click_ray_pos = _get_ray_pos(p_point); _edit.plane = TRANSFORM_VIEW; @@ -1018,24 +1041,40 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) { int col_axis = -1; - float col_d = 1e20; - for (int i = 0; i < 3; i++) { - Plane plane(gt.basis.get_axis(i).normalized(), gt.origin); - Vector3 r; - if (!plane.intersects_ray(ray_pos, ray, &r)) { - continue; + Vector3 hit_position; + Vector3 hit_normal; + real_t ray_length = gt.origin.distance_to(ray_pos) + (GIZMO_CIRCLE_SIZE * gizmo_scale) * 4.0f; + if (Geometry3D::segment_intersects_sphere(ray_pos, ray_pos + ray * ray_length, gt.origin, gizmo_scale * (GIZMO_CIRCLE_SIZE), &hit_position, &hit_normal)) { + if (hit_normal.dot(_get_camera_normal()) < 0.05) { + hit_position = gt.xform_inv(hit_position).abs(); + int min_axis = hit_position.min_axis_index(); + if (hit_position[min_axis] < gizmo_scale * GIZMO_RING_HALF_WIDTH) { + col_axis = min_axis; + } } + } - const real_t dist = r.distance_to(gt.origin); - const Vector3 r_dir = (r - gt.origin).normalized(); + if (col_axis == -1) { + float col_d = 1e20; - if (_get_camera_normal().dot(r_dir) <= 0.005) { - if (dist > gizmo_scale * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gizmo_scale * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) { - const real_t d = ray_pos.distance_to(r); - if (d < col_d) { - col_d = d; - col_axis = i; + for (int i = 0; i < 3; i++) { + Plane plane(gt.basis.get_axis(i).normalized(), gt.origin); + Vector3 r; + if (!plane.intersects_ray(ray_pos, ray, &r)) { + continue; + } + + const real_t dist = r.distance_to(gt.origin); + const Vector3 r_dir = (r - gt.origin).normalized(); + + if (_get_camera_normal().dot(r_dir) <= 0.005) { + if (dist > gizmo_scale * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gizmo_scale * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) { + const real_t d = ray_pos.distance_to(r); + if (d < col_d) { + col_d = d; + col_axis = i; + } } } } @@ -1375,39 +1414,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } if (_edit.mode != TRANSFORM_NONE && b->is_pressed()) { - //cancel motion - _edit.mode = TRANSFORM_NONE; - - List<Node *> &selection = editor_selection->get_selected_node_list(); - - for (Node *E : selection) { - Node3D *sp = Object::cast_to<Node3D>(E); - if (!sp) { - continue; - } - - Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); - if (!se) { - continue; - } - - if (se->gizmo.is_valid()) { - Vector<int> ids; - Vector<Transform3D> restore; - - for (const KeyValue<int, Transform3D> &GE : se->subgizmos) { - ids.push_back(GE.key); - restore.push_back(GE.value); - } - - se->gizmo->commit_subgizmos(ids, restore, true); - spatial_editor->update_transform_gizmo(); - } else { - sp->set_global_transform(se->original); - } - } - surface->update(); - set_message(TTR("Transform Aborted."), 3); + cancel_transform(); } if (b->is_pressed()) { @@ -1461,6 +1468,12 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } break; case MouseButton::LEFT: { if (b->is_pressed()) { + clicked_wants_append = b->is_shift_pressed(); + + if (_edit.mode != TRANSFORM_NONE && _edit.instant) { + commit_transform(); + break; // just commit the edit, stop processing the event so we don't deselect the object + } NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->is_alt_pressed()) { break; @@ -1567,33 +1580,17 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { clicked = ObjectID(); if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->is_command_pressed()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) { - /* HANDLE ROTATION */ - if (get_selected_count() == 0) { - break; //bye - } - //handle rotate - _edit.mode = TRANSFORM_ROTATE; - _compute_edit(b->get_position()); + begin_transform(TRANSFORM_ROTATE, false); break; } if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE) { - if (get_selected_count() == 0) { - break; //bye - } - //handle translate - _edit.mode = TRANSFORM_TRANSLATE; - _compute_edit(b->get_position()); + begin_transform(TRANSFORM_TRANSLATE, false); break; } if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE) { - if (get_selected_count() == 0) { - break; //bye - } - //handle scale - _edit.mode = TRANSFORM_SCALE; - _compute_edit(b->get_position()); + begin_transform(TRANSFORM_SCALE, false); break; } @@ -1602,8 +1599,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { //clicking is always deferred to either move or release - clicked_wants_append = b->is_shift_pressed(); - if (clicked.is_null()) { //default to regionselect cursor.region_select = true; @@ -1648,32 +1643,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { se->gizmo->commit_subgizmos(ids, restore, false); spatial_editor->update_transform_gizmo(); } else { - static const char *_transform_name[4] = { - TTRC("None"), - TTRC("Rotate"), - // TRANSLATORS: This refers to the movement that changes the position of an object. - TTRC("Translate"), - TTRC("Scale"), - }; - undo_redo->create_action(TTRGET(_transform_name[_edit.mode])); - - List<Node *> &selection = editor_selection->get_selected_node_list(); - - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->get()); - if (!sp) { - continue; - } - - Node3DEditorSelectedItem *sel_item = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); - if (!sel_item) { - continue; - } - - undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); - undo_redo->add_undo_method(sp, "set_global_transform", sel_item->original); - } - undo_redo->commit_action(); + commit_transform(); } _edit.mode = TRANSFORM_NONE; set_message(""); @@ -1739,7 +1709,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle, _edit.gizmo_handle_secondary); set_message(n + ": " + String(v)); - } else if ((m->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { + } else if ((m->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE || _edit.instant) { if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) { nav_mode = NAVIGATION_ORBIT; } else if (nav_scheme == NAVIGATION_MODO && m->is_alt_pressed() && m->is_shift_pressed()) { @@ -1757,6 +1727,12 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { _edit.mode = TRANSFORM_TRANSLATE; } + // enable region-select if nothing has been selected yet or multi-select (shift key) is active + if (movement_threshold_passed && (get_selected_count() == 0 || clicked_wants_append)) { + cursor.region_select = true; + cursor.region_begin = _edit.original_mouse_pos; + } + if (cursor.region_select) { cursor.region_end = m->get_position(); surface->update(); @@ -1767,324 +1743,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { return; } - Vector3 ray_pos = _get_ray_pos(m->get_position()); - Vector3 ray = _get_ray(m->get_position()); - double snap = EDITOR_GET("interface/inspector/default_float_step"); - int snap_step_decimals = Math::range_step_decimals(snap); - - switch (_edit.mode) { - case TRANSFORM_SCALE: { - Vector3 motion_mask; - Plane plane; - bool plane_mv = false; - - switch (_edit.plane) { - case TRANSFORM_VIEW: - motion_mask = Vector3(0, 0, 0); - plane = Plane(_get_camera_normal(), _edit.center); - break; - case TRANSFORM_X_AXIS: - motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(); - plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); - break; - case TRANSFORM_Y_AXIS: - motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(); - plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); - break; - case TRANSFORM_Z_AXIS: - motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(); - plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); - break; - case TRANSFORM_YZ: - motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(); - plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center); - plane_mv = true; - break; - case TRANSFORM_XZ: - motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(); - plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center); - plane_mv = true; - break; - case TRANSFORM_XY: - motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(); - plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center); - plane_mv = true; - break; - } - - Vector3 intersection; - if (!plane.intersects_ray(ray_pos, ray, &intersection)) { - break; - } - - Vector3 click; - if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) { - break; - } - - Vector3 motion = intersection - click; - if (_edit.plane != TRANSFORM_VIEW) { - if (!plane_mv) { - motion = motion_mask.dot(motion) * motion_mask; - - } else { - // Alternative planar scaling mode - if (_get_key_modifier(m) != Key::SHIFT) { - motion = motion_mask.dot(motion) * motion_mask; - } - } - - } else { - const real_t center_click_dist = click.distance_to(_edit.center); - const real_t center_inters_dist = intersection.distance_to(_edit.center); - if (center_click_dist == 0) { - break; - } - - const real_t scale = center_inters_dist - center_click_dist; - motion = Vector3(scale, scale, scale); - } - - motion /= click.distance_to(_edit.center); - - // Disable local transformation for TRANSFORM_VIEW - bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); - - if (_edit.snap || spatial_editor->is_snap_enabled()) { - snap = spatial_editor->get_scale_snap() / 100; - } - Vector3 motion_snapped = motion; - motion_snapped.snap(Vector3(snap, snap, snap)); - // This might not be necessary anymore after issue #288 is solved (in 4.0?). - set_message(TTR("Scaling: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " + - String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")"); - motion = _edit.original.basis.inverse().xform(motion); - - List<Node *> &selection = editor_selection->get_selected_node_list(); - for (Node *E : selection) { - Node3D *sp = Object::cast_to<Node3D>(E); - if (!sp) { - continue; - } - - Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); - if (!se) { - continue; - } - - if (sp->has_meta("_edit_lock_")) { - continue; - } - - if (se->gizmo.is_valid()) { - for (KeyValue<int, Transform3D> &GE : se->subgizmos) { - Transform3D xform = GE.value; - Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo. - if (!local_coords) { - new_xform = se->original.affine_inverse() * new_xform; - } - se->gizmo->set_subgizmo_transform(GE.key, new_xform); - } - } else { - Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS); - _transform_gizmo_apply(se->sp, new_xform, local_coords); - } - } - - spatial_editor->update_transform_gizmo(); - surface->update(); - - } break; - - case TRANSFORM_TRANSLATE: { - Vector3 motion_mask; - Plane plane; - bool plane_mv = false; - - switch (_edit.plane) { - case TRANSFORM_VIEW: - plane = Plane(_get_camera_normal(), _edit.center); - break; - case TRANSFORM_X_AXIS: - motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(); - plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); - break; - case TRANSFORM_Y_AXIS: - motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(); - plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); - break; - case TRANSFORM_Z_AXIS: - motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(); - plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); - break; - case TRANSFORM_YZ: - plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center); - plane_mv = true; - break; - case TRANSFORM_XZ: - plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center); - plane_mv = true; - break; - case TRANSFORM_XY: - plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center); - plane_mv = true; - break; - } - - Vector3 intersection; - if (!plane.intersects_ray(ray_pos, ray, &intersection)) { - break; - } - - Vector3 click; - if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) { - break; - } - - Vector3 motion = intersection - click; - if (_edit.plane != TRANSFORM_VIEW) { - if (!plane_mv) { - motion = motion_mask.dot(motion) * motion_mask; - } - } - - // Disable local transformation for TRANSFORM_VIEW - bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); - - if (_edit.snap || spatial_editor->is_snap_enabled()) { - snap = spatial_editor->get_translate_snap(); - } - Vector3 motion_snapped = motion; - motion_snapped.snap(Vector3(snap, snap, snap)); - set_message(TTR("Translating: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " + - String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")"); - motion = spatial_editor->get_gizmo_transform().basis.inverse().xform(motion); - - List<Node *> &selection = editor_selection->get_selected_node_list(); - for (Node *E : selection) { - Node3D *sp = Object::cast_to<Node3D>(E); - if (!sp) { - continue; - } - - Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); - if (!se) { - continue; - } - - if (sp->has_meta("_edit_lock_")) { - continue; - } - - if (se->gizmo.is_valid()) { - for (KeyValue<int, Transform3D> &GE : se->subgizmos) { - Transform3D xform = GE.value; - Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo. - new_xform = se->original.affine_inverse() * new_xform; - se->gizmo->set_subgizmo_transform(GE.key, new_xform); - } - } else { - Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS); - _transform_gizmo_apply(se->sp, new_xform, false); - } - } - - spatial_editor->update_transform_gizmo(); - surface->update(); - - } break; - - case TRANSFORM_ROTATE: { - Plane plane; - Vector3 axis; - - switch (_edit.plane) { - case TRANSFORM_VIEW: - plane = Plane(_get_camera_normal(), _edit.center); - break; - case TRANSFORM_X_AXIS: - plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center); - axis = Vector3(1, 0, 0); - break; - case TRANSFORM_Y_AXIS: - plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center); - axis = Vector3(0, 1, 0); - break; - case TRANSFORM_Z_AXIS: - plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center); - axis = Vector3(0, 0, 1); - break; - case TRANSFORM_YZ: - case TRANSFORM_XZ: - case TRANSFORM_XY: - break; - } - - Vector3 intersection; - if (!plane.intersects_ray(ray_pos, ray, &intersection)) { - break; - } - - Vector3 click; - if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) { - break; - } - - Vector3 y_axis = (click - _edit.center).normalized(); - Vector3 x_axis = plane.normal.cross(y_axis).normalized(); - - double angle = Math::atan2(x_axis.dot(intersection - _edit.center), y_axis.dot(intersection - _edit.center)); - - if (_edit.snap || spatial_editor->is_snap_enabled()) { - snap = spatial_editor->get_rotate_snap(); - } - angle = Math::rad2deg(angle) + snap * 0.5; //else it won't reach +180 - angle -= Math::fmod(angle, snap); - set_message(vformat(TTR("Rotating %s degrees."), String::num(angle, snap_step_decimals))); - angle = Math::deg2rad(angle); - - bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW - - List<Node *> &selection = editor_selection->get_selected_node_list(); - for (Node *E : selection) { - Node3D *sp = Object::cast_to<Node3D>(E); - if (!sp) { - continue; - } - - Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); - if (!se) { - continue; - } - - if (sp->has_meta("_edit_lock_")) { - continue; - } - - Vector3 compute_axis = local_coords ? axis : plane.normal; - if (se->gizmo.is_valid()) { - for (KeyValue<int, Transform3D> &GE : se->subgizmos) { - Transform3D xform = GE.value; - - Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original * xform, xform, compute_axis, angle, local_coords, true); // Force orthogonal with subgizmo. - if (!local_coords) { - new_xform = se->original.affine_inverse() * new_xform; - } - se->gizmo->set_subgizmo_transform(GE.key, new_xform); - } - } else { - Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original, se->original_local, compute_axis, angle, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS); - _transform_gizmo_apply(se->sp, new_xform, local_coords); - } - } - - spatial_editor->update_transform_gizmo(); - surface->update(); - - } break; - default: { - } - } + update_transform(m->get_position(), _get_key_modifier(m) == Key::SHIFT); } } else if ((m->get_button_mask() & MouseButton::MASK_RIGHT) != MouseButton::NONE || freelook_active) { if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) { @@ -2225,6 +1884,51 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } + if (_edit.mode != TRANSFORM_NONE) { + // We're actively transforming, handle keys specially + TransformPlane new_plane = TRANSFORM_VIEW; + String new_message; + if (ED_IS_SHORTCUT("spatial_editor/lock_transform_x", p_event)) { + new_plane = TRANSFORM_X_AXIS; + new_message = TTR("X-Axis Transform."); + } else if (ED_IS_SHORTCUT("spatial_editor/lock_transform_y", p_event)) { + new_plane = TRANSFORM_Y_AXIS; + new_message = TTR("Y-Axis Transform."); + } else if (ED_IS_SHORTCUT("spatial_editor/lock_transform_z", p_event)) { + new_plane = TRANSFORM_Z_AXIS; + new_message = TTR("Z-Axis Transform."); + } else if (_edit.mode != TRANSFORM_ROTATE) { // rotating on a plane doesn't make sense + if (ED_IS_SHORTCUT("spatial_editor/lock_transform_yz", p_event)) { + new_plane = TRANSFORM_YZ; + new_message = TTR("YZ-Plane Transform."); + } else if (ED_IS_SHORTCUT("spatial_editor/lock_transform_xz", p_event)) { + new_plane = TRANSFORM_XZ; + new_message = TTR("XZ-Plane Transform."); + } else if (ED_IS_SHORTCUT("spatial_editor/lock_transform_xy", p_event)) { + new_plane = TRANSFORM_XY; + new_message = TTR("XY-Plane Transform."); + } + } + + if (new_plane != TRANSFORM_VIEW) { + if (new_plane != _edit.plane) { + // lock me once and get a global constraint + _edit.plane = new_plane; + spatial_editor->set_local_coords_enabled(false); + } else if (!spatial_editor->are_local_coords_enabled()) { + // lock me twice and get a local constraint + spatial_editor->set_local_coords_enabled(true); + } else { + // lock me thrice and we're back where we started + _edit.plane = TRANSFORM_VIEW; + spatial_editor->set_local_coords_enabled(false); + } + update_transform(_edit.mouse_pos, Input::get_singleton()->is_key_pressed(Key::SHIFT)); + set_message(new_message, 2); + accept_event(); + return; + } + } if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) { if (_edit.mode != TRANSFORM_NONE) { _edit.snap = !_edit.snap; @@ -2315,6 +2019,18 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { set_message(TTR("Animation Key Inserted.")); } + if (ED_IS_SHORTCUT("spatial_editor/cancel_transform", p_event) && _edit.mode != TRANSFORM_NONE) { + cancel_transform(); + } + if (ED_IS_SHORTCUT("spatial_editor/instant_translate", p_event)) { + begin_transform(TRANSFORM_TRANSLATE, true); + } + if (ED_IS_SHORTCUT("spatial_editor/instant_rotate", p_event)) { + begin_transform(TRANSFORM_ROTATE, true); + } + if (ED_IS_SHORTCUT("spatial_editor/instant_scale", p_event)) { + begin_transform(TRANSFORM_SCALE, true); + } // Freelook doesn't work in orthogonal mode. if (!orthogonal && ED_IS_SHORTCUT("spatial_editor/freelook_toggle", p_event)) { @@ -3036,7 +2752,7 @@ void Node3DEditorViewport::_draw() { font->draw_string(ci, msgpos, message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 1)); } - if (_edit.mode == TRANSFORM_ROTATE) { + if (_edit.mode == TRANSFORM_ROTATE && _edit.show_rotation_line) { Point2 center = _point_to_screen(_edit.center); Color handle_color; @@ -3544,6 +3260,13 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) { RS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_plane_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF); RS::get_singleton()->instance_set_layer_mask(scale_plane_gizmo_instance[i], layer); RS::get_singleton()->instance_geometry_set_flag(scale_plane_gizmo_instance[i], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true); + + axis_gizmo_instance[i] = RS::get_singleton()->instance_create(); + RS::get_singleton()->instance_set_base(axis_gizmo_instance[i], spatial_editor->get_axis_gizmo(i)->get_rid()); + RS::get_singleton()->instance_set_scenario(axis_gizmo_instance[i], get_tree()->get_root()->get_world_3d()->get_scenario()); + RS::get_singleton()->instance_set_visible(axis_gizmo_instance[i], true); + RS::get_singleton()->instance_geometry_set_cast_shadows_setting(axis_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF); + RS::get_singleton()->instance_set_layer_mask(axis_gizmo_instance[i], layer); } // Rotation white outline @@ -3563,6 +3286,7 @@ void Node3DEditorViewport::_finish_gizmo_instances() { RS::get_singleton()->free(rotate_gizmo_instance[i]); RS::get_singleton()->free(scale_gizmo_instance[i]); RS::get_singleton()->free(scale_plane_gizmo_instance[i]); + RS::get_singleton()->free(axis_gizmo_instance[i]); } // Rotation white outline RS::get_singleton()->free(rotate_gizmo_instance[3]); @@ -3655,6 +3379,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], false); RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], false); RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], false); + RenderingServer::get_singleton()->instance_set_visible(axis_gizmo_instance[i], false); } // Rotation white outline RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], false); @@ -3711,7 +3436,15 @@ void Node3DEditorViewport::update_transform_gizmo_view() { RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE)); RenderingServer::get_singleton()->instance_set_transform(scale_plane_gizmo_instance[i], axis_angle); RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE)); + RenderingServer::get_singleton()->instance_set_transform(axis_gizmo_instance[i], xform); } + + bool show_axes = spatial_editor->is_gizmo_visible() && _edit.mode != TRANSFORM_NONE; + RenderingServer *rs = RenderingServer::get_singleton(); + rs->instance_set_visible(axis_gizmo_instance[0], show_axes && (_edit.plane == TRANSFORM_X_AXIS || _edit.plane == TRANSFORM_XY || _edit.plane == TRANSFORM_XZ)); + rs->instance_set_visible(axis_gizmo_instance[1], show_axes && (_edit.plane == TRANSFORM_Y_AXIS || _edit.plane == TRANSFORM_XY || _edit.plane == TRANSFORM_YZ)); + rs->instance_set_visible(axis_gizmo_instance[2], show_axes && (_edit.plane == TRANSFORM_Z_AXIS || _edit.plane == TRANSFORM_XZ || _edit.plane == TRANSFORM_YZ)); + // Rotation white outline xform.orthonormalize(); xform.basis.scale(scale); @@ -3978,7 +3711,7 @@ AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, boo if (child) { AABB child_bounds = _calculate_spatial_bounds(child, false); - if (bounds.size == Vector3() && p_parent->get_class_name() == StringName("Node3D")) { + if (bounds.size == Vector3() && Object::cast_to<Node3D>(p_parent)) { bounds = child_bounds; } else { bounds.merge_with(child_bounds); @@ -3986,7 +3719,7 @@ AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, boo } } - if (bounds.size == Vector3() && p_parent->get_class_name() != StringName("Node3D")) { + if (bounds.size == Vector3() && !Object::cast_to<Node3D>(p_parent)) { bounds = AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4)); } @@ -4213,25 +3946,19 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant ResourceLoader::get_recognized_extensions_for_type("Mesh", &mesh_extensions); for (int i = 0; i < files.size(); i++) { + // Check if dragged files with mesh or scene extension can be created at least once. if (mesh_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) { RES res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; } - - String type = res->get_class(); - if (type == "PackedScene") { - Ref<PackedScene> sdata = ResourceLoader::load(files[i]); - Node *instantiated_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); + Ref<PackedScene> scn = res; + if (scn.is_valid()) { + Node *instantiated_scene = scn->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); if (!instantiated_scene) { continue; } memdelete(instantiated_scene); - } else if (ClassDB::is_parent_class(type, "Mesh")) { - Ref<Mesh> mesh = ResourceLoader::load(files[i]); - if (!mesh.is_valid()) { - continue; - } } else { continue; } @@ -4299,6 +4026,387 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_ _perform_drop_data(); } +void Node3DEditorViewport::begin_transform(TransformMode p_mode, bool instant) { + if (get_selected_count() > 0) { + _edit.mode = p_mode; + _compute_edit(_edit.mouse_pos); + _edit.instant = instant; + _edit.snap = spatial_editor->is_snap_enabled(); + } +} + +void Node3DEditorViewport::commit_transform() { + ERR_FAIL_COND(_edit.mode == TRANSFORM_NONE); + static const char *_transform_name[4] = { + TTRC("None"), + TTRC("Rotate"), + // TRANSLATORS: This refers to the movement that changes the position of an object. + TTRC("Translate"), + TTRC("Scale"), + }; + undo_redo->create_action(_transform_name[_edit.mode]); + + List<Node *> &selection = editor_selection->get_selected_node_list(); + + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + Node3D *sp = Object::cast_to<Node3D>(E->get()); + if (!sp) { + continue; + } + + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); + if (!se) { + continue; + } + + undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); + undo_redo->add_undo_method(sp, "set_global_transform", se->original); + } + undo_redo->commit_action(); + _edit.mode = TRANSFORM_NONE; + _edit.instant = false; + spatial_editor->set_local_coords_enabled(_edit.original_local); + set_message(""); + spatial_editor->update_transform_gizmo(); + surface->update(); +} + +void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) { + Vector3 ray_pos = _get_ray_pos(p_mousepos); + Vector3 ray = _get_ray(p_mousepos); + double snap = EDITOR_GET("interface/inspector/default_float_step"); + int snap_step_decimals = Math::range_step_decimals(snap); + + switch (_edit.mode) { + case TRANSFORM_SCALE: { + Vector3 motion_mask; + Plane plane; + bool plane_mv = false; + + switch (_edit.plane) { + case TRANSFORM_VIEW: + motion_mask = Vector3(0, 0, 0); + plane = Plane(_get_camera_normal(), _edit.center); + break; + case TRANSFORM_X_AXIS: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(); + plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); + break; + case TRANSFORM_Y_AXIS: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(); + plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); + break; + case TRANSFORM_Z_AXIS: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(); + plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); + break; + case TRANSFORM_YZ: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(); + plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center); + plane_mv = true; + break; + case TRANSFORM_XZ: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(); + plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center); + plane_mv = true; + break; + case TRANSFORM_XY: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(); + plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center); + plane_mv = true; + break; + } + + Vector3 intersection; + if (!plane.intersects_ray(ray_pos, ray, &intersection)) { + break; + } + + Vector3 click; + if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) { + break; + } + + Vector3 motion = intersection - click; + if (_edit.plane != TRANSFORM_VIEW) { + if (!plane_mv) { + motion = motion_mask.dot(motion) * motion_mask; + + } else { + // Alternative planar scaling mode + if (p_shift) { + motion = motion_mask.dot(motion) * motion_mask; + } + } + + } else { + const real_t center_click_dist = click.distance_to(_edit.center); + const real_t center_inters_dist = intersection.distance_to(_edit.center); + if (center_click_dist == 0) { + break; + } + + const real_t scale = center_inters_dist - center_click_dist; + motion = Vector3(scale, scale, scale); + } + + motion /= click.distance_to(_edit.center); + + // Disable local transformation for TRANSFORM_VIEW + bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); + + if (_edit.snap || spatial_editor->is_snap_enabled()) { + snap = spatial_editor->get_scale_snap() / 100; + } + Vector3 motion_snapped = motion; + motion_snapped.snap(Vector3(snap, snap, snap)); + // This might not be necessary anymore after issue #288 is solved (in 4.0?). + set_message(TTR("Scaling: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " + + String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")"); + motion = _edit.original.basis.inverse().xform(motion); + + List<Node *> &selection = editor_selection->get_selected_node_list(); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); + if (!sp) { + continue; + } + + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); + if (!se) { + continue; + } + + if (sp->has_meta("_edit_lock_")) { + continue; + } + + if (se->gizmo.is_valid()) { + for (KeyValue<int, Transform3D> &GE : se->subgizmos) { + Transform3D xform = GE.value; + Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo. + if (!local_coords) { + new_xform = se->original.affine_inverse() * new_xform; + } + se->gizmo->set_subgizmo_transform(GE.key, new_xform); + } + } else { + Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS); + _transform_gizmo_apply(se->sp, new_xform, local_coords); + } + } + + spatial_editor->update_transform_gizmo(); + surface->update(); + + } break; + + case TRANSFORM_TRANSLATE: { + Vector3 motion_mask; + Plane plane; + bool plane_mv = false; + + switch (_edit.plane) { + case TRANSFORM_VIEW: + plane = Plane(_get_camera_normal(), _edit.center); + break; + case TRANSFORM_X_AXIS: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(); + plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); + break; + case TRANSFORM_Y_AXIS: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(); + plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); + break; + case TRANSFORM_Z_AXIS: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(); + plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center); + break; + case TRANSFORM_YZ: + plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center); + plane_mv = true; + break; + case TRANSFORM_XZ: + plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center); + plane_mv = true; + break; + case TRANSFORM_XY: + plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center); + plane_mv = true; + break; + } + + Vector3 intersection; + if (!plane.intersects_ray(ray_pos, ray, &intersection)) { + break; + } + + Vector3 click; + if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) { + break; + } + + Vector3 motion = intersection - click; + if (_edit.plane != TRANSFORM_VIEW) { + if (!plane_mv) { + motion = motion_mask.dot(motion) * motion_mask; + } + } + + // Disable local transformation for TRANSFORM_VIEW + bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); + + if (_edit.snap || spatial_editor->is_snap_enabled()) { + snap = spatial_editor->get_translate_snap(); + } + Vector3 motion_snapped = motion; + motion_snapped.snap(Vector3(snap, snap, snap)); + set_message(TTR("Translating: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " + + String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")"); + motion = spatial_editor->get_gizmo_transform().basis.inverse().xform(motion); + + List<Node *> &selection = editor_selection->get_selected_node_list(); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); + if (!sp) { + continue; + } + + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); + if (!se) { + continue; + } + + if (sp->has_meta("_edit_lock_")) { + continue; + } + + if (se->gizmo.is_valid()) { + for (KeyValue<int, Transform3D> &GE : se->subgizmos) { + Transform3D xform = GE.value; + Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo. + new_xform = se->original.affine_inverse() * new_xform; + se->gizmo->set_subgizmo_transform(GE.key, new_xform); + } + } else { + Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS); + _transform_gizmo_apply(se->sp, new_xform, false); + } + } + + spatial_editor->update_transform_gizmo(); + surface->update(); + + } break; + + case TRANSFORM_ROTATE: { + Plane plane = Plane(_get_camera_normal(), _edit.center); + + Vector3 local_axis; + Vector3 global_axis; + switch (_edit.plane) { + case TRANSFORM_VIEW: + // local_axis unused + global_axis = _get_camera_normal(); + break; + case TRANSFORM_X_AXIS: + local_axis = Vector3(1, 0, 0); + break; + case TRANSFORM_Y_AXIS: + local_axis = Vector3(0, 1, 0); + break; + case TRANSFORM_Z_AXIS: + local_axis = Vector3(0, 0, 1); + break; + case TRANSFORM_YZ: + case TRANSFORM_XZ: + case TRANSFORM_XY: + break; + } + + if (_edit.plane != TRANSFORM_VIEW) { + global_axis = spatial_editor->get_gizmo_transform().basis.xform(local_axis).normalized(); + } + + Vector3 intersection; + if (!plane.intersects_ray(ray_pos, ray, &intersection)) { + break; + } + + Vector3 click; + if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) { + break; + } + + static const float orthogonal_threshold = Math::cos(Math::deg2rad(87.0f)); + bool axis_is_orthogonal = ABS(plane.normal.dot(global_axis)) < orthogonal_threshold; + + double angle = 0.0f; + if (axis_is_orthogonal) { + _edit.show_rotation_line = false; + Vector3 projection_axis = plane.normal.cross(global_axis); + Vector3 delta = intersection - click; + float projection = delta.dot(projection_axis); + angle = (projection * (Math_PI / 2.0f)) / (gizmo_scale * GIZMO_CIRCLE_SIZE); + } else { + _edit.show_rotation_line = true; + Vector3 click_axis = (click - _edit.center).normalized(); + Vector3 current_axis = (intersection - _edit.center).normalized(); + angle = click_axis.signed_angle_to(current_axis, global_axis); + } + + if (_edit.snap || spatial_editor->is_snap_enabled()) { + snap = spatial_editor->get_rotate_snap(); + } + angle = Math::rad2deg(angle) + snap * 0.5; //else it won't reach +180 + angle -= Math::fmod(angle, snap); + set_message(vformat(TTR("Rotating %s degrees."), String::num(angle, snap_step_decimals))); + angle = Math::deg2rad(angle); + + bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW + + List<Node *> &selection = editor_selection->get_selected_node_list(); + for (Node *E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E); + if (!sp) { + continue; + } + + Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp); + if (!se) { + continue; + } + + if (sp->has_meta("_edit_lock_")) { + continue; + } + + Vector3 compute_axis = local_coords ? local_axis : global_axis; + if (se->gizmo.is_valid()) { + for (KeyValue<int, Transform3D> &GE : se->subgizmos) { + Transform3D xform = GE.value; + + Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original * xform, xform, compute_axis, angle, local_coords, true); // Force orthogonal with subgizmo. + if (!local_coords) { + new_xform = se->original.affine_inverse() * new_xform; + } + se->gizmo->set_subgizmo_transform(GE.key, new_xform); + } + } else { + Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original, se->original_local, compute_axis, angle, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS); + _transform_gizmo_apply(se->sp, new_xform, local_coords); + } + } + + spatial_editor->update_transform_gizmo(); + surface->update(); + + } break; + default: { + } + } +} + Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, EditorNode *p_editor, int p_index) { cpu_time_history_index = 0; gpu_time_history_index = 0; @@ -4306,6 +4414,8 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito _edit.mode = TRANSFORM_NONE; _edit.plane = TRANSFORM_VIEW; _edit.snap = true; + _edit.show_rotation_line = true; + _edit.instant = false; _edit.gizmo_handle = -1; _edit.gizmo_handle_secondary = false; @@ -4383,7 +4493,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito display_submenu->add_radio_check_item(TTR("Normal Buffer"), VIEW_DISPLAY_NORMAL_BUFFER); display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("Shadow Atlas"), VIEW_DISPLAY_DEBUG_SHADOW_ATLAS); - display_submenu->add_radio_check_item(TTR("Directional Shadow"), VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS); + display_submenu->add_radio_check_item(TTR("Directional Shadow Map"), VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS); display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("Decal Atlas"), VIEW_DISPLAY_DEBUG_DECAL_ATLAS); display_submenu->add_separator(); @@ -4399,14 +4509,14 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito display_submenu->add_radio_check_item(TTR("SSAO"), VIEW_DISPLAY_DEBUG_SSAO); display_submenu->add_radio_check_item(TTR("SSIL"), VIEW_DISPLAY_DEBUG_SSIL); display_submenu->add_separator(); - display_submenu->add_radio_check_item(TTR("GI Buffer"), VIEW_DISPLAY_DEBUG_GI_BUFFER); + display_submenu->add_radio_check_item(TTR("VoxelGI/SDFGI Buffer"), VIEW_DISPLAY_DEBUG_GI_BUFFER); display_submenu->add_separator(); - display_submenu->add_radio_check_item(TTR("Disable LOD"), VIEW_DISPLAY_DEBUG_DISABLE_LOD); + display_submenu->add_radio_check_item(TTR("Disable Mesh LOD"), VIEW_DISPLAY_DEBUG_DISABLE_LOD); display_submenu->add_separator(); - display_submenu->add_radio_check_item(TTR("Omni Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS); - display_submenu->add_radio_check_item(TTR("Spot Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS); + display_submenu->add_radio_check_item(TTR("OmniLight3D Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS); + display_submenu->add_radio_check_item(TTR("SpotLight3D Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS); display_submenu->add_radio_check_item(TTR("Decal Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_DECALS); - display_submenu->add_radio_check_item(TTR("Reflection Probe Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES); + display_submenu->add_radio_check_item(TTR("ReflectionProbe Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES); display_submenu->add_radio_check_item(TTR("Occlusion Culling Buffer"), VIEW_DISPLAY_DEBUG_OCCLUDERS); display_submenu->set_name("display_advanced"); @@ -4465,6 +4575,16 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), Key::Q); ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), Key::SHIFT); ED_SHORTCUT("spatial_editor/freelook_slow_modifier", TTR("Freelook Slow Modifier"), Key::ALT); + ED_SHORTCUT("spatial_editor/lock_transform_x", TTR("Lock Transformation to X axis"), Key::X); + ED_SHORTCUT("spatial_editor/lock_transform_y", TTR("Lock Transformation to Y axis"), Key::Y); + ED_SHORTCUT("spatial_editor/lock_transform_z", TTR("Lock Transformation to Z axis"), Key::Z); + ED_SHORTCUT("spatial_editor/lock_transform_yz", TTR("Lock Transformation to YZ plane"), KeyModifierMask::SHIFT | Key::X); + ED_SHORTCUT("spatial_editor/lock_transform_xz", TTR("Lock Transformation to XZ plane"), KeyModifierMask::SHIFT | Key::Y); + ED_SHORTCUT("spatial_editor/lock_transform_xy", TTR("Lock Transformation to XY plane"), KeyModifierMask::SHIFT | Key::Z); + ED_SHORTCUT("spatial_editor/cancel_transform", TTR("Cancel Transformation"), Key::ESCAPE); + ED_SHORTCUT("spatial_editor/instant_translate", TTR("Begin Translate Transformation")); + ED_SHORTCUT("spatial_editor/instant_rotate", TTR("Begin Rotate Transformation")); + ED_SHORTCUT("spatial_editor/instant_scale", TTR("Begin Scale Transformation")); preview_camera = memnew(CheckBox); preview_camera->set_text(TTR("Preview")); @@ -5854,6 +5974,7 @@ void fragment() { rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); scale_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); scale_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); + axis_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); @@ -6175,6 +6296,21 @@ void fragment() { plane_mat_hl->set_albedo(col.from_hsv(col.get_h(), 0.25, 1.0, 1)); plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides } + + // Lines to visualize transforms locked to an axis/plane + { + Ref<SurfaceTool> surftool = memnew(SurfaceTool); + surftool->begin(Mesh::PRIMITIVE_LINES); + + Vector3 vec; + vec[i] = 1; + + // line extending through infinity(ish) + surftool->add_vertex(vec * -99999); + surftool->add_vertex(vec * 99999); + surftool->set_material(mat_hl); + surftool->commit(axis_gizmo[i]); + } } } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 20a782c8a8..bbe5615570 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -247,6 +247,7 @@ private: Point2 _point_to_screen(const Vector3 &p_point); Transform3D _get_camera_transform() const; int get_selected_count() const; + void cancel_transform(); Vector3 _get_camera_position() const; Vector3 _get_camera_normal() const; @@ -310,10 +311,13 @@ private: Point2 mouse_pos; Point2 original_mouse_pos; bool snap = false; + bool show_rotation_line = false; Ref<EditorNode3DGizmo> gizmo; int gizmo_handle = 0; bool gizmo_handle_secondary = false; Variant gizmo_initial_value; + bool original_local; + bool instant; } _edit; struct Cursor { @@ -347,7 +351,7 @@ private: real_t zoom_indicator_delay; int zoom_failed_attempts_count = 0; - RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[4], scale_gizmo_instance[3], scale_plane_gizmo_instance[3]; + RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[4], scale_gizmo_instance[3], scale_plane_gizmo_instance[3], axis_gizmo_instance[3]; String last_message; String message; @@ -402,6 +406,10 @@ private: Transform3D _compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local, bool p_orthogonal); + void begin_transform(TransformMode p_mode, bool instant); + void commit_transform(); + void update_transform(Point2 p_mousepos, bool p_shift); + protected: void _notification(int p_what); static void _bind_methods(); @@ -546,7 +554,7 @@ private: Camera3D::Projection grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; Vector3 grid_camera_last_update_position = Vector3(); - Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3]; + Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3], axis_gizmo[3]; Ref<StandardMaterial3D> gizmo_color[3]; Ref<StandardMaterial3D> plane_gizmo_color[3]; Ref<ShaderMaterial> rotate_gizmo_color[3]; @@ -773,12 +781,14 @@ public: ToolMode get_tool_mode() const { return tool_mode; } bool are_local_coords_enabled() const { return tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); } + void set_local_coords_enabled(bool on) const { tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->set_pressed(on); } bool is_snap_enabled() const { return snap_enabled ^ snap_key_enabled; } double get_translate_snap() const; double get_rotate_snap() const; double get_scale_snap() const; Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; } + Ref<ArrayMesh> get_axis_gizmo(int idx) const { return axis_gizmo[idx]; } Ref<ArrayMesh> get_move_plane_gizmo(int idx) const { return move_plane_gizmo[idx]; } Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; } Ref<ArrayMesh> get_scale_gizmo(int idx) const { return scale_gizmo[idx]; } diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.cpp b/editor/plugins/occluder_instance_3d_editor_plugin.cpp index 2dd760275e..e7fe8da716 100644 --- a/editor/plugins/occluder_instance_3d_editor_plugin.cpp +++ b/editor/plugins/occluder_instance_3d_editor_plugin.cpp @@ -34,9 +34,9 @@ void OccluderInstance3DEditorPlugin::_bake_select_file(const String &p_file) { if (occluder_instance) { OccluderInstance3D::BakeError err; if (get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root() == occluder_instance) { - err = occluder_instance->bake(occluder_instance, p_file); + err = occluder_instance->bake_scene(occluder_instance, p_file); } else { - err = occluder_instance->bake(occluder_instance->get_parent(), p_file); + err = occluder_instance->bake_scene(occluder_instance->get_parent(), p_file); } switch (err) { @@ -59,6 +59,10 @@ void OccluderInstance3DEditorPlugin::_bake_select_file(const String &p_file) { EditorNode::get_singleton()->show_warning(TTR("No meshes to bake.\nMake sure there is at least one MeshInstance3D node in the scene whose visual layers are part of the OccluderInstance3D's Bake Mask property.")); break; } + case OccluderInstance3D::BAKE_ERROR_CANT_SAVE: { + EditorNode::get_singleton()->show_warning(TTR("Could not save the new occluder at the specified path: ") + p_file); + break; + } default: { } } diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp index b492c27f41..9a8584f4a2 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.cpp +++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp @@ -132,10 +132,7 @@ PackedSceneEditorTranslationParserPlugin::PackedSceneEditorTranslationParserPlug lookup_properties.insert("script"); // Exception list (to prevent false positives). - exception_list.insert("LineEdit", Vector<StringName>()); - exception_list["LineEdit"].append("text"); - exception_list.insert("TextEdit", Vector<StringName>()); - exception_list["TextEdit"].append("text"); - exception_list.insert("CodeEdit", Vector<StringName>()); - exception_list["CodeEdit"].append("text"); + exception_list.insert("LineEdit", { "text" }); + exception_list.insert("TextEdit", { "text" }); + exception_list.insert("CodeEdit", { "text" }); } diff --git a/editor/plugins/packed_scene_translation_parser_plugin.h b/editor/plugins/packed_scene_translation_parser_plugin.h index fc19496eb6..ecd090b31b 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.h +++ b/editor/plugins/packed_scene_translation_parser_plugin.h @@ -37,9 +37,9 @@ class PackedSceneEditorTranslationParserPlugin : public EditorTranslationParserP GDCLASS(PackedSceneEditorTranslationParserPlugin, EditorTranslationParserPlugin); // Scene Node's properties that contain translation strings. - Set<StringName> lookup_properties; + Set<String> lookup_properties; // Properties from specific Nodes that should be ignored. - Map<StringName, Vector<StringName>> exception_list; + Map<String, Vector<String>> exception_list; public: virtual Error parse_file(const String &p_path, Vector<String> *r_ids, Vector<Vector<String>> *r_ids_ctx_plural) override; diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp index 52651ae380..4014da2441 100644 --- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp +++ b/editor/plugins/polygon_3d_editor_plugin.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_polygon_3d_editor_plugin.cpp */ +/* polygon_3d_editor_plugin.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,9 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "collision_polygon_3d_editor_plugin.h" +#include "polygon_3d_editor_plugin.h" #include "canvas_item_editor_plugin.h" +#include "core/core_string_names.h" #include "core/input/input.h" #include "core/io/file_access.h" #include "core/math/geometry_2d.h" @@ -39,13 +40,13 @@ #include "node_3d_editor_plugin.h" #include "scene/3d/camera_3d.h" -void CollisionPolygon3DEditor::_notification(int p_what) { +void Polygon3DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { button_create->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); button_edit->set_icon(get_theme_icon(SNAME("MovePoint"), SNAME("EditorIcons"))); button_edit->set_pressed(true); - get_tree()->connect("node_removed", callable_mp(this, &CollisionPolygon3DEditor::_node_removed)); + get_tree()->connect("node_removed", callable_mp(this, &Polygon3DEditor::_node_removed)); } break; case NOTIFICATION_PROCESS: { @@ -62,7 +63,7 @@ void CollisionPolygon3DEditor::_notification(int p_what) { } } -void CollisionPolygon3DEditor::_node_removed(Node *p_node) { +void Polygon3DEditor::_node_removed(Node *p_node) { if (p_node == node) { node = nullptr; if (imgeom->get_parent() == p_node) { @@ -73,7 +74,7 @@ void CollisionPolygon3DEditor::_node_removed(Node *p_node) { } } -void CollisionPolygon3DEditor::_menu_option(int p_option) { +void Polygon3DEditor::_menu_option(int p_option) { switch (p_option) { case MODE_CREATE: { mode = MODE_CREATE; @@ -88,10 +89,12 @@ void CollisionPolygon3DEditor::_menu_option(int p_option) { } } -void CollisionPolygon3DEditor::_wip_close() { +void Polygon3DEditor::_wip_close() { + Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node; + ERR_FAIL_COND_MSG(!obj, "Edited object is not valid."); undo_redo->create_action(TTR("Create Polygon3D")); - undo_redo->add_undo_method(node, "set_polygon", node->call("get_polygon")); - undo_redo->add_do_method(node, "set_polygon", wip); + undo_redo->add_undo_method(obj, "set_polygon", obj->call("get_polygon")); + undo_redo->add_do_method(obj, "set_polygon", wip); undo_redo->add_do_method(this, "_polygon_draw"); undo_redo->add_undo_method(this, "_polygon_draw"); wip.clear(); @@ -103,11 +106,12 @@ void CollisionPolygon3DEditor::_wip_close() { undo_redo->commit_action(); } -EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { +EditorPlugin::AfterGUIInput Polygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { if (!node) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } + Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node; Transform3D gt = node->get_global_transform(); Transform3D gi = gt.affine_inverse(); float depth = _get_depth() * 0.5; @@ -135,7 +139,7 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input( //Let the snap happen when the point is being moved, instead. //cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint); - Vector<Vector2> poly = node->call("get_polygon"); + PackedVector2Array poly = _get_polygon(); //first check if a point is to be added (segment split) real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius"); @@ -178,9 +182,9 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input( if (mb->is_ctrl_pressed()) { if (poly.size() < 3) { undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_undo_method(node, "set_polygon", poly); + undo_redo->add_undo_method(obj, "set_polygon", poly); poly.push_back(cpoint); - undo_redo->add_do_method(node, "set_polygon", poly); + undo_redo->add_do_method(obj, "set_polygon", poly); undo_redo->add_do_method(this, "_polygon_draw"); undo_redo->add_undo_method(this, "_polygon_draw"); undo_redo->commit_action(); @@ -215,7 +219,7 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input( poly.insert(closest_idx + 1, cpoint); edited_point = closest_idx + 1; edited_point_pos = cpoint; - node->call("set_polygon", poly); + _set_polygon(poly); _polygon_draw(); snap_ignore = true; @@ -256,8 +260,8 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input( ERR_FAIL_INDEX_V(edited_point, poly.size(), EditorPlugin::AFTER_GUI_INPUT_PASS); poly.write[edited_point] = edited_point_pos; undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_do_method(node, "set_polygon", poly); - undo_redo->add_undo_method(node, "set_polygon", pre_move_edit); + undo_redo->add_do_method(obj, "set_polygon", poly); + undo_redo->add_undo_method(obj, "set_polygon", pre_move_edit); undo_redo->add_do_method(this, "_polygon_draw"); undo_redo->add_undo_method(this, "_polygon_draw"); undo_redo->commit_action(); @@ -284,9 +288,9 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input( if (closest_idx >= 0) { undo_redo->create_action(TTR("Edit Poly (Remove Point)")); - undo_redo->add_undo_method(node, "set_polygon", poly); + undo_redo->add_undo_method(obj, "set_polygon", poly); poly.remove_at(closest_idx); - undo_redo->add_do_method(node, "set_polygon", poly); + undo_redo->add_do_method(obj, "set_polygon", poly); undo_redo->add_do_method(this, "_polygon_draw"); undo_redo->add_undo_method(this, "_polygon_draw"); undo_redo->commit_action(); @@ -335,25 +339,40 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input( return EditorPlugin::AFTER_GUI_INPUT_PASS; } -float CollisionPolygon3DEditor::_get_depth() { - if (bool(node->call("_has_editable_3d_polygon_no_depth"))) { - return 0; +float Polygon3DEditor::_get_depth() { + Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node; + ERR_FAIL_COND_V_MSG(!obj, 0.0f, "Edited object is not valid."); + + if (bool(obj->call("_has_editable_3d_polygon_no_depth"))) { + return 0.0f; } - return float(node->call("get_depth")); + return float(obj->call("get_depth")); +} + +PackedVector2Array Polygon3DEditor::_get_polygon() { + Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node; + ERR_FAIL_COND_V_MSG(!obj, PackedVector2Array(), "Edited object is not valid."); + return PackedVector2Array(obj->call("get_polygon")); +} + +void Polygon3DEditor::_set_polygon(PackedVector2Array p_poly) { + Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node; + ERR_FAIL_COND_MSG(!obj, "Edited object is not valid."); + obj->call("set_polygon", p_poly); } -void CollisionPolygon3DEditor::_polygon_draw() { +void Polygon3DEditor::_polygon_draw() { if (!node) { return; } - Vector<Vector2> poly; + PackedVector2Array poly; if (wip_active) { poly = wip; } else { - poly = node->call("get_polygon"); + poly = _get_polygon(); } float depth = _get_depth() * 0.5; @@ -464,23 +483,32 @@ void CollisionPolygon3DEditor::_polygon_draw() { m->surface_set_material(0, handle_material); } -void CollisionPolygon3DEditor::edit(Node *p_collision_polygon) { - if (p_collision_polygon) { - node = Object::cast_to<Node3D>(p_collision_polygon); +void Polygon3DEditor::edit(Node *p_node) { + if (p_node) { + node = Object::cast_to<Node3D>(p_node); + node_resource = node->call("_get_editable_3d_polygon_resource"); + + if (node_resource.is_valid()) { + node_resource->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Polygon3DEditor::_polygon_draw)); + } //Enable the pencil tool if the polygon is empty - if (Vector<Vector2>(node->call("get_polygon")).size() == 0) { + if (_get_polygon().is_empty()) { _menu_option(MODE_CREATE); } wip.clear(); wip_active = false; edited_point = -1; - p_collision_polygon->add_child(imgeom); + p_node->add_child(imgeom); _polygon_draw(); set_process(true); prev_depth = -1; } else { node = nullptr; + if (node_resource.is_valid()) { + node_resource->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Polygon3DEditor::_polygon_draw)); + } + node_resource.unref(); if (imgeom->get_parent()) { imgeom->get_parent()->remove_child(imgeom); @@ -490,11 +518,11 @@ void CollisionPolygon3DEditor::edit(Node *p_collision_polygon) { } } -void CollisionPolygon3DEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_polygon_draw"), &CollisionPolygon3DEditor::_polygon_draw); +void Polygon3DEditor::_bind_methods() { + ClassDB::bind_method(D_METHOD("_polygon_draw"), &Polygon3DEditor::_polygon_draw); } -CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) { +Polygon3DEditor::Polygon3DEditor(EditorNode *p_editor) { node = nullptr; editor = p_editor; undo_redo = EditorNode::get_undo_redo(); @@ -503,13 +531,13 @@ CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) { button_create = memnew(Button); button_create->set_flat(true); add_child(button_create); - button_create->connect("pressed", callable_mp(this, &CollisionPolygon3DEditor::_menu_option), varray(MODE_CREATE)); + button_create->connect("pressed", callable_mp(this, &Polygon3DEditor::_menu_option), varray(MODE_CREATE)); button_create->set_toggle_mode(true); button_edit = memnew(Button); button_edit->set_flat(true); add_child(button_edit); - button_edit->connect("pressed", callable_mp(this, &CollisionPolygon3DEditor::_menu_option), varray(MODE_EDIT)); + button_edit->connect("pressed", callable_mp(this, &Polygon3DEditor::_menu_option), varray(MODE_EDIT)); button_edit->set_toggle_mode(true); mode = MODE_EDIT; @@ -545,12 +573,12 @@ CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) { snap_ignore = false; } -CollisionPolygon3DEditor::~CollisionPolygon3DEditor() { +Polygon3DEditor::~Polygon3DEditor() { memdelete(imgeom); } void Polygon3DEditorPlugin::edit(Object *p_object) { - collision_polygon_editor->edit(Object::cast_to<Node>(p_object)); + polygon_editor->edit(Object::cast_to<Node>(p_object)); } bool Polygon3DEditorPlugin::handles(Object *p_object) const { @@ -559,19 +587,19 @@ bool Polygon3DEditorPlugin::handles(Object *p_object) const { void Polygon3DEditorPlugin::make_visible(bool p_visible) { if (p_visible) { - collision_polygon_editor->show(); + polygon_editor->show(); } else { - collision_polygon_editor->hide(); - collision_polygon_editor->edit(nullptr); + polygon_editor->hide(); + polygon_editor->edit(nullptr); } } Polygon3DEditorPlugin::Polygon3DEditorPlugin(EditorNode *p_node) { editor = p_node; - collision_polygon_editor = memnew(CollisionPolygon3DEditor(p_node)); - Node3DEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); + polygon_editor = memnew(Polygon3DEditor(p_node)); + Node3DEditor::get_singleton()->add_control_to_menu_panel(polygon_editor); - collision_polygon_editor->hide(); + polygon_editor->hide(); } Polygon3DEditorPlugin::~Polygon3DEditorPlugin() { diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.h b/editor/plugins/polygon_3d_editor_plugin.h index cd8c857398..6b0370541e 100644 --- a/editor/plugins/collision_polygon_3d_editor_plugin.h +++ b/editor/plugins/polygon_3d_editor_plugin.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* collision_polygon_3d_editor_plugin.h */ +/* polygon_3d_editor_plugin.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COLLISION_POLYGON_EDITOR_PLUGIN_H -#define COLLISION_POLYGON_EDITOR_PLUGIN_H +#ifndef POLYGON_3D_EDITOR_PLUGIN_H +#define POLYGON_3D_EDITOR_PLUGIN_H #include "editor/editor_node.h" #include "editor/editor_plugin.h" @@ -39,8 +39,8 @@ class CanvasItemEditor; -class CollisionPolygon3DEditor : public HBoxContainer { - GDCLASS(CollisionPolygon3DEditor, HBoxContainer); +class Polygon3DEditor : public HBoxContainer { + GDCLASS(Polygon3DEditor, HBoxContainer); UndoRedo *undo_redo; enum Mode { @@ -60,6 +60,7 @@ class CollisionPolygon3DEditor : public HBoxContainer { EditorNode *editor; Panel *panel; Node3D *node; + Ref<Resource> node_resource; Ref<ImmediateMesh> imesh; MeshInstance3D *imgeom; MeshInstance3D *pointsm; @@ -69,8 +70,8 @@ class CollisionPolygon3DEditor : public HBoxContainer { int edited_point; Vector2 edited_point_pos; - Vector<Vector2> pre_move_edit; - Vector<Vector2> wip; + PackedVector2Array pre_move_edit; + PackedVector2Array wip; bool wip_active; bool snap_ignore; @@ -81,6 +82,8 @@ class CollisionPolygon3DEditor : public HBoxContainer { void _menu_option(int p_option); float _get_depth(); + PackedVector2Array _get_polygon(); + void _set_polygon(PackedVector2Array p_poly); protected: void _notification(int p_what); @@ -89,19 +92,19 @@ protected: public: virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event); - void edit(Node *p_collision_polygon); - CollisionPolygon3DEditor(EditorNode *p_editor); - ~CollisionPolygon3DEditor(); + void edit(Node *p_node); + Polygon3DEditor(EditorNode *p_editor); + ~Polygon3DEditor(); }; class Polygon3DEditorPlugin : public EditorPlugin { GDCLASS(Polygon3DEditorPlugin, EditorPlugin); - CollisionPolygon3DEditor *collision_polygon_editor; + Polygon3DEditor *polygon_editor; EditorNode *editor; public: - virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return collision_polygon_editor->forward_spatial_gui_input(p_camera, p_event); } + virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return polygon_editor->forward_spatial_gui_input(p_camera, p_event); } virtual String get_name() const override { return "Polygon3DEditor"; } bool has_main_screen() const override { return false; } @@ -113,4 +116,4 @@ public: ~Polygon3DEditorPlugin(); }; -#endif // COLLISION_POLYGON_EDITOR_PLUGIN_H +#endif // POLYGON_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/replication_editor_plugin.cpp b/editor/plugins/replication_editor_plugin.cpp index 93f4a853f3..fd4fc8f59c 100644 --- a/editor/plugins/replication_editor_plugin.cpp +++ b/editor/plugins/replication_editor_plugin.cpp @@ -258,7 +258,7 @@ void ReplicationEditor::edit(MultiplayerSynchronizer *p_sync) { Ref<Texture2D> ReplicationEditor::_get_class_icon(const Node *p_node) { if (!p_node || !has_theme_icon(p_node->get_class(), "EditorIcons")) { - return get_theme_icon("ImportFail", "EditorIcons"); + return get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons")); } return get_theme_icon(p_node->get_class(), "EditorIcons"); } @@ -285,7 +285,7 @@ void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn, icon = _get_class_icon(node); } item->set_icon(0, icon); - item->add_button(3, get_theme_icon("Remove", "EditorIcons")); + item->add_button(3, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); item->set_text_alignment(1, HORIZONTAL_ALIGNMENT_CENTER); item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK); item->set_checked(1, p_spawn); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 26227fa5bb..17de3ba026 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -2265,7 +2265,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra if (use_external_editor && (EditorDebuggerNode::get_singleton()->get_dump_stack_script() != p_resource || EditorDebuggerNode::get_singleton()->get_debug_with_external_editor()) && p_resource->get_path().is_resource_file() && - p_resource->get_class_name() != StringName("VisualScript")) { + !Ref<VisualScript>(p_resource).is_valid()) { String path = EditorSettings::get_singleton()->get("text_editor/external/exec_path"); String flags = EditorSettings::get_singleton()->get("text_editor/external/exec_flags"); @@ -2364,7 +2364,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra se->set_edited_resource(p_resource); - if (p_resource->get_class_name() != StringName("VisualScript")) { + if (!Ref<VisualScript>(p_resource).is_valid()) { bool highlighter_set = false; for (int i = 0; i < syntax_highlighters.size(); i++) { Ref<EditorSyntaxHighlighter> highlighter = syntax_highlighters[i]->_create(); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 7b4ebbc6d8..c3d61dfd58 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -930,21 +930,22 @@ void ScriptTextEditor::_update_connected_methods() { continue; } - if (methods_found.has(connection.callable.get_method())) { + const StringName method = connection.callable.get_method(); + if (methods_found.has(method)) { continue; } - if (!ClassDB::has_method(script->get_instance_base_type(), connection.callable.get_method())) { + if (!ClassDB::has_method(script->get_instance_base_type(), method)) { int line = -1; for (int j = 0; j < functions.size(); j++) { String name = functions[j].get_slice(":", 0); - if (name == connection.callable.get_method()) { + if (name == method) { line = functions[j].get_slice(":", 1).to_int() - 1; - text_edit->set_line_gutter_metadata(line, connection_gutter, connection.callable.get_method()); + text_edit->set_line_gutter_metadata(line, connection_gutter, method); text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("Slot"), SNAME("EditorIcons"))); text_edit->set_line_gutter_clickable(line, connection_gutter, true); - methods_found.insert(connection.callable.get_method()); + methods_found.insert(method); break; } } @@ -957,7 +958,7 @@ void ScriptTextEditor::_update_connected_methods() { bool found_inherited_function = false; Ref<Script> inherited_script = script->get_base_script(); while (!inherited_script.is_null()) { - if (inherited_script->has_method(connection.callable.get_method())) { + if (inherited_script->has_method(method)) { found_inherited_function = true; break; } @@ -1373,7 +1374,7 @@ void ScriptTextEditor::reload(bool p_soft) { return; } scr->set_source_code(te->get_text()); - bool soft = p_soft || scr->get_instance_base_type() == "EditorPlugin"; //always soft-reload editor plugins + bool soft = p_soft || scr->get_instance_base_type() == "EditorPlugin"; // Always soft-reload editor plugins. scr->get_language()->reload_tool_script(scr, soft); } diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 014fa0e7a5..419076a3f6 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -285,7 +285,7 @@ void SpriteFramesEditor::_sheet_spin_changed(double) { } void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) { - Ref<Resource> texture = ResourceLoader::load(p_file); + Ref<Texture2D> texture = ResourceLoader::load(p_file); if (!texture.is_valid()) { EditorNode::get_singleton()->show_warning(TTR("Unable to load images")); ERR_FAIL_COND(!texture.is_valid()); diff --git a/editor/plugins/text_control_editor_plugin.cpp b/editor/plugins/text_control_editor_plugin.cpp index 87eff9c3e9..4ce94176e5 100644 --- a/editor/plugins/text_control_editor_plugin.cpp +++ b/editor/plugins/text_control_editor_plugin.cpp @@ -110,7 +110,7 @@ void TextControlEditor::_update_styles_menu() { for (Map<String, String>::Element *E = fonts[name].front(); E; E = E->next()) { font_style_list->add_item(E->key()); } - } else { + } else if (font_list->get_selected() >= 0) { font_style_list->add_item("Default"); } @@ -123,9 +123,9 @@ void TextControlEditor::_update_styles_menu() { void TextControlEditor::_update_control() { if (!edited_controls.is_empty()) { - int font_selected = 0; + String font_selected; bool same_font = true; - int style_selected = 0; + String style_selected; bool same_style = true; int font_size = 0; bool same_font_size = true; @@ -136,26 +136,23 @@ void TextControlEditor::_update_control() { Color outline_color = Color{ 1.0f, 1.0f, 1.0f }; bool same_outline_color = true; - _update_fonts_menu(); - _update_styles_menu(); - int count = edited_controls.size(); for (int i = 0; i < count; ++i) { Control *edited_control = edited_controls[i]; - String edited_color; - String edited_font; - String edited_font_size; + StringName edited_color; + StringName edited_font; + StringName edited_font_size; // Get override names. - if (edited_control->is_class("RichTextLabel")) { - edited_color = "default_color"; - edited_font = "normal_font"; - edited_font_size = "normal_font_size"; + if (Object::cast_to<RichTextLabel>(edited_control)) { + edited_color = SNAME("default_color"); + edited_font = SNAME("normal_font"); + edited_font_size = SNAME("normal_font_size"); } else { - edited_color = "font_color"; - edited_font = "font"; - edited_font_size = "font_size"; + edited_color = SNAME("font_color"); + edited_font = SNAME("font"); + edited_font_size = SNAME("font_size"); } // Get font override. @@ -166,63 +163,46 @@ void TextControlEditor::_update_control() { if (font.is_valid()) { if (font->get_data_count() != 1) { - custom_font = font; if (i > 0) { - same_font = same_font && (font_selected == FONT_INFO_USER_CUSTOM); - same_style = same_style && (style_selected == 0); + same_font = same_font && (custom_font == font); } + custom_font = font; - font_selected = FONT_INFO_USER_CUSTOM; - style_selected = 0; + font_selected = TTR("[Custom Font]"); + same_style = false; } else { String name = font->get_data(0)->get_font_name(); String style = font->get_data(0)->get_font_style_name(); if (fonts.has(name) && fonts[name].has(style)) { - for (int j = 0; j < font_list->get_item_count(); j++) { - if (font_list->get_item_text(j) == name) { - if (i > 0) { - same_font = same_font && (j == font_selected); - } - - font_selected = j; - break; - } - } - for (int j = 0; j < font_style_list->get_item_count(); j++) { - if (font_style_list->get_item_text(j) == style) { - if (i > 0) { - same_style = same_style && (j == style_selected); - } - - style_selected = j; - break; - } + if (i > 0) { + same_font = same_font && (name == font_selected); + same_style = same_style && (style == style_selected); } + font_selected = name; + style_selected = style; } else { - custom_font = font; if (i > 0) { - same_font = same_font && (font_selected == FONT_INFO_USER_CUSTOM); - same_style = same_style && (style_selected == 0); + same_font = same_font && (custom_font == font); } + custom_font = font; - font_selected = FONT_INFO_USER_CUSTOM; - style_selected = 0; + font_selected = TTR("[Custom Font]"); + same_style = false; } } } else { if (i > 0) { - same_font = same_font && (font_selected == FONT_INFO_THEME_DEFAULT); - same_style = same_style && (style_selected == 0); + same_font = same_font && (font_selected == TTR("[Theme Default]")); } - font_selected = FONT_INFO_THEME_DEFAULT; - style_selected = 0; + font_selected = TTR("[Theme Default]"); + same_style = false; } int current_font_size = edited_control->get_theme_font_size(edited_font_size); - int current_outline_size = edited_control->get_theme_constant("outline_size"); + int current_outline_size = edited_control->get_theme_constant(SNAME("outline_size")); Color current_font_color = edited_control->get_theme_color(edited_color); - Color current_outline_color = edited_control->get_theme_color("font_outline_color"); + Color current_outline_color = edited_control->get_theme_color(SNAME("font_outline_color")); if (i > 0) { same_font_size = same_font_size && (font_size == current_font_size); same_outline_size = same_outline_size && (outline_size == current_outline_size); @@ -235,19 +215,29 @@ void TextControlEditor::_update_control() { font_color = current_font_color; outline_color = current_outline_color; } - _update_fonts_menu(); if (same_font) { - font_list->select(font_selected); + for (int j = 0; j < font_list->get_item_count(); j++) { + if (font_list->get_item_text(j) == font_selected) { + font_list->select(j); + break; + } + } } else { + custom_font = Ref<Font>(); font_list->select(-1); } _update_styles_menu(); if (same_style) { - font_style_list->select(style_selected); + for (int j = 0; j < font_style_list->get_item_count(); j++) { + if (font_style_list->get_item_text(j) == style_selected) { + font_style_list->select(j); + break; + } + } } else { - font_list->select(-1); + font_style_list->select(-1); } // Get other theme overrides. @@ -282,6 +272,7 @@ void TextControlEditor::_update_control() { } void TextControlEditor::_font_selected(int p_id) { + _update_styles_menu(); _set_font(); } @@ -301,11 +292,11 @@ void TextControlEditor::_set_font() { for (int i = 0; i < count; ++i) { Control *edited_control = edited_controls[i]; - String edited_font; - if (edited_control->is_class("RichTextLabel")) { - edited_font = "normal_font"; + StringName edited_font; + if (Object::cast_to<RichTextLabel>(edited_control)) { + edited_font = SNAME("normal_font"); } else { - edited_font = "font"; + edited_font = SNAME("font"); } if (font_list->get_selected_id() == FONT_INFO_THEME_DEFAULT) { @@ -314,14 +305,13 @@ void TextControlEditor::_set_font() { } else if (font_list->get_selected_id() == FONT_INFO_USER_CUSTOM) { // Restore "custom_font". ur->add_do_method(edited_control, "add_theme_font_override", edited_font, custom_font); - } else { + } else if (font_list->get_selected() >= 0) { // Load new font resource using selected name and style. String name = font_list->get_item_text(font_list->get_selected()); String style = font_style_list->get_item_text(font_style_list->get_selected()); if (style.is_empty()) { style = "Default"; } - if (fonts.has(name)) { Ref<FontData> fd = ResourceLoader::load(fonts[name][style]); if (fd.is_valid()) { @@ -358,11 +348,11 @@ void TextControlEditor::_font_size_selected(double p_size) { for (int i = 0; i < count; ++i) { Control *edited_control = edited_controls[i]; - String edited_font_size; - if (edited_control->is_class("RichTextLabel")) { - edited_font_size = "normal_font_size"; + StringName edited_font_size; + if (Object::cast_to<RichTextLabel>(edited_control)) { + edited_font_size = SNAME("normal_font_size"); } else { - edited_font_size = "font_size"; + edited_font_size = SNAME("font_size"); } ur->add_do_method(edited_control, "add_theme_font_size_override", edited_font_size, p_size); @@ -393,7 +383,7 @@ void TextControlEditor::_outline_size_selected(double p_size) { ur->add_do_method(edited_control, "add_theme_constant_override", "outline_size", p_size); if (edited_control->has_theme_constant_override("outline_size")) { - ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant("outline_size")); + ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant(SNAME("outline_size"))); } else { ur->add_undo_method(edited_control, "remove_theme_constant_override", "outline_size"); } @@ -417,11 +407,11 @@ void TextControlEditor::_font_color_changed(const Color &p_color) { for (int i = 0; i < count; ++i) { Control *edited_control = edited_controls[i]; - String edited_color; - if (edited_control->is_class("RichTextLabel")) { - edited_color = "default_color"; + StringName edited_color; + if (Object::cast_to<RichTextLabel>(edited_control)) { + edited_color = SNAME("default_color"); } else { - edited_color = "font_color"; + edited_color = SNAME("font_color"); } ur->add_do_method(edited_control, "add_theme_color_override", edited_color, p_color); @@ -452,7 +442,7 @@ void TextControlEditor::_outline_color_changed(const Color &p_color) { ur->add_do_method(edited_control, "add_theme_color_override", "font_outline_color", p_color); if (edited_control->has_theme_color_override("font_outline_color")) { - ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color("font_outline_color")); + ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color(SNAME("font_outline_color"))); } else { ur->add_undo_method(edited_control, "remove_theme_color_override", "font_outline_color"); } @@ -476,19 +466,19 @@ void TextControlEditor::_clear_formatting() { for (int i = 0; i < count; ++i) { Control *edited_control = edited_controls[i]; - String edited_color; - String edited_font; - String edited_font_size; + StringName edited_color; + StringName edited_font; + StringName edited_font_size; // Get override names. - if (edited_control->is_class("RichTextLabel")) { - edited_color = "default_color"; - edited_font = "normal_font"; - edited_font_size = "normal_font_size"; + if (Object::cast_to<RichTextLabel>(edited_control)) { + edited_color = SNAME("default_color"); + edited_font = SNAME("normal_font"); + edited_font_size = SNAME("normal_font_size"); } else { - edited_color = "font_color"; - edited_font = "font"; - edited_font_size = "font_size"; + edited_color = SNAME("font_color"); + edited_font = SNAME("font"); + edited_font_size = SNAME("font_size"); } ur->add_do_method(edited_control, "begin_bulk_theme_override"); @@ -511,12 +501,12 @@ void TextControlEditor::_clear_formatting() { ur->add_do_method(edited_control, "remove_theme_color_override", "font_outline_color"); if (edited_control->has_theme_color_override("font_outline_color")) { - ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color("font_outline_color")); + ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color(SNAME("font_outline_color"))); } ur->add_do_method(edited_control, "remove_theme_constant_override", "outline_size"); if (edited_control->has_theme_constant_override("outline_size")) { - ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant("outline_size")); + ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant(SNAME("outline_size"))); } ur->add_do_method(edited_control, "end_bulk_theme_override"); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 9ab53bf5c3..dd19f3d781 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -585,14 +585,14 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Button *add_input_btn = memnew(Button); add_input_btn->set_text(TTR("Add Input")); - add_input_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_input_port), varray(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, input_port_name), CONNECT_DEFERRED); + add_input_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_input_port), varray(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR_3D, input_port_name), CONNECT_DEFERRED); hb2->add_child(add_input_btn); hb2->add_spacer(); Button *add_output_btn = memnew(Button); add_output_btn->set_text(TTR("Add Output")); - add_output_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_output_port), varray(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, output_port_name), CONNECT_DEFERRED); + add_output_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_output_port), varray(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR_3D, output_port_name), CONNECT_DEFERRED); hb2->add_child(add_output_btn); node->add_child(hb2); @@ -606,7 +606,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { case VisualShaderNode::PORT_TYPE_VECTOR_2D: { output_port_count += 2; } break; - case VisualShaderNode::PORT_TYPE_VECTOR: { + case VisualShaderNode::PORT_TYPE_VECTOR_3D: { output_port_count += 3; } break; default: @@ -628,7 +628,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { i -= 2; } } break; - case VisualShaderNode::PORT_TYPE_VECTOR: { + case VisualShaderNode::PORT_TYPE_VECTOR_3D: { if (expanded_port_counter >= 3) { expanded_type = VisualShaderNode::PORT_TYPE_SCALAR; expanded_port_counter = 0; @@ -852,7 +852,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_2D; } break; - case VisualShaderNode::PORT_TYPE_VECTOR: { + case VisualShaderNode::PORT_TYPE_VECTOR_3D: { port_offset++; valid_left = (i + 1) < vsnode->get_input_port_count(); port_left = VisualShaderNode::PORT_TYPE_SCALAR; @@ -877,7 +877,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]); - expanded_type = VisualShaderNode::PORT_TYPE_VECTOR; + expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_3D; } break; default: break; @@ -1432,7 +1432,7 @@ void VisualShaderEditor::_update_options_menu() { case VisualShaderNode::PORT_TYPE_VECTOR_2D: item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons"))); break; - case VisualShaderNode::PORT_TYPE_VECTOR: + case VisualShaderNode::PORT_TYPE_VECTOR_3D: item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons"))); break; case VisualShaderNode::PORT_TYPE_BOOLEAN: @@ -1789,7 +1789,7 @@ void VisualShaderEditor::_expand_output_port(int p_node, int p_port, bool p_expa case VisualShaderNode::PORT_TYPE_VECTOR_2D: { type_size = 2; } break; - case VisualShaderNode::PORT_TYPE_VECTOR: { + case VisualShaderNode::PORT_TYPE_VECTOR_3D: { type_size = 3; } break; default: @@ -2584,7 +2584,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri vsnode = Ref<VisualShaderNode>(vsn); } else { ERR_FAIL_COND(add_options[p_idx].script.is_null()); - String base_type = add_options[p_idx].script->get_instance_base_type(); + StringName base_type = add_options[p_idx].script->get_instance_base_type(); VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instantiate(base_type)); ERR_FAIL_COND(!vsn); vsnode = Ref<VisualShaderNode>(vsn); @@ -2648,7 +2648,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri case VisualShaderNode::PORT_TYPE_VECTOR_2D: initial_expression_code = "output0 = vec2(1.0, 1.0);"; break; - case VisualShaderNode::PORT_TYPE_VECTOR: + case VisualShaderNode::PORT_TYPE_VECTOR_3D: initial_expression_code = "output0 = vec3(1.0, 1.0, 1.0);"; break; case VisualShaderNode::PORT_TYPE_BOOLEAN: @@ -4182,7 +4182,7 @@ VisualShaderEditor::VisualShaderEditor() { graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_VECTOR_2D); - graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_VECTOR); + graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_VECTOR_3D); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_TRANSFORM); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SAMPLER); //graph->add_valid_left_disconnect_type(0); @@ -4202,27 +4202,27 @@ VisualShaderEditor::VisualShaderEditor() { graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR_2D); - graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR_3D); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_BOOLEAN); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_VECTOR_2D); - graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_VECTOR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_VECTOR_3D); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_BOOLEAN); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_VECTOR_2D); - graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_VECTOR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_VECTOR_3D); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_BOOLEAN); - graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_SCALAR); - graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_SCALAR_INT); - graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR_2D); - graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR); - graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_BOOLEAN); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_SCALAR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_SCALAR_INT); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_VECTOR_2D); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_VECTOR_3D); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_BOOLEAN); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_VECTOR_2D); - graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_VECTOR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_VECTOR_3D); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_BOOLEAN); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SAMPLER, VisualShaderNode::PORT_TYPE_SAMPLER); @@ -4446,23 +4446,23 @@ VisualShaderEditor::VisualShaderEditor() { // COLOR - add_options.push_back(AddOption("ColorFunc", "Color", "Common", "VisualShaderNodeColorFunc", TTR("Color function."), {}, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("ColorOp", "Color", "Common", "VisualShaderNodeColorOp", TTR("Color operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ColorFunc", "Color", "Common", "VisualShaderNodeColorFunc", TTR("Color function."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("ColorOp", "Color", "Common", "VisualShaderNodeColorOp", TTR("Color operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Grayscale", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Grayscale function."), { VisualShaderNodeColorFunc::FUNC_GRAYSCALE }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("HSV2RGB", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeVectorFunc::FUNC_HSV2RGB }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("RGB2HSV", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeVectorFunc::FUNC_RGB2HSV }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Sepia", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Sepia function."), { VisualShaderNodeColorFunc::FUNC_SEPIA }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Grayscale", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Grayscale function."), { VisualShaderNodeColorFunc::FUNC_GRAYSCALE }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("HSV2RGB", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeVectorFunc::FUNC_HSV2RGB }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("RGB2HSV", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeVectorFunc::FUNC_RGB2HSV }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Sepia", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Sepia function."), { VisualShaderNodeColorFunc::FUNC_SEPIA }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Burn", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Burn operator."), { VisualShaderNodeColorOp::OP_BURN }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Darken", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Darken operator."), { VisualShaderNodeColorOp::OP_DARKEN }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Difference", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Difference operator."), { VisualShaderNodeColorOp::OP_DIFFERENCE }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Dodge", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Dodge operator."), { VisualShaderNodeColorOp::OP_DODGE }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("HardLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("HardLight operator."), { VisualShaderNodeColorOp::OP_HARD_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Lighten", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Lighten operator."), { VisualShaderNodeColorOp::OP_LIGHTEN }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Overlay", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Overlay operator."), { VisualShaderNodeColorOp::OP_OVERLAY }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Screen", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Screen operator."), { VisualShaderNodeColorOp::OP_SCREEN }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), { VisualShaderNodeColorOp::OP_SOFT_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Burn", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Burn operator."), { VisualShaderNodeColorOp::OP_BURN }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Darken", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Darken operator."), { VisualShaderNodeColorOp::OP_DARKEN }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Difference", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Difference operator."), { VisualShaderNodeColorOp::OP_DIFFERENCE }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Dodge", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Dodge operator."), { VisualShaderNodeColorOp::OP_DODGE }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("HardLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("HardLight operator."), { VisualShaderNodeColorOp::OP_HARD_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Lighten", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Lighten operator."), { VisualShaderNodeColorOp::OP_LIGHTEN }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Overlay", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Overlay operator."), { VisualShaderNodeColorOp::OP_OVERLAY }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Screen", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Screen operator."), { VisualShaderNodeColorOp::OP_SCREEN }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), { VisualShaderNodeColorOp::OP_SOFT_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant."))); add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."))); @@ -4478,13 +4478,13 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Equal", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Equal (==)")), { VisualShaderNodeCompare::FUNC_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("GreaterThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than (>)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("GreaterThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than or Equal (>=)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("If", "Conditional", "Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), {}, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("If", "Conditional", "Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("IsInf", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF and a scalar parameter."), { VisualShaderNodeIs::FUNC_IS_INF }, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("IsNaN", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between NaN and a scalar parameter."), { VisualShaderNodeIs::FUNC_IS_NAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), { VisualShaderNodeCompare::FUNC_LESS_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), { VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), { VisualShaderNodeCompare::FUNC_NOT_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 3D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 3D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Switch2D", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 2D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("SwitchBool", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_BOOLEAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("SwitchFloat", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_FLOAT }, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -4506,7 +4506,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), { "camera" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), { "inv_camera" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), { "inv_projection" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("OutputIsSRGB", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "output_is_srgb"), { "output_is_srgb" }, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Projection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "projection"), { "projection" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_SPATIAL)); @@ -4518,7 +4518,7 @@ VisualShaderEditor::VisualShaderEditor() { // CANVASITEM-FOR-ALL add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("TexturePixelSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "texture_pixel_size"), { "texture_pixel_size" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, -1, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), { "uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, -1, Shader::MODE_CANVAS_ITEM)); @@ -4527,9 +4527,9 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Active", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), { "active" }, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("AttractorForce", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "attractor_force"), { "attractor_force" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Custom", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), { "custom" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("AttractorForce", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "attractor_force"), { "attractor_force" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Custom", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), { "custom" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("CustomAlpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), { "custom_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("Delta", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), { "delta" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("EmissionTransform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), { "emission_transform" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES)); @@ -4538,7 +4538,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Restart", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), { "restart" }, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("Transform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), { "transform" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Velocity", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), { "velocity" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Velocity", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), { "velocity" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_PARTICLES)); ///////////////// @@ -4561,46 +4561,46 @@ VisualShaderEditor::VisualShaderEditor() { // NODE3D INPUTS add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("InstanceId", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_id"), { "instance_id" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), { "instance_custom_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "modelview"), { "modelview" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), { "point_size" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("DepthTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "depth_texture"), { "depth_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("FrontFacing", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "front_facing"), { "front_facing" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "point_coord"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), { "screen_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), { "albedo" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), { "albedo" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation"), { "attenuation" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Backlight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "backlight"), { "backlight" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), { "diffuse" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Backlight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "backlight"), { "backlight" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), { "diffuse" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Metallic", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "metallic"), { "metallic" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Roughness", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "roughness"), { "roughness" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), { "specular" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), { "specular" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); // CANVASITEM INPUTS add_options.push_back(AddOption("AtLightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), { "at_light_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("Canvas", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "canvas"), { "canvas" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), { "instance_custom_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), { "point_size" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("Screen", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "screen"), { "screen" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); @@ -4608,31 +4608,31 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), { "world" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("AtLightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), { "at_light_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("NormalTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "normal_texture"), { "normal_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("ScreenPixelSize", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_pixel_size"), { "screen_pixel_size" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), { "screen_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("SpecularShininess", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("SpecularShininess", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), { "specular_shininess_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("SpecularShininessTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "specular_shininess_texture"), { "specular_shininess_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("Texture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), { "texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_alpha"), { "light_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("LightColorAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color_alpha"), { "light_color_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightPosition", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_position"), { "light_position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightVertex", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "light_vertex"), { "light_vertex" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightPosition", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_position"), { "light_position" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightVertex", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "light_vertex"), { "light_vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Shadow", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow"), { "shadow" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Shadow", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow"), { "shadow" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("ShadowAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_alpha"), { "shadow_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("SpecularShininess", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("SpecularShininess", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), { "specular_shininess_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("Texture", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), { "texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); @@ -4641,27 +4641,27 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("AtCubeMapPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_cubemap_pass"), { "at_cubemap_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("AtHalfResPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_half_res_pass"), { "at_half_res_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("AtQuarterResPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_quarter_res_pass"), { "at_quarter_res_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("EyeDir", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "eyedir"), { "eyedir" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("HalfResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_color"), { "half_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("EyeDir", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "eyedir"), { "eyedir" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("HalfResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_color"), { "half_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("HalfResAlpha", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_alpha"), { "half_res_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("Light0Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_color"), { "light0_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("Light0Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_direction"), { "light0_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("Light0Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_color"), { "light0_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("Light0Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_direction"), { "light0_direction" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Light0Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_enabled"), { "light0_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Light0Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_energy"), { "light0_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("Light1Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_color"), { "light1_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("Light1Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_direction"), { "light1_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("Light1Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_color"), { "light1_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("Light1Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_direction"), { "light1_direction" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Light1Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_enabled"), { "light1_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Light1Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_energy"), { "light1_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("Light2Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_color"), { "light2_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("Light2Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_direction"), { "light2_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("Light2Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_color"), { "light2_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("Light2Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_direction"), { "light2_direction" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Light2Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_enabled"), { "light2_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Light2Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_energy"), { "light2_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("Light3Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_color"), { "light3_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("Light3Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_direction"), { "light3_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("Light3Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_color"), { "light3_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("Light3Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_direction"), { "light3_direction" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Light3Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_enabled"), { "light3_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Light3Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_energy"), { "light3_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("Position", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "position"), { "position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); - add_options.push_back(AddOption("QuarterResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_color"), { "quarter_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("Position", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "position"), { "position" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + add_options.push_back(AddOption("QuarterResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_color"), { "quarter_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("QuarterResAlpha", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_alpha"), { "quarter_res_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Radiance", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "radiance"), { "radiance" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("ScreenUV", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_SKY, Shader::MODE_SKY)); @@ -4670,31 +4670,31 @@ VisualShaderEditor::VisualShaderEditor() { // FOG INPUTS - add_options.push_back(AddOption("WorldPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "world_position"), { "world_position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); - add_options.push_back(AddOption("ObjectPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "object_position"), { "object_position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); - add_options.push_back(AddOption("UVW", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "uvw"), { "uvw" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); - add_options.push_back(AddOption("Extents", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "extents"), { "extents" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); + add_options.push_back(AddOption("WorldPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "world_position"), { "world_position" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FOG, Shader::MODE_FOG)); + add_options.push_back(AddOption("ObjectPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "object_position"), { "object_position" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FOG, Shader::MODE_FOG)); + add_options.push_back(AddOption("UVW", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "uvw"), { "uvw" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FOG, Shader::MODE_FOG)); + add_options.push_back(AddOption("Extents", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "extents"), { "extents" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FOG, Shader::MODE_FOG)); add_options.push_back(AddOption("SDF", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "sdf"), { "sdf" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); add_options.push_back(AddOption("Time", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG)); // PARTICLES INPUTS add_options.push_back(AddOption("CollisionDepth", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_depth"), { "collision_depth" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), { "collision_normal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), { "collision_normal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); // PARTICLES add_options.push_back(AddOption("EmitParticle", "Particles", "", "VisualShaderNodeParticleEmit", "", {}, -1, TYPE_FLAGS_PROCESS | TYPE_FLAGS_PROCESS_CUSTOM | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("ParticleRandomness", "Particles", "", "VisualShaderNodeParticleRandomness", "", {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", TTR("A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", TTR("A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("BoxEmitter", "Particles", "Emitters", "VisualShaderNodeParticleBoxEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("MeshEmitter", "Particles", "Emitters", "VisualShaderNodeParticleMeshEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("RingEmitter", "Particles", "Emitters", "VisualShaderNodeParticleRingEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("SphereEmitter", "Particles", "Emitters", "VisualShaderNodeParticleSphereEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("BoxEmitter", "Particles", "Emitters", "VisualShaderNodeParticleBoxEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("MeshEmitter", "Particles", "Emitters", "VisualShaderNodeParticleMeshEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("RingEmitter", "Particles", "Emitters", "VisualShaderNodeParticleRingEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("SphereEmitter", "Particles", "Emitters", "VisualShaderNodeParticleSphereEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("ConeVelocity", "Particles", "Velocity", "VisualShaderNodeParticleConeVelocity", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("ConeVelocity", "Particles", "Velocity", "VisualShaderNodeParticleConeVelocity", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); // SCALAR @@ -4783,11 +4783,11 @@ VisualShaderEditor::VisualShaderEditor() { // SDF { - add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); } // TEXTURES @@ -4834,146 +4834,146 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Multiply", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Multiplies two transforms."), { VisualShaderNodeTransformOp::OP_AxB }, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("MultiplyComp", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Performs per-component multiplication of two transforms."), { VisualShaderNodeTransformOp::OP_AxB_COMP }, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("Subtract", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Subtracts two transforms."), { VisualShaderNodeTransformOp::OP_A_MINUS_B }, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), {}, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("TransformConstant", "Transform", "Variables", "VisualShaderNodeTransformConstant", TTR("Transform constant."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("TransformUniform", "Transform", "Variables", "VisualShaderNodeTransformUniform", TTR("Transform uniform."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM)); // VECTOR - add_options.push_back(AddOption("VectorFunc", "Vector", "Common", "VisualShaderNodeVectorFunc", TTR("Vector function."), {}, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("VectorOp", "Vector", "Common", "VisualShaderNodeVectorOp", TTR("Vector operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("VectorFunc", "Vector", "Common", "VisualShaderNodeVectorFunc", TTR("Vector function."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("VectorOp", "Vector", "Common", "VisualShaderNodeVectorOp", TTR("Vector operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("VectorCompose", "Vector", "Common", "VisualShaderNodeVectorCompose", TTR("Composes vector from three scalars."))); add_options.push_back(AddOption("VectorDecompose", "Vector", "Common", "VisualShaderNodeVectorDecompose", TTR("Decomposes vector to three scalars."))); add_options.push_back(AddOption("Vector2Compose", "Vector", "Composition", "VisualShaderNodeVectorCompose", TTR("Composes 2D vector from three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Vector2Decompose", "Vector", "Composition", "VisualShaderNodeVectorDecompose", TTR("Decomposes 2D vector to three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_2D })); - add_options.push_back(AddOption("Vector3Compose", "Vector", "Composition", "VisualShaderNodeVectorCompose", TTR("Composes 3D vector from three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Vector3Compose", "Vector", "Composition", "VisualShaderNodeVectorCompose", TTR("Composes 3D vector from three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Vector3Decompose", "Vector", "Composition", "VisualShaderNodeVectorDecompose", TTR("Decomposes 3D vector to three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_3D })); add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), { VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), { VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), { VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), { VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), { VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), { VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), { VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), { VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("DFdX", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_X, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); - add_options.push_back(AddOption("DFdX", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_X, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); + add_options.push_back(AddOption("DFdX", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_X, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); add_options.push_back(AddOption("DFdY", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_Y, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); - add_options.push_back(AddOption("DFdY", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_Y, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); + add_options.push_back(AddOption("DFdY", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_Y, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); add_options.push_back(AddOption("Distance2D", "Vector", "Functions", "VisualShaderNodeVectorDistance", TTR("Returns the distance between two points."), { VisualShaderNodeVectorDistance::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Distance3D", "Vector", "Functions", "VisualShaderNodeVectorDistance", TTR("Returns the distance between two points."), { VisualShaderNodeVectorDistance::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Dot", "Vector", "Functions", "VisualShaderNodeDotProduct", TTR("Calculates the dot product of two vectors."), {}, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns the vector that points in the same direction as a reference vector. The function has three vector parameters : N, the vector to orient, I, the incident vector, and Nref, the reference vector. If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned."), { VisualShaderNodeFaceForward::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns the vector that points in the same direction as a reference vector. The function has three vector parameters : N, the vector to orient, I, the incident vector, and Nref, the reference vector. If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned."), { VisualShaderNodeFaceForward::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns the vector that points in the same direction as a reference vector. The function has three vector parameters : N, the vector to orient, I, the incident vector, and Nref, the reference vector. If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned."), { VisualShaderNodeFaceForward::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Fresnel", "Vector", "Functions", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), {}, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), { VisualShaderNodeVectorOp::OP_MAX, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), { VisualShaderNodeVectorOp::OP_MAX, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), { VisualShaderNodeVectorOp::OP_MAX, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), { VisualShaderNodeVectorOp::OP_MIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), { VisualShaderNodeVectorOp::OP_MIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), { VisualShaderNodeVectorOp::OP_MIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), { VisualShaderNodeMix::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), { VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), {}, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), { VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), { VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), { VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), { VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Sum", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); - add_options.push_back(AddOption("Sum", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); + add_options.push_back(AddOption("Sum", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds 2D vector to 2D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds 3D vector to 3D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds 3D vector to 3D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Multiply", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Multiply", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Multiply", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Remainder", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 2D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Remainder", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 3D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Remainder", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 3D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 2D vector from 2D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 3D vector from 3D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 3D vector from 3D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Vector2Constant", "Vector", "Variables", "VisualShaderNodeVec2Constant", TTR("2D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Vector2Uniform", "Vector", "Variables", "VisualShaderNodeVec2Uniform", TTR("2D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Vector3Uniform", "Vector", "Variables", "VisualShaderNodeVec3Uniform", TTR("3D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Vector3Uniform", "Vector", "Variables", "VisualShaderNodeVec3Uniform", TTR("3D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); // SPECIAL diff --git a/editor/project_export.cpp b/editor/project_export.cpp index f39a494df8..b8775cd3ed 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -1275,8 +1275,6 @@ ProjectExportDialog::ProjectExportDialog() { set_hide_on_ok(false); - editor_icons = "EditorIcons"; - default_filename = EditorSettings::get_singleton()->get_project_metadata("export_options", "default_filename", ""); // If no default set, use project name if (default_filename.is_empty()) { diff --git a/editor/project_export.h b/editor/project_export.h index 3d90a0d3ff..09e402c67f 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -85,8 +85,6 @@ private: Label *include_label; MarginContainer *include_margin; - StringName editor_icons; - Button *export_button; Button *export_all_button; AcceptDialog *export_all_dialog; diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index cfb42c0741..57e47a15fd 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -40,7 +40,6 @@ #include "core/os/os.h" #include "core/string/translation.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "editor/editor_vcs_interface.h" #include "editor_scale.h" #include "editor_settings.h" diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 27fe696cc3..405e263a62 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -269,7 +269,9 @@ void CustomPropertyEditor::_menu_option(int p_which) { res->call("set_instance_base_type", owner->get_class()); } + EditorNode::get_editor_data().instantiate_object_properties(obj); v = obj; + emit_signal(SNAME("variant_changed")); } break; @@ -1092,7 +1094,9 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) { ERR_FAIL_COND(!obj); ERR_FAIL_COND(!Object::cast_to<Resource>(obj)); + EditorNode::get_editor_data().instantiate_object_properties(obj); v = obj; + emit_signal(SNAME("variant_changed")); hide(); } @@ -1283,7 +1287,9 @@ void CustomPropertyEditor::_action_pressed(int p_which) { ERR_BREAK(!obj); ERR_BREAK(!Object::cast_to<Resource>(obj)); + EditorNode::get_editor_data().instantiate_object_properties(obj); v = obj; + emit_signal(SNAME("variant_changed")); hide(); } diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index 406bcbe342..0862efb4ee 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -214,10 +214,13 @@ void PropertySelector::_update_search() { Variant::construct(type, v, nullptr, 0, ce); v.get_method_list(&methods); } else { - Object *obj = ObjectDB::get_instance(script); - if (Object::cast_to<Script>(obj)) { + Ref<Script> script_ref = Object::cast_to<Script>(ObjectDB::get_instance(script)); + if (script_ref.is_valid()) { methods.push_back(MethodInfo("*Script Methods")); - Object::cast_to<Script>(obj)->get_script_method_list(&methods); + if (script_ref->is_built_in()) { + script_ref->reload(true); + } + script_ref->get_script_method_list(&methods); } StringName base = base_type; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 9b18d3a491..0e362b13c6 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1206,8 +1206,16 @@ void SceneTreeDock::_notification(int p_what) { create_root_dialog->add_child(top_row); + ScrollContainer *scroll_container = memnew(ScrollContainer); + scroll_container->set_name("NodeShortcutsScrollContainer"); + create_root_dialog->add_child(scroll_container); + scroll_container->set_v_size_flags(SIZE_EXPAND_FILL); + scroll_container->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); + VBoxContainer *node_shortcuts = memnew(VBoxContainer); node_shortcuts->set_name("NodeShortcuts"); + scroll_container->add_child(node_shortcuts); + node_shortcuts->set_h_size_flags(SIZE_EXPAND_FILL); VBoxContainer *beginner_node_shortcuts = memnew(VBoxContainer); beginner_node_shortcuts->set_name("BeginnerNodeShortcuts"); @@ -1247,8 +1255,6 @@ void SceneTreeDock::_notification(int p_what) { button_clipboard->set_icon(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons"))); button_clipboard->connect("pressed", callable_bind(callable_mp(this, &SceneTreeDock::_tool_selected), TOOL_PASTE, false)); - node_shortcuts->add_spacer(); - create_root_dialog->add_child(node_shortcuts); _update_create_root_dialog(); } break; @@ -3112,7 +3118,7 @@ void SceneTreeDock::_local_tree_selected() { void SceneTreeDock::_update_create_root_dialog() { BaseButton *toggle = Object::cast_to<BaseButton>(create_root_dialog->get_node(String("NodeShortcutsTopRow/NodeShortcutsToggle"))); - Node *node_shortcuts = create_root_dialog->get_node(String("NodeShortcuts")); + Node *node_shortcuts = create_root_dialog->get_node(String("NodeShortcutsScrollContainer/NodeShortcuts")); if (!toggle || !node_shortcuts) { return; @@ -3142,6 +3148,7 @@ void SceneTreeDock::_update_create_root_dialog() { Button *button = memnew(Button); favorite_nodes->add_child(button); button->set_text(l); + button->set_clip_text(true); String name = l.get_slicec(' ', 0); if (ScriptServer::is_global_class(name)) { name = ScriptServer::get_global_class_native_base(name); @@ -3403,6 +3410,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel create_root_dialog = memnew(VBoxContainer); vbc->add_child(create_root_dialog); + create_root_dialog->set_v_size_flags(SIZE_EXPAND_FILL); create_root_dialog->hide(); scene_tree = memnew(SceneTreeEditor(false, true, true)); |