@@ -5802,7 +5802,16 @@ void GLTFDocument::_assign_node_names(Ref<GLTFState> p_state) {
5802
5802
}
5803
5803
}
5804
5804
5805
- BoneAttachment3D *GLTFDocument::_generate_bone_attachment (Ref<GLTFState> p_state, Skeleton3D *p_skeleton, const GLTFNodeIndex p_node_index, const GLTFNodeIndex p_bone_index) {
5805
+ BoneAttachment3D *GLTFDocument::_generate_bone_attachment (Skeleton3D *p_godot_skeleton, const Ref<GLTFNode> &p_bone_node) {
5806
+ BoneAttachment3D *bone_attachment = memnew (BoneAttachment3D);
5807
+ print_verbose (" glTF: Creating bone attachment for: " + p_bone_node->get_name ());
5808
+ bone_attachment->set_name (p_bone_node->get_name ());
5809
+ p_godot_skeleton->add_child (bone_attachment, true );
5810
+ bone_attachment->set_bone_name (p_bone_node->get_name ());
5811
+ return bone_attachment;
5812
+ }
5813
+
5814
+ BoneAttachment3D *GLTFDocument::_generate_bone_attachment_compat_4pt4 (Ref<GLTFState> p_state, Skeleton3D *p_skeleton, const GLTFNodeIndex p_node_index, const GLTFNodeIndex p_bone_index) {
5806
5815
Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
5807
5816
Ref<GLTFNode> bone_node = p_state->nodes [p_bone_index];
5808
5817
BoneAttachment3D *bone_attachment = memnew (BoneAttachment3D);
@@ -6275,11 +6284,208 @@ void GLTFDocument::_convert_mesh_instance_to_gltf(MeshInstance3D *p_scene_parent
6275
6284
}
6276
6285
}
6277
6286
6287
+ void _set_node_tree_owner (Node *p_current_node, Node *&p_scene_root) {
6288
+ // Note: p_scene_parent and p_scene_root must either both be null or both be valid.
6289
+ if (p_scene_root == nullptr ) {
6290
+ // If the root node argument is null, this is the root node.
6291
+ p_scene_root = p_current_node;
6292
+ // If multiple nodes were generated under the root node, ensure they have the owner set.
6293
+ if (unlikely (p_current_node->get_child_count () > 0 )) {
6294
+ Array args;
6295
+ args.append (p_scene_root);
6296
+ for (int i = 0 ; i < p_current_node->get_child_count (); i++) {
6297
+ Node *child = p_current_node->get_child (i);
6298
+ child->propagate_call (StringName (" set_owner" ), args);
6299
+ }
6300
+ }
6301
+ } else {
6302
+ // Add the node we generated and set the owner to the scene root.
6303
+ Array args;
6304
+ args.append (p_scene_root);
6305
+ p_current_node->propagate_call (StringName (" set_owner" ), args);
6306
+ }
6307
+ }
6308
+
6309
+ bool GLTFDocument::_does_skinned_mesh_require_placeholder_node (Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node) {
6310
+ if (p_gltf_node->skin < 0 ) {
6311
+ return false ; // Not a skinned mesh.
6312
+ }
6313
+ // Check for child nodes that aren't joints/bones.
6314
+ for (int i = 0 ; i < p_gltf_node->children .size (); ++i) {
6315
+ Ref<GLTFNode> child = p_state->nodes [p_gltf_node->children [i]];
6316
+ if (!child->joint ) {
6317
+ return true ;
6318
+ }
6319
+ // Edge case: If a child's skeleton is not yet in the tree, then we must add it as a child of this node.
6320
+ // While the Skeleton3D node isn't a glTF node, it's still a case where we need a placeholder.
6321
+ // This is required to handle this issue: https://github.com/godotengine/godot/issues/67773
6322
+ const GLTFSkeletonIndex skel_index = child->skeleton ;
6323
+ ERR_FAIL_INDEX_V (skel_index, p_state->skeletons .size (), false );
6324
+ if (p_state->skeletons [skel_index]->godot_skeleton ->get_parent () == nullptr ) {
6325
+ return true ;
6326
+ }
6327
+ }
6328
+ return false ;
6329
+ }
6330
+
6278
6331
void GLTFDocument::_generate_scene_node (Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
6279
6332
Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
6333
+ Node3D *current_node = nullptr ;
6334
+ // Check if any GLTFDocumentExtension classes want to generate a node for us.
6335
+ for (Ref<GLTFDocumentExtension> ext : document_extensions) {
6336
+ ERR_CONTINUE (ext.is_null ());
6337
+ current_node = ext->generate_scene_node (p_state, gltf_node, p_scene_parent);
6338
+ if (current_node) {
6339
+ break ;
6340
+ }
6341
+ }
6342
+ // If none of our GLTFDocumentExtension classes generated us a node, try using built-in glTF types.
6343
+ if (!current_node) {
6344
+ if (gltf_node->mesh >= 0 ) {
6345
+ current_node = _generate_mesh_instance (p_state, p_node_index);
6346
+ // glTF specifies that skinned meshes should ignore their node transforms,
6347
+ // only being controlled by the skeleton, so Godot will reparent a skinned
6348
+ // mesh to its skeleton. However, we still need to ensure any child nodes
6349
+ // keep their place in the tree, so if there are any child nodes, the skinned
6350
+ // mesh must not be the base node, so generate an empty spatial base.
6351
+ if (_does_skinned_mesh_require_placeholder_node (p_state, gltf_node)) {
6352
+ Node3D *placeholder;
6353
+ // We need a placeholder, but maybe the Skeleton3D *is* the placeholder?
6354
+ if (gltf_node->skeleton >= 0 && p_state->skeletons [gltf_node->skeleton ]->godot_skeleton ->get_parent () == nullptr ) {
6355
+ placeholder = p_state->skeletons [gltf_node->skeleton ]->godot_skeleton ;
6356
+ } else {
6357
+ placeholder = _generate_spatial (p_state, p_node_index);
6358
+ }
6359
+ current_node->set_name (gltf_node->get_name ());
6360
+ placeholder->add_child (current_node, true );
6361
+ current_node = placeholder;
6362
+ }
6363
+ } else if (gltf_node->camera >= 0 ) {
6364
+ current_node = _generate_camera (p_state, p_node_index);
6365
+ } else if (gltf_node->light >= 0 ) {
6366
+ current_node = _generate_light (p_state, p_node_index);
6367
+ }
6368
+ }
6369
+ // The only case where current_node is a Skeleton3D is when it is the placeholder for a skinned mesh.
6370
+ // In that case, we don't set the name or possibly generate a bone attachment. But usually, we do.
6371
+ if (likely (!Object::cast_to<Skeleton3D>(current_node))) {
6372
+ if (current_node) {
6373
+ // Set the name of the Godot node to the name of the glTF node.
6374
+ String gltf_node_name = gltf_node->get_name ();
6375
+ if (!gltf_node_name.is_empty ()) {
6376
+ current_node->set_name (gltf_node_name);
6377
+ }
6378
+ }
6379
+ // Skeleton stuff: If this node is in a skeleton, we need to attach it to a bone attachment pointing to its bone.
6380
+ if (gltf_node->skeleton >= 0 ) {
6381
+ _generate_skeleton_bone_node (p_state, p_node_index, current_node, p_scene_parent, p_scene_root);
6382
+ return ;
6383
+ }
6384
+ }
6385
+ // 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.
6386
+ if (Object::cast_to<Skeleton3D>(p_scene_parent)) {
6387
+ Skeleton3D *parent_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
6388
+ _attach_node_to_skeleton (p_state, p_node_index, current_node, parent_skeleton, p_scene_root);
6389
+ return ;
6390
+ }
6391
+ // Not a skeleton bone, so definitely some kind of node that goes in the Godot scene tree.
6392
+ if (current_node == nullptr ) {
6393
+ current_node = _generate_spatial (p_state, p_node_index);
6394
+ // Set the name of the Godot node to the name of the glTF node.
6395
+ String gltf_node_name = gltf_node->get_name ();
6396
+ if (!gltf_node_name.is_empty ()) {
6397
+ current_node->set_name (gltf_node_name);
6398
+ }
6399
+ }
6400
+ if (p_scene_parent) {
6401
+ p_scene_parent->add_child (current_node, true );
6402
+ }
6403
+ // Set the owner of the nodes to the scene root.
6404
+ // Note: p_scene_parent and p_scene_root must either both be null or both be valid.
6405
+ _set_node_tree_owner (current_node, p_scene_root);
6406
+ current_node->set_transform (gltf_node->transform );
6407
+ current_node->merge_meta_from (*gltf_node);
6408
+ p_state->scene_nodes .insert (p_node_index, current_node);
6409
+ for (int i = 0 ; i < gltf_node->children .size (); ++i) {
6410
+ _generate_scene_node (p_state, gltf_node->children [i], current_node, p_scene_root);
6411
+ }
6412
+ }
6413
+
6414
+ 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) {
6415
+ Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
6416
+ // Grab the current skeleton, and ensure it's added to the tree.
6417
+ Skeleton3D *godot_skeleton = p_state->skeletons [gltf_node->skeleton ]->godot_skeleton ;
6418
+ if (godot_skeleton->get_parent () == nullptr ) {
6419
+ if (p_scene_root) {
6420
+ if (Object::cast_to<Skeleton3D>(p_scene_parent)) {
6421
+ Skeleton3D *parent_skeleton = Object::cast_to<Skeleton3D>(p_scene_parent);
6422
+ // Explicitly specifying the bone of the parent glTF node is required to
6423
+ // handle the edge case where a skeleton is a child of another skeleton.
6424
+ _attach_node_to_skeleton (p_state, p_node_index, godot_skeleton, parent_skeleton, p_scene_root, gltf_node->parent );
6425
+ } else {
6426
+ p_scene_parent->add_child (godot_skeleton, true );
6427
+ godot_skeleton->set_owner (p_scene_root);
6428
+ }
6429
+ } else {
6430
+ p_scene_root = godot_skeleton;
6431
+ }
6432
+ }
6433
+ _attach_node_to_skeleton (p_state, p_node_index, p_current_node, godot_skeleton, p_scene_root);
6434
+ }
6435
+
6436
+ 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) {
6437
+ ERR_FAIL_NULL (p_godot_skeleton->get_parent ());
6438
+ Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
6439
+ if (Object::cast_to<ImporterMeshInstance3D>(p_current_node) && gltf_node->skin >= 0 ) {
6440
+ // Skinned meshes should be attached directly to the skeleton without a BoneAttachment3D.
6441
+ 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`)." );
6442
+ p_godot_skeleton->add_child (p_current_node, true );
6443
+ } else if (p_current_node || !gltf_node->joint ) {
6444
+ // If we have a node in need of attaching, we need a BoneAttachment3D.
6445
+ // This happens when a node in Blender has Relations -> Parent set to a bone.
6446
+ GLTFNodeIndex attachment_node_index = likely (p_bone_node_index == -1 ) ? (gltf_node->joint ? p_node_index : gltf_node->parent ) : p_bone_node_index;
6447
+ ERR_FAIL_COND (!p_state->scene_nodes .has (attachment_node_index));
6448
+ Node *attachment_godot_node = p_state->scene_nodes [attachment_node_index];
6449
+ // If the parent is a Skeleton3D, we need to make a BoneAttachment3D.
6450
+ if (Object::cast_to<Skeleton3D>(attachment_godot_node)) {
6451
+ Ref<GLTFNode> attachment_gltf_node = p_state->nodes [attachment_node_index];
6452
+ BoneAttachment3D *bone_attachment = _generate_bone_attachment (p_godot_skeleton, attachment_gltf_node);
6453
+ bone_attachment->set_owner (p_scene_root);
6454
+ bone_attachment->merge_meta_from (*p_state->nodes [attachment_node_index]);
6455
+ p_state->scene_nodes .insert (attachment_node_index, bone_attachment);
6456
+ attachment_godot_node = bone_attachment;
6457
+ }
6458
+ // By this point, `attachment_godot_node` is either a BoneAttachment3D or part of a BoneAttachment3D subtree.
6459
+ // If the node is a plain non-joint, we should generate a Godot node for it.
6460
+ if (p_current_node == nullptr ) {
6461
+ DEV_ASSERT (!gltf_node->joint );
6462
+ p_current_node = _generate_spatial (p_state, p_node_index);
6463
+ }
6464
+ if (!gltf_node->joint ) {
6465
+ p_current_node->set_transform (gltf_node->transform );
6466
+ }
6467
+ p_current_node->set_name (gltf_node->get_name ());
6468
+ attachment_godot_node->add_child (p_current_node, true );
6469
+ } else {
6470
+ // If this glTF is a plain joint, this glTF node only becomes a Godot bone.
6471
+ // We refer to the skeleton itself as this glTF node's corresponding Godot node.
6472
+ // This may be overridden later if the joint has a non-joint as a child in need of an attachment.
6473
+ p_current_node = p_godot_skeleton;
6474
+ }
6475
+ _set_node_tree_owner (p_current_node, p_scene_root);
6476
+ p_current_node->merge_meta_from (*gltf_node);
6477
+ p_state->scene_nodes .insert (p_node_index, p_current_node);
6478
+ for (int i = 0 ; i < gltf_node->children .size (); ++i) {
6479
+ _generate_scene_node (p_state, gltf_node->children [i], p_current_node, p_scene_root);
6480
+ }
6481
+ }
6482
+
6483
+ // Deprecated code used when naming_version is 0 or 1 (Godot 4.0 to 4.4).
6484
+ void GLTFDocument::_generate_scene_node_compat_4pt4 (Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
6485
+ Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
6280
6486
6281
6487
if (gltf_node->skeleton >= 0 ) {
6282
- _generate_skeleton_bone_node (p_state, p_node_index, p_scene_parent, p_scene_root);
6488
+ _generate_skeleton_bone_node_compat_4pt4 (p_state, p_node_index, p_scene_parent, p_scene_root);
6283
6489
return ;
6284
6490
}
6285
6491
@@ -6293,7 +6499,7 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
6293
6499
// skinned meshes must not be placed in a bone attachment.
6294
6500
if (non_bone_parented_to_skeleton && gltf_node->skin < 0 ) {
6295
6501
// Bone Attachment - Parent Case
6296
- BoneAttachment3D *bone_attachment = _generate_bone_attachment (p_state, active_skeleton, p_node_index, gltf_node->parent );
6502
+ BoneAttachment3D *bone_attachment = _generate_bone_attachment_compat_4pt4 (p_state, active_skeleton, p_node_index, gltf_node->parent );
6297
6503
6298
6504
p_scene_parent->add_child (bone_attachment, true );
6299
6505
@@ -6370,11 +6576,12 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
6370
6576
6371
6577
p_state->scene_nodes .insert (p_node_index, current_node);
6372
6578
for (int i = 0 ; i < gltf_node->children .size (); ++i) {
6373
- _generate_scene_node (p_state, gltf_node->children [i], current_node, p_scene_root);
6579
+ _generate_scene_node_compat_4pt4 (p_state, gltf_node->children [i], current_node, p_scene_root);
6374
6580
}
6375
6581
}
6376
6582
6377
- void GLTFDocument::_generate_skeleton_bone_node (Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root) {
6583
+ // Deprecated code used when naming_version is 0 or 1 (Godot 4.0 to 4.4).
6584
+ 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) {
6378
6585
Ref<GLTFNode> gltf_node = p_state->nodes [p_node_index];
6379
6586
6380
6587
Node3D *current_node = nullptr ;
@@ -6389,7 +6596,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL
6389
6596
if (active_skeleton) {
6390
6597
// Should no longer be possible.
6391
6598
ERR_PRINT (vformat (" glTF: Generating scene detected direct parented Skeletons at node %d" , p_node_index));
6392
- BoneAttachment3D *bone_attachment = _generate_bone_attachment (p_state, active_skeleton, p_node_index, gltf_node->parent );
6599
+ BoneAttachment3D *bone_attachment = _generate_bone_attachment_compat_4pt4 (p_state, active_skeleton, p_node_index, gltf_node->parent );
6393
6600
p_scene_parent->add_child (bone_attachment, true );
6394
6601
bone_attachment->set_owner (p_scene_root);
6395
6602
// There is no gltf_node that represent this, so just directly create a unique name
@@ -6420,7 +6627,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL
6420
6627
// skinned meshes must not be placed in a bone attachment.
6421
6628
if (!is_skinned_mesh) {
6422
6629
// Bone Attachment - Same Node Case
6423
- BoneAttachment3D *bone_attachment = _generate_bone_attachment (p_state, active_skeleton, p_node_index, p_node_index);
6630
+ BoneAttachment3D *bone_attachment = _generate_bone_attachment_compat_4pt4 (p_state, active_skeleton, p_node_index, p_node_index);
6424
6631
6425
6632
p_scene_parent->add_child (bone_attachment, true );
6426
6633
@@ -6470,7 +6677,7 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL
6470
6677
p_state->scene_nodes .insert (p_node_index, current_node);
6471
6678
6472
6679
for (int i = 0 ; i < gltf_node->children .size (); ++i) {
6473
- _generate_scene_node (p_state, gltf_node->children [i], active_skeleton, p_scene_root);
6680
+ _generate_scene_node_compat_4pt4 (p_state, gltf_node->children [i], active_skeleton, p_scene_root);
6474
6681
}
6475
6682
}
6476
6683
@@ -7499,6 +7706,7 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> p_state, Node *p_scene
7499
7706
mi = Object::cast_to<ImporterMeshInstance3D>(si_element->value );
7500
7707
ERR_CONTINUE_MSG (mi == nullptr , vformat (" Unable to cast node %d of type %s to ImporterMeshInstance3D" , node_i, si_element->value ->get_class_name ()));
7501
7708
}
7709
+ 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." );
7502
7710
7503
7711
const GLTFSkeletonIndex skel_i = p_state->skins .write [node->skin ]->skeleton ;
7504
7712
Ref<GLTFSkeleton> gltf_skeleton = p_state->skeletons .write [skel_i];
@@ -8412,15 +8620,23 @@ Node *GLTFDocument::_generate_scene_node_tree(Ref<GLTFState> p_state) {
8412
8620
// Generate the node tree.
8413
8621
Node *single_root;
8414
8622
if (p_state->extensions_used .has (" GODOT_single_root" )) {
8415
- _generate_scene_node (p_state, 0 , nullptr , nullptr );
8623
+ if (_naming_version < 2 ) {
8624
+ _generate_scene_node_compat_4pt4 (p_state, 0 , nullptr , nullptr );
8625
+ } else {
8626
+ _generate_scene_node (p_state, 0 , nullptr , nullptr );
8627
+ }
8416
8628
single_root = p_state->scene_nodes [0 ];
8417
8629
if (single_root && single_root->get_owner () && single_root->get_owner () != single_root) {
8418
8630
single_root = single_root->get_owner ();
8419
8631
}
8420
8632
} else {
8421
8633
single_root = memnew (Node3D);
8422
8634
for (int32_t root_i = 0 ; root_i < p_state->root_nodes .size (); root_i++) {
8423
- _generate_scene_node (p_state, p_state->root_nodes [root_i], single_root, single_root);
8635
+ if (_naming_version < 2 ) {
8636
+ _generate_scene_node_compat_4pt4 (p_state, p_state->root_nodes [root_i], single_root, single_root);
8637
+ } else {
8638
+ _generate_scene_node (p_state, p_state->root_nodes [root_i], single_root, single_root);
8639
+ }
8424
8640
}
8425
8641
}
8426
8642
// Assign the scene name and single root name to each other
@@ -8512,7 +8728,11 @@ Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> p_state, const String &p_se
8512
8728
ERR_FAIL_COND_V (err != OK, ERR_PARSE_ERROR);
8513
8729
8514
8730
/* DETERMINE SKELETONS */
8515
- 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>());
8731
+ if (p_state->get_import_as_skeleton_bones ()) {
8732
+ err = SkinTool::_determine_skeletons (p_state->skins , p_state->nodes , p_state->skeletons , p_state->root_nodes , true );
8733
+ } else {
8734
+ err = SkinTool::_determine_skeletons (p_state->skins , p_state->nodes , p_state->skeletons , Vector<GLTFNodeIndex>(), _naming_version < 2 );
8735
+ }
8516
8736
ERR_FAIL_COND_V (err != OK, ERR_PARSE_ERROR);
8517
8737
8518
8738
/* ASSIGN SCENE NODE NAMES */
0 commit comments