diff --git a/.github/workflows/all_builds.yml b/.github/workflows/all_builds.yml index ea5590cc..0e5f4785 100644 --- a/.github/workflows/all_builds.yml +++ b/.github/workflows/all_builds.yml @@ -28,7 +28,7 @@ env: # TODO: change this back to godotengine/godot and target master when #109685 and #109475 are merged GODOT_REPOSITORY: nikitalita/godot # Change the README too - GODOT_MAIN_SYNC_REF: gdre-wb-e2a10cd4 + GODOT_MAIN_SYNC_REF: gdre-wb-63227bb SCONSFLAGS: verbose=yes warnings=all werror=no module_text_server_fb_enabled=yes minizip=yes deprecated=yes SCONSFLAGS_TEMPLATE: no_editor_splash=yes module_camera_enabled=no module_mobile_vr_enabled=no module_upnp_enabled=no module_websocket_enabled=no module_csg_enabled=yes module_gridmap_enabled=yes use_static_cpp=yes builtin_freetype=yes builtin_libpng=yes builtin_zlib=yes builtin_libwebp=yes builtin_libvorbis=yes builtin_libogg=yes disable_3d=no SCONS_CACHE_MSVC_CONFIG: true @@ -367,7 +367,6 @@ jobs: shell: bash run: | ${{matrix.bin}} --headless --test --force-colors "--test-case=[GDSDecomp]*" - export: needs: build runs-on: ${{ matrix.os }} diff --git a/.scripts/rebase_godot.sh b/.scripts/rebase_godot.sh index 8b38b9d3..0595d55f 100755 --- a/.scripts/rebase_godot.sh +++ b/.scripts/rebase_godot.sh @@ -19,6 +19,9 @@ git checkout working-branch git reset --hard $HEAD BRANCHES_TO_MERGE=( + gltf-dupe-images + material-fix-deprecated-param + fix-dummy-mesh-blend-shape fix-pack-error convert-3.x-escn fix-svg diff --git a/README.md b/README.md index 500344d7..6d5ca06f 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ Note: Make sure to build the editor build first, and to launch the editor to edi ### Requirements -[Our fork of godot](https://github.com/nikitalita/godot/tree/working-branch) @ `gdre-wb-e2a10cd4` +[Our fork of godot](https://github.com/nikitalita/godot/tree/working-branch) @ `gdre-wb-63227bb` - Support for building on 3.x has been dropped and no new features are being pushed - Godot RE Tools still retains the ability to decompile 3.x and 2.x projects, however. diff --git a/SCsub b/SCsub index 8bee7da6..18c095fe 100644 --- a/SCsub +++ b/SCsub @@ -43,7 +43,6 @@ if env["platform"] == "android" or (is_using_clang and env["platform"] == "macos # force shared on macos with clang++, because `ld` does not support multiple definitions of the same symbol mono_native_lib_type = "Shared" -etcpak_dir = "#thirdparty/etcpak/" mmp3thirdparty_dir = "#thirdparty/minimp3/" liboggthirdparty_dir = "#thirdparty/libogg/" libtheorathirdparty_dir = "#thirdparty/libtheora/" @@ -195,7 +194,6 @@ def write_version_header(): write_version_header() -env_gdsdecomp.Prepend(CPPPATH=[etcpak_dir]) if env["builtin_libogg"]: env_gdsdecomp.Prepend(CPPPATH=[liboggthirdparty_dir]) if env["builtin_libvorbis"]: @@ -862,7 +860,6 @@ if env["tests"]: env_gdsdecomp.add_source_files(module_obj, "utility/*.cpp") env_gdsdecomp.add_source_files(module_obj, "external/tga/*.cpp") -env_gdsdecomp.add_source_files(module_obj, "external/etcpak-decompress/*.cpp") env_gdsdecomp.add_source_files(module_obj, "external/tinygltf/tiny_gltf.cc") env_gdsdecomp.add_source_files(module_obj, "module_etc_decompress/*.cpp") diff --git a/compat/resource_compat_binary.cpp b/compat/resource_compat_binary.cpp index 9e82b163..37c49613 100644 --- a/compat/resource_compat_binary.cpp +++ b/compat/resource_compat_binary.cpp @@ -972,7 +972,16 @@ Error ResourceLoaderCompatBinary::load() { if (!missing_resource && ver_major <= 2 && name == "resource/name") { name = "resource_name"; } - res->set(name, value); + bool valid = false; + res->set(name, value, &valid); + if (!valid) { + missing_resource_properties[name] = value; +#ifdef DEBUG_ENABLED + if (ver_major < GODOT_VERSION_MAJOR) { + WARN_PRINT(vformat("Failed to set deprecated %d.%d property '%s' (type: %s) on res class '%s' (remap: %s)", ver_major, ver_minor, name, Variant::get_type_name(value.get_type()), t, res->get_class())); + } +#endif + } } } diff --git a/compat/resource_compat_text.cpp b/compat/resource_compat_text.cpp index 6d82217e..713746ac 100644 --- a/compat/resource_compat_text.cpp +++ b/compat/resource_compat_text.cpp @@ -803,7 +803,16 @@ Error ResourceLoaderCompatText::load() { if (!missing_resource && ver_major <= 2 && assign == "resource/name") { assign = "resource_name"; } - res->set(assign, value); + bool valid = false; + res->set(assign, value, &valid); + if (!valid) { + missing_resource_properties[assign] = value; +#ifdef DEBUG_ENABLED + if (ver_major < GODOT_VERSION_MAJOR) { + WARN_PRINT(vformat("Failed to set deprecated %d.%d property '%s' (type: %s) on res class '%s' (class remap: %s)", ver_major, ver_minor, assign, Variant::get_type_name(value.get_type()), type, res->get_class())); + } +#endif + } } } //it's assignment @@ -1010,7 +1019,16 @@ Error ResourceLoaderCompatText::load() { if (!missing_resource && ver_major <= 2 && assign == "resource/name") { assign = "resource_name"; } - resource->set(assign, value); + bool valid = false; + resource->set(assign, value, &valid); + if (!valid) { + missing_resource_properties[assign] = value; +#ifdef DEBUG_ENABLED + if (ver_major < GODOT_VERSION_MAJOR) { + WARN_PRINT(vformat("Failed to set deprecated %d.%d property '%s' (type: %s) on res class '%s' (class remap: %s)", ver_major, ver_minor, assign, Variant::get_type_name(value.get_type()), res_type, resource->get_class())); + } +#endif + } } //it's assignment } else if (!next_tag.name.is_empty()) { diff --git a/editor/gdre_editor.cpp b/editor/gdre_editor.cpp index 7fcbb8cd..a8d2e5b2 100644 --- a/editor/gdre_editor.cpp +++ b/editor/gdre_editor.cpp @@ -258,6 +258,22 @@ void GodotREEditor::init_gui(Control *p_control, HBoxContainer *p_menu, bool p_l smpl_file_selection->set_current_dir(desktop_dir); p_control->add_child(smpl_file_selection); + export_resource_file_selection = memnew(FileDialog); + export_resource_file_selection->set_access(FileDialog::ACCESS_FILESYSTEM); + export_resource_file_selection->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE); + export_resource_file_selection->connect("file_selected", callable_mp(this, &GodotREEditor::_export_resource_request)); + export_resource_file_selection->set_show_hidden_files(true); + export_resource_file_selection->set_current_dir(desktop_dir); + p_control->add_child(export_resource_file_selection); + + export_resource_output_selection = memnew(FileDialog); + export_resource_output_selection->set_access(FileDialog::ACCESS_FILESYSTEM); + export_resource_output_selection->set_file_mode(FileDialog::FILE_MODE_SAVE_FILE); + export_resource_output_selection->connect("file_selected", callable_mp(this, &GodotREEditor::_export_resource_output_request)); + export_resource_output_selection->set_show_hidden_files(true); + export_resource_output_selection->set_current_dir(desktop_dir); + p_control->add_child(export_resource_output_selection); + //Init about/warning dialog { about_dialog = memnew(AcceptDialog); @@ -344,6 +360,8 @@ void GodotREEditor::init_gui(Control *p_control, HBoxContainer *p_menu, bool p_l menu_popup->add_icon_item(GDREGuiIcons::get_icon("REResOther", scale), RTR("Convert stream textures to PNG..."), MENU_STEX_TO_PNG); menu_popup->add_icon_item(GDREGuiIcons::get_icon("REResOther", scale), RTR("Convert OGG Samples to OGG..."), MENU_OSTR_TO_OGG); menu_popup->add_icon_item(GDREGuiIcons::get_icon("REResOther", scale), RTR("Convert WAV Samples to WAV..."), MENU_SMPL_TO_WAV); + menu_popup->add_icon_item(GDREGuiIcons::get_icon("REResOther", scale), RTR("Export Resource..."), MENU_EXPORT_RESOURCE); + menu_popup->connect("id_pressed", callable_mp(this, &GodotREEditor::menu_option_pressed)); menu_button->set_anchor(Side::SIDE_TOP, 0); p_menu->add_child(menu_button); @@ -374,6 +392,7 @@ void GodotREEditor::init_gui(Control *p_control, HBoxContainer *p_menu, bool p_l menu_popup->add_icon_item(GDREGuiIcons::get_icon("REResOther", scale), RTR("Convert stream textures to PNG..."), MENU_STEX_TO_PNG); menu_popup->add_icon_item(GDREGuiIcons::get_icon("REResOther", scale), RTR("Convert OGG Samples to OGG..."), MENU_OSTR_TO_OGG); menu_popup->add_icon_item(GDREGuiIcons::get_icon("REResOther", scale), RTR("Convert WAV Samples to WAV..."), MENU_SMPL_TO_WAV); + menu_popup->add_icon_item(GDREGuiIcons::get_icon("REResOther", scale), RTR("Export Resource..."), MENU_EXPORT_RESOURCE); menu_popup->connect("id_pressed", callable_mp(this, &GodotREEditor::menu_option_pressed)); menu_button->set_anchor(Side::SIDE_TOP, 0); p_menu->add_child(menu_button); @@ -454,6 +473,9 @@ void GodotREEditor::menu_option_pressed(int p_id) { case MENU_SMPL_TO_WAV: { smpl_file_selection->popup_centered(Size2(600, 400)); } break; + case MENU_EXPORT_RESOURCE: { + export_resource_file_selection->popup_centered(); + } break; case MENU_ABOUT_RE: { show_about_dialog(); } break; @@ -1077,6 +1099,55 @@ void GodotREEditor::_res_bin_2_txt_process() { } } +void GodotREEditor::_export_resource_request(const String &p_file) { + res_files = { p_file }; + Vector extensions = Exporter::get_export_extensions(p_file); + if (extensions.size() == 0) { + show_warning(RTR("No exporters found for resource " + p_file), RTR("Export resource"), RTR("No exporters found for resource " + p_file)); + return; + } + String default_extension = extensions.size() > 0 ? extensions[0] : ""; + String default_filename = p_file.get_file().get_basename() + "." + default_extension; + export_resource_output_selection->clear_filters(); + for (const String &extension : extensions) { + export_resource_output_selection->add_filter("*." + extension); + } + export_resource_output_selection->set_current_file(default_filename); + export_resource_output_selection->popup_centered(Size2(600, 400)); +} + +void GodotREEditor::_export_resource_output_request(const String &p_path) { + _export_resource_process(p_path); +} + +void GodotREEditor::_export_resource_process(const String &p_output_path) { + EditorProgressGDDC *pr = memnew(EditorProgressGDDC(ne_parent, "re_export_res", RTR("Exporting resources..."), res_files.size(), true)); + + String failed_files; + for (int i = 0; i < res_files.size(); i++) { + GDRESettings::get_singleton()->get_errors(); + // print_warning("exporting " + res_files[i], RTR("Export resources")); + bool cancel = pr->step(res_files[i], i, true); + if (cancel) { + break; + } + + Error err = Exporter::export_file(p_output_path, res_files[i]); + if (err != OK) { + failed_files += res_files[i] + " failed:\n" + GDRESettings::get_singleton()->get_recent_error_string() + "\n"; + } + } + + memdelete(pr); + res_files = Vector(); + + if (failed_files.length() > 0) { + show_warning(failed_files, RTR("Export resources"), RTR("At least one error was detected!")); + } else { + show_warning(RTR("No errors detected."), RTR("Export resources"), RTR("The operation completed successfully!")); + } +} + Error GodotREEditor::convert_file_to_text(const String &p_src_path, const String &p_dst_path) { return ResourceCompatLoader::to_text(p_src_path, p_dst_path); } diff --git a/editor/gdre_editor.h b/editor/gdre_editor.h index a285cd7f..51700079 100644 --- a/editor/gdre_editor.h +++ b/editor/gdre_editor.h @@ -95,6 +95,8 @@ class GodotREEditor : public Node { FileDialog *stex_file_selection = nullptr; FileDialog *ostr_file_selection = nullptr; FileDialog *smpl_file_selection = nullptr; + FileDialog *export_resource_file_selection = nullptr; + FileDialog *export_resource_output_selection = nullptr; MenuButton *menu_button = nullptr; PopupMenu *menu_popup = nullptr; @@ -135,6 +137,10 @@ class GodotREEditor : public Node { void _res_smpl_2_wav_request(const Vector &p_files); void _res_smpl_2_wav_process(); + void _export_resource_request(const String &p_file); + void _export_resource_output_request(const String &p_path); + void _export_resource_process(const String &p_output_dir); + Error convert_file_to_binary(const String &p_src_path, const String &p_dst_path); Error convert_file_to_text(const String &p_src_path, const String &p_dst_path); @@ -159,6 +165,7 @@ class GodotREEditor : public Node { MENU_STEX_TO_PNG, MENU_OSTR_TO_OGG, MENU_SMPL_TO_WAV, + MENU_EXPORT_RESOURCE, MENU_ABOUT_RE, MENU_REPORT_ISSUE, MENU_EXIT_RE, diff --git a/exporters/autoconverted_exporter.cpp b/exporters/autoconverted_exporter.cpp index 02108e77..1a9c66b7 100644 --- a/exporters/autoconverted_exporter.cpp +++ b/exporters/autoconverted_exporter.cpp @@ -37,3 +37,10 @@ String AutoConvertedExporter::get_default_export_extension(const String &res_pat } return "tres"; } + +Vector AutoConvertedExporter::get_export_extensions(const String &res_path) const { + if (res_path.get_extension().to_lower() == "scn") { + return { "tscn", "tres" }; + } + return { "tres" }; +} diff --git a/exporters/autoconverted_exporter.h b/exporters/autoconverted_exporter.h index 0013d762..0e51a594 100644 --- a/exporters/autoconverted_exporter.h +++ b/exporters/autoconverted_exporter.h @@ -13,4 +13,5 @@ class AutoConvertedExporter : public ResourceExporter { virtual void get_handled_types(List *out) const override; virtual void get_handled_importers(List *out) const override; virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; }; diff --git a/exporters/csharp_exporter.cpp b/exporters/csharp_exporter.cpp index 99a13115..4c795174 100644 --- a/exporters/csharp_exporter.cpp +++ b/exporters/csharp_exporter.cpp @@ -55,3 +55,9 @@ String CSharpExporter::get_name() const { String CSharpExporter::get_default_export_extension(const String &res_path) const { return "cs"; } + +Vector CSharpExporter::get_export_extensions(const String &res_path) const { + Vector extensions; + extensions.push_back("cs"); + return extensions; +} diff --git a/exporters/csharp_exporter.h b/exporters/csharp_exporter.h index 64ac530e..e1cbc621 100644 --- a/exporters/csharp_exporter.h +++ b/exporters/csharp_exporter.h @@ -22,6 +22,7 @@ class CSharpExporter : public ResourceExporter { virtual String get_name() const override; virtual bool supports_nonpack_export() const override { return false; } virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; CSharpExporter() = default; ~CSharpExporter() = default; }; diff --git a/exporters/dialogue_exporter.cpp b/exporters/dialogue_exporter.cpp index fc2b681d..d0ede7a7 100644 --- a/exporters/dialogue_exporter.cpp +++ b/exporters/dialogue_exporter.cpp @@ -72,3 +72,9 @@ void DialogueExporter::get_handled_importers(List *out) const { String DialogueExporter::get_default_export_extension(const String &res_path) const { return "dialogue"; } + +Vector DialogueExporter::get_export_extensions(const String &res_path) const { + Vector extensions; + extensions.push_back("dialogue"); + return extensions; +} diff --git a/exporters/dialogue_exporter.h b/exporters/dialogue_exporter.h index c6a17576..4bebca15 100644 --- a/exporters/dialogue_exporter.h +++ b/exporters/dialogue_exporter.h @@ -13,4 +13,5 @@ class DialogueExporter : public ResourceExporter { virtual void get_handled_types(List *out) const override; virtual void get_handled_importers(List *out) const override; virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; }; diff --git a/exporters/fontfile_exporter.cpp b/exporters/fontfile_exporter.cpp index 9e07f36a..a4f3b60b 100644 --- a/exporters/fontfile_exporter.cpp +++ b/exporters/fontfile_exporter.cpp @@ -387,3 +387,9 @@ String FontFileExporter::get_name() const { String FontFileExporter::get_default_export_extension(const String &res_path) const { return "ttf"; } + +Vector FontFileExporter::get_export_extensions(const String &res_path) const { + Vector extensions = { "ttf", "otf" }; + extensions.append_array(ImageSaver::get_supported_extensions()); + return extensions; +} diff --git a/exporters/fontfile_exporter.h b/exporters/fontfile_exporter.h index 8eb63176..eda1b43c 100644 --- a/exporters/fontfile_exporter.h +++ b/exporters/fontfile_exporter.h @@ -16,4 +16,5 @@ class FontFileExporter : public ResourceExporter { virtual void get_handled_importers(List *out) const override; virtual String get_name() const override; virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; }; diff --git a/exporters/gdextension_exporter.cpp b/exporters/gdextension_exporter.cpp index ff6b148b..f1c7c3de 100644 --- a/exporters/gdextension_exporter.cpp +++ b/exporters/gdextension_exporter.cpp @@ -374,3 +374,9 @@ String GDExtensionExporter::get_name() const { String GDExtensionExporter::get_default_export_extension(const String &res_path) const { return "gdext"; } + +Vector GDExtensionExporter::get_export_extensions(const String &res_path) const { + Vector extensions; + extensions.push_back("gdext"); + return extensions; +} diff --git a/exporters/gdextension_exporter.h b/exporters/gdextension_exporter.h index 37085595..f9f74404 100644 --- a/exporters/gdextension_exporter.h +++ b/exporters/gdextension_exporter.h @@ -14,4 +14,5 @@ class GDExtensionExporter : public ResourceExporter { virtual String get_name() const override; virtual bool supports_nonpack_export() const override { return false; } virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; }; diff --git a/exporters/gdscript_exporter.cpp b/exporters/gdscript_exporter.cpp index c167dd24..713812fe 100644 --- a/exporters/gdscript_exporter.cpp +++ b/exporters/gdscript_exporter.cpp @@ -100,6 +100,12 @@ String GDScriptExporter::get_default_export_extension(const String &res_path) co return "gd"; } +Vector GDScriptExporter::get_export_extensions(const String &res_path) const { + Vector extensions; + extensions.push_back("gd"); + return extensions; +} + Error GDScriptExporter::test_export(const Ref &export_report, const String &original_project_dir) const { Error _ret_err = OK; { diff --git a/exporters/gdscript_exporter.h b/exporters/gdscript_exporter.h index ac0628ac..75100c5f 100644 --- a/exporters/gdscript_exporter.h +++ b/exporters/gdscript_exporter.h @@ -24,6 +24,7 @@ class GDScriptExporter : public ResourceExporter { virtual String get_name() const override; virtual bool supports_nonpack_export() const override { return false; } virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; virtual Error test_export(const Ref &export_report, const String &original_project_dir) const override; GDScriptExporter() = default; ~GDScriptExporter() = default; diff --git a/exporters/mp3str_exporter.cpp b/exporters/mp3str_exporter.cpp index ac1b628f..71027670 100644 --- a/exporters/mp3str_exporter.cpp +++ b/exporters/mp3str_exporter.cpp @@ -73,6 +73,10 @@ String Mp3StrExporter::get_default_export_extension(const String &res_path) cons return "mp3"; } +Vector Mp3StrExporter::get_export_extensions(const String &res_path) const { + return { "mp3" }; +} + Error Mp3StrExporter::test_export(const Ref &export_report, const String &original_project_dir) const { Error _ret_err = OK; { diff --git a/exporters/mp3str_exporter.h b/exporters/mp3str_exporter.h index 42f60e74..ab4f2af2 100644 --- a/exporters/mp3str_exporter.h +++ b/exporters/mp3str_exporter.h @@ -15,5 +15,6 @@ class Mp3StrExporter : public ResourceExporter { virtual void get_handled_types(List *out) const override; virtual void get_handled_importers(List *out) const override; virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; virtual Error test_export(const Ref &export_report, const String &original_project_dir) const override; }; diff --git a/exporters/obj_exporter.cpp b/exporters/obj_exporter.cpp index 5cb1da9c..af5c93a3 100644 --- a/exporters/obj_exporter.cpp +++ b/exporters/obj_exporter.cpp @@ -620,3 +620,7 @@ String ObjExporter::get_name() const { String ObjExporter::get_default_export_extension(const String &res_path) const { return "obj"; } + +Vector ObjExporter::get_export_extensions(const String &res_path) const { + return { "obj" }; +} diff --git a/exporters/obj_exporter.h b/exporters/obj_exporter.h index ba4eba81..1852eb1d 100644 --- a/exporters/obj_exporter.h +++ b/exporters/obj_exporter.h @@ -39,6 +39,7 @@ class ObjExporter : public ResourceExporter { virtual Ref export_resource(const String &p_output_dir, Ref p_import_info) override; virtual bool supports_multithread() const override; virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; }; #endif // OBJ_EXPORTER_H diff --git a/exporters/oggstr_exporter.cpp b/exporters/oggstr_exporter.cpp index 712e5e07..03c596e8 100644 --- a/exporters/oggstr_exporter.cpp +++ b/exporters/oggstr_exporter.cpp @@ -204,6 +204,10 @@ String OggStrExporter::get_default_export_extension(const String &res_path) cons return "ogg"; } +Vector OggStrExporter::get_export_extensions(const String &res_path) const { + return { "ogg" }; +} + namespace { auto packet_data_to_flat_vector(const TypedArray &packet_data) -> Vector> { Vector> data; diff --git a/exporters/oggstr_exporter.h b/exporters/oggstr_exporter.h index a1929aa9..20a85803 100644 --- a/exporters/oggstr_exporter.h +++ b/exporters/oggstr_exporter.h @@ -19,5 +19,6 @@ class OggStrExporter : public ResourceExporter { virtual void get_handled_types(List *out) const override; virtual void get_handled_importers(List *out) const override; virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; virtual Error test_export(const Ref &export_report, const String &original_project_dir) const override; }; diff --git a/exporters/resource_exporter.cpp b/exporters/resource_exporter.cpp index 04a1cb62..e56bef01 100644 --- a/exporters/resource_exporter.cpp +++ b/exporters/resource_exporter.cpp @@ -83,6 +83,10 @@ String ResourceExporter::get_default_export_extension(const String &res_path) co ERR_FAIL_V_MSG(String(), "Not implemented"); } +Vector ResourceExporter::get_export_extensions(const String &res_path) const { + ERR_FAIL_V_MSG(Vector(), "Not implemented"); +} + Error ResourceExporter::test_export(const Ref &export_report, const String &original_project_dir) const { return ERR_UNAVAILABLE; } @@ -94,6 +98,7 @@ void ResourceExporter::_bind_methods() { ClassDB::bind_method(D_METHOD("export_resource", "output_dir", "import_infos"), &ResourceExporter::export_resource); ClassDB::bind_method(D_METHOD("handles_import", "importer", "resource_type"), &ResourceExporter::handles_import); ClassDB::bind_method(D_METHOD("get_default_export_extension", "res_path"), &ResourceExporter::get_default_export_extension); + ClassDB::bind_method(D_METHOD("get_export_extensions", "res_path"), &ResourceExporter::get_export_extensions); } Ref ResourceExporter::_check_for_existing_resources(const Ref &iinfo) { @@ -212,6 +217,11 @@ String Exporter::get_default_export_extension(const String &res_path) { return exporter.is_null() ? "" : exporter->get_default_export_extension(res_path); } +Vector Exporter::get_export_extensions(const String &res_path) { + auto exporter = get_exporter_from_path(res_path, false); + return exporter.is_null() ? Vector() : exporter->get_export_extensions(res_path); +} + Error Exporter::test_export(const Ref &export_report, const String &original_project_dir) { ERR_FAIL_NULL_V(export_report, ERR_BUG); ERR_FAIL_NULL_V(export_report->get_import_info(), ERR_BUG); @@ -233,4 +243,5 @@ void Exporter::_bind_methods() { ClassDB::bind_static_method(get_class_static(), D_METHOD("get_exporter_from_path", "res_path", "nonpack_export"), &Exporter::get_exporter_from_path, DEFVAL(true)); ClassDB::bind_static_method(get_class_static(), D_METHOD("is_exportable_resource", "res_path"), &Exporter::is_exportable_resource); ClassDB::bind_static_method(get_class_static(), D_METHOD("get_default_export_extension", "res_path"), &Exporter::get_default_export_extension); + ClassDB::bind_static_method(get_class_static(), D_METHOD("get_export_extensions", "res_path"), &Exporter::get_export_extensions); } diff --git a/exporters/resource_exporter.h b/exporters/resource_exporter.h index 1cf6fce2..2fa97ffa 100644 --- a/exporters/resource_exporter.h +++ b/exporters/resource_exporter.h @@ -22,6 +22,7 @@ class ResourceExporter : public RefCounted { virtual bool supports_multithread() const; virtual bool supports_nonpack_export() const; virtual String get_default_export_extension(const String &res_path) const; + virtual Vector get_export_extensions(const String &res_path) const; virtual Error test_export(const Ref &export_report, const String &original_project_dir) const; static Ref _check_for_existing_resources(const Ref &iinfo); @@ -49,5 +50,6 @@ class Exporter : public Object { static Ref get_exporter_from_path(const String &res_path, bool p_nonpack_export = false); static bool is_exportable_resource(const String &res_path); static String get_default_export_extension(const String &res_path); + static Vector get_export_extensions(const String &res_path); static Error test_export(const Ref &export_report, const String &original_project_dir); }; diff --git a/exporters/sample_exporter.cpp b/exporters/sample_exporter.cpp index 6f943736..667fe34b 100644 --- a/exporters/sample_exporter.cpp +++ b/exporters/sample_exporter.cpp @@ -286,6 +286,10 @@ String SampleExporter::get_default_export_extension(const String &res_path) cons return "wav"; } +Vector SampleExporter::get_export_extensions(const String &res_path) const { + return { "wav" }; +} + Error SampleExporter::test_export(const Ref &export_report, const String &original_project_dir) const { Error _ret_err = OK; { diff --git a/exporters/sample_exporter.h b/exporters/sample_exporter.h index d78b9bf6..bb16138d 100644 --- a/exporters/sample_exporter.h +++ b/exporters/sample_exporter.h @@ -18,5 +18,6 @@ class SampleExporter : public ResourceExporter { virtual void get_handled_importers(List *out) const override; virtual String get_name() const override; virtual String get_default_export_extension(const String &res_path) const override; + virtual Vector get_export_extensions(const String &res_path) const override; virtual Error test_export(const Ref &export_report, const String &original_project_dir) const override; }; diff --git a/exporters/scene_exporter.cpp b/exporters/scene_exporter.cpp index 234e5e8f..95fccab6 100644 --- a/exporters/scene_exporter.cpp +++ b/exporters/scene_exporter.cpp @@ -4,6 +4,7 @@ #include "core/io/file_access.h" #include "core/io/resource_loader.h" #include "core/variant/variant.h" +#include "core/version_generated.gen.h" #include "exporters/export_report.h" #include "exporters/obj_exporter.h" #include "external/tinygltf/tiny_gltf.h" @@ -12,25 +13,28 @@ #include "modules/gltf/structures/gltf_node.h" #include "modules/regex/regex.h" #include "scene/3d/mesh_instance_3d.h" +#include "scene/3d/navigation/navigation_region_3d.h" #include "scene/3d/occluder_instance_3d.h" +#include "scene/3d/physics/area_3d.h" #include "scene/3d/physics/rigid_body_3d.h" #include "scene/3d/physics/static_body_3d.h" #include "scene/resources/3d/box_shape_3d.h" #include "scene/resources/3d/capsule_shape_3d.h" #include "scene/resources/3d/cylinder_shape_3d.h" #include "scene/resources/3d/sphere_shape_3d.h" +#include "scene/resources/surface_tool.h" #include "scene/resources/texture.h" #include "utility/common.h" #include "utility/gdre_config.h" #include "utility/gdre_logger.h" #include "utility/gdre_settings.h" -#include "core/crypto/crypto_core.h" #include "core/error/error_list.h" #include "core/error/error_macros.h" #include "main/main.h" #include "scene/resources/compressed_texture.h" #include "scene/resources/packed_scene.h" +#include "servers/navigation_3d/navigation_server_3d.h" #include "utility/task_manager.h" #ifndef MAKE_GLTF_COPY @@ -676,6 +680,8 @@ String GLBExporterInstance::add_errors_to_report(Error p_err, const String &err_ err_message = "Export was cancelled"; } else if (p_err == ERR_TIMEOUT) { err_message = "Export timed out"; + } else if (p_err == OK) { + err_message = ""; } if (!err_msg.is_empty()) { err_message += ":\n " + err_msg; @@ -685,6 +691,10 @@ String GLBExporterInstance::add_errors_to_report(Error p_err, const String &err_ } error_statement = err_message; Vector errors; + if (scene_loading_error_messages.size() > 0) { + errors.append("** Errors during scene loading:"); + errors.append_array(scene_loading_error_messages); + } if (scene_instantiation_error_messages.size() > 0) { errors.append("** Errors during scene instantiation:"); errors.append_array(scene_instantiation_error_messages); @@ -718,8 +728,9 @@ String GLBExporterInstance::add_errors_to_report(Error p_err, const String &err_ } } report->set_message(error_statement + "\n"); - report->append_message_detail({ "Dependencies:" }); - report->append_message_detail(dependency_resolution_list); + Dictionary extra_info = report->get_extra_info(); + extra_info["dependencies"] = dependency_resolution_list; + report->set_extra_info(extra_info); report->set_error(p_err); report->append_error_messages(errors); } @@ -763,15 +774,14 @@ void GLBExporterInstance::set_cache_res(const dep_info &info, const Ref &res, int64_t idx) { - String name = dict.get("name", String()); + String name; + name = dict.get("name", String()); if (name.is_empty()) { name = res->get_name(); if (name.is_empty()) { Ref info = ResourceInfo::get_info_from_resource(res); if (info.is_valid() && !info->resource_name.is_empty()) { name = info->resource_name; - } else { - // name = res->get_class() + "_" + String::num_int64(idx); } } } @@ -880,6 +890,7 @@ void GLBExporterInstance::_initial_set(const String &p_src_path, Ref %s does not exist.", source_path, info.dep, info.remap)); continue; } @@ -983,6 +995,7 @@ Error GLBExporterInstance::_load_deps() { ResourceFormatLoader::CACHE_MODE_IGNORE); // not ignore deep, we want to reuse dependencies if they exist if (err || texture.is_null()) { if (ignore_missing_dependencies) { + missing_dependencies.push_back(info.dep); WARN_PRINT(vformat("%s: Dependency %s:%s failed to load.", source_path, info.dep, info.remap)); continue; } @@ -1029,6 +1042,7 @@ Error GLBExporterInstance::_load_deps() { report->set_loss_type(ImportInfo::STORED_LOSSY); } + scene_loading_error_messages.append_array(_get_logged_error_messages()); return OK; } @@ -1093,9 +1107,9 @@ Dictionary get_default_node_options() { // INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE dict["generate/physics"] = false; - dict["generate/navmesh"] = 0; - dict["physics/body_type"] = 0; - dict["physics/shape_type"] = 7; + dict["generate/navmesh"] = SceneExporterEnums::NAVMESH_DISABLED; + dict["physics/body_type"] = SceneExporterEnums::BODY_TYPE_STATIC; + dict["physics/shape_type"] = SceneExporterEnums::SHAPE_TYPE_AUTOMATIC; dict["physics/physics_material_override"] = Variant(); dict["physics/layer"] = 1; dict["physics/mask"] = 1; @@ -1134,7 +1148,7 @@ Dictionary get_default_node_options() { dict["primitive/position"] = Vector3(); dict["primitive/rotation"] = Vector3(); - dict["generate/occluder"] = 0; + dict["generate/occluder"] = SceneExporterEnums::OCCLUDER_DISABLED; dict["occluder/simplification_distance"] = 0.1f; // animation node @@ -1157,20 +1171,55 @@ Dictionary get_default_node_options() { return dict; } -Dictionary get_node_options(Node *p_node) { +bool is_auto_generated_node(Node *p_node) { + ERR_FAIL_NULL_V(p_node, false); + RigidBody3D *parent_rigid_body = Object::cast_to(p_node); + if (parent_rigid_body) { + for (auto &child : p_node->get_children()) { + if (Object::cast_to(child)) { + return true; + } + } + } + Node *parent = p_node->get_parent(); + Node *parent_parent = parent ? parent->get_parent() : nullptr; + if (parent && p_node->get_owner() != parent->get_owner()) { + parent_parent = nullptr; + } + bool parent_is_mesh_instance = parent ? !!Object::cast_to(parent) : false; + bool parent_is_root_and_node3d = parent && parent_parent == nullptr && parent->get_class() == "Node3D"; + if (Object::cast_to(p_node) && (!parent || parent_is_root_and_node3d || parent_is_mesh_instance || Object::cast_to(parent))) { + return true; + } + if (!parent || parent_is_mesh_instance || parent_is_root_and_node3d) { + if (Object::cast_to(p_node)) { + return true; + } + if (Object::cast_to(p_node)) { + return true; + } + } + if (parent && Object::cast_to(p_node)) { + if (Object::cast_to(parent)) { + return true; + } + return is_auto_generated_node(parent); + } + return false; +} + +Dictionary get_node_options(Node *p_node, Node *original_node = nullptr) { + ERR_FAIL_NULL_V(p_node, Dictionary()); Dictionary node_options_dict = Dictionary(); MeshInstance3D *mesh_instance = Object::cast_to(p_node); AnimationPlayer *animation_player = Object::cast_to(p_node); + Skeleton3D *skeleton = Object::cast_to(p_node); Ref