From d92a1728790bc28405b7f0e047b4c17a9b65b4db Mon Sep 17 00:00:00 2001 From: Lyuma Date: Tue, 20 Apr 2021 21:06:00 -0700 Subject: [PATCH] Add an import setting use_legacy_names. During the development of 3.3, internationalization features were added to allow arbitrary bone and node names. However, doing so will break all references and existing animation clips for projects upgraded from 3.2 This adds an import setting, enabled by default, but disabled for newly generated .import files which restores the old behavior. --- editor/editor_file_system.cpp | 1 + editor/import/editor_scene_importer_gltf.cpp | 83 ++++++++++++++++---- editor/import/editor_scene_importer_gltf.h | 5 +- editor/import/resource_importer_scene.cpp | 4 + editor/import/resource_importer_scene.h | 1 + 5 files changed, 79 insertions(+), 15 deletions(-) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index fffba63e99d..c638faee21f 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1754,6 +1754,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { } else { late_added_files.insert(p_file); //imported files do not call update_file(), but just in case.. + params["nodes/use_legacy_names"] = false; } if (importer_name == "keep") { diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 878fcbf77b0..7017da798a0 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -35,6 +35,7 @@ #include "core/math/math_defs.h" #include "core/os/file_access.h" #include "core/os/os.h" +#include "modules/regex/regex.h" #include "scene/3d/bone_attachment.h" #include "scene/3d/camera.h" #include "scene/3d/mesh_instance.h" @@ -155,9 +156,29 @@ static Transform _arr_to_xform(const Array &p_array) { return xform; } +String EditorSceneImporterGLTF::_sanitize_scene_name(GLTFState &state, const String &p_name) { + if (state.use_legacy_names) { + RegEx regex("([^a-zA-Z0-9_ -]+)"); + String s_name = regex.sub(p_name, "", true); + return s_name; + } else { + return p_name.validate_node_name(); + } +} + +String EditorSceneImporterGLTF::_legacy_validate_node_name(const String &p_name) { + String invalid_character = ". : @ / \""; + String name = p_name; + Vector chars = invalid_character.split(" "); + for (int i = 0; i < chars.size(); i++) { + name = name.replace(chars[i], ""); + } + return name; +} + String EditorSceneImporterGLTF::_gen_unique_name(GLTFState &state, const String &p_name) { - const String s_name = p_name.validate_node_name(); + const String s_name = _sanitize_scene_name(state, p_name); String name; int index = 1; @@ -165,7 +186,10 @@ String EditorSceneImporterGLTF::_gen_unique_name(GLTFState &state, const String name = s_name; if (index > 1) { - name += " " + itos(index); + if (state.use_legacy_names) { + name += " "; + } + name += itos(index); } if (!state.unique_names.has(name)) { break; @@ -212,19 +236,37 @@ String EditorSceneImporterGLTF::_gen_unique_animation_name(GLTFState &state, con return name; } -String EditorSceneImporterGLTF::_sanitize_bone_name(const String &p_name) { - String name = p_name; - name = name.replace(":", "_"); - name = name.replace("/", "_"); - return name; +String EditorSceneImporterGLTF::_sanitize_bone_name(GLTFState &state, const String &p_name) { + if (state.use_legacy_names) { + String name = p_name.camelcase_to_underscore(true); + RegEx pattern_del("([^a-zA-Z0-9_ ])+"); + + name = pattern_del.sub(name, "", true); + + RegEx pattern_nospace(" +"); + name = pattern_nospace.sub(name, "_", true); + + RegEx pattern_multiple("_+"); + name = pattern_multiple.sub(name, "_", true); + + RegEx pattern_padded("0+(\\d+)"); + name = pattern_padded.sub(name, "$1", true); + + return name; + } else { + String name = p_name; + name = name.replace(":", "_"); + name = name.replace("/", "_"); + if (name.empty()) { + name = "bone"; + } + return name; + } } String EditorSceneImporterGLTF::_gen_unique_bone_name(GLTFState &state, const GLTFSkeletonIndex skel_i, const String &p_name) { - String s_name = _sanitize_bone_name(p_name); - if (s_name.empty()) { - s_name = "bone"; - } + String s_name = _sanitize_bone_name(state, p_name); String name; int index = 1; while (true) { @@ -2487,7 +2529,11 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) { if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) { animation.loop = true; } - animation.name = _gen_unique_animation_name(state, name); + if (state.use_legacy_names) { + animation.name = _sanitize_scene_name(state, name); + } else { + animation.name = _gen_unique_animation_name(state, name); + } } for (int j = 0; j < channels.size(); j++) { @@ -2795,7 +2841,11 @@ void EditorSceneImporterGLTF::_generate_scene_node(GLTFState &state, Node *scene scene_parent->add_child(current_node); current_node->set_owner(scene_root); current_node->set_transform(gltf_node->xform); - current_node->set_name(gltf_node->name); + if (state.use_legacy_names) { + current_node->set_name(_legacy_validate_node_name(gltf_node->name)); + } else { + current_node->set_name(gltf_node->name); + } } state.scene_nodes.insert(node_index, current_node); @@ -3147,7 +3197,11 @@ Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, const int p_ Spatial *root = memnew(Spatial); // scene_name is already unique - root->set_name(state.scene_name); + if (state.use_legacy_names) { + root->set_name(_legacy_validate_node_name(state.scene_name)); + } else { + root->set_name(state.scene_name); + } for (int i = 0; i < state.root_nodes.size(); ++i) { _generate_scene_node(state, root, root, state.root_nodes[i]); @@ -3201,6 +3255,7 @@ Node *EditorSceneImporterGLTF::import_scene(const String &p_path, uint32_t p_fla state.major_version = version.get_slice(".", 0).to_int(); state.minor_version = version.get_slice(".", 1).to_int(); state.use_named_skin_binds = p_flags & IMPORT_USE_NAMED_SKIN_BINDS; + state.use_legacy_names = p_flags & IMPORT_USE_LEGACY_NAMES; /* STEP 0 PARSE SCENE */ Error err = _parse_scenes(state); diff --git a/editor/import/editor_scene_importer_gltf.h b/editor/import/editor_scene_importer_gltf.h index d02a1f32bac..6cb22dee53b 100644 --- a/editor/import/editor_scene_importer_gltf.h +++ b/editor/import/editor_scene_importer_gltf.h @@ -322,6 +322,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter { Vector glb_data; bool use_named_skin_binds; + bool use_legacy_names; Vector nodes; Vector > buffers; @@ -359,12 +360,14 @@ class EditorSceneImporterGLTF : public EditorSceneImporter { } }; + String _sanitize_scene_name(GLTFState &state, const String &p_name); + String _legacy_validate_node_name(const String &p_name); String _gen_unique_name(GLTFState &state, const String &p_name); String _sanitize_animation_name(const String &p_name); String _gen_unique_animation_name(GLTFState &state, const String &p_name); - String _sanitize_bone_name(const String &p_name); + String _sanitize_bone_name(GLTFState &state, const String &p_name); String _gen_unique_bone_name(GLTFState &state, const GLTFSkeletonIndex skel_i, const String &p_name); Ref _get_texture(GLTFState &state, const GLTFTextureIndex p_texture); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 589a916e954..f0a5a3a2656 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1158,6 +1158,7 @@ void ResourceImporterScene::get_import_options(List *r_options, in r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "nodes/root_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001"), 1.0)); r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), "")); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "nodes/use_legacy_names"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), (meshes_out || materials_out) ? 1 : 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Built-In,Files (.material),Files (.tres)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), materials_out ? 1 : 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "materials/keep_on_reimport"), materials_out)); @@ -1312,6 +1313,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p if (bool(p_options["skins/use_named_skins"])) import_flags |= EditorSceneImporter::IMPORT_USE_NAMED_SKIN_BINDS; + if (bool(p_options["nodes/use_legacy_names"])) + import_flags |= EditorSceneImporter::IMPORT_USE_LEGACY_NAMES; + Error err = OK; List missing_deps; // for now, not much will be done with this Node *scene = importer->import_scene(src_path, import_flags, fps, &missing_deps, &err); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index fdcc3e77027..d0d70a40095 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -60,6 +60,7 @@ public: IMPORT_MATERIALS_IN_INSTANCES = 1024, IMPORT_USE_COMPRESSION = 2048, IMPORT_USE_NAMED_SKIN_BINDS = 4096, + IMPORT_USE_LEGACY_NAMES = 8192, };