@@ -5798,7 +5798,16 @@ void GLTFDocument::_assign_node_names(Ref<GLTFState> p_state) {
57985798 }
57995799}
58005800
5801- BoneAttachment3D *GLTFDocument::_generate_bone_attachment (Ref<GLTFState> p_state, Skeleton3D *p_skeleton, const GLTFNodeIndex p_node_index, const GLTFNodeIndex p_bone_index) {
5801+ BoneAttachment3D *GLTFDocument::_generate_bone_attachment (Skeleton3D *p_godot_skeleton, const Ref<GLTFNode> &p_bone_node) {
5802+ BoneAttachment3D *bone_attachment = memnew (BoneAttachment3D);
5803+ print_verbose (" glTF: Creating bone attachment for: " + p_bone_node->get_name ());
5804+ bone_attachment->set_name (p_bone_node->get_name ());
5805+ p_godot_skeleton->add_child (bone_attachment, true );
5806+ bone_attachment->set_bone_name (p_bone_node->get_name ());
5807+ return bone_attachment;
5808+ }
5809+
5810+ BoneAttachment3D *GLTFDocument::_generate_bone_attachment_compat_4pt4 (Ref<GLTFState> p_state, Skeleton3D *p_skeleton, const GLTFNodeIndex p_node_index, const GLTFNodeIndex p_bone_index) {
58025811 Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
58035812 Ref<GLTFNode> bone_node = p_state->nodes [p_bone_index];
58045813 BoneAttachment3D *bone_attachment = memnew (BoneAttachment3D);
@@ -6271,11 +6280,210 @@ void GLTFDocument::_convert_mesh_instance_to_gltf(MeshInstance3D *p_scene_parent
62716280 }
62726281}
62736282
6283+ void _set_node_tree_owner (Node *p_current_node, Node *&p_scene_root) {
6284+ // Note: p_scene_parent and p_scene_root must either both be null or both be valid.
6285+ if (p_scene_root == nullptr ) {
6286+ // If the root node argument is null, this is the root node.
6287+ p_scene_root = p_current_node;
6288+ // If multiple nodes were generated under the root node, ensure they have the owner set.
6289+ if (unlikely (p_current_node->get_child_count () > 0 )) {
6290+ Array args;
6291+ args.append (p_scene_root);
6292+ for (int i = 0 ; i < p_current_node->get_child_count (); i++) {
6293+ Node *child = p_current_node->get_child (i);
6294+ child->propagate_call (StringName (" set_owner" ), args);
6295+ }
6296+ }
6297+ } else {
6298+ // Add the node we generated and set the owner to the scene root.
6299+ Array args;
6300+ args.append (p_scene_root);
6301+ p_current_node->propagate_call (StringName (" set_owner" ), args);
6302+ }
6303+ }
6304+
6305+ bool GLTFDocument::_does_skinned_mesh_require_placeholder_node (Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
6306+ if (p_gltf_node->skin < 0 ) {
6307+ return false ; // Not a skinned mesh.
6308+ }
6309+ // Check for child nodes that aren't joints/bones.
6310+ for (int i = 0 ; i < p_gltf_node->children .size (); ++i) {
6311+ Ref<GLTFNode> child = p_state->nodes [p_gltf_node->children [i]];
6312+ if (!child->joint ) {
6313+ return true ;
6314+ }
6315+ // Edge case: If a child's skeleton is not yet in the tree, then we must add it as a child of this node.
6316+ // While the Skeleton3D node isn't a glTF node, it's still a case where we need a placeholder.
6317+ // This is required to handle this issue: https://github.com/godotengine/godot/issues/67773
6318+ const GLTFSkeletonIndex skel_index = child->skeleton ;
6319+ ERR_FAIL_INDEX_V (skel_index, p_state->skeletons .size (), false );
6320+ if (p_state->skeletons [skel_index]->godot_skeleton ->get_parent () == nullptr ) {
6321+ return true ;
6322+ }
6323+ }
6324+ return false ;
6325+ }
6326+
62746327void GLTFDocument::_generate_scene_node (Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
62756328 Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
6329+ Node3D *current_node = nullptr ;
6330+ // Check if any GLTFDocumentExtension classes want to generate a node for us.
6331+ for (Ref<GLTFDocumentExtension> ext : document_extensions) {
6332+ ERR_CONTINUE (ext.is_null ());
6333+ current_node = ext->generate_scene_node (p_state, gltf_node, p_scene_parent);
6334+ if (current_node) {
6335+ break ;
6336+ }
6337+ }
6338+ // If none of our GLTFDocumentExtension classes generated us a node, try using built-in glTF types.
6339+ if (!current_node) {
6340+ if (gltf_node->mesh >= 0 ) {
6341+ current_node = _generate_mesh_instance (p_state, p_node_index);
6342+ // glTF specifies that skinned meshes should ignore their node transforms,
6343+ // only being controlled by the skeleton, so Godot will reparent a skinned
6344+ // mesh to its skeleton. However, we still need to ensure any child nodes
6345+ // keep their place in the tree, so if there are any child nodes, the skinned
6346+ // mesh must not be the base node, so generate an empty spatial base.
6347+ if (_does_skinned_mesh_require_placeholder_node (p_state, gltf_node)) {
6348+ Node3D *placeholder;
6349+ // We need a placeholder, but maybe the Skeleton3D *is* the placeholder?
6350+ const GLTFSkeletonIndex skel_index = gltf_node->skeleton ;
6351+ if (skel_index >= 0 && skel_index < p_state->skeletons .size () && p_state->skeletons [skel_index]->godot_skeleton ->get_parent () == nullptr ) {
6352+ placeholder = p_state->skeletons [skel_index]->godot_skeleton ;
6353+ } else {
6354+ placeholder = _generate_spatial (p_state, p_node_index);
6355+ }
6356+ current_node->set_name (gltf_node->get_name ());
6357+ placeholder->add_child (current_node, true );
6358+ current_node = placeholder;
6359+ }
6360+ } else if (gltf_node->camera >= 0 ) {
6361+ current_node = _generate_camera (p_state, p_node_index);
6362+ } else if (gltf_node->light >= 0 ) {
6363+ current_node = _generate_light (p_state, p_node_index);
6364+ }
6365+ }
6366+ // The only case where current_node is a Skeleton3D is when it is the placeholder for a skinned mesh.
6367+ // In that case, we don't set the name or possibly generate a bone attachment. But usually, we do.
6368+ // It is also possible that user code generates a Skeleton3D node, and this code also works for that case.
6369+ if (likely (!Object::cast_to<Skeleton3D>(current_node))) {
6370+ if (current_node) {
6371+ // Set the name of the Godot node to the name of the glTF node.
6372+ String gltf_node_name = gltf_node->get_name ();
6373+ if (!gltf_node_name.is_empty ()) {
6374+ current_node->set_name (gltf_node_name);
6375+ }
6376+ }
6377+ // Skeleton stuff: If this node is in a skeleton, we need to attach it to a bone attachment pointing to its bone.
6378+ if (gltf_node->skeleton >= 0 ) {
6379+ _generate_skeleton_bone_node (p_state, p_node_index, current_node, p_scene_parent, p_scene_root);
6380+ return ;
6381+ }
6382+ }
6383+ // Skeleton stuff: If the parent node is in a skeleton, we need to attach this node to a bone attachment pointing to the parent's bone.
6384+ if (Object::cast_to<Skeleton3D>(p_scene_parent)) {
6385+ Skeleton3D *parent_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
6386+ _attach_node_to_skeleton (p_state, p_node_index, current_node, parent_skeleton, p_scene_root);
6387+ return ;
6388+ }
6389+ // Not a skeleton bone, so definitely some kind of node that goes in the Godot scene tree.
6390+ if (current_node == nullptr ) {
6391+ current_node = _generate_spatial (p_state, p_node_index);
6392+ // Set the name of the Godot node to the name of the glTF node.
6393+ String gltf_node_name = gltf_node->get_name ();
6394+ if (!gltf_node_name.is_empty ()) {
6395+ current_node->set_name (gltf_node_name);
6396+ }
6397+ }
6398+ if (p_scene_parent) {
6399+ p_scene_parent->add_child (current_node, true );
6400+ }
6401+ // Set the owner of the nodes to the scene root.
6402+ // Note: p_scene_parent and p_scene_root must either both be null or both be valid.
6403+ _set_node_tree_owner (current_node, p_scene_root);
6404+ current_node->set_transform (gltf_node->transform );
6405+ current_node->merge_meta_from (*gltf_node);
6406+ p_state->scene_nodes .insert (p_node_index, current_node);
6407+ for (int i = 0 ; i < gltf_node->children .size (); ++i) {
6408+ _generate_scene_node (p_state, gltf_node->children [i], current_node, p_scene_root);
6409+ }
6410+ }
6411+
6412+ void GLTFDocument::_generate_skeleton_bone_node (Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node3D *p_current_node, Node *p_scene_parent, Node *p_scene_root) {
6413+ Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
6414+ // Grab the current skeleton, and ensure it's added to the tree.
6415+ Skeleton3D *godot_skeleton = p_state->skeletons [gltf_node->skeleton ]->godot_skeleton ;
6416+ if (godot_skeleton->get_parent () == nullptr ) {
6417+ if (p_scene_root) {
6418+ if (Object::cast_to<Skeleton3D>(p_scene_parent)) {
6419+ Skeleton3D *parent_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
6420+ // Explicitly specifying the bone of the parent glTF node is required to
6421+ // handle the edge case where a skeleton is a child of another skeleton.
6422+ _attach_node_to_skeleton (p_state, p_node_index, godot_skeleton, parent_skeleton, p_scene_root, gltf_node->parent );
6423+ } else {
6424+ p_scene_parent->add_child (godot_skeleton, true );
6425+ godot_skeleton->set_owner (p_scene_root);
6426+ }
6427+ } else {
6428+ p_scene_root = godot_skeleton;
6429+ }
6430+ }
6431+ _attach_node_to_skeleton (p_state, p_node_index, p_current_node, godot_skeleton, p_scene_root);
6432+ }
6433+
6434+ void GLTFDocument::_attach_node_to_skeleton (Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node3D *p_current_node, Skeleton3D *p_godot_skeleton, Node *p_scene_root, GLTFNodeIndex p_bone_node_index) {
6435+ ERR_FAIL_NULL (p_godot_skeleton->get_parent ());
6436+ Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
6437+ if (Object::cast_to<ImporterMeshInstance3D>(p_current_node) && gltf_node->skin >= 0 ) {
6438+ // Skinned meshes should be attached directly to the skeleton without a BoneAttachment3D.
6439+ ERR_FAIL_COND_MSG (p_current_node->get_child_count () > 0 , " Skinned mesh nodes passed to this function should not have children (a placeholder should be inserted by `_generate_scene_node`)." );
6440+ p_godot_skeleton->add_child (p_current_node, true );
6441+ } else if (p_current_node || !gltf_node->joint ) {
6442+ // If we have a node in need of attaching, we need a BoneAttachment3D.
6443+ // This happens when a node in Blender has Relations -> Parent set to a bone.
6444+ GLTFNodeIndex attachment_node_index = likely (p_bone_node_index == -1 ) ? (gltf_node->joint ? p_node_index : gltf_node->parent ) : p_bone_node_index;
6445+ ERR_FAIL_COND (!p_state->scene_nodes .has (attachment_node_index));
6446+ Node *attachment_godot_node = p_state->scene_nodes [attachment_node_index];
6447+ // If the parent is a Skeleton3D, we need to make a BoneAttachment3D.
6448+ if (Object::cast_to<Skeleton3D>(attachment_godot_node)) {
6449+ Ref<GLTFNode> attachment_gltf_node = p_state->nodes [attachment_node_index];
6450+ BoneAttachment3D *bone_attachment = _generate_bone_attachment (p_godot_skeleton, attachment_gltf_node);
6451+ bone_attachment->set_owner (p_scene_root);
6452+ bone_attachment->merge_meta_from (*p_state->nodes [attachment_node_index]);
6453+ p_state->scene_nodes .insert (attachment_node_index, bone_attachment);
6454+ attachment_godot_node = bone_attachment;
6455+ }
6456+ // By this point, `attachment_godot_node` is either a BoneAttachment3D or part of a BoneAttachment3D subtree.
6457+ // If the node is a plain non-joint, we should generate a Godot node for it.
6458+ if (p_current_node == nullptr ) {
6459+ DEV_ASSERT (!gltf_node->joint );
6460+ p_current_node = _generate_spatial (p_state, p_node_index);
6461+ }
6462+ if (!gltf_node->joint ) {
6463+ p_current_node->set_transform (gltf_node->transform );
6464+ }
6465+ p_current_node->set_name (gltf_node->get_name ());
6466+ attachment_godot_node->add_child (p_current_node, true );
6467+ } else {
6468+ // If this glTF is a plain joint, this glTF node only becomes a Godot bone.
6469+ // We refer to the skeleton itself as this glTF node's corresponding Godot node.
6470+ // This may be overridden later if the joint has a non-joint as a child in need of an attachment.
6471+ p_current_node = p_godot_skeleton;
6472+ }
6473+ _set_node_tree_owner (p_current_node, p_scene_root);
6474+ p_current_node->merge_meta_from (*gltf_node);
6475+ p_state->scene_nodes .insert (p_node_index, p_current_node);
6476+ for (int i = 0 ; i < gltf_node->children .size (); ++i) {
6477+ _generate_scene_node (p_state, gltf_node->children [i], p_current_node, p_scene_root);
6478+ }
6479+ }
6480+
6481+ // Deprecated code used when naming_version is 0 or 1 (Godot 4.0 to 4.4).
6482+ void GLTFDocument::_generate_scene_node_compat_4pt4 (Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
6483+ Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
62766484
62776485 if (gltf_node->skeleton >= 0 ) {
6278- _generate_skeleton_bone_node (p_state, p_node_index, p_scene_parent, p_scene_root);
6486+ _generate_skeleton_bone_node_compat_4pt4 (p_state, p_node_index, p_scene_parent, p_scene_root);
62796487 return ;
62806488 }
62816489
@@ -6289,7 +6497,7 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
62896497 // skinned meshes must not be placed in a bone attachment.
62906498 if (non_bone_parented_to_skeleton && gltf_node->skin < 0 ) {
62916499 // Bone Attachment - Parent Case
6292- BoneAttachment3D *bone_attachment = _generate_bone_attachment (p_state, active_skeleton, p_node_index, gltf_node->parent );
6500+ BoneAttachment3D *bone_attachment = _generate_bone_attachment_compat_4pt4 (p_state, active_skeleton, p_node_index, gltf_node->parent );
62936501
62946502 p_scene_parent->add_child (bone_attachment, true );
62956503
@@ -6366,11 +6574,12 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
63666574
63676575 p_state->scene_nodes .insert (p_node_index, current_node);
63686576 for (int i = 0 ; i < gltf_node->children .size (); ++i) {
6369- _generate_scene_node (p_state, gltf_node->children [i], current_node, p_scene_root);
6577+ _generate_scene_node_compat_4pt4 (p_state, gltf_node->children [i], current_node, p_scene_root);
63706578 }
63716579}
63726580
6373- void GLTFDocument::_generate_skeleton_bone_node (Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
6581+ // Deprecated code used when naming_version is 0 or 1 (Godot 4.0 to 4.4).
6582+ void GLTFDocument::_generate_skeleton_bone_node_compat_4pt4 (Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
63746583 Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
63756584
63766585 Node3D *current_node = nullptr ;
@@ -6385,7 +6594,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL
63856594 if (active_skeleton) {
63866595 // Should no longer be possible.
63876596 ERR_PRINT (vformat (" glTF: Generating scene detected direct parented Skeletons at node %d" , p_node_index));
6388- BoneAttachment3D *bone_attachment = _generate_bone_attachment (p_state, active_skeleton, p_node_index, gltf_node->parent );
6597+ BoneAttachment3D *bone_attachment = _generate_bone_attachment_compat_4pt4 (p_state, active_skeleton, p_node_index, gltf_node->parent );
63896598 p_scene_parent->add_child (bone_attachment, true );
63906599 bone_attachment->set_owner (p_scene_root);
63916600 // There is no gltf_node that represent this, so just directly create a unique name
@@ -6416,7 +6625,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL
64166625 // skinned meshes must not be placed in a bone attachment.
64176626 if (!is_skinned_mesh) {
64186627 // Bone Attachment - Same Node Case
6419- BoneAttachment3D *bone_attachment = _generate_bone_attachment (p_state, active_skeleton, p_node_index, p_node_index);
6628+ BoneAttachment3D *bone_attachment = _generate_bone_attachment_compat_4pt4 (p_state, active_skeleton, p_node_index, p_node_index);
64206629
64216630 p_scene_parent->add_child (bone_attachment, true );
64226631
@@ -6466,7 +6675,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL
64666675 p_state->scene_nodes .insert (p_node_index, current_node);
64676676
64686677 for (int i = 0 ; i < gltf_node->children .size (); ++i) {
6469- _generate_scene_node (p_state, gltf_node->children [i], active_skeleton, p_scene_root);
6678+ _generate_scene_node_compat_4pt4 (p_state, gltf_node->children [i], active_skeleton, p_scene_root);
64706679 }
64716680}
64726681
@@ -7495,6 +7704,7 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> p_state, Node *p_scene
74957704 mi = Object::cast_to<ImporterMeshInstance3D>(si_element->value );
74967705 ERR_CONTINUE_MSG (mi == nullptr , vformat (" Unable to cast node %d of type %s to ImporterMeshInstance3D" , node_i, si_element->value ->get_class_name ()));
74977706 }
7707+ ERR_CONTINUE_MSG (mi->get_child_count () > 0 , " The glTF importer must generate skinned mesh instances as leaf nodes without any children to allow them to be repositioned in the tree without affecting other nodes." );
74987708
74997709 const GLTFSkeletonIndex skel_i = p_state->skins .write [node->skin ]->skeleton ;
75007710 Ref<GLTFSkeleton> gltf_skeleton = p_state->skeletons .write [skel_i];
@@ -8425,15 +8635,23 @@ Node *GLTFDocument::_generate_scene_node_tree(Ref<GLTFState> p_state) {
84258635 // Generate the node tree.
84268636 Node *single_root;
84278637 if (p_state->extensions_used .has (" GODOT_single_root" )) {
8428- _generate_scene_node (p_state, 0 , nullptr , nullptr );
8638+ if (_naming_version < 2 ) {
8639+ _generate_scene_node_compat_4pt4 (p_state, 0 , nullptr , nullptr );
8640+ } else {
8641+ _generate_scene_node (p_state, 0 , nullptr , nullptr );
8642+ }
84298643 single_root = p_state->scene_nodes [0 ];
84308644 if (single_root && single_root->get_owner () && single_root->get_owner () != single_root) {
84318645 single_root = single_root->get_owner ();
84328646 }
84338647 } else {
84348648 single_root = memnew (Node3D);
84358649 for (int32_t root_i = 0 ; root_i < p_state->root_nodes .size (); root_i++) {
8436- _generate_scene_node (p_state, p_state->root_nodes [root_i], single_root, single_root);
8650+ if (_naming_version < 2 ) {
8651+ _generate_scene_node_compat_4pt4 (p_state, p_state->root_nodes [root_i], single_root, single_root);
8652+ } else {
8653+ _generate_scene_node (p_state, p_state->root_nodes [root_i], single_root, single_root);
8654+ }
84378655 }
84388656 }
84398657 // Assign the scene name and single root name to each other
@@ -8525,7 +8743,11 @@ Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> p_state, const String &p_se
85258743 ERR_FAIL_COND_V (err != OK, ERR_PARSE_ERROR);
85268744
85278745 /* DETERMINE SKELETONS */
8528- err = SkinTool::_determine_skeletons (p_state->skins , p_state->nodes , p_state->skeletons , p_state->get_import_as_skeleton_bones () ? p_state->root_nodes : Vector<GLTFNodeIndex>());
8746+ if (p_state->get_import_as_skeleton_bones ()) {
8747+ err = SkinTool::_determine_skeletons (p_state->skins , p_state->nodes , p_state->skeletons , p_state->root_nodes , true );
8748+ } else {
8749+ err = SkinTool::_determine_skeletons (p_state->skins , p_state->nodes , p_state->skeletons , Vector<GLTFNodeIndex>(), _naming_version < 2 );
8750+ }
85298751 ERR_FAIL_COND_V (err != OK, ERR_PARSE_ERROR);
85308752
85318753 /* ASSIGN SCENE NODE NAMES */
0 commit comments