From 5b7001dccf50a95292106becfadff59de36e2fe7 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Fri, 21 Jul 2023 21:59:39 -0500 Subject: [PATCH] GLTF: Improve logic for keeping track of the real root node --- .../doc_classes/GLTFDocumentExtension.xml | 8 ++--- .../gltf/extensions/gltf_document_extension.h | 2 +- modules/gltf/gltf_document.cpp | 33 ++++++++++++------- modules/gltf/gltf_document.h | 3 +- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml index bae980fb562..5c8b4fd50d1 100644 --- a/modules/gltf/doc_classes/GLTFDocumentExtension.xml +++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml @@ -63,7 +63,7 @@ - Part of the import process. This method is run after [method _parse_node_extensions] and before [method _import_post_parse]. + Part of the import process. This method is run after [method _import_post_parse] and before [method _import_node]. Runs when generating a Godot scene node from a GLTFNode. The returned node will be added to the scene tree. Multiple nodes can be generated in this step if they are added as a child of the returned node. @@ -87,7 +87,7 @@ - Part of the import process. This method is run after [method _import_post_parse] and before [method _import_post]. + Part of the import process. This method is run after [method _generate_scene_node] and before [method _import_post]. This method can be used to make modifications to each of the generated Godot scene nodes. @@ -104,7 +104,7 @@ - Part of the import process. This method is run after [method _generate_scene_node] and before [method _import_node]. + Part of the import process. This method is run after [method _parse_node_extensions] and before [method _generate_scene_node]. This method can be used to modify any of the data imported so far, including any scene nodes, before running the final per-node import step. @@ -134,7 +134,7 @@ - Part of the import process. This method is run after [method _get_supported_extensions] and before [method _generate_scene_node]. + Part of the import process. This method is run after [method _get_supported_extensions] and before [method _import_post_parse]. Runs when parsing the node extensions of a GLTFNode. This method can be used to process the extension JSON data into a format that can be used by [method _generate_scene_node]. The return value should be a member of the [enum Error] enum. diff --git a/modules/gltf/extensions/gltf_document_extension.h b/modules/gltf/extensions/gltf_document_extension.h index 0a631bb6c54..1eb11e6fb72 100644 --- a/modules/gltf/extensions/gltf_document_extension.h +++ b/modules/gltf/extensions/gltf_document_extension.h @@ -47,8 +47,8 @@ public: virtual Error parse_image_data(Ref p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref r_image); virtual String get_image_file_extension(); virtual Error parse_texture_json(Ref p_state, const Dictionary &p_texture_json, Ref r_gltf_texture); - virtual Node3D *generate_scene_node(Ref p_state, Ref p_gltf_node, Node *p_scene_parent); virtual Error import_post_parse(Ref p_state); + virtual Node3D *generate_scene_node(Ref p_state, Ref p_gltf_node, Node *p_scene_parent); virtual Error import_node(Ref p_state, Ref p_gltf_node, Dictionary &r_json, Node *p_node); virtual Error import_post(Ref p_state, Node *p_node); // Export process. diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 74de40e901a..955a9d8d7e7 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -5817,6 +5817,10 @@ void GLTFDocument::_generate_scene_node(Ref p_state, const GLTFNodeIn current_node = _generate_spatial(p_state, p_node_index); } } + String gltf_node_name = gltf_node->get_name(); + if (!gltf_node_name.is_empty()) { + current_node->set_name(gltf_node_name); + } // Add the node we generated and set the owner to the scene root. p_scene_parent->add_child(current_node, true); if (current_node != p_scene_root) { @@ -5825,7 +5829,6 @@ void GLTFDocument::_generate_scene_node(Ref p_state, const GLTFNodeIn current_node->propagate_call(StringName("set_owner"), args); } current_node->set_transform(gltf_node->xform); - current_node->set_name(gltf_node->get_name()); p_state->scene_nodes.insert(p_node_index, current_node); for (int i = 0; i < gltf_node->children.size(); ++i) { @@ -6439,7 +6442,7 @@ float GLTFDocument::get_max_component(const Color &p_color) { return MAX(MAX(r, g), b); } -void GLTFDocument::_process_mesh_instances(Ref p_state, Node *p_scene_root) { +void GLTFDocument::_process_mesh_instances(Ref p_state) { for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); ++node_i) { Ref node = p_state->nodes[node_i]; @@ -7262,15 +7265,28 @@ Error GLTFDocument::write_to_filesystem(Ref p_state, const String &p_ return OK; } +Node *GLTFDocument::_generate_scene_node_tree(Ref p_state) { + Node *single_root = memnew(Node3D); + for (int32_t root_i = 0; root_i < p_state->root_nodes.size(); root_i++) { + _generate_scene_node(p_state, p_state->root_nodes[root_i], single_root, single_root); + } + // Assign the scene name and single root name to each other + // if one is missing, or do nothing if both are already set. + if (unlikely(p_state->scene_name.is_empty())) { + p_state->scene_name = single_root->get_name(); + } else if (single_root->get_name() == StringName()) { + single_root->set_name(_gen_unique_name(p_state, p_state->scene_name)); + } + return single_root; +} + Node *GLTFDocument::generate_scene(Ref p_state, float p_bake_fps, bool p_trimming, bool p_remove_immutable_tracks) { ERR_FAIL_NULL_V(p_state, nullptr); ERR_FAIL_INDEX_V(0, p_state->root_nodes.size(), nullptr); Error err = OK; - GLTFNodeIndex gltf_root = p_state->root_nodes.write[0]; - Node *gltf_root_node = p_state->get_scene_node(gltf_root); - Node *root = gltf_root_node->get_parent(); + Node *root = _generate_scene_node_tree(p_state); ERR_FAIL_NULL_V(root, nullptr); - _process_mesh_instances(p_state, root); + _process_mesh_instances(p_state); if (p_state->get_create_animations() && p_state->animations.size()) { AnimationPlayer *ap = memnew(AnimationPlayer); root->add_child(ap, true); @@ -7450,11 +7466,6 @@ Error GLTFDocument::_parse_gltf_state(Ref p_state, const String &p_se /* ASSIGN SCENE NAMES */ _assign_node_names(p_state); - Node3D *root = memnew(Node3D); - for (int32_t root_i = 0; root_i < p_state->root_nodes.size(); root_i++) { - _generate_scene_node(p_state, p_state->root_nodes[root_i], root, root); - } - return OK; } diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index f2e36a04576..7faaa864d6a 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -306,7 +306,8 @@ public: Error _parse_gltf_state(Ref p_state, const String &p_search_path); Error _parse_asset_header(Ref p_state); Error _parse_gltf_extensions(Ref p_state); - void _process_mesh_instances(Ref p_state, Node *p_scene_root); + void _process_mesh_instances(Ref p_state); + Node *_generate_scene_node_tree(Ref p_state); void _generate_scene_node(Ref p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root); void _generate_skeleton_bone_node(Ref p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root); void _import_animation(Ref p_state, AnimationPlayer *p_animation_player,