mirror of
https://github.com/godotengine/godot.git
synced 2024-11-24 13:12:42 +00:00
Merge pull request #96468 from aaronfranke/gltf-append-node
GLTF: Add `append_gltf_node` to GLTFState
This commit is contained in:
commit
a9364a9e75
@ -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" />
|
||||
|
@ -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>
|
||||
|
@ -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) {
|
||||
@ -5258,6 +5257,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);
|
||||
@ -5303,14 +5303,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);
|
||||
}
|
||||
@ -5371,18 +5375,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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user