diff options
author | Aaron Franke <arnfranke@yahoo.com> | 2024-09-02 01:28:07 -0700 |
---|---|---|
committer | Aaron Franke <arnfranke@yahoo.com> | 2024-09-02 19:05:03 -0700 |
commit | f82262eecb558accb926628aa95b6e66209dcad3 (patch) | |
tree | 12b0e7e65703b2959d59d11014b9f21a07cf08bc | |
parent | 7c383767a29969b0c3db036742da00ef58b765dd (diff) | |
download | redot-engine-f82262eecb558accb926628aa95b6e66209dcad3.tar.gz |
GLTF: Add append_gltf_node to GLTFState
-rw-r--r-- | modules/gltf/doc_classes/GLTFNode.xml | 7 | ||||
-rw-r--r-- | modules/gltf/doc_classes/GLTFState.xml | 11 | ||||
-rw-r--r-- | modules/gltf/gltf_document.cpp | 34 | ||||
-rw-r--r-- | modules/gltf/gltf_document.h | 6 | ||||
-rw-r--r-- | modules/gltf/gltf_state.cpp | 14 | ||||
-rw-r--r-- | modules/gltf/gltf_state.h | 1 | ||||
-rw-r--r-- | modules/gltf/structures/gltf_node.cpp | 5 | ||||
-rw-r--r-- | modules/gltf/structures/gltf_node.h | 1 |
8 files changed, 52 insertions, 27 deletions
diff --git a/modules/gltf/doc_classes/GLTFNode.xml b/modules/gltf/doc_classes/GLTFNode.xml index 2786c25e9a..a242a0d1d8 100644 --- a/modules/gltf/doc_classes/GLTFNode.xml +++ b/modules/gltf/doc_classes/GLTFNode.xml @@ -12,6 +12,13 @@ <link title="glTF scene and node spec">https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_004_ScenesNodes.md"</link> </tutorials> <methods> + <method name="append_child_index"> + <return type="void" /> + <param index="0" name="child_index" type="int" /> + <description> + Appends the given child node index to the [member children] array. + </description> + </method> <method name="get_additional_data"> <return type="Variant" /> <param index="0" name="extension_name" type="StringName" /> diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml index c049acf557..de7ec2a4ca 100644 --- a/modules/gltf/doc_classes/GLTFState.xml +++ b/modules/gltf/doc_classes/GLTFState.xml @@ -28,6 +28,17 @@ Appends the given byte array data to the buffers and creates a [GLTFBufferView] for it. The index of the destination [GLTFBufferView] is returned. If [param deduplication] is true, the buffers will first be searched for duplicate data, otherwise new bytes will always be appended. </description> </method> + <method name="append_gltf_node"> + <return type="int" /> + <param index="0" name="gltf_node" type="GLTFNode" /> + <param index="1" name="godot_scene_node" type="Node" /> + <param index="2" name="parent_node_index" type="int" /> + <description> + Append the given [GLTFNode] to the state, and return its new index. This can be used to export one Godot node as multiple glTF nodes, or inject new glTF nodes at import time. On import, this must be called before [method GLTFDocumentExtension._generate_scene_node] finishes for the parent node. On export, this must be called before [method GLTFDocumentExtension._export_node] runs for the parent node. + The [param godot_scene_node] parameter is the Godot scene node that corresponds to this glTF node. This is highly recommended to be set to a valid node, but may be null if there is no corresponding Godot scene node. One Godot scene node may be used for multiple glTF nodes, so if exporting multiple glTF nodes for one Godot scene node, use the same Godot scene node for each. + The [param parent_node_index] parameter is the index of the parent [GLTFNode] in the state. If [code]-1[/code], the node will be a root node, otherwise the new node will be added to the parent's list of children. The index will also be written to the [member GLTFNode.parent] property of the new node. + </description> + </method> <method name="get_accessors"> <return type="GLTFAccessor[]" /> <description> diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 69973a34dd..acb72c552f 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -414,7 +414,6 @@ static Vector<real_t> _xform_to_array(const Transform3D p_transform) { Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) { Array nodes; - const int scene_node_count = p_state->scene_nodes.size(); for (int i = 0; i < p_state->nodes.size(); i++) { Dictionary node; Ref<GLTFNode> gltf_node = p_state->nodes[i]; @@ -465,7 +464,7 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> p_state) { } Node *scene_node = nullptr; - if (i < scene_node_count) { + if (i < (int)p_state->scene_nodes.size()) { scene_node = p_state->scene_nodes[i]; } for (Ref<GLTFDocumentExtension> ext : document_extensions) { @@ -5264,6 +5263,7 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> p_state, Node *p_current, gltf_node.instantiate(); gltf_node->set_original_name(p_current->get_name()); gltf_node->set_name(_gen_unique_name(p_state, p_current->get_name())); + gltf_node->merge_meta_from(p_current); if (cast_to<Node3D>(p_current)) { Node3D *spatial = cast_to<Node3D>(p_current); _convert_spatial(p_state, spatial, gltf_node); @@ -5309,14 +5309,18 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> p_state, Node *p_current, ERR_CONTINUE(ext.is_null()); ext->convert_scene_node(p_state, gltf_node, p_current); } - GLTFNodeIndex current_node_i = p_state->nodes.size(); - GLTFNodeIndex gltf_root = p_gltf_root; - if (gltf_root == -1) { - gltf_root = current_node_i; - p_state->root_nodes.push_back(gltf_root); + GLTFNodeIndex current_node_i; + if (gltf_node->get_parent() == -1) { + current_node_i = p_state->append_gltf_node(gltf_node, p_current, p_gltf_parent); + } else if (gltf_node->get_parent() < -1) { + return; + } else { + current_node_i = p_state->nodes.size() - 1; + while (gltf_node != p_state->nodes[current_node_i]) { + current_node_i--; + } } - gltf_node->merge_meta_from(p_current); - _create_gltf_node(p_state, p_current, current_node_i, p_gltf_parent, gltf_root, gltf_node); + const GLTFNodeIndex gltf_root = (p_gltf_root == -1) ? current_node_i : p_gltf_root; for (int node_i = 0; node_i < p_current->get_child_count(); node_i++) { _convert_scene_node(p_state, p_current->get_child(node_i), current_node_i, gltf_root); } @@ -5377,18 +5381,6 @@ void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeInd } #endif // MODULE_CSG_ENABLED -void GLTFDocument::_create_gltf_node(Ref<GLTFState> p_state, Node *p_scene_parent, GLTFNodeIndex p_current_node_i, - GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_gltf_node, Ref<GLTFNode> p_gltf_node) { - p_state->scene_nodes.insert(p_current_node_i, p_scene_parent); - p_state->nodes.push_back(p_gltf_node); - ERR_FAIL_COND(p_current_node_i == p_parent_node_index); - p_state->nodes.write[p_current_node_i]->parent = p_parent_node_index; - if (p_parent_node_index == -1) { - return; - } - p_state->nodes.write[p_parent_node_index]->children.push_back(p_current_node_i); -} - void GLTFDocument::_convert_animation_player_to_gltf(AnimationPlayer *p_animation_player, Ref<GLTFState> p_state, GLTFNodeIndex p_gltf_current, GLTFNodeIndex p_gltf_root_index, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent) { ERR_FAIL_NULL(p_animation_player); p_state->animation_players.push_back(p_animation_player); diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index b3e6dcf54a..d347d49102 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -342,12 +342,6 @@ public: void _convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> p_gltf_node, Ref<GLTFState> p_state); #endif // MODULE_CSG_ENABLED - void _create_gltf_node(Ref<GLTFState> p_state, - Node *p_scene_parent, - GLTFNodeIndex p_current_node_i, - GLTFNodeIndex p_parent_node_index, - GLTFNodeIndex p_root_gltf_node, - Ref<GLTFNode> p_gltf_node); void _convert_animation_player_to_gltf( AnimationPlayer *p_animation_player, Ref<GLTFState> p_state, GLTFNodeIndex p_gltf_current, diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index 73a61ff77f..7763874d02 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -35,6 +35,7 @@ void GLTFState::_bind_methods() { ClassDB::bind_method(D_METHOD("add_used_extension", "extension_name", "required"), &GLTFState::add_used_extension); ClassDB::bind_method(D_METHOD("append_data_to_buffers", "data", "deduplication"), &GLTFState::append_data_to_buffers); + ClassDB::bind_method(D_METHOD("append_gltf_node", "gltf_node", "godot_scene_node", "parent_node_index"), &GLTFState::append_gltf_node); ClassDB::bind_method(D_METHOD("get_json"), &GLTFState::get_json); ClassDB::bind_method(D_METHOD("set_json", "json"), &GLTFState::set_json); @@ -441,3 +442,16 @@ GLTFBufferViewIndex GLTFState::append_data_to_buffers(const Vector<uint8_t> &p_d buffer_views.push_back(buffer_view); return new_index; } + +GLTFNodeIndex GLTFState::append_gltf_node(Ref<GLTFNode> p_gltf_node, Node *p_godot_scene_node, GLTFNodeIndex p_parent_node_index) { + p_gltf_node->set_parent(p_parent_node_index); + const GLTFNodeIndex new_index = nodes.size(); + nodes.append(p_gltf_node); + scene_nodes.insert(new_index, p_godot_scene_node); + if (p_parent_node_index == -1) { + root_nodes.append(new_index); + } else if (p_parent_node_index < new_index) { + nodes.write[p_parent_node_index]->append_child_index(new_index); + } + return new_index; +} diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 07efafe13b..7954049192 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -119,6 +119,7 @@ public: void add_used_extension(const String &p_extension, bool p_required = false); GLTFBufferViewIndex append_data_to_buffers(const Vector<uint8_t> &p_data, const bool p_deduplication); + GLTFNodeIndex append_gltf_node(Ref<GLTFNode> p_gltf_node, Node *p_godot_scene_node, GLTFNodeIndex p_parent_node_index); enum GLTFHandleBinary { HANDLE_BINARY_DISCARD_TEXTURES = 0, diff --git a/modules/gltf/structures/gltf_node.cpp b/modules/gltf/structures/gltf_node.cpp index 2934e4b5ee..ccee5e8ca4 100644 --- a/modules/gltf/structures/gltf_node.cpp +++ b/modules/gltf/structures/gltf_node.cpp @@ -55,6 +55,7 @@ void GLTFNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_scale", "scale"), &GLTFNode::set_scale); ClassDB::bind_method(D_METHOD("get_children"), &GLTFNode::get_children); ClassDB::bind_method(D_METHOD("set_children", "children"), &GLTFNode::set_children); + ClassDB::bind_method(D_METHOD("append_child_index", "child_index"), &GLTFNode::append_child_index); ClassDB::bind_method(D_METHOD("get_light"), &GLTFNode::get_light); ClassDB::bind_method(D_METHOD("set_light", "light"), &GLTFNode::set_light); ClassDB::bind_method(D_METHOD("get_additional_data", "extension_name"), &GLTFNode::get_additional_data); @@ -170,6 +171,10 @@ void GLTFNode::set_children(Vector<int> p_children) { children = p_children; } +void GLTFNode::append_child_index(int p_child_index) { + children.append(p_child_index); +} + GLTFLightIndex GLTFNode::get_light() { return light; } diff --git a/modules/gltf/structures/gltf_node.h b/modules/gltf/structures/gltf_node.h index 63399fb32b..f3f6bfa2f1 100644 --- a/modules/gltf/structures/gltf_node.h +++ b/modules/gltf/structures/gltf_node.h @@ -97,6 +97,7 @@ public: Vector<int> get_children(); void set_children(Vector<int> p_children); + void append_child_index(int p_child_index); GLTFLightIndex get_light(); void set_light(GLTFLightIndex p_light); |