From 36800f159bcb9a3e75d08743bd91b2b4f5ec4fc5 Mon Sep 17 00:00:00 2001 From: Lyuma Date: Mon, 24 May 2021 18:51:10 -0700 Subject: [PATCH] Legacy bone name support for the gltf module --- modules/gltf/editor_scene_importer_gltf.cpp | 7 ++ modules/gltf/gltf_document.cpp | 80 +++++++++++++++++---- modules/gltf/gltf_document.h | 5 +- modules/gltf/gltf_state.h | 1 + 4 files changed, 78 insertions(+), 15 deletions(-) diff --git a/modules/gltf/editor_scene_importer_gltf.cpp b/modules/gltf/editor_scene_importer_gltf.cpp index f9ffd6ace05c..cd31a6ca65ae 100644 --- a/modules/gltf/editor_scene_importer_gltf.cpp +++ b/modules/gltf/editor_scene_importer_gltf.cpp @@ -95,6 +95,8 @@ Node *PackedSceneGLTF::import_scene(const String &p_path, uint32_t p_flags, } r_state->use_named_skin_binds = p_flags & EditorSceneImporter::IMPORT_USE_NAMED_SKIN_BINDS; + r_state->use_legacy_names = + p_flags & EditorSceneImporter::IMPORT_USE_LEGACY_NAMES; Ref gltf_document; gltf_document.instance(); @@ -103,6 +105,11 @@ Node *PackedSceneGLTF::import_scene(const String &p_path, uint32_t p_flags, ERR_FAIL_COND_V(err != Error::OK, nullptr); Spatial *root = memnew(Spatial); + if (r_state->use_legacy_names) { + root->set_name(gltf_document->_legacy_validate_node_name(r_state->scene_name)); + } else { + root->set_name(r_state->scene_name); + } for (int32_t root_i = 0; root_i < r_state->root_nodes.size(); root_i++) { gltf_document->_generate_scene_node(r_state, root, root, r_state->root_nodes[root_i]); } diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index af85f61af95b..9178f146c94e 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -63,6 +63,7 @@ #ifdef MODULE_GRIDMAP_ENABLED #include "modules/gridmap/grid_map.h" #endif // MODULE_GRIDMAP_ENABLED +#include "modules/regex/regex.h" #include "scene/2d/node_2d.h" #include "scene/3d/bone_attachment.h" #include "scene/3d/camera.h" @@ -256,7 +257,7 @@ Error GLTFDocument::_serialize_bone_attachment(Ref state) { for (int attachment_i = 0; attachment_i < state->skeletons[skeleton_i]->bone_attachments.size(); attachment_i++) { BoneAttachment *bone_attachment = state->skeletons[skeleton_i]->bone_attachments[attachment_i]; String bone_name = bone_attachment->get_bone_name(); - bone_name = _sanitize_bone_name(bone_name); + bone_name = _sanitize_bone_name(state, bone_name); int32_t bone = state->skeletons[skeleton_i]->godot_skeleton->find_bone(bone_name); ERR_CONTINUE(bone == -1); for (int skin_i = 0; skin_i < state->skins.size(); skin_i++) { @@ -449,8 +450,28 @@ Error GLTFDocument::_serialize_nodes(Ref state) { return OK; } +String GLTFDocument::_sanitize_scene_name(Ref 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 GLTFDocument::_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 GLTFDocument::_gen_unique_name(Ref 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; @@ -458,6 +479,9 @@ String GLTFDocument::_gen_unique_name(Ref state, const String &p_name name = s_name; if (index > 1) { + if (state->use_legacy_names) { + name += " "; + } name += itos(index); } if (!state->unique_names.has(name)) { @@ -504,18 +528,36 @@ String GLTFDocument::_gen_unique_animation_name(Ref state, const Stri return name; } -String GLTFDocument::_sanitize_bone_name(const String &p_name) { - String name = p_name; - name = name.replace(":", "_"); - name = name.replace("/", "_"); - return name; +String GLTFDocument::_sanitize_bone_name(Ref 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 GLTFDocument::_gen_unique_bone_name(Ref 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) { @@ -4809,7 +4851,11 @@ Error GLTFDocument::_parse_animations(Ref state) { if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) { animation->set_loop(true); } - animation->set_name(_gen_unique_animation_name(state, name)); + if (state->use_legacy_names) { + animation->set_name(_sanitize_scene_name(state, name)); + } else { + animation->set_name(_gen_unique_animation_name(state, name)); + } } for (int j = 0; j < channels.size(); j++) { @@ -5507,8 +5553,14 @@ void GLTFDocument::_generate_scene_node(Ref state, Node *scene_parent if (current_node != scene_root) { current_node->set_owner(scene_root); } - current_node->set_transform(gltf_node->xform); - current_node->set_name(gltf_node->get_name()); + if (use_xform) { + current_node->set_transform(gltf_node->xform); + } + if (state->use_legacy_names) { + current_node->set_name(_legacy_validate_node_name(gltf_node->get_name())); + } else { + current_node->set_name(gltf_node->get_name()); + } } state->scene_nodes.insert(node_index, current_node); diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 85e0bc67b4e6..a606c37bea59 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -161,7 +161,7 @@ class GLTFDocument : public Resource { String _gen_unique_name(Ref state, const String &p_name); String _sanitize_animation_name(const String &name); String _gen_unique_animation_name(Ref state, const String &p_name); - String _sanitize_bone_name(const String &name); + String _sanitize_bone_name(Ref state, const String &name); String _gen_unique_bone_name(Ref state, const GLTFSkeletonIndex skel_i, const String &p_name); @@ -357,6 +357,9 @@ class GLTFDocument : public Resource { static float get_max_component(const Color &p_color); public: + String _sanitize_scene_name(Ref state, const String &p_name); + String _legacy_validate_node_name(const String &p_name); + void _process_mesh_instances(Ref state, Node *scene_root); void _generate_scene_node(Ref state, Node *scene_parent, Spatial *scene_root, diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 6231015f9225..646a7c19c345 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -60,6 +60,7 @@ class GLTFState : public Resource { Vector glb_data; bool use_named_skin_binds = false; + bool use_legacy_names = false; Vector> nodes; Vector> buffers;