GLTF: Improve logic for keeping track of the real root node

This commit is contained in:
Aaron Franke 2023-07-21 21:59:39 -05:00
parent fa3428ff25
commit 5b7001dccf
No known key found for this signature in database
GPG key ID: 40A1750B977E56BF
4 changed files with 29 additions and 17 deletions

View file

@ -63,7 +63,7 @@
<param index="1" name="gltf_node" type="GLTFNode" /> <param index="1" name="gltf_node" type="GLTFNode" />
<param index="2" name="scene_parent" type="Node" /> <param index="2" name="scene_parent" type="Node" />
<description> <description>
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. 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.
</description> </description>
</method> </method>
@ -87,7 +87,7 @@
<param index="2" name="json" type="Dictionary" /> <param index="2" name="json" type="Dictionary" />
<param index="3" name="node" type="Node" /> <param index="3" name="node" type="Node" />
<description> <description>
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. This method can be used to make modifications to each of the generated Godot scene nodes.
</description> </description>
</method> </method>
@ -104,7 +104,7 @@
<return type="int" enum="Error" /> <return type="int" enum="Error" />
<param index="0" name="state" type="GLTFState" /> <param index="0" name="state" type="GLTFState" />
<description> <description>
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. 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.
</description> </description>
</method> </method>
@ -134,7 +134,7 @@
<param index="1" name="gltf_node" type="GLTFNode" /> <param index="1" name="gltf_node" type="GLTFNode" />
<param index="2" name="extensions" type="Dictionary" /> <param index="2" name="extensions" type="Dictionary" />
<description> <description>
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. 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.
</description> </description>
</method> </method>

View file

@ -47,8 +47,8 @@ public:
virtual Error parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image); virtual Error parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image);
virtual String get_image_file_extension(); virtual String get_image_file_extension();
virtual Error parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture); virtual Error parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture);
virtual Node3D *generate_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent);
virtual Error import_post_parse(Ref<GLTFState> p_state); virtual Error import_post_parse(Ref<GLTFState> p_state);
virtual Node3D *generate_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent);
virtual Error import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node); virtual Error import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node);
virtual Error import_post(Ref<GLTFState> p_state, Node *p_node); virtual Error import_post(Ref<GLTFState> p_state, Node *p_node);
// Export process. // Export process.

View file

@ -5817,6 +5817,10 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
current_node = _generate_spatial(p_state, p_node_index); 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. // Add the node we generated and set the owner to the scene root.
p_scene_parent->add_child(current_node, true); p_scene_parent->add_child(current_node, true);
if (current_node != p_scene_root) { if (current_node != p_scene_root) {
@ -5825,7 +5829,6 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
current_node->propagate_call(StringName("set_owner"), args); current_node->propagate_call(StringName("set_owner"), args);
} }
current_node->set_transform(gltf_node->xform); 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); p_state->scene_nodes.insert(p_node_index, current_node);
for (int i = 0; i < gltf_node->children.size(); ++i) { 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); return MAX(MAX(r, g), b);
} }
void GLTFDocument::_process_mesh_instances(Ref<GLTFState> p_state, Node *p_scene_root) { void GLTFDocument::_process_mesh_instances(Ref<GLTFState> p_state) {
for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); ++node_i) { for (GLTFNodeIndex node_i = 0; node_i < p_state->nodes.size(); ++node_i) {
Ref<GLTFNode> node = p_state->nodes[node_i]; Ref<GLTFNode> node = p_state->nodes[node_i];
@ -7262,15 +7265,28 @@ Error GLTFDocument::write_to_filesystem(Ref<GLTFState> p_state, const String &p_
return OK; return OK;
} }
Node *GLTFDocument::_generate_scene_node_tree(Ref<GLTFState> 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<GLTFState> p_state, float p_bake_fps, bool p_trimming, bool p_remove_immutable_tracks) { Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, bool p_trimming, bool p_remove_immutable_tracks) {
ERR_FAIL_NULL_V(p_state, nullptr); ERR_FAIL_NULL_V(p_state, nullptr);
ERR_FAIL_INDEX_V(0, p_state->root_nodes.size(), nullptr); ERR_FAIL_INDEX_V(0, p_state->root_nodes.size(), nullptr);
Error err = OK; Error err = OK;
GLTFNodeIndex gltf_root = p_state->root_nodes.write[0]; Node *root = _generate_scene_node_tree(p_state);
Node *gltf_root_node = p_state->get_scene_node(gltf_root);
Node *root = gltf_root_node->get_parent();
ERR_FAIL_NULL_V(root, nullptr); 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()) { if (p_state->get_create_animations() && p_state->animations.size()) {
AnimationPlayer *ap = memnew(AnimationPlayer); AnimationPlayer *ap = memnew(AnimationPlayer);
root->add_child(ap, true); root->add_child(ap, true);
@ -7450,11 +7466,6 @@ Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> p_state, const String &p_se
/* ASSIGN SCENE NAMES */ /* ASSIGN SCENE NAMES */
_assign_node_names(p_state); _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; return OK;
} }

View file

@ -306,7 +306,8 @@ public:
Error _parse_gltf_state(Ref<GLTFState> p_state, const String &p_search_path); Error _parse_gltf_state(Ref<GLTFState> p_state, const String &p_search_path);
Error _parse_asset_header(Ref<GLTFState> p_state); Error _parse_asset_header(Ref<GLTFState> p_state);
Error _parse_gltf_extensions(Ref<GLTFState> p_state); Error _parse_gltf_extensions(Ref<GLTFState> p_state);
void _process_mesh_instances(Ref<GLTFState> p_state, Node *p_scene_root); void _process_mesh_instances(Ref<GLTFState> p_state);
Node *_generate_scene_node_tree(Ref<GLTFState> p_state);
void _generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root); void _generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
void _generate_skeleton_bone_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root); void _generate_skeleton_bone_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
void _import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, void _import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player,