From f20517380d451f628d382b9f1d30a6fc14b701ee Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Wed, 25 Feb 2026 18:57:30 -0800 Subject: [PATCH] GLTF: Duplicate extensions at the start of the import and export process --- .../gltf/doc_classes/GLTFDocumentExtension.xml | 2 +- modules/gltf/gltf_document.cpp | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml index abdbce7eeb..b217955edc 100644 --- a/modules/gltf/doc_classes/GLTFDocumentExtension.xml +++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml @@ -6,7 +6,7 @@ Extends the functionality of the [GLTFDocument] class by allowing you to run arbitrary code at various stages of glTF import or export. To use, make a new class extending GLTFDocumentExtension, override any methods you need, make an instance of your class, and register it using [method GLTFDocument.register_gltf_document_extension]. - [b]Note:[/b] Like GLTFDocument itself, all GLTFDocumentExtension classes must be stateless in order to function properly. If you need to store data, use the [code]set_additional_data[/code] and [code]get_additional_data[/code] methods in [GLTFState] or [GLTFNode]. + [b]Note:[/b] All GLTFDocumentExtension classes are duplicated when beginning the import or export process. Except for configuration values, these classes must be stateless in order to function properly. If you need to store data, use the [code]set_additional_data[/code] and [code]get_additional_data[/code] methods in [GLTFState] or [GLTFNode]. $DOCS_URL/tutorials/io/runtime_file_loading_and_saving.html diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 1bda104af6..52c2ab846a 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -6552,9 +6552,13 @@ Error GLTFDocument::_parse(Ref p_state, const String &p_path, Ref ext : all_document_extensions) { ERR_CONTINUE(ext.is_null()); - err = ext->import_preflight(p_state, p_state->json["extensionsUsed"]); + Ref ext_dup = ext; + if (ClassDB::is_class_exposed(ext->get_class_name())) { + ext_dup = ext->duplicate(); + } + err = ext_dup->import_preflight(p_state, p_state->json["extensionsUsed"]); if (err == OK) { - document_extensions.push_back(ext); + document_extensions.push_back(ext_dup); } } @@ -7118,9 +7122,13 @@ Error GLTFDocument::append_from_scene(Node *p_node, Ref p_state, uint document_extensions.clear(); for (Ref ext : all_document_extensions) { ERR_CONTINUE(ext.is_null()); - Error err = ext->export_preflight(state, p_node); + Ref ext_dup = ext; + if (ClassDB::is_class_exposed(ext->get_class_name())) { + ext_dup = ext->duplicate(); + } + Error err = ext_dup->export_preflight(state, p_node); if (err == OK) { - document_extensions.push_back(ext); + document_extensions.push_back(ext_dup); } } // Add the root node(s) and their descendants to the state.