diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp index 91271da331e..4967913b856 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.cpp +++ b/modules/gltf/editor/editor_scene_importer_blend.cpp @@ -48,6 +48,67 @@ #include #endif +static bool _get_blender_version(const String &p_path, int &r_major, int &r_minor, String *r_err = nullptr) { + String path = p_path; +#ifdef WINDOWS_ENABLED + path = path.path_join("blender.exe"); +#else + path = path.path_join("blender"); +#endif + +#if defined(MACOS_ENABLED) + if (!FileAccess::exists(path)) { + path = p_path.path_join("Blender"); + } +#endif + + if (!FileAccess::exists(path)) { + if (r_err) { + *r_err = TTR("Path does not contain a Blender installation."); + } + return false; + } + List args; + args.push_back("--version"); + String pipe; + Error err = OS::get_singleton()->execute(path, args, &pipe); + if (err != OK) { + if (r_err) { + *r_err = TTR("Can't execute Blender binary."); + } + return false; + } + int bl = pipe.find("Blender "); + if (bl == -1) { + if (r_err) { + *r_err = vformat(TTR("Unexpected --version output from Blender binary at: %s."), path); + } + return false; + } + pipe = pipe.substr(bl); + pipe = pipe.replace_first("Blender ", ""); + int pp = pipe.find("."); + if (pp == -1) { + if (r_err) { + *r_err = TTR("Path supplied lacks a Blender binary."); + } + return false; + } + String v = pipe.substr(0, pp); + r_major = v.to_int(); + if (r_major < 3) { + if (r_err) { + *r_err = TTR("This Blender installation is too old for this importer (not 3.0+)."); + } + return false; + } + + int pp2 = pipe.find(".", pp + 1); + r_minor = pp2 > pp ? pipe.substr(pp + 1, pp2 - pp - 1).to_int() : 0; + + return true; +} + uint32_t EditorSceneFormatImporterBlend::get_import_flags() const { return ImportFlags::IMPORT_SCENE | ImportFlags::IMPORT_ANIMATION; } @@ -59,8 +120,13 @@ void EditorSceneFormatImporterBlend::get_extensions(List *r_extensions) Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_t p_flags, const HashMap &p_options, List *r_missing_deps, Error *r_err) { - // Get global paths for source and sink. + String blender_path = EDITOR_GET("filesystem/import/blender/blender3_path"); + if (blender_major_version == -1 || blender_minor_version == -1) { + _get_blender_version(blender_path, blender_major_version, blender_minor_version, nullptr); + } + + // Get global paths for source and sink. // Escape paths to be valid Python strings to embed in the script. const String source_global = ProjectSettings::get_singleton()->globalize_path(p_path).c_escape(); const String sink = ProjectSettings::get_singleton()->get_imported_files_path().path_join( @@ -152,9 +218,17 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_ parameters_map["export_tangents"] = false; } if (p_options.has(SNAME("blender/animation/group_tracks")) && p_options[SNAME("blender/animation/group_tracks")]) { - parameters_map["export_nla_strips"] = true; + if (blender_major_version > 3 || (blender_major_version == 3 && blender_minor_version >= 6)) { + parameters_map["export_animation_mode"] = "ACTIONS"; + } else { + parameters_map["export_nla_strips"] = true; + } } else { - parameters_map["export_nla_strips"] = false; + if (blender_major_version > 3 || (blender_major_version == 3 && blender_minor_version >= 6)) { + parameters_map["export_animation_mode"] = "ACTIVE_ACTIONS"; + } else { + parameters_map["export_nla_strips"] = false; + } } if (p_options.has(SNAME("blender/animation/limit_playback")) && p_options[SNAME("blender/animation/limit_playback")]) { parameters_map["export_frame_range"] = true; @@ -268,67 +342,8 @@ void EditorSceneFormatImporterBlend::get_import_options(const String &p_path, Li /////////////////////////// static bool _test_blender_path(const String &p_path, String *r_err = nullptr) { - String path = p_path; -#ifdef WINDOWS_ENABLED - path = path.path_join("blender.exe"); -#else - path = path.path_join("blender"); -#endif - -#if defined(MACOS_ENABLED) - if (!FileAccess::exists(path)) { - path = path.path_join("Blender"); - } -#endif - - if (!FileAccess::exists(path)) { - if (r_err) { - *r_err = TTR("Path does not contain a Blender installation."); - } - return false; - } - List args; - args.push_back("--version"); - String pipe; - Error err = OS::get_singleton()->execute(path, args, &pipe); - if (err != OK) { - if (r_err) { - *r_err = TTR("Can't execute Blender binary."); - } - return false; - } - int bl = pipe.find("Blender "); - if (bl == -1) { - if (r_err) { - *r_err = vformat(TTR("Unexpected --version output from Blender binary at: %s"), path); - } - return false; - } - pipe = pipe.substr(bl); - pipe = pipe.replace_first("Blender ", ""); - int pp = pipe.find("."); - if (pp == -1) { - if (r_err) { - *r_err = TTR("Path supplied lacks a Blender binary."); - } - return false; - } - String v = pipe.substr(0, pp); - int version = v.to_int(); - if (version < 3) { - if (r_err) { - *r_err = TTR("This Blender installation is too old for this importer (not 3.0+)."); - } - return false; - } - if (version > 3) { - if (r_err) { - *r_err = TTR("This Blender installation is too new for this importer (not 3.x)."); - } - return false; - } - - return true; + int major, minor; + return _get_blender_version(p_path, major, minor, r_err); } bool EditorFileSystemImportFormatSupportQueryBlend::is_active() const { diff --git a/modules/gltf/editor/editor_scene_importer_blend.h b/modules/gltf/editor/editor_scene_importer_blend.h index c77a23f9f69..ec467db457d 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.h +++ b/modules/gltf/editor/editor_scene_importer_blend.h @@ -43,6 +43,9 @@ class ConfirmationDialog; class EditorSceneFormatImporterBlend : public EditorSceneFormatImporter { GDCLASS(EditorSceneFormatImporterBlend, EditorSceneFormatImporter); + int blender_major_version = -1; + int blender_minor_version = -1; + public: enum { BLEND_VISIBLE_ALL,