1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

GLTF: Make skeleton bone names unique per-skeleton instead of scene-wide

This commit is contained in:
Aaron Franke
2025-05-17 12:18:46 -07:00
parent fc523ec5f6
commit 8350919575
5 changed files with 21 additions and 5 deletions

View File

@@ -2221,7 +2221,7 @@ Error FBXDocument::_parse_fbx_state(Ref<FBXState> p_state, const String &p_searc
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
/* CREATE SKELETONS */
err = SkinTool::_create_skeletons(p_state->unique_names, p_state->skins, p_state->nodes, p_state->skeleton3d_to_fbx_skeleton, p_state->skeletons, p_state->scene_nodes);
err = SkinTool::_create_skeletons(p_state->unique_names, p_state->skins, p_state->nodes, p_state->skeleton3d_to_fbx_skeleton, p_state->skeletons, p_state->scene_nodes, _naming_version);
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
/* CREATE SKINS */

View File

@@ -40,6 +40,8 @@
class FBXDocument : public GLTFDocument {
GDCLASS(FBXDocument, GLTFDocument);
int _naming_version = 2;
public:
enum {
TEXTURE_TYPE_GENERIC = 0,

View File

@@ -8622,7 +8622,7 @@ Node *GLTFDocument::_generate_scene_node_tree(Ref<GLTFState> p_state) {
// Generate the skeletons and skins (if any).
HashMap<ObjectID, SkinSkeletonIndex> skeleton_map;
Error err = SkinTool::_create_skeletons(p_state->unique_names, p_state->skins, p_state->nodes,
skeleton_map, p_state->skeletons, p_state->scene_nodes);
skeleton_map, p_state->skeletons, p_state->scene_nodes, _naming_version);
ERR_FAIL_COND_V_MSG(err != OK, nullptr, "glTF: Failed to create skeletons.");
err = _create_skins(p_state);
ERR_FAIL_COND_V_MSG(err != OK, nullptr, "glTF: Failed to create skins.");

View File

@@ -563,9 +563,13 @@ Error SkinTool::_create_skeletons(
Vector<Ref<GLTFNode>> &nodes,
HashMap<ObjectID, GLTFSkeletonIndex> &skeleton3d_to_gltf_skeleton,
Vector<Ref<GLTFSkeleton>> &skeletons,
HashMap<GLTFNodeIndex, Node *> &scene_nodes) {
HashMap<GLTFNodeIndex, Node *> &scene_nodes,
int p_naming_version) {
// This is the syntax to duplicate a Godot HashSet.
HashSet<String> unique_node_names(unique_names);
for (SkinSkeletonIndex skel_i = 0; skel_i < skeletons.size(); ++skel_i) {
Ref<GLTFSkeleton> gltf_skeleton = skeletons.write[skel_i];
HashSet<String> skel_unique_names(unique_node_names);
Skeleton3D *skeleton = memnew(Skeleton3D);
gltf_skeleton->godot_skeleton = skeleton;
@@ -613,7 +617,16 @@ Error SkinTool::_create_skeletons(
node->set_name("bone");
}
node->set_name(_gen_unique_bone_name(unique_names, node->get_name()));
if (p_naming_version < 2) {
node->set_name(_gen_unique_bone_name(unique_names, node->get_name()));
} else {
// Make sure the bone name is unique in the skeleton and unique compared
// to scene nodes, but bone names may be duplicated between skeletons.
// Example: Two skeletons with a "Head" bone should not have one become "Head_2".
const String unique_bone_name = _gen_unique_bone_name(skel_unique_names, node->get_name());
unique_names.insert(unique_bone_name);
node->set_name(unique_bone_name);
}
skeleton->add_bone(node->get_name());
Transform3D rest_transform = node->get_additional_data("GODOT_rest_transform");

View File

@@ -97,6 +97,7 @@ public:
Vector<Ref<GLTFNode>> &r_nodes,
HashMap<ObjectID, GLTFSkeletonIndex> &r_skeleton3d_to_fbx_skeleton,
Vector<Ref<GLTFSkeleton>> &r_skeletons,
HashMap<GLTFNodeIndex, Node *> &r_scene_nodes);
HashMap<GLTFNodeIndex, Node *> &r_scene_nodes,
int p_naming_version);
static Error _create_skins(Vector<Ref<GLTFSkin>> &skins, Vector<Ref<GLTFNode>> &nodes, bool use_named_skin_binds, HashSet<String> &unique_names);
};