Merge pull request #68981 from aaronfranke/gltf-methods
Add three new methods to GLTFDocumentExtension and document all of its methods
This commit is contained in:
commit
3f2ca44534
|
@ -11,6 +11,16 @@
|
|||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="_convert_scene_node" qualifiers="virtual">
|
||||
<return type="void" />
|
||||
<param index="0" name="state" type="GLTFState" />
|
||||
<param index="1" name="gltf_node" type="GLTFNode" />
|
||||
<param index="2" name="scene_node" type="Node" />
|
||||
<description>
|
||||
Part of the export process. This method is run after [method _export_preflight] and before [method _export_node].
|
||||
Runs when converting the data from a Godot scene node. This method can be used to process the Godot scene node data into a format that can be used by [method _export_node].
|
||||
</description>
|
||||
</method>
|
||||
<method name="_export_node" qualifiers="virtual">
|
||||
<return type="int" />
|
||||
<param index="0" name="state" type="GLTFState" />
|
||||
|
@ -18,23 +28,40 @@
|
|||
<param index="2" name="json" type="Dictionary" />
|
||||
<param index="3" name="node" type="Node" />
|
||||
<description>
|
||||
Part of the export process. This method is run after [method _convert_scene_node] and before [method _export_post].
|
||||
This method can be used to modify the final JSON of each node.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_export_post" qualifiers="virtual">
|
||||
<return type="int" />
|
||||
<param index="0" name="state" type="GLTFState" />
|
||||
<description>
|
||||
Part of the export process. This method is run last, after all other parts of the export process.
|
||||
This method can be used to modify the final JSON of the generated GLTF file.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_export_preflight" qualifiers="virtual">
|
||||
<return type="int" />
|
||||
<param index="0" name="root" type="Node" />
|
||||
<description>
|
||||
Part of the export process. This method is run first, before all other parts of the export process.
|
||||
The return value is used to determine if this GLTFDocumentExtension class should be used for exporting a given GLTF file. If [constant OK], the export will use this GLTFDocumentExtension class. If not overridden, [constant OK] is returned.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_generate_scene_node" qualifiers="virtual">
|
||||
<return type="Node3D" />
|
||||
<param index="0" name="state" type="GLTFState" />
|
||||
<param index="1" name="gltf_node" type="GLTFNode" />
|
||||
<param index="2" name="scene_parent" type="Node" />
|
||||
<description>
|
||||
Part of the import process. This method is run after [method _parse_node_extensions] and before [method _import_post_parse].
|
||||
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>
|
||||
</method>
|
||||
<method name="_get_supported_extensions" qualifiers="virtual">
|
||||
<return type="PackedStringArray" />
|
||||
<description>
|
||||
Part of the import process. This method is run after [method _import_preflight] and before [method _parse_node_extensions].
|
||||
Returns an array of the GLTF extensions supported by this GLTFDocumentExtension class. This is used to validate if a GLTF file with required extensions can be loaded.
|
||||
</description>
|
||||
</method>
|
||||
|
@ -45,6 +72,8 @@
|
|||
<param index="2" name="json" type="Dictionary" />
|
||||
<param index="3" name="node" type="Node" />
|
||||
<description>
|
||||
Part of the import process. This method is run after [method _import_post_parse] and before [method _import_post].
|
||||
This method can be used to make modifications to each of the generated Godot scene nodes.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_import_post" qualifiers="virtual">
|
||||
|
@ -52,12 +81,16 @@
|
|||
<param index="0" name="state" type="GLTFState" />
|
||||
<param index="1" name="root" type="Node" />
|
||||
<description>
|
||||
Part of the import process. This method is run last, after all other parts of the import process.
|
||||
This method can be used to modify the final Godot scene generated by the import process.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_import_post_parse" qualifiers="virtual">
|
||||
<return type="int" />
|
||||
<param index="0" name="state" type="GLTFState" />
|
||||
<description>
|
||||
Part of the import process. This method is run after [method _generate_scene_node] and before [method _import_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.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_import_preflight" qualifiers="virtual">
|
||||
|
@ -65,7 +98,18 @@
|
|||
<param index="0" name="state" type="GLTFState" />
|
||||
<param index="1" name="extensions" type="PackedStringArray" />
|
||||
<description>
|
||||
This callback is run first. It is used to determine if this GLTFDocumentExtension class should be used for importing a given GLTF file. If [constant OK], the import will use this GLTFDocumentExtension class.
|
||||
Part of the import process. This method is run first, before all other parts of the import process.
|
||||
The return value is used to determine if this GLTFDocumentExtension class should be used for importing a given GLTF file. If [constant OK], the import will use this GLTFDocumentExtension class. If not overridden, [constant OK] is returned.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_parse_node_extensions" qualifiers="virtual">
|
||||
<return type="int" />
|
||||
<param index="0" name="state" type="GLTFState" />
|
||||
<param index="1" name="gltf_node" type="GLTFNode" />
|
||||
<param index="2" name="extensions" type="Dictionary" />
|
||||
<description>
|
||||
Part of the import process. This method is run after [method _get_supported_extensions] and before [method _generate_scene_node].
|
||||
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].
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
|
|
@ -31,35 +31,50 @@
|
|||
#include "gltf_document_extension.h"
|
||||
|
||||
void GLTFDocumentExtension::_bind_methods() {
|
||||
GDVIRTUAL_BIND(_get_supported_extensions);
|
||||
// Import process.
|
||||
GDVIRTUAL_BIND(_import_preflight, "state", "extensions");
|
||||
GDVIRTUAL_BIND(_get_supported_extensions);
|
||||
GDVIRTUAL_BIND(_parse_node_extensions, "state", "gltf_node", "extensions");
|
||||
GDVIRTUAL_BIND(_generate_scene_node, "state", "gltf_node", "scene_parent");
|
||||
GDVIRTUAL_BIND(_import_post_parse, "state");
|
||||
GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node");
|
||||
GDVIRTUAL_BIND(_import_post, "state", "root");
|
||||
// Export process.
|
||||
GDVIRTUAL_BIND(_export_preflight, "root");
|
||||
GDVIRTUAL_BIND(_convert_scene_node, "state", "gltf_node", "scene_node");
|
||||
GDVIRTUAL_BIND(_export_node, "state", "gltf_node", "json", "node");
|
||||
GDVIRTUAL_BIND(_export_post, "state");
|
||||
}
|
||||
|
||||
// Import process.
|
||||
Error GLTFDocumentExtension::import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) {
|
||||
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
|
||||
int err = OK;
|
||||
GDVIRTUAL_CALL(_import_preflight, p_state, p_extensions, err);
|
||||
return Error(err);
|
||||
}
|
||||
|
||||
Vector<String> GLTFDocumentExtension::get_supported_extensions() {
|
||||
Vector<String> ret;
|
||||
GDVIRTUAL_CALL(_get_supported_extensions, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Error GLTFDocumentExtension::import_post(Ref<GLTFState> p_state, Node *p_root) {
|
||||
ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
|
||||
Error GLTFDocumentExtension::parse_node_extensions(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &p_extensions) {
|
||||
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_NULL_V(p_gltf_node, ERR_INVALID_PARAMETER);
|
||||
int err = OK;
|
||||
GDVIRTUAL_CALL(_import_post, p_state, p_root, err);
|
||||
GDVIRTUAL_CALL(_parse_node_extensions, p_state, p_gltf_node, p_extensions, err);
|
||||
return Error(err);
|
||||
}
|
||||
|
||||
Error GLTFDocumentExtension::import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) {
|
||||
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
|
||||
int err = OK;
|
||||
GDVIRTUAL_CALL(_import_preflight, p_state, p_extensions, err);
|
||||
return Error(err);
|
||||
Node3D *GLTFDocumentExtension::generate_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent) {
|
||||
ERR_FAIL_NULL_V(p_state, nullptr);
|
||||
ERR_FAIL_NULL_V(p_gltf_node, nullptr);
|
||||
ERR_FAIL_NULL_V(p_scene_parent, nullptr);
|
||||
Node3D *ret_node = nullptr;
|
||||
GDVIRTUAL_CALL(_generate_scene_node, p_state, p_gltf_node, p_scene_parent, ret_node);
|
||||
return ret_node;
|
||||
}
|
||||
|
||||
Error GLTFDocumentExtension::import_post_parse(Ref<GLTFState> p_state) {
|
||||
|
@ -69,19 +84,6 @@ Error GLTFDocumentExtension::import_post_parse(Ref<GLTFState> p_state) {
|
|||
return Error(err);
|
||||
}
|
||||
|
||||
Error GLTFDocumentExtension::export_post(Ref<GLTFState> p_state) {
|
||||
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
|
||||
int err = OK;
|
||||
GDVIRTUAL_CALL(_export_post, p_state, err);
|
||||
return Error(err);
|
||||
}
|
||||
Error GLTFDocumentExtension::export_preflight(Node *p_root) {
|
||||
ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
|
||||
int err = OK;
|
||||
GDVIRTUAL_CALL(_export_preflight, p_root, err);
|
||||
return Error(err);
|
||||
}
|
||||
|
||||
Error GLTFDocumentExtension::import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_dict, Node *p_node) {
|
||||
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_NULL_V(p_gltf_node, ERR_INVALID_PARAMETER);
|
||||
|
@ -91,6 +93,29 @@ Error GLTFDocumentExtension::import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p
|
|||
return Error(err);
|
||||
}
|
||||
|
||||
Error GLTFDocumentExtension::import_post(Ref<GLTFState> p_state, Node *p_root) {
|
||||
ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
|
||||
int err = OK;
|
||||
GDVIRTUAL_CALL(_import_post, p_state, p_root, err);
|
||||
return Error(err);
|
||||
}
|
||||
|
||||
// Export process.
|
||||
Error GLTFDocumentExtension::export_preflight(Node *p_root) {
|
||||
ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
|
||||
int err = OK;
|
||||
GDVIRTUAL_CALL(_export_preflight, p_root, err);
|
||||
return Error(err);
|
||||
}
|
||||
|
||||
void GLTFDocumentExtension::convert_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_node) {
|
||||
ERR_FAIL_NULL(p_state);
|
||||
ERR_FAIL_NULL(p_gltf_node);
|
||||
ERR_FAIL_NULL(p_scene_node);
|
||||
GDVIRTUAL_CALL(_convert_scene_node, p_state, p_gltf_node, p_scene_node);
|
||||
}
|
||||
|
||||
Error GLTFDocumentExtension::export_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_dict, Node *p_node) {
|
||||
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_NULL_V(p_gltf_node, ERR_INVALID_PARAMETER);
|
||||
|
@ -99,3 +124,10 @@ Error GLTFDocumentExtension::export_node(Ref<GLTFState> p_state, Ref<GLTFNode> p
|
|||
GDVIRTUAL_CALL(_export_node, p_state, p_gltf_node, r_dict, p_node, err);
|
||||
return Error(err);
|
||||
}
|
||||
|
||||
Error GLTFDocumentExtension::export_post(Ref<GLTFState> p_state) {
|
||||
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
|
||||
int err = OK;
|
||||
GDVIRTUAL_CALL(_export_post, p_state, err);
|
||||
return Error(err);
|
||||
}
|
||||
|
|
|
@ -40,20 +40,31 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual Vector<String> get_supported_extensions();
|
||||
// Import process.
|
||||
virtual Error import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions);
|
||||
virtual Vector<String> get_supported_extensions();
|
||||
virtual Error parse_node_extensions(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &p_extensions);
|
||||
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 export_post(Ref<GLTFState> p_state);
|
||||
virtual Error import_post(Ref<GLTFState> p_state, Node *p_node);
|
||||
virtual Error export_preflight(Node *p_state);
|
||||
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);
|
||||
// Export process.
|
||||
virtual Error export_preflight(Node *p_state);
|
||||
virtual void convert_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_node);
|
||||
virtual Error export_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node);
|
||||
GDVIRTUAL0R(Vector<String>, _get_supported_extensions);
|
||||
virtual Error export_post(Ref<GLTFState> p_state);
|
||||
|
||||
// Import process.
|
||||
GDVIRTUAL2R(int, _import_preflight, Ref<GLTFState>, Vector<String>);
|
||||
GDVIRTUAL0R(Vector<String>, _get_supported_extensions);
|
||||
GDVIRTUAL3R(int, _parse_node_extensions, Ref<GLTFState>, Ref<GLTFNode>, Dictionary);
|
||||
GDVIRTUAL3R(Node3D *, _generate_scene_node, Ref<GLTFState>, Ref<GLTFNode>, Node *);
|
||||
GDVIRTUAL1R(int, _import_post_parse, Ref<GLTFState>);
|
||||
GDVIRTUAL4R(int, _import_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
|
||||
GDVIRTUAL2R(int, _import_post, Ref<GLTFState>, Node *);
|
||||
// Export process.
|
||||
GDVIRTUAL1R(int, _export_preflight, Node *);
|
||||
GDVIRTUAL3(_convert_scene_node, Ref<GLTFState>, Ref<GLTFNode>, Node *);
|
||||
GDVIRTUAL4R(int, _export_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
|
||||
GDVIRTUAL1R(int, _export_post, Ref<GLTFState>);
|
||||
};
|
||||
|
|
|
@ -625,6 +625,11 @@ Error GLTFDocument::_parse_nodes(Ref<GLTFState> state) {
|
|||
node->light = light;
|
||||
}
|
||||
}
|
||||
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
|
||||
ERR_CONTINUE(ext.is_null());
|
||||
Error err = ext->parse_node_extensions(state, node, extensions);
|
||||
ERR_CONTINUE_MSG(err != OK, "GLTF: Encountered error " + itos(err) + " when parsing node extensions for node " + node->get_name() + " in file " + state->filename + ". Continuing.");
|
||||
}
|
||||
}
|
||||
|
||||
if (n.has("children")) {
|
||||
|
@ -5266,6 +5271,10 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, co
|
|||
AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_current);
|
||||
_convert_animation_player_to_gltf(animation_player, state, p_gltf_parent, p_gltf_root, gltf_node, p_current);
|
||||
}
|
||||
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
|
||||
ERR_CONTINUE(ext.is_null());
|
||||
ext->convert_scene_node(state, gltf_node, p_current);
|
||||
}
|
||||
GLTFNodeIndex current_node_i = state->nodes.size();
|
||||
GLTFNodeIndex gltf_root = p_gltf_root;
|
||||
if (gltf_root == -1) {
|
||||
|
@ -5589,21 +5598,32 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent
|
|||
// and attach it to the bone_attachment
|
||||
scene_parent = bone_attachment;
|
||||
}
|
||||
if (gltf_node->mesh >= 0) {
|
||||
current_node = _generate_mesh_instance(state, node_index);
|
||||
} else if (gltf_node->camera >= 0) {
|
||||
current_node = _generate_camera(state, node_index);
|
||||
} else if (gltf_node->light >= 0) {
|
||||
current_node = _generate_light(state, node_index);
|
||||
// Check if any GLTFDocumentExtension classes want to generate a node for us.
|
||||
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
|
||||
ERR_CONTINUE(ext.is_null());
|
||||
current_node = ext->generate_scene_node(state, gltf_node, scene_parent);
|
||||
if (current_node) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We still have not managed to make a node.
|
||||
// If none of our GLTFDocumentExtension classes generated us a node, we generate one.
|
||||
if (!current_node) {
|
||||
current_node = _generate_spatial(state, node_index);
|
||||
if (gltf_node->mesh >= 0) {
|
||||
current_node = _generate_mesh_instance(state, node_index);
|
||||
} else if (gltf_node->camera >= 0) {
|
||||
current_node = _generate_camera(state, node_index);
|
||||
} else if (gltf_node->light >= 0) {
|
||||
current_node = _generate_light(state, node_index);
|
||||
} else {
|
||||
current_node = _generate_spatial(state, node_index);
|
||||
}
|
||||
}
|
||||
// Add the node we generated and set the owner to the scene root.
|
||||
scene_parent->add_child(current_node, true);
|
||||
if (current_node != scene_root) {
|
||||
current_node->set_owner(scene_root);
|
||||
Array args;
|
||||
args.append(scene_root);
|
||||
current_node->propagate_call(StringName("set_owner"), args);
|
||||
}
|
||||
current_node->set_transform(gltf_node->xform);
|
||||
current_node->set_name(gltf_node->get_name());
|
||||
|
@ -5669,19 +5689,32 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> state, Node *scen
|
|||
// and attach it to the bone_attachment
|
||||
scene_parent = bone_attachment;
|
||||
}
|
||||
|
||||
// We still have not managed to make a node
|
||||
if (gltf_node->mesh >= 0) {
|
||||
current_node = _generate_mesh_instance(state, node_index);
|
||||
} else if (gltf_node->camera >= 0) {
|
||||
current_node = _generate_camera(state, node_index);
|
||||
} else if (gltf_node->light >= 0) {
|
||||
current_node = _generate_light(state, node_index);
|
||||
// Check if any GLTFDocumentExtension classes want to generate a node for us.
|
||||
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
|
||||
ERR_CONTINUE(ext.is_null());
|
||||
current_node = ext->generate_scene_node(state, gltf_node, scene_parent);
|
||||
if (current_node) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If none of our GLTFDocumentExtension classes generated us a node, we generate one.
|
||||
if (!current_node) {
|
||||
if (gltf_node->mesh >= 0) {
|
||||
current_node = _generate_mesh_instance(state, node_index);
|
||||
} else if (gltf_node->camera >= 0) {
|
||||
current_node = _generate_camera(state, node_index);
|
||||
} else if (gltf_node->light >= 0) {
|
||||
current_node = _generate_light(state, node_index);
|
||||
} else {
|
||||
current_node = _generate_spatial(state, node_index);
|
||||
}
|
||||
}
|
||||
// Add the node we generated and set the owner to the scene root.
|
||||
scene_parent->add_child(current_node, true);
|
||||
if (current_node != scene_root) {
|
||||
current_node->set_owner(scene_root);
|
||||
Array args;
|
||||
args.append(scene_root);
|
||||
current_node->propagate_call(StringName("set_owner"), args);
|
||||
}
|
||||
// Do not set transform here. Transform is already applied to our bone.
|
||||
current_node->set_name(gltf_node->get_name());
|
||||
|
|
Loading…
Reference in New Issue