diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml
index 5c548c472f6..b33e296e1ca 100644
--- a/modules/gltf/doc_classes/GLTFDocumentExtension.xml
+++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml
@@ -18,7 +18,7 @@
- Part of the export process. This method is run after [method _export_preflight] and before [method _export_preserialize].
+ Part of the export process. This method is run after [method _export_preflight] and before [method _export_post_convert].
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].
@@ -41,6 +41,15 @@
This method can be used to modify the final JSON of the generated glTF file.
+
+
+
+
+
+ Part of the export process. This method is run after [method _convert_scene_node] and before [method _export_preserialize].
+ This method can be used to modify the converted node data structures before serialization with any additional data from the scene tree.
+
+
@@ -54,7 +63,7 @@
- Part of the export process. This method is run after [method _convert_scene_node] and before [method _get_saveable_image_formats].
+ Part of the export process. This method is run after [method _export_post_convert] and before [method _get_saveable_image_formats].
This method can be used to alter the state before performing serialization. It runs every time when generating a buffer with [method GLTFDocument.generate_buffer] or writing to the file system with [method GLTFDocument.write_to_filesystem].
@@ -64,7 +73,7 @@
- Part of the import process. This method is run after [method _import_post_parse] and before [method _import_node].
+ Part of the import process. This method is run after [method _import_pre_generate] 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.
[b]Note:[/b] The [param scene_parent] parameter may be null if this is the single root node.
@@ -113,8 +122,16 @@
- 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 after parsing, before generating the nodes and then running the final per-node import step.
+ Part of the import process. This method is run after [method _parse_node_extensions] and before [method _import_pre_generate].
+ This method can be used to modify any of the data imported so far after parsing each node, but before generating the scene or any of its nodes.
+
+
+
+
+
+
+ Part of the import process. This method is run after [method _import_post_parse] and before [method _generate_scene_node].
+ This method can be used to modify or read from any of the processed data structures, before generating the nodes and then running the final per-node import step.
diff --git a/modules/gltf/extensions/gltf_document_extension.cpp b/modules/gltf/extensions/gltf_document_extension.cpp
index c6540ebb22f..6e611762b69 100644
--- a/modules/gltf/extensions/gltf_document_extension.cpp
+++ b/modules/gltf/extensions/gltf_document_extension.cpp
@@ -38,13 +38,15 @@ void GLTFDocumentExtension::_bind_methods() {
GDVIRTUAL_BIND(_parse_image_data, "state", "image_data", "mime_type", "ret_image");
GDVIRTUAL_BIND(_get_image_file_extension);
GDVIRTUAL_BIND(_parse_texture_json, "state", "texture_json", "ret_gltf_texture");
- GDVIRTUAL_BIND(_generate_scene_node, "state", "gltf_node", "scene_parent");
GDVIRTUAL_BIND(_import_post_parse, "state");
+ GDVIRTUAL_BIND(_import_pre_generate, "state");
+ GDVIRTUAL_BIND(_generate_scene_node, "state", "gltf_node", "scene_parent");
GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node");
GDVIRTUAL_BIND(_import_post, "state", "root");
// Export process.
GDVIRTUAL_BIND(_export_preflight, "state", "root");
GDVIRTUAL_BIND(_convert_scene_node, "state", "gltf_node", "scene_node");
+ GDVIRTUAL_BIND(_export_post_convert, "state", "root");
GDVIRTUAL_BIND(_export_preserialize, "state");
GDVIRTUAL_BIND(_get_saveable_image_formats);
GDVIRTUAL_BIND(_serialize_image_to_bytes, "state", "image", "image_dict", "image_format", "lossy_quality");
@@ -98,6 +100,20 @@ Error GLTFDocumentExtension::parse_texture_json(Ref p_state, const Di
return err;
}
+Error GLTFDocumentExtension::import_post_parse(Ref p_state) {
+ ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER);
+ Error err = OK;
+ GDVIRTUAL_CALL(_import_post_parse, p_state, err);
+ return err;
+}
+
+Error GLTFDocumentExtension::import_pre_generate(Ref p_state) {
+ ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER);
+ Error err = OK;
+ GDVIRTUAL_CALL(_import_pre_generate, p_state, err);
+ return err;
+}
+
Node3D *GLTFDocumentExtension::generate_scene_node(Ref p_state, Ref p_gltf_node, Node *p_scene_parent) {
ERR_FAIL_COND_V(p_state.is_null(), nullptr);
ERR_FAIL_COND_V(p_gltf_node.is_null(), nullptr);
@@ -106,13 +122,6 @@ Node3D *GLTFDocumentExtension::generate_scene_node(Ref p_state, Ref p_state) {
- ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER);
- Error err = OK;
- GDVIRTUAL_CALL(_import_post_parse, p_state, err);
- return err;
-}
-
Error GLTFDocumentExtension::import_node(Ref p_state, Ref p_gltf_node, Dictionary &r_dict, Node *p_node) {
ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_gltf_node.is_null(), ERR_INVALID_PARAMETER);
@@ -145,6 +154,14 @@ void GLTFDocumentExtension::convert_scene_node(Ref p_state, Ref p_state, Node *p_root) {
+ ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
+ Error err = OK;
+ GDVIRTUAL_CALL(_export_post_convert, p_state, p_root, err);
+ return err;
+}
+
Error GLTFDocumentExtension::export_preserialize(Ref p_state) {
ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER);
Error err = OK;
diff --git a/modules/gltf/extensions/gltf_document_extension.h b/modules/gltf/extensions/gltf_document_extension.h
index 761dff725c2..b70710e0150 100644
--- a/modules/gltf/extensions/gltf_document_extension.h
+++ b/modules/gltf/extensions/gltf_document_extension.h
@@ -50,12 +50,14 @@ public:
virtual String get_image_file_extension();
virtual Error parse_texture_json(Ref p_state, const Dictionary &p_texture_json, Ref r_gltf_texture);
virtual Error import_post_parse(Ref p_state);
+ virtual Error import_pre_generate(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.
virtual Error export_preflight(Ref p_state, Node *p_root);
virtual void convert_scene_node(Ref p_state, Ref p_gltf_node, Node *p_scene_node);
+ virtual Error export_post_convert(Ref p_state, Node *p_root);
virtual Error export_preserialize(Ref p_state);
virtual Vector get_saveable_image_formats();
virtual PackedByteArray serialize_image_to_bytes(Ref p_state, Ref p_image, Dictionary p_image_dict, const String &p_image_format, float p_lossy_quality);
@@ -71,13 +73,15 @@ public:
GDVIRTUAL4R(Error, _parse_image_data, Ref, PackedByteArray, String, Ref);
GDVIRTUAL0R(String, _get_image_file_extension);
GDVIRTUAL3R(Error, _parse_texture_json, Ref, Dictionary, Ref);
- GDVIRTUAL3R(Node3D *, _generate_scene_node, Ref, Ref, Node *);
GDVIRTUAL1R(Error, _import_post_parse, Ref);
+ GDVIRTUAL1R(Error, _import_pre_generate, Ref);
+ GDVIRTUAL3R(Node3D *, _generate_scene_node, Ref, Ref, Node *);
GDVIRTUAL4R(Error, _import_node, Ref, Ref, Dictionary, Node *);
GDVIRTUAL2R(Error, _import_post, Ref, Node *);
// Export process.
GDVIRTUAL2R(Error, _export_preflight, Ref, Node *);
GDVIRTUAL3(_convert_scene_node, Ref, Ref, Node *);
+ GDVIRTUAL2R(Error, _export_post_convert, Ref, Node *);
GDVIRTUAL1R(Error, _export_preserialize, Ref);
GDVIRTUAL0R(Vector, _get_saveable_image_formats);
GDVIRTUAL5R(PackedByteArray, _serialize_image_to_bytes, Ref, Ref, Dictionary, String, float);
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index bd034cbdc5d..992075e980e 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -7205,6 +7205,12 @@ Node *GLTFDocument::_generate_scene_node_tree(Ref p_state) {
ERR_FAIL_COND_V_MSG(err != OK, nullptr, "glTF: Failed to create skeletons.");
err = _create_skins(p_state);
ERR_FAIL_COND_V_MSG(err != OK, nullptr, "glTF: Failed to create skins.");
+ // Run pre-generate for each extension, in case an extension needs to do something before generating the scene.
+ for (Ref ext : document_extensions) {
+ ERR_CONTINUE(ext.is_null());
+ err = ext->import_pre_generate(p_state);
+ ERR_CONTINUE(err != OK);
+ }
// Generate the node tree.
Node *single_root;
if (p_state->extensions_used.has("GODOT_single_root")) {
@@ -7439,6 +7445,12 @@ Error GLTFDocument::append_from_scene(Node *p_node, Ref p_state, uint
state->extensions_used.append("GODOT_single_root");
}
_convert_scene_node(state, p_node, -1, -1);
+ // Run post-convert for each extension, in case an extension needs to do something after converting the scene.
+ for (Ref ext : document_extensions) {
+ ERR_CONTINUE(ext.is_null());
+ Error err = ext->export_post_convert(p_state, p_node);
+ ERR_CONTINUE(err != OK);
+ }
return OK;
}