Skip to content

Commit

Permalink
Legacy bone name support for the gltf module
Browse files Browse the repository at this point in the history
  • Loading branch information
lyuma committed May 26, 2021
1 parent 5b01755 commit 36800f1
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 15 deletions.
7 changes: 7 additions & 0 deletions modules/gltf/editor_scene_importer_gltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<GLTFDocument> gltf_document;
gltf_document.instance();
Expand All @@ -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]);
}
Expand Down
80 changes: 66 additions & 14 deletions modules/gltf/gltf_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -256,7 +257,7 @@ Error GLTFDocument::_serialize_bone_attachment(Ref<GLTFState> 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++) {
Expand Down Expand Up @@ -449,15 +450,38 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> state) {
return OK;
}

String GLTFDocument::_sanitize_scene_name(Ref<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 GLTFDocument::_legacy_validate_node_name(const String &p_name) {
String invalid_character = ". : @ / \"";
String name = p_name;
Vector<String> 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<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;
while (true) {
name = s_name;

if (index > 1) {
if (state->use_legacy_names) {
name += " ";
}
name += itos(index);
}
if (!state->unique_names.has(name)) {
Expand Down Expand Up @@ -504,18 +528,36 @@ String GLTFDocument::_gen_unique_animation_name(Ref<GLTFState> 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<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 GLTFDocument::_gen_unique_bone_name(Ref<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) {
Expand Down Expand Up @@ -4809,7 +4851,11 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> 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++) {
Expand Down Expand Up @@ -5507,8 +5553,14 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> 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);
Expand Down
5 changes: 4 additions & 1 deletion modules/gltf/gltf_document.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class GLTFDocument : public Resource {
String _gen_unique_name(Ref<GLTFState> state, const String &p_name);
String _sanitize_animation_name(const String &name);
String _gen_unique_animation_name(Ref<GLTFState> state, const String &p_name);
String _sanitize_bone_name(const String &name);
String _sanitize_bone_name(Ref<GLTFState> state, const String &name);
String _gen_unique_bone_name(Ref<GLTFState> state,
const GLTFSkeletonIndex skel_i,
const String &p_name);
Expand Down Expand Up @@ -357,6 +357,9 @@ class GLTFDocument : public Resource {
static float get_max_component(const Color &p_color);

public:
String _sanitize_scene_name(Ref<GLTFState> state, const String &p_name);
String _legacy_validate_node_name(const String &p_name);

void _process_mesh_instances(Ref<GLTFState> state, Node *scene_root);
void _generate_scene_node(Ref<GLTFState> state, Node *scene_parent,
Spatial *scene_root,
Expand Down
1 change: 1 addition & 0 deletions modules/gltf/gltf_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class GLTFState : public Resource {
Vector<uint8_t> glb_data;

bool use_named_skin_binds = false;
bool use_legacy_names = false;

Vector<Ref<GLTFNode>> nodes;
Vector<Vector<uint8_t>> buffers;
Expand Down

0 comments on commit 36800f1

Please sign in to comment.