summaryrefslogtreecommitdiffstats
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/animation_track_editor.cpp28
-rw-r--r--editor/debugger/editor_debugger_node.cpp2
-rw-r--r--editor/debugger/editor_performance_profiler.cpp3
-rw-r--r--editor/debugger/script_editor_debugger.cpp1
-rw-r--r--editor/doc_tools.cpp17
-rw-r--r--editor/editor_inspector.cpp20
-rw-r--r--editor/editor_node.cpp9
-rw-r--r--editor/editor_properties.cpp3
-rw-r--r--editor/export/editor_export_platform.cpp26
-rw-r--r--editor/export/editor_export_platform.h2
-rw-r--r--editor/icons/RetargetModifier3D.svg1
-rw-r--r--editor/import/3d/post_import_plugin_skeleton_renamer.cpp2
-rw-r--r--editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp227
-rw-r--r--editor/import/3d/post_import_plugin_skeleton_track_organizer.cpp42
-rw-r--r--editor/import/3d/resource_importer_scene.cpp1
-rw-r--r--editor/plugins/camera_3d_editor_plugin.cpp51
-rw-r--r--editor/plugins/camera_3d_editor_plugin.h27
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp19
-rw-r--r--editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp20
-rw-r--r--editor/plugins/gizmos/camera_3d_gizmo_plugin.h1
-rw-r--r--editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp75
-rw-r--r--editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h2
-rw-r--r--editor/plugins/lightmap_gi_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp7
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp28
-rw-r--r--editor/plugins/node_3d_editor_plugin.h2
-rw-r--r--editor/plugins/plugin_config_dialog.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_text_editor.cpp1
-rw-r--r--editor/plugins/theme_editor_plugin.cpp2
-rw-r--r--editor/plugins/theme_editor_preview.cpp6
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp3
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.cpp10
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.h4
34 files changed, 532 insertions, 116 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 19e0647fb7..1a612a3e55 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -1400,12 +1400,26 @@ void AnimationTimelineEdit::_anim_loop_pressed() {
undo_redo->add_undo_method(this, "update_values");
undo_redo->commit_action();
} else {
- String base_path = animation->get_path();
- if (FileAccess::exists(base_path + ".import")) {
- EditorNode::get_singleton()->show_warning(TTR("Can't change loop mode on animation instanced from imported scene."));
+ String base = animation->get_path();
+ int srpos = base.find("::");
+ if (srpos != -1) {
+ base = animation->get_path().substr(0, srpos);
+ }
+
+ if (FileAccess::exists(base + ".import")) {
+ if (ResourceLoader::get_resource_type(base) == "PackedScene") {
+ EditorNode::get_singleton()->show_warning(TTR("Can't change loop mode on animation instanced from an imported scene.\n\nTo change this animation's loop mode, navigate to the scene's Advanced Import settings and select the animation.\nYou can then change the loop mode from the inspector menu."));
+ } else {
+ EditorNode::get_singleton()->show_warning(TTR("Can't change loop mode on animation instanced from an imported resource."));
+ }
} else {
- EditorNode::get_singleton()->show_warning(TTR("Can't change loop mode on animation embedded in another scene."));
+ if (ResourceLoader::get_resource_type(base) == "PackedScene") {
+ EditorNode::get_singleton()->show_warning(TTR("Can't change loop mode on animation embedded in another scene.\n\nYou must open this scene and change the animation's loop mode from there."));
+ } else {
+ EditorNode::get_singleton()->show_warning(TTR("Can't change loop mode on animation embedded in another resource."));
+ }
}
+
update_values();
}
}
@@ -6628,6 +6642,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
case EDIT_SCALE_SELECTION:
case EDIT_SCALE_FROM_CURSOR: {
scale_dialog->popup_centered(Size2(200, 100) * EDSCALE);
+ scale->get_line_edit()->grab_focus();
} break;
case EDIT_SCALE_CONFIRM: {
if (selection.is_empty()) {
@@ -7875,10 +7890,13 @@ AnimationTrackEditor::AnimationTrackEditor() {
scale->set_min(-99999);
scale->set_max(99999);
scale->set_step(0.001);
+ scale->set_select_all_on_focus(true);
vbc->add_margin_child(TTR("Scale Ratio:"), scale);
- scale_dialog->connect(SceneStringName(confirmed), callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_SCALE_CONFIRM));
+ scale_dialog->connect(SceneStringName(confirmed), callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_SCALE_CONFIRM), CONNECT_DEFERRED);
add_child(scale_dialog);
+ scale_dialog->register_text_enter(scale->get_line_edit());
+
//
ease_dialog = memnew(ConfirmationDialog);
ease_dialog->set_title(TTR("Select Transition and Easing"));
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index 909651da45..f06d9be78f 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -120,7 +120,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() {
tabs->add_child(node);
- node->set_name("Session " + itos(tabs->get_tab_count()));
+ node->set_name(vformat(TTR("Session %d"), tabs->get_tab_count()));
if (tabs->get_tab_count() > 1) {
node->clear_style();
tabs->set_tabs_visible(true);
diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp
index 1ea9a66534..31c09c9b37 100644
--- a/editor/debugger/editor_performance_profiler.cpp
+++ b/editor/debugger/editor_performance_profiler.cpp
@@ -81,6 +81,9 @@ void EditorPerformanceProfiler::Monitor::reset() {
String EditorPerformanceProfiler::_create_label(float p_value, Performance::MonitorType p_type) {
switch (p_type) {
+ case Performance::MONITOR_TYPE_QUANTITY: {
+ return TS->format_number(itos(p_value));
+ }
case Performance::MONITOR_TYPE_MEMORY: {
return String::humanize_size(p_value);
}
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index da59450dd0..416e6f07dd 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -1062,6 +1062,7 @@ void ScriptEditorDebugger::_update_buttons_state() {
for (KeyValue<uint64_t, ThreadDebugged> &I : threads_debugged) {
threadss.push_back(&I.value);
}
+ threads->set_disabled(threadss.is_empty());
threadss.sort_custom<ThreadSort>();
threads->clear();
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 79e0c7ebd1..842c4acce0 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -908,6 +908,23 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
c.properties.sort();
+ List<StringName> enums;
+ Variant::get_enums_for_type(Variant::Type(i), &enums);
+
+ for (const StringName &E : enums) {
+ List<StringName> enumerations;
+ Variant::get_enumerations_for_enum(Variant::Type(i), E, &enumerations);
+
+ for (const StringName &F : enumerations) {
+ DocData::ConstantDoc constant;
+ constant.name = F;
+ constant.value = itos(Variant::get_enum_value(Variant::Type(i), E, F));
+ constant.is_value_valid = true;
+ constant.enumeration = E;
+ c.constants.push_back(constant);
+ }
+ }
+
List<StringName> constants;
Variant::get_constants_for_type(Variant::Type(i), &constants);
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 6b3c6b462d..1a973d7b77 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -3472,6 +3472,14 @@ void EditorInspector::update_tree() {
editors.append_array(late_editors);
+ const Node *node = Object::cast_to<Node>(object);
+
+ Vector<SceneState::PackState> sstack;
+ if (node != nullptr) {
+ const Node *es = EditorNode::get_singleton()->get_edited_scene();
+ sstack = PropertyUtils::get_node_states_stack(node, es);
+ }
+
for (int i = 0; i < editors.size(); i++) {
EditorProperty *ep = Object::cast_to<EditorProperty>(editors[i].property_editor);
const Vector<String> &properties = editors[i].properties;
@@ -3525,7 +3533,15 @@ void EditorInspector::update_tree() {
ep->set_checked(checked);
ep->set_keying(keying);
ep->set_read_only(property_read_only || all_read_only);
- ep->set_deletable(deletable_properties || p.name.begins_with("metadata/"));
+ if (p.name.begins_with("metadata/")) {
+ Variant _default = Variant();
+ if (node != nullptr) {
+ _default = PropertyUtils::get_property_default_value(node, p.name, nullptr, &sstack, false, nullptr, nullptr);
+ }
+ ep->set_deletable(_default == Variant());
+ } else {
+ ep->set_deletable(deletable_properties);
+ }
}
if (ep && ep->is_favoritable() && current_favorites.has(p.name)) {
@@ -3648,8 +3664,6 @@ void EditorInspector::update_tree() {
for (List<EditorInspectorSection *>::Element *I = sections.back(); I; I = I->prev()) {
EditorInspectorSection *section = I->get();
if (section->get_vbox()->get_child_count() == 0) {
- I = I->prev();
-
sections.erase(section);
vbox_per_path[main_vbox].erase(section->get_section());
memdelete(section);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index f056a477c4..222696a608 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5190,7 +5190,8 @@ void EditorNode::show_accept(const String &p_text, const String &p_title) {
_close_save_scene_progress();
accept->set_ok_button_text(p_title);
accept->set_text(p_text);
- EditorInterface::get_singleton()->popup_dialog_centered(accept);
+ accept->reset_size();
+ EditorInterface::get_singleton()->popup_dialog_centered_clamped(accept, Size2i(), 0.0);
}
}
@@ -5200,7 +5201,8 @@ void EditorNode::show_save_accept(const String &p_text, const String &p_title) {
_close_save_scene_progress();
save_accept->set_ok_button_text(p_title);
save_accept->set_text(p_text);
- EditorInterface::get_singleton()->popup_dialog_centered(save_accept);
+ save_accept->reset_size();
+ EditorInterface::get_singleton()->popup_dialog_centered_clamped(save_accept, Size2i(), 0.0);
}
}
@@ -5209,7 +5211,8 @@ void EditorNode::show_warning(const String &p_text, const String &p_title) {
_close_save_scene_progress();
warning->set_text(p_text);
warning->set_title(p_title);
- EditorInterface::get_singleton()->popup_dialog_centered(warning);
+ warning->reset_size();
+ EditorInterface::get_singleton()->popup_dialog_centered_clamped(warning, Size2i(), 0.0);
} else {
WARN_PRINT(p_title + " " + p_text);
}
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 2b2b32eb22..b600e49b61 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -52,6 +52,7 @@
#include "scene/3d/fog_volume.h"
#include "scene/3d/gpu_particles_3d.h"
#include "scene/gui/color_picker.h"
+#include "scene/gui/grid_container.h"
#include "scene/main/window.h"
#include "scene/resources/font.h"
#include "scene/resources/mesh.h"
@@ -2645,7 +2646,7 @@ EditorPropertyColor::EditorPropertyColor() {
add_child(picker);
picker->set_flat(true);
picker->connect("color_changed", callable_mp(this, &EditorPropertyColor::_color_changed));
- picker->connect("popup_closed", callable_mp(this, &EditorPropertyColor::_popup_closed));
+ picker->connect("popup_closed", callable_mp(this, &EditorPropertyColor::_popup_closed), CONNECT_DEFERRED);
picker->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(picker->get_picker()));
picker->get_popup()->connect("about_to_popup", callable_mp(this, &EditorPropertyColor::_picker_opening));
}
diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp
index 91c9ff9807..27216c2399 100644
--- a/editor/export/editor_export_platform.cpp
+++ b/editor/export/editor_export_platform.cpp
@@ -1495,7 +1495,15 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<String> forced_export = get_forced_export_files();
for (int i = 0; i < forced_export.size(); i++) {
- Vector<uint8_t> array = FileAccess::get_file_as_bytes(forced_export[i]);
+ Vector<uint8_t> array;
+ if (GDExtension::get_extension_list_config_file() == forced_export[i]) {
+ array = _filter_extension_list_config_file(forced_export[i], paths);
+ if (array.size() == 0) {
+ continue;
+ }
+ } else {
+ array = FileAccess::get_file_as_bytes(forced_export[i]);
+ }
err = p_save_func(p_udata, forced_export[i], array, idx, total, enc_in_filters, enc_ex_filters, key, seed);
if (err != OK) {
return err;
@@ -1534,6 +1542,22 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
return OK;
}
+Vector<uint8_t> EditorExportPlatform::_filter_extension_list_config_file(const String &p_config_path, const HashSet<String> &p_paths) {
+ Ref<FileAccess> f = FileAccess::open(p_config_path, FileAccess::READ);
+ if (f.is_null()) {
+ ERR_FAIL_V_MSG(Vector<uint8_t>(), "Can't open file from path '" + String(p_config_path) + "'.");
+ }
+ Vector<uint8_t> data;
+ while (!f->eof_reached()) {
+ String l = f->get_line().strip_edges();
+ if (p_paths.has(l)) {
+ data.append_array(l.to_utf8_buffer());
+ data.append('\n');
+ }
+ }
+ return data;
+}
+
Error EditorExportPlatform::_pack_add_shared_object(void *p_userdata, const SharedObject &p_so) {
PackData *pack_data = (PackData *)p_userdata;
if (pack_data->so_files) {
diff --git a/editor/export/editor_export_platform.h b/editor/export/editor_export_platform.h
index c7378ffec7..a33bdce72a 100644
--- a/editor/export/editor_export_platform.h
+++ b/editor/export/editor_export_platform.h
@@ -135,6 +135,8 @@ private:
void _edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, HashSet<String> &r_list, bool exclude);
void _edit_filter_list(HashSet<String> &r_list, const String &p_filter, bool exclude);
+ static Vector<uint8_t> _filter_extension_list_config_file(const String &p_config_path, const HashSet<String> &p_paths);
+
struct FileExportCache {
uint64_t source_modified_time = 0;
String source_md5;
diff --git a/editor/icons/RetargetModifier3D.svg b/editor/icons/RetargetModifier3D.svg
new file mode 100644
index 0000000000..2ca7af6c6e
--- /dev/null
+++ b/editor/icons/RetargetModifier3D.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#fc7f7f"><path d="m11.667 4.166h-3.334c-1.841 0-3.333 1.492-3.333 3.334.003 1.188.638 2.283 1.667 2.877v2.956c0 .597.317 1.146.833 1.444.254.146.54.221.833.221v.002h3.334v-.002c.293 0 .579-.075.833-.221.516-.299.833-.851.833-1.444v-2.956c1.028-.594 1.664-1.689 1.667-2.877 0-1.842-1.492-3.334-3.333-3.334zm-2.5 4.166h1.666v.834h-1.666zm-2.5-.832c0-.461.372-.834.833-.834s.833.373.833.834-.372.832-.833.832-.833-.371-.833-.832zm5.833 3.223v2.61h-.833v-.833h-.834v.833h-1.666v-.833h-.834v.833h-.833v-2.608-.725h.833v.832h.834v-.832h1.666v.832h.834v-.832h.833zm0-2.391c-.461 0-.833-.371-.833-.832s.372-.834.833-.834.833.373.833.834-.372.832-.833.832z"/><path d="m4.418 9.334h-.085v.833h-.833v-2.608-.725h.567c.323-2.072 2.104-3.668 4.266-3.668h2.445c-.473-1.263-1.682-2.166-3.111-2.166h-3.334c-1.841 0-3.333 1.492-3.333 3.334.003 1.188.638 2.283 1.667 2.877v2.956c0 .597.317 1.146.833 1.444.254.146.54.221.833.221v.002h1.334v-.929c-.538-.421-.962-.962-1.249-1.571zm-1.751-5c0-.461.372-.834.833-.834s.833.373.833.834-.372.832-.833.832-.833-.371-.833-.832z"/></g></svg> \ No newline at end of file
diff --git a/editor/import/3d/post_import_plugin_skeleton_renamer.cpp b/editor/import/3d/post_import_plugin_skeleton_renamer.cpp
index 3f6bfdcf05..700b2bc719 100644
--- a/editor/import/3d/post_import_plugin_skeleton_renamer.cpp
+++ b/editor/import/3d/post_import_plugin_skeleton_renamer.cpp
@@ -39,7 +39,7 @@
void PostImportPluginSkeletonRenamer::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) {
if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) {
- r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/bone_renamer/rename_bones"), true));
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/bone_renamer/rename_bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/bone_renamer/unique_node/make_unique"), true));
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::STRING, "retarget/bone_renamer/unique_node/skeleton_name"), "GeneralSkeleton"));
}
diff --git a/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp b/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp
index 64bec0532b..82940f9cef 100644
--- a/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp
+++ b/editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp
@@ -33,6 +33,7 @@
#include "editor/import/3d/scene_import_settings.h"
#include "scene/3d/bone_attachment_3d.h"
#include "scene/3d/importer_mesh_instance_3d.h"
+#include "scene/3d/retarget_modifier_3d.h"
#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/bone_map.h"
@@ -42,8 +43,18 @@ void PostImportPluginSkeletonRestFixer::get_internal_import_options(InternalImpo
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/apply_node_transforms"), true));
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/normalize_position_tracks"), true));
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/reset_all_bone_poses_after_import"), true));
- r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/overwrite_axis", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
+
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "retarget/rest_fixer/retarget_method", PROPERTY_HINT_ENUM, "None,Overwrite Axis,Use Retarget Modifier", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/keep_global_rest_on_leftovers"), true));
+ String skeleton_bones_must_be_renamed_warning = String(
+ "The skeleton modifier option uses SkeletonProfile as a list of bone names and retargets by name matching. Without renaming, retargeting by modifier will not work and the track path of the animation will be broken and it will be not playbacked correctly."); // TODO: translate.
+ r_options->push_back(ResourceImporter::ImportOption(
+ PropertyInfo(
+ Variant::STRING, U"retarget/rest_fixer/\u26A0_validation_warning/skeleton_bones_must_be_renamed",
+ PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY),
+ Variant(skeleton_bones_must_be_renamed_warning)));
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/use_global_pose"), true));
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::STRING, "retarget/rest_fixer/original_skeleton_name"), "OriginalSkeleton"));
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/fix_silhouette/enable", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
// TODO: PostImportPlugin need to be implemented such as validate_option(PropertyInfo &property, const Dictionary &p_options).
// get_internal_option_visibility() is not sufficient because it can only retrieve options implemented in the core and can only read option values.
@@ -63,7 +74,11 @@ Variant PostImportPluginSkeletonRestFixer::get_internal_option_visibility(Intern
}
}
} else if (p_option == "retarget/rest_fixer/keep_global_rest_on_leftovers") {
- return bool(p_options["retarget/rest_fixer/overwrite_axis"]);
+ return int(p_options["retarget/rest_fixer/retarget_method"]) == 1;
+ } else if (p_option == "retarget/rest_fixer/original_skeleton_name" || p_option == "retarget/rest_fixer/use_global_pose") {
+ return int(p_options["retarget/rest_fixer/retarget_method"]) == 2;
+ } else if (p_option.begins_with("retarget/") && p_option.ends_with("skeleton_bones_must_be_renamed")) {
+ return int(p_options["retarget/rest_fixer/retarget_method"]) == 2 && bool(p_options["retarget/bone_renamer/rename_bones"]) == false;
}
}
return true;
@@ -147,7 +162,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
src_skeleton->set_bone_pose_position(src_idx, src_skeleton->get_bone_pose_position(src_idx) * scl);
}
- // Fix animation.
+ // Fix animation by changing node transform.
bones_to_process = src_skeleton->get_parentless_bones();
{
TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer");
@@ -224,6 +239,10 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
List<StringName> anims;
ap->get_animation_list(&anims);
for (const StringName &name : anims) {
+ if (String(name).contains("/")) {
+ continue; // Avoid animation library which may be created by importer dynamically.
+ }
+
Ref<Animation> anim = ap->get_animation(name);
int track_len = anim->get_track_count();
@@ -454,8 +473,13 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
}
}
- // Overwrite axis.
- if (bool(p_options["retarget/rest_fixer/overwrite_axis"])) {
+ bool is_using_modifier = int(p_options["retarget/rest_fixer/retarget_method"]) == 2;
+ bool is_using_global_pose = bool(p_options["retarget/rest_fixer/use_global_pose"]);
+ Skeleton3D *orig_skeleton = nullptr;
+ Skeleton3D *profile_skeleton = nullptr;
+
+ // Retarget in some way.
+ if (int(p_options["retarget/rest_fixer/retarget_method"]) > 0) {
LocalVector<Transform3D> old_skeleton_rest;
LocalVector<Transform3D> old_skeleton_global_rest;
for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
@@ -463,11 +487,151 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
old_skeleton_global_rest.push_back(src_skeleton->get_bone_global_rest(i));
}
+ // Build structure for modifier.
+ if (is_using_modifier) {
+ orig_skeleton = src_skeleton;
+
+ // Duplicate src_skeleton to modify animation tracks, it will memdelele after that animation track modification.
+ src_skeleton = memnew(Skeleton3D);
+ for (int i = 0; i < orig_skeleton->get_bone_count(); i++) {
+ src_skeleton->add_bone(orig_skeleton->get_bone_name(i));
+ src_skeleton->set_bone_rest(i, orig_skeleton->get_bone_rest(i));
+ src_skeleton->set_bone_pose(i, orig_skeleton->get_bone_pose(i));
+ }
+ for (int i = 0; i < orig_skeleton->get_bone_count(); i++) {
+ src_skeleton->set_bone_parent(i, orig_skeleton->get_bone_parent(i));
+ }
+ src_skeleton->set_motion_scale(orig_skeleton->get_motion_scale());
+
+ // Rename orig_skeleton (previous src_skeleton), since it is not animated by animation track with GeneralSkeleton.
+ String original_skeleton_name = String(p_options["retarget/rest_fixer/original_skeleton_name"]);
+ String skel_name = orig_skeleton->get_name();
+ ERR_FAIL_COND_MSG(original_skeleton_name.is_empty(), "Original skeleton name cannot be empty.");
+ ERR_FAIL_COND_MSG(original_skeleton_name == skel_name, "Original skeleton name must be different from unique skeleton name.");
+
+ // Rename profile skeleton to be general skeleton.
+ profile_skeleton = memnew(Skeleton3D);
+ bool is_unique = orig_skeleton->is_unique_name_in_owner();
+ if (is_unique) {
+ orig_skeleton->set_unique_name_in_owner(false);
+ }
+ orig_skeleton->set_name(original_skeleton_name);
+ profile_skeleton->set_name(skel_name);
+ if (is_unique) {
+ profile_skeleton->set_unique_name_in_owner(true);
+ }
+ // Build profile skeleton bones.
+ int len = profile->get_bone_size();
+ for (int i = 0; i < len; i++) {
+ profile_skeleton->add_bone(profile->get_bone_name(i));
+ profile_skeleton->set_bone_rest(i, profile->get_reference_pose(i));
+ }
+ for (int i = 0; i < len; i++) {
+ int target_parent = profile_skeleton->find_bone(profile->get_bone_parent(i));
+ if (target_parent >= 0) {
+ profile_skeleton->set_bone_parent(i, target_parent);
+ }
+ }
+ for (int i = 0; i < len; i++) {
+ Vector3 origin;
+ int found = orig_skeleton->find_bone(profile->get_bone_name(i));
+ String parent_name = profile->get_bone_parent(i);
+ if (found >= 0) {
+ origin = orig_skeleton->get_bone_global_rest(found).origin;
+ if (profile->get_bone_name(i) != profile->get_root_bone()) {
+ int src_parent = -1;
+ while (src_parent < 0 && !parent_name.is_empty()) {
+ src_parent = orig_skeleton->find_bone(parent_name);
+ parent_name = profile->get_bone_parent(profile->find_bone(parent_name));
+ }
+ if (src_parent >= 0) {
+ Transform3D parent_grest = orig_skeleton->get_bone_global_rest(src_parent);
+ origin = origin - parent_grest.origin;
+ }
+ }
+ }
+ int target_parent = profile_skeleton->find_bone(profile->get_bone_parent(i));
+ if (target_parent >= 0) {
+ origin = profile_skeleton->get_bone_global_rest(target_parent).basis.get_rotation_quaternion().xform_inv(origin);
+ }
+ profile_skeleton->set_bone_rest(i, Transform3D(profile_skeleton->get_bone_rest(i).basis, origin));
+ }
+ profile_skeleton->set_motion_scale(orig_skeleton->get_motion_scale());
+ profile_skeleton->reset_bone_poses();
+ // Make structure with modifier.
+ Node *owner = p_node->get_owner();
+
+ Node *pr = orig_skeleton->get_parent();
+ pr->add_child(profile_skeleton);
+ profile_skeleton->set_owner(owner);
+
+ RetargetModifier3D *mod = memnew(RetargetModifier3D);
+ profile_skeleton->add_child(mod);
+ mod->set_owner(owner);
+ mod->set_name("RetargetModifier3D");
+
+ orig_skeleton->set_owner(nullptr);
+ orig_skeleton->reparent(mod, false);
+ orig_skeleton->set_owner(owner);
+ orig_skeleton->set_unique_name_in_owner(true);
+
+ mod->set_use_global_pose(is_using_global_pose);
+ mod->set_profile(profile);
+
+ // Fix skeleton name in animation.
+ // Mapped skeleton is animated by %GenerarSkeleton:RenamedBoneName.
+ // Unmapped skeleton is animated by %OriginalSkeleton:OriginalBoneName.
+ if (is_using_modifier) {
+ TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer");
+ String general_skeleton_pathname = UNIQUE_NODE_PREFIX + profile_skeleton->get_name();
+ while (nodes.size()) {
+ AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back());
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (const StringName &name : anims) {
+ Ref<Animation> anim = ap->get_animation(name);
+ int track_len = anim->get_track_count();
+ for (int i = 0; i < track_len; i++) {
+ if (anim->track_get_path(i).get_name_count() == 0) {
+ return;
+ }
+ if (anim->track_get_path(i).get_name(0) == general_skeleton_pathname) {
+ bool replace = false;
+ if (anim->track_get_path(i).get_subname_count() > 0) {
+ int found = profile_skeleton->find_bone(anim->track_get_path(i).get_concatenated_subnames());
+ if (found < 0) {
+ replace = true;
+ }
+ } else {
+ replace = true;
+ }
+ if (replace) {
+ String path_string = UNIQUE_NODE_PREFIX + original_skeleton_name;
+ if (anim->track_get_path(i).get_name_count() > 1) {
+ Vector<StringName> names = anim->track_get_path(i).get_names();
+ names.remove_at(0);
+ for (int j = 0; j < names.size(); j++) {
+ path_string += "/" + names[i].operator String();
+ }
+ }
+ if (anim->track_get_path(i).get_subname_count() > 0) {
+ path_string = path_string + String(":") + anim->track_get_path(i).get_concatenated_subnames();
+ }
+ anim->track_set_path(i, path_string);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
bool keep_global_rest_leftovers = bool(p_options["retarget/rest_fixer/keep_global_rest_on_leftovers"]);
// Scan hierarchy and populate a whitelist of unmapped bones without mapped descendants.
+ // When both is_using_modifier and is_using_global_pose are enabled, this array is used for detecting warning.
Vector<int> keep_bone_rest;
- if (keep_global_rest_leftovers) {
+ if (is_using_modifier || keep_global_rest_leftovers) {
Vector<int> bones_to_process = src_skeleton->get_parentless_bones();
while (bones_to_process.size() > 0) {
int src_idx = bones_to_process[0];
@@ -526,12 +690,14 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
if (src_parent_idx >= 0) {
src_pg = src_skeleton->get_bone_global_rest(src_parent_idx).basis;
}
-
int prof_idx = profile->find_bone(src_bone_name);
if (prof_idx >= 0) {
- tgt_rot = src_pg.inverse() * prof_skeleton->get_bone_global_rest(prof_idx).basis; // Mapped bone uses reference pose.
+ // Mapped bone uses reference pose.
+ // It is fine to change rest here even though is_using_modifier is enabled, since next process is aborted with unmapped bones.
+ tgt_rot = src_pg.inverse() * prof_skeleton->get_bone_global_rest(prof_idx).basis;
} else if (keep_global_rest_leftovers && keep_bone_rest.has(src_idx)) {
- tgt_rot = src_pg.inverse() * old_skeleton_global_rest[src_idx].basis; // Non-Mapped bone without mapped children keeps global rest.
+ // Non-Mapped bones without mapped children keeps global rest.
+ tgt_rot = src_pg.inverse() * old_skeleton_global_rest[src_idx].basis;
}
}
@@ -548,7 +714,8 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
src_skeleton->set_bone_rest(src_idx, Transform3D(tgt_rot, diff.xform(src_skeleton->get_bone_rest(src_idx).origin)));
}
- // Fix animation.
+ // Fix animation by changing rest.
+ bool warning_detected = false;
{
TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer");
while (nodes.size()) {
@@ -573,7 +740,9 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
ERR_CONTINUE(!node);
Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node);
- if (!track_skeleton || track_skeleton != src_skeleton) {
+ if (!track_skeleton ||
+ (is_using_modifier && track_skeleton != profile_skeleton && track_skeleton != orig_skeleton) ||
+ (!is_using_modifier && track_skeleton != src_skeleton)) {
continue;
}
@@ -584,6 +753,16 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
int bone_idx = src_skeleton->find_bone(bn);
+ if (is_using_modifier) {
+ int prof_idx = profile->find_bone(bn);
+ if (prof_idx < 0) {
+ if (keep_bone_rest.has(bone_idx)) {
+ warning_detected = true;
+ }
+ continue; // If is_using_modifier, the original skeleton rest is not changed.
+ }
+ }
+
Transform3D old_rest = old_skeleton_rest[bone_idx];
Transform3D new_rest = src_skeleton->get_bone_rest(bone_idx);
Transform3D old_pg;
@@ -629,6 +808,13 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
}
}
}
+ if (is_using_global_pose && warning_detected) {
+ // TODO:
+ // Theoretically, if A and its conversion are calculated correctly taking into account the difference in the number of bones,
+ // there is no need to disable use_global_pose, but this is probably a fairly niche case.
+ WARN_PRINT_ED("Animated extra bone between mapped bones detected, consider disabling Use Global Pose option to prevent that the pose origin be overridden by the RetargetModifier3D.");
+ }
+
if (p_options.has("retarget/rest_fixer/reset_all_bone_poses_after_import") && !bool(p_options["retarget/rest_fixer/reset_all_bone_poses_after_import"])) {
// If Reset All Bone Poses After Import is disabled, preserve the original bone pose, adjusted for the new bone rolls.
for (int bone_idx = 0; bone_idx < src_skeleton->get_bone_count(); bone_idx++) {
@@ -654,6 +840,11 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
}
}
+ if (is_using_modifier) {
+ memdelete(src_skeleton);
+ src_skeleton = profile_skeleton;
+ }
+
is_rest_changed = true;
}
@@ -681,7 +872,9 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
ERR_CONTINUE(!node);
Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node);
- if (!track_skeleton || track_skeleton != src_skeleton) {
+ if (!track_skeleton ||
+ (is_using_modifier && track_skeleton != profile_skeleton && track_skeleton != orig_skeleton) ||
+ (!is_using_modifier && track_skeleton != src_skeleton)) {
continue;
}
@@ -696,7 +889,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
}
}
- if (is_rest_changed) {
+ if (!is_using_modifier && is_rest_changed) {
// Fix skin.
{
HashSet<Ref<Skin>> mutated_skins;
@@ -766,6 +959,14 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
src_skeleton->set_bone_pose_rotation(i, fixed_rest.basis.get_rotation_quaternion());
src_skeleton->set_bone_pose_scale(i, fixed_rest.basis.get_scale());
}
+ if (orig_skeleton) {
+ for (int i = 0; i < orig_skeleton->get_bone_count(); i++) {
+ Transform3D fixed_rest = orig_skeleton->get_bone_rest(i);
+ orig_skeleton->set_bone_pose_position(i, fixed_rest.origin);
+ orig_skeleton->set_bone_pose_rotation(i, fixed_rest.basis.get_rotation_quaternion());
+ orig_skeleton->set_bone_pose_scale(i, fixed_rest.basis.get_scale());
+ }
+ }
}
}
diff --git a/editor/import/3d/post_import_plugin_skeleton_track_organizer.cpp b/editor/import/3d/post_import_plugin_skeleton_track_organizer.cpp
index 53bcc59fcb..98312d3521 100644
--- a/editor/import/3d/post_import_plugin_skeleton_track_organizer.cpp
+++ b/editor/import/3d/post_import_plugin_skeleton_track_organizer.cpp
@@ -39,7 +39,7 @@ void PostImportPluginSkeletonTrackOrganizer::get_internal_import_options(Interna
if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) {
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/remove_tracks/except_bone_transform"), false));
r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/remove_tracks/unimportant_positions"), true));
- r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/remove_tracks/unmapped_bones"), false));
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "retarget/remove_tracks/unmapped_bones", PROPERTY_HINT_ENUM, "None,Remove,Separate Library"), 0));
}
}
@@ -61,9 +61,9 @@ void PostImportPluginSkeletonTrackOrganizer::internal_process(InternalImportCate
}
bool remove_except_bone = bool(p_options["retarget/remove_tracks/except_bone_transform"]);
bool remove_positions = bool(p_options["retarget/remove_tracks/unimportant_positions"]);
- bool remove_unmapped_bones = bool(p_options["retarget/remove_tracks/unmapped_bones"]);
+ int separate_unmapped_bones = int(p_options["retarget/remove_tracks/unmapped_bones"]);
- if (!remove_positions && !remove_unmapped_bones) {
+ if (!remove_positions && separate_unmapped_bones == 0) {
return;
}
@@ -72,10 +72,16 @@ void PostImportPluginSkeletonTrackOrganizer::internal_process(InternalImportCate
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back());
List<StringName> anims;
ap->get_animation_list(&anims);
+
+ Ref<AnimationLibrary> unmapped_al;
+ unmapped_al.instantiate();
+
for (const StringName &name : anims) {
Ref<Animation> anim = ap->get_animation(name);
int track_len = anim->get_track_count();
Vector<int> remove_indices;
+ Vector<int> mapped_bone_indices;
+ Vector<int> unmapped_bone_indices;
for (int i = 0; i < track_len; i++) {
String track_path = String(anim->track_get_path(i).get_concatenated_names());
Node *node = (ap->get_node(ap->get_root_node()))->get_node(NodePath(track_path));
@@ -96,16 +102,19 @@ void PostImportPluginSkeletonTrackOrganizer::internal_process(InternalImportCate
StringName bn = anim->track_get_path(i).get_subname(0);
if (bn) {
int prof_idx = profile->find_bone(bone_map->find_profile_bone_name(bn));
- if (remove_unmapped_bones && prof_idx < 0) {
- remove_indices.push_back(i);
+ if (prof_idx < 0) {
+ unmapped_bone_indices.push_back(i);
continue;
}
if (remove_positions && anim->track_get_type(i) == Animation::TYPE_POSITION_3D && prof_idx >= 0) {
StringName prof_bn = profile->get_bone_name(prof_idx);
if (prof_bn == profile->get_root_bone() || prof_bn == profile->get_scale_base_bone()) {
+ mapped_bone_indices.push_back(i);
continue;
}
remove_indices.push_back(i);
+ } else {
+ mapped_bone_indices.push_back(i);
}
}
}
@@ -114,11 +123,34 @@ void PostImportPluginSkeletonTrackOrganizer::internal_process(InternalImportCate
}
}
+ if (separate_unmapped_bones == 2 && !unmapped_bone_indices.is_empty()) {
+ Ref<Animation> unmapped_anim = anim->duplicate();
+ Vector<int> to_delete;
+ to_delete.append_array(mapped_bone_indices);
+ to_delete.append_array(remove_indices);
+ to_delete.sort();
+ to_delete.reverse();
+ for (int E : to_delete) {
+ unmapped_anim->remove_track(E);
+ }
+ unmapped_al->add_animation(name, unmapped_anim);
+ }
+
+ if (separate_unmapped_bones >= 1) {
+ remove_indices.append_array(unmapped_bone_indices);
+ remove_indices.sort();
+ }
remove_indices.reverse();
for (int i = 0; i < remove_indices.size(); i++) {
anim->remove_track(remove_indices[i]);
}
}
+
+ if (unmapped_al->get_animation_list_size() == 0) {
+ unmapped_al.unref();
+ } else if (separate_unmapped_bones == 2) {
+ ap->add_animation_library("unmapped_bones", unmapped_al);
+ }
}
}
}
diff --git a/editor/import/3d/resource_importer_scene.cpp b/editor/import/3d/resource_importer_scene.cpp
index 6c45d89125..9ab97abd56 100644
--- a/editor/import/3d/resource_importer_scene.cpp
+++ b/editor/import/3d/resource_importer_scene.cpp
@@ -2313,6 +2313,7 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor
}
}
+ // TODO: If there are more than 2 or equal get_internal_option_visibility method, visibility state is broken.
for (int i = 0; i < post_importer_plugins.size(); i++) {
Variant ret = post_importer_plugins.write[i]->get_internal_option_visibility(EditorScenePostImportPlugin::InternalImportCategory(p_category), _scene_import_type, p_option, p_options);
if (ret.get_type() == Variant::BOOL) {
diff --git a/editor/plugins/camera_3d_editor_plugin.cpp b/editor/plugins/camera_3d_editor_plugin.cpp
index f4116ed364..10ed7d1902 100644
--- a/editor/plugins/camera_3d_editor_plugin.cpp
+++ b/editor/plugins/camera_3d_editor_plugin.cpp
@@ -30,8 +30,11 @@
#include "camera_3d_editor_plugin.h"
+#include "core/config/project_settings.h"
#include "editor/editor_node.h"
#include "node_3d_editor_plugin.h"
+#include "scene/gui/texture_rect.h"
+#include "scene/main/viewport.h"
void Camera3DEditor::_node_removed(Node *p_node) {
if (p_node == node) {
@@ -76,9 +79,35 @@ Camera3DEditor::Camera3DEditor() {
preview->connect(SceneStringName(pressed), callable_mp(this, &Camera3DEditor::_pressed));
}
+void Camera3DPreview::_update_sub_viewport_size() {
+ sub_viewport->set_size(Node3DEditor::get_camera_viewport_size(camera));
+}
+
+Camera3DPreview::Camera3DPreview(Camera3D *p_camera) :
+ TexturePreview(nullptr, false), camera(p_camera), sub_viewport(memnew(SubViewport)) {
+ RenderingServer::get_singleton()->viewport_attach_camera(sub_viewport->get_viewport_rid(), camera->get_camera());
+ add_child(sub_viewport);
+
+ TextureRect *display = get_texture_display();
+ display->set_texture(sub_viewport->get_texture());
+ sub_viewport->connect("size_changed", callable_mp((CanvasItem *)display, &CanvasItem::queue_redraw));
+
+ ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Camera3DPreview::_update_sub_viewport_size));
+ _update_sub_viewport_size();
+}
+
+bool EditorInspectorPluginCamera3DPreview::can_handle(Object *p_object) {
+ return Object::cast_to<Camera3D>(p_object) != nullptr;
+}
+
+void EditorInspectorPluginCamera3DPreview::parse_begin(Object *p_object) {
+ Camera3D *camera = Object::cast_to<Camera3D>(p_object);
+ Camera3DPreview *preview = memnew(Camera3DPreview(camera));
+ add_custom_control(preview);
+}
+
void Camera3DEditorPlugin::edit(Object *p_object) {
Node3DEditor::get_singleton()->set_can_preview(Object::cast_to<Camera3D>(p_object));
- //camera_editor->edit(Object::cast_to<Node>(p_object));
}
bool Camera3DEditorPlugin::handles(Object *p_object) const {
@@ -86,27 +115,15 @@ bool Camera3DEditorPlugin::handles(Object *p_object) const {
}
void Camera3DEditorPlugin::make_visible(bool p_visible) {
- if (p_visible) {
- //Node3DEditor::get_singleton()->set_can_preview(Object::cast_to<Camera3D>(p_object));
- } else {
+ if (!p_visible) {
Node3DEditor::get_singleton()->set_can_preview(nullptr);
}
}
Camera3DEditorPlugin::Camera3DEditorPlugin() {
- /* camera_editor = memnew( CameraEditor );
- EditorNode::get_singleton()->get_main_screen_control()->add_child(camera_editor);
-
- camera_editor->set_anchor(SIDE_LEFT,Control::ANCHOR_END);
- camera_editor->set_anchor(SIDE_RIGHT,Control::ANCHOR_END);
- camera_editor->set_offset(SIDE_LEFT,60);
- camera_editor->set_offset(SIDE_RIGHT,0);
- camera_editor->set_offset(SIDE_TOP,0);
- camera_editor->set_offset(SIDE_BOTTOM,10);
-
-
- camera_editor->hide();
-*/
+ Ref<EditorInspectorPluginCamera3DPreview> plugin;
+ plugin.instantiate();
+ add_inspector_plugin(plugin);
}
Camera3DEditorPlugin::~Camera3DEditorPlugin() {
diff --git a/editor/plugins/camera_3d_editor_plugin.h b/editor/plugins/camera_3d_editor_plugin.h
index 1c6838aa02..98d0bcc40c 100644
--- a/editor/plugins/camera_3d_editor_plugin.h
+++ b/editor/plugins/camera_3d_editor_plugin.h
@@ -32,7 +32,10 @@
#define CAMERA_3D_EDITOR_PLUGIN_H
#include "editor/plugins/editor_plugin.h"
-#include "scene/3d/camera_3d.h"
+#include "editor/plugins/texture_editor_plugin.h"
+
+class Camera3D;
+class SubViewport;
class Camera3DEditor : public Control {
GDCLASS(Camera3DEditor, Control);
@@ -51,11 +54,29 @@ public:
Camera3DEditor();
};
+class Camera3DPreview : public TexturePreview {
+ GDCLASS(Camera3DPreview, TexturePreview);
+
+ Camera3D *camera = nullptr;
+ SubViewport *sub_viewport = nullptr;
+
+ void _update_sub_viewport_size();
+
+public:
+ Camera3DPreview(Camera3D *p_camera);
+};
+
+class EditorInspectorPluginCamera3DPreview : public EditorInspectorPluginTexture {
+ GDCLASS(EditorInspectorPluginCamera3DPreview, EditorInspectorPluginTexture);
+
+public:
+ virtual bool can_handle(Object *p_object) override;
+ virtual void parse_begin(Object *p_object) override;
+};
+
class Camera3DEditorPlugin : public EditorPlugin {
GDCLASS(Camera3DEditorPlugin, EditorPlugin);
- //CameraEditor *camera_editor;
-
public:
virtual String get_name() const override { return "Camera3D"; }
bool has_main_screen() const override { return false; }
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index f91a052a24..f73867575d 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1995,15 +1995,14 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
}
}
+ Transform2D edit_transform;
+ bool using_temp_pivot = !Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y);
+ if (using_temp_pivot) {
+ edit_transform = Transform2D(drag_selection.front()->get()->_edit_get_rotation(), temp_pivot);
+ } else {
+ edit_transform = drag_selection.front()->get()->_edit_get_transform();
+ }
for (CanvasItem *ci : drag_selection) {
- Transform2D edit_transform;
- bool using_temp_pivot = !Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y);
- if (using_temp_pivot) {
- edit_transform = Transform2D(ci->_edit_get_rotation(), temp_pivot);
- } else {
- edit_transform = ci->_edit_get_transform();
- }
-
Transform2D parent_xform = ci->get_global_transform_with_canvas() * ci->get_transform().affine_inverse();
Transform2D unscaled_transform = (transform * parent_xform * edit_transform).orthonormalized();
Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform;
@@ -3612,7 +3611,7 @@ void CanvasItemEditor::_draw_selection() {
// Remove non-movable nodes.
for (CanvasItem *ci : selection) {
- if (!_is_node_movable(ci, true)) {
+ if (!_is_node_movable(ci)) {
selection.erase(ci);
}
}
@@ -3913,7 +3912,7 @@ void CanvasItemEditor::_draw_message() {
Ref<Font> font = get_theme_font(SceneStringName(font), SNAME("Label"));
int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label"));
- Point2 msgpos = Point2(RULER_WIDTH + 5 * EDSCALE, viewport->get_size().y - 20 * EDSCALE);
+ Point2 msgpos = Point2(RULER_WIDTH + 10 * EDSCALE, viewport->get_size().y - 14 * EDSCALE);
viewport->draw_string(font, msgpos + Point2(1, 1), message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
viewport->draw_string(font, msgpos + Point2(-1, -1), message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
viewport->draw_string(font, msgpos, message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 1));
diff --git a/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp
index 63a48d4165..359bb59098 100644
--- a/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp
@@ -46,24 +46,6 @@ Camera3DGizmoPlugin::Camera3DGizmoPlugin() {
create_handle_material("handles");
}
-Size2i Camera3DGizmoPlugin::_get_viewport_size(Camera3D *p_camera) {
- Viewport *viewport = p_camera->get_viewport();
-
- Window *window = Object::cast_to<Window>(viewport);
- if (window) {
- return window->get_size();
- }
-
- SubViewport *sub_viewport = Object::cast_to<SubViewport>(viewport);
- ERR_FAIL_NULL_V(sub_viewport, Size2i());
-
- if (sub_viewport == EditorNode::get_singleton()->get_scene_root()) {
- return Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
- }
-
- return sub_viewport->get_size();
-}
-
bool Camera3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<Camera3D>(p_spatial) != nullptr;
}
@@ -166,7 +148,7 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Ref<Material> material = get_material("camera_material", p_gizmo);
Ref<Material> icon = get_material("camera_icon", p_gizmo);
- const Size2i viewport_size = _get_viewport_size(camera);
+ const Size2i viewport_size = Node3DEditor::get_camera_viewport_size(camera);
const real_t viewport_aspect = viewport_size.x > 0 && viewport_size.y > 0 ? viewport_size.aspect() : 1.0;
const Size2 size_factor = viewport_aspect > 1.0 ? Size2(1.0, 1.0 / viewport_aspect) : Size2(viewport_aspect, 1.0);
diff --git a/editor/plugins/gizmos/camera_3d_gizmo_plugin.h b/editor/plugins/gizmos/camera_3d_gizmo_plugin.h
index ba65ebb8de..94238704c1 100644
--- a/editor/plugins/gizmos/camera_3d_gizmo_plugin.h
+++ b/editor/plugins/gizmos/camera_3d_gizmo_plugin.h
@@ -37,7 +37,6 @@ class Camera3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(Camera3DGizmoPlugin, EditorNode3DGizmoPlugin);
private:
- static Size2i _get_viewport_size(Camera3D *p_camera);
static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vector3 &p_to, float p_arc_radius, const Transform3D &p_arc_xform);
public:
diff --git a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp
index 573c686d57..b92abbcf79 100644
--- a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp
@@ -49,17 +49,47 @@
CollisionShape3DGizmoPlugin::CollisionShape3DGizmoPlugin() {
helper.instantiate();
- const Color gizmo_color = SceneTree::get_singleton()->get_debug_collisions_color();
- create_material("shape_material", gizmo_color);
- const float gizmo_value = gizmo_color.get_v();
- const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65);
- create_material("shape_material_disabled", gizmo_color_disabled);
+
+ create_collision_material("shape_material", 2.0);
+ create_collision_material("shape_material_arraymesh", 0.0625);
+
+ create_collision_material("shape_material_disabled", 0.0625);
+ create_collision_material("shape_material_arraymesh_disabled", 0.015625);
+
create_handle_material("handles");
}
CollisionShape3DGizmoPlugin::~CollisionShape3DGizmoPlugin() {
}
+void CollisionShape3DGizmoPlugin::create_collision_material(const String &p_name, float p_alpha) {
+ Vector<Ref<StandardMaterial3D>> mats;
+
+ const Color collision_color(1.0, 1.0, 1.0, p_alpha);
+
+ for (int i = 0; i < 4; i++) {
+ bool instantiated = i < 2;
+
+ Ref<StandardMaterial3D> material = memnew(StandardMaterial3D);
+
+ Color color = collision_color;
+ color.a *= instantiated ? 0.25 : 1.0;
+
+ material->set_albedo(color);
+ material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
+ material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MIN + 1);
+ material->set_cull_mode(StandardMaterial3D::CULL_BACK);
+ material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true);
+ material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
+
+ mats.push_back(material);
+ }
+
+ materials[p_name] = mats;
+}
+
bool CollisionShape3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<CollisionShape3D>(p_spatial) != nullptr;
}
@@ -311,9 +341,20 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
return;
}
- const Ref<Material> material =
+ const Ref<StandardMaterial3D> material =
get_material(!cs->is_disabled() ? "shape_material" : "shape_material_disabled", p_gizmo);
- Ref<Material> handles_material = get_material("handles");
+ const Ref<StandardMaterial3D> material_arraymesh =
+ get_material(!cs->is_disabled() ? "shape_material_arraymesh" : "shape_material_arraymesh_disabled", p_gizmo);
+ const Ref<Material> handles_material = get_material("handles");
+
+ const Color collision_color = cs->is_disabled() ? Color(1.0, 1.0, 1.0, 0.75) : cs->get_debug_color();
+
+ if (cs->get_debug_fill_enabled()) {
+ Ref<ArrayMesh> array_mesh = s->get_debug_arraymesh_faces(collision_color);
+ if (array_mesh.is_valid()) {
+ p_gizmo->add_mesh(array_mesh, material_arraymesh);
+ }
+ }
if (Object::cast_to<SphereShape3D>(*s)) {
Ref<SphereShape3D> sp = s;
@@ -351,7 +392,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
collision_segments.push_back(Vector3(b.x, b.y, 0));
}
- p_gizmo->add_lines(points, material);
+ p_gizmo->add_lines(points, material, false, collision_color);
p_gizmo->add_collision_segments(collision_segments);
Vector<Vector3> handles;
handles.push_back(Vector3(r, 0, 0));
@@ -374,7 +415,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
const Vector<Vector3> handles = helper->box_get_handles(bs->get_size());
- p_gizmo->add_lines(lines, material);
+ p_gizmo->add_lines(lines, material, false, collision_color);
p_gizmo->add_collision_segments(lines);
p_gizmo->add_handles(handles, handles_material);
}
@@ -412,7 +453,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
points.push_back(Vector3(b.y, b.x, 0) + dud);
}
- p_gizmo->add_lines(points, material);
+ p_gizmo->add_lines(points, material, false, collision_color);
Vector<Vector3> collision_segments;
@@ -476,7 +517,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
}
- p_gizmo->add_lines(points, material);
+ p_gizmo->add_lines(points, material, false, collision_color);
Vector<Vector3> collision_segments;
@@ -531,7 +572,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p.normal * p.d + p.normal * 3
};
- p_gizmo->add_lines(points, material);
+ p_gizmo->add_lines(points, material, false, collision_color);
p_gizmo->add_collision_segments(points);
}
@@ -549,7 +590,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
lines.write[i * 2 + 0] = md.vertices[md.edges[i].vertex_a];
lines.write[i * 2 + 1] = md.vertices[md.edges[i].vertex_b];
}
- p_gizmo->add_lines(lines, material);
+ p_gizmo->add_lines(lines, material, false, collision_color);
p_gizmo->add_collision_segments(lines);
}
}
@@ -558,7 +599,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
if (Object::cast_to<ConcavePolygonShape3D>(*s)) {
Ref<ConcavePolygonShape3D> cs2 = s;
Ref<ArrayMesh> mesh = cs2->get_debug_mesh();
- p_gizmo->add_mesh(mesh, material);
+ p_gizmo->add_lines(cs2->get_debug_mesh_lines(), material, false, collision_color);
p_gizmo->add_collision_segments(cs2->get_debug_mesh_lines());
}
@@ -569,7 +610,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector3(),
Vector3(0, 0, rs->get_length())
};
- p_gizmo->add_lines(points, material);
+ p_gizmo->add_lines(points, material, false, collision_color);
p_gizmo->add_collision_segments(points);
Vector<Vector3> handles;
handles.push_back(Vector3(0, 0, rs->get_length()));
@@ -579,7 +620,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
if (Object::cast_to<HeightMapShape3D>(*s)) {
Ref<HeightMapShape3D> hms = s;
- Ref<ArrayMesh> mesh = hms->get_debug_mesh();
- p_gizmo->add_mesh(mesh, material);
+ Vector<Vector3> lines = hms->get_debug_mesh_lines();
+ p_gizmo->add_lines(lines, material, false, collision_color);
}
}
diff --git a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h
index 464012acf9..09590fba58 100644
--- a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h
+++ b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h
@@ -38,6 +38,8 @@ class Gizmo3DHelper;
class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(CollisionShape3DGizmoPlugin, EditorNode3DGizmoPlugin);
+ void create_collision_material(const String &p_name, float p_alpha);
+
Ref<Gizmo3DHelper> helper;
public:
diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp
index 4cff3504f5..3f21d5d11c 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.cpp
+++ b/editor/plugins/lightmap_gi_editor_plugin.cpp
@@ -152,7 +152,7 @@ EditorProgress *LightmapGIEditorPlugin::tmp_progress = nullptr;
bool LightmapGIEditorPlugin::bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh) {
if (!tmp_progress) {
- tmp_progress = memnew(EditorProgress("bake_lightmaps", TTR("Bake Lightmaps"), 1000, false));
+ tmp_progress = memnew(EditorProgress("bake_lightmaps", TTR("Bake Lightmaps"), 1000, true));
ERR_FAIL_NULL_V(tmp_progress, false);
}
return tmp_progress->step(p_description, p_progress * 1000, p_refresh);
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 8aff3c9aec..b716e925cb 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -292,14 +292,11 @@ void EditorNode3DGizmo::add_vertices(const Vector<Vector3> &p_vertices, const Re
Vector<Color> color;
color.resize(p_vertices.size());
+ const Color vertex_color = (is_selected() ? Color(1, 1, 1, 0.8) : Color(1, 1, 1, 0.2)) * p_modulate;
{
Color *w = color.ptrw();
for (int i = 0; i < p_vertices.size(); i++) {
- if (is_selected()) {
- w[i] = Color(1, 1, 1, 0.8) * p_modulate;
- } else {
- w[i] = Color(1, 1, 1, 0.2) * p_modulate;
- }
+ w[i] = vertex_color;
}
}
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 810d1674ca..c321ff1db5 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -92,6 +92,7 @@
#include "scene/gui/center_container.h"
#include "scene/gui/color_picker.h"
#include "scene/gui/flow_container.h"
+#include "scene/gui/separator.h"
#include "scene/gui/split_container.h"
#include "scene/gui/subviewport_container.h"
#include "scene/resources/3d/sky_material.h"
@@ -3265,7 +3266,7 @@ void Node3DEditorViewport::_draw() {
if (message_time > 0) {
Ref<Font> font = get_theme_font(SceneStringName(font), SNAME("Label"));
int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label"));
- Point2 msgpos = Point2(5, get_size().y - 20);
+ Point2 msgpos = Point2(10 * EDSCALE, get_size().y - 14 * EDSCALE);
font->draw_string(ci, msgpos + Point2(1, 1), message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
font->draw_string(ci, msgpos + Point2(-1, -1), message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
font->draw_string(ci, msgpos, message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 1));
@@ -8818,7 +8819,12 @@ Node3DEditor::Node3DEditor() {
ED_SHORTCUT("spatial_editor/focus_origin", TTR("Focus Origin"), Key::O);
ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), Key::F);
ED_SHORTCUT_ARRAY("spatial_editor/align_transform_with_view", TTR("Align Transform with View"),
- { int32_t(KeyModifierMask::ALT | KeyModifierMask::CMD_OR_CTRL | Key::KP_0), int32_t(KeyModifierMask::ALT | KeyModifierMask::CMD_OR_CTRL | Key::M) });
+ { int32_t(KeyModifierMask::ALT | KeyModifierMask::CTRL | Key::KP_0),
+ int32_t(KeyModifierMask::ALT | KeyModifierMask::CTRL | Key::M),
+ int32_t(KeyModifierMask::ALT | KeyModifierMask::CTRL | Key::G) });
+ ED_SHORTCUT_OVERRIDE_ARRAY("spatial_editor/align_transform_with_view", "macos",
+ { int32_t(KeyModifierMask::ALT | KeyModifierMask::META | Key::KP_0),
+ int32_t(KeyModifierMask::ALT | KeyModifierMask::META | Key::G) });
ED_SHORTCUT("spatial_editor/align_rotation_with_view", TTR("Align Rotation with View"), KeyModifierMask::ALT + KeyModifierMask::CMD_OR_CTRL + Key::F);
ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KeyModifierMask::SHIFT + Key::F);
ED_SHORTCUT("spatial_editor/decrease_fov", TTR("Decrease Field of View"), KeyModifierMask::CMD_OR_CTRL + Key::EQUAL); // Usually direct access key for `KEY_PLUS`.
@@ -9302,6 +9308,24 @@ void Node3DEditorPlugin::set_state(const Dictionary &p_state) {
spatial_editor->set_state(p_state);
}
+Size2i Node3DEditor::get_camera_viewport_size(Camera3D *p_camera) {
+ Viewport *viewport = p_camera->get_viewport();
+
+ Window *window = Object::cast_to<Window>(viewport);
+ if (window) {
+ return window->get_size();
+ }
+
+ SubViewport *sub_viewport = Object::cast_to<SubViewport>(viewport);
+ ERR_FAIL_NULL_V(sub_viewport, Size2i());
+
+ if (sub_viewport == EditorNode::get_singleton()->get_scene_root()) {
+ return Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
+ }
+
+ return sub_viewport->get_size();
+}
+
Vector3 Node3DEditor::snap_point(Vector3 p_target, Vector3 p_start) const {
if (is_snap_enabled()) {
real_t snap = get_translate_snap();
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index d35fcb7653..27db7f27f3 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -880,6 +880,8 @@ protected:
public:
static Node3DEditor *get_singleton() { return singleton; }
+ static Size2i get_camera_viewport_size(Camera3D *p_camera);
+
Vector3 snap_point(Vector3 p_target, Vector3 p_start = Vector3(0, 0, 0)) const;
float get_znear() const { return settings_znear->get_value(); }
diff --git a/editor/plugins/plugin_config_dialog.cpp b/editor/plugins/plugin_config_dialog.cpp
index af9efda939..c3e87c508e 100644
--- a/editor/plugins/plugin_config_dialog.cpp
+++ b/editor/plugins/plugin_config_dialog.cpp
@@ -305,7 +305,7 @@ PluginConfigDialog::PluginConfigDialog() {
grid->add_child(script_name_label);
script_edit = memnew(LineEdit);
- script_edit->set_tooltip_text(TTR("Optional. The path to the script (relative to the add-on folder). If left empty, will default to \"plugin.gd\"."));
+ script_edit->set_tooltip_text(TTR("Optional. The name of the script file. If left empty, will default to the subfolder name."));
script_edit->set_placeholder("\"plugin.gd\" -> res://addons/my_plugin/plugin.gd");
script_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
grid->add_child(script_edit);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 49ecbac751..2ed819baf4 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -64,6 +64,8 @@
#include "editor/themes/editor_scale.h"
#include "editor/themes/editor_theme_manager.h"
#include "editor/window_wrapper.h"
+#include "scene/gui/separator.h"
+#include "scene/gui/texture_rect.h"
#include "scene/main/node.h"
#include "scene/main/window.h"
#include "script_text_editor.h"
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index cf586c792e..a28d709b15 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_string_names.h"
#include "editor/gui/editor_toaster.h"
#include "editor/themes/editor_scale.h"
+#include "scene/gui/menu_button.h"
#include "scene/gui/rich_text_label.h"
#include "scene/gui/split_container.h"
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index de75ed8c12..b5ddf2f48b 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -48,6 +48,8 @@
#include "scene/gui/option_button.h"
#include "scene/gui/panel_container.h"
#include "scene/gui/scroll_container.h"
+#include "scene/gui/separator.h"
+#include "scene/gui/spin_box.h"
#include "scene/gui/split_container.h"
#include "scene/gui/tab_bar.h"
#include "scene/gui/tab_container.h"
diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp
index ea5e8a8ad7..3790b23f76 100644
--- a/editor/plugins/theme_editor_preview.cpp
+++ b/editor/plugins/theme_editor_preview.cpp
@@ -41,9 +41,15 @@
#include "scene/gui/check_button.h"
#include "scene/gui/color_picker.h"
#include "scene/gui/color_rect.h"
+#include "scene/gui/label.h"
#include "scene/gui/margin_container.h"
+#include "scene/gui/menu_button.h"
+#include "scene/gui/option_button.h"
+#include "scene/gui/panel.h"
#include "scene/gui/progress_bar.h"
#include "scene/gui/scroll_container.h"
+#include "scene/gui/separator.h"
+#include "scene/gui/spin_box.h"
#include "scene/gui/tab_container.h"
#include "scene/gui/text_edit.h"
#include "scene/gui/tree.h"
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 987002f472..69492081e0 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -59,6 +59,7 @@
#include "scene/gui/rich_text_label.h"
#include "scene/gui/separator.h"
#include "scene/gui/split_container.h"
+#include "scene/gui/texture_rect.h"
#include "scene/gui/tree.h"
#include "scene/gui/view_panner.h"
#include "scene/main/window.h"
@@ -6879,8 +6880,10 @@ VisualShaderEditor::VisualShaderEditor() {
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", "VisualShaderNodeColorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeColorFunc::FUNC_HSV2RGB, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("LinearToSRGB", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Converts color from linear to sRGB color space."), { VisualShaderNodeColorFunc::FUNC_LINEAR_TO_SRGB }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("RGB2HSV", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeColorFunc::FUNC_RGB2HSV, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, 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("SRGBToLinear", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Converts color from sRGB to linear color space."), { VisualShaderNodeColorFunc::FUNC_SRGB_TO_LINEAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
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));
diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp
index 68fe013c08..527138e060 100644
--- a/editor/plugins/voxel_gi_editor_plugin.cpp
+++ b/editor/plugins/voxel_gi_editor_plugin.cpp
@@ -146,15 +146,15 @@ void VoxelGIEditorPlugin::make_visible(bool p_visible) {
EditorProgress *VoxelGIEditorPlugin::tmp_progress = nullptr;
-void VoxelGIEditorPlugin::bake_func_begin(int p_steps) {
+void VoxelGIEditorPlugin::bake_func_begin() {
ERR_FAIL_COND(tmp_progress != nullptr);
- tmp_progress = memnew(EditorProgress("bake_gi", TTR("Bake VoxelGI"), p_steps));
+ tmp_progress = memnew(EditorProgress("bake_gi", TTR("Bake VoxelGI"), 1000, true));
}
-void VoxelGIEditorPlugin::bake_func_step(int p_step, const String &p_description) {
- ERR_FAIL_NULL(tmp_progress);
- tmp_progress->step(p_description, p_step, false);
+bool VoxelGIEditorPlugin::bake_func_step(int p_progress, const String &p_description) {
+ ERR_FAIL_NULL_V(tmp_progress, false);
+ return tmp_progress->step(p_description, p_progress, false);
}
void VoxelGIEditorPlugin::bake_func_end() {
diff --git a/editor/plugins/voxel_gi_editor_plugin.h b/editor/plugins/voxel_gi_editor_plugin.h
index d09822dda6..01a2ab4bd1 100644
--- a/editor/plugins/voxel_gi_editor_plugin.h
+++ b/editor/plugins/voxel_gi_editor_plugin.h
@@ -50,8 +50,8 @@ class VoxelGIEditorPlugin : public EditorPlugin {
EditorFileDialog *probe_file = nullptr;
static EditorProgress *tmp_progress;
- static void bake_func_begin(int p_steps);
- static void bake_func_step(int p_step, const String &p_description);
+ static void bake_func_begin();
+ static bool bake_func_step(int p_progress, const String &p_description);
static void bake_func_end();
void _bake();