From 73c673a614b47716ce467cd43adf770505c016cd Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Sun, 18 Sep 2022 20:35:13 -0500 Subject: [PATCH] Change the way GLTFDocumentExtension classes are registered Also move GLTFDocumentExtension into the extensions folder --- modules/gltf/doc_classes/GLTFDocument.xml | 13 +++- .../doc_classes/GLTFDocumentExtension.xml | 4 + .../gltf/editor/editor_scene_importer_gltf.h | 3 - .../gltf_document_extension.cpp | 6 +- .../gltf_document_extension.h | 7 +- ...cument_extension_convert_importer_mesh.cpp | 2 +- ...document_extension_convert_importer_mesh.h | 0 modules/gltf/gltf_document.cpp | 77 ++++++++----------- modules/gltf/gltf_document.h | 10 +-- modules/gltf/register_types.cpp | 14 +++- modules/gltf/structures/gltf_buffer_view.cpp | 2 - 11 files changed, 69 insertions(+), 69 deletions(-) rename modules/gltf/{ => extensions}/gltf_document_extension.cpp (96%) rename modules/gltf/{ => extensions}/gltf_document_extension.h (94%) rename modules/gltf/{ => extensions}/gltf_document_extension_convert_importer_mesh.cpp (99%) rename modules/gltf/{ => extensions}/gltf_document_extension_convert_importer_mesh.h (100%) diff --git a/modules/gltf/doc_classes/GLTFDocument.xml b/modules/gltf/doc_classes/GLTFDocument.xml index 3cd0f5c0f95..57727a74161 100644 --- a/modules/gltf/doc_classes/GLTFDocument.xml +++ b/modules/gltf/doc_classes/GLTFDocument.xml @@ -50,6 +50,15 @@ + + + + + + Registers this GLTFDocumentExtension instance with GLTFDocument. If [param first_priority] is true, this extension will be ran first. Otherwise, it will be ran last. + [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]. + + @@ -58,8 +67,4 @@ - - - - diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml index 936794976d7..adc32df8dc0 100644 --- a/modules/gltf/doc_classes/GLTFDocumentExtension.xml +++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml @@ -5,6 +5,8 @@ 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]. @@ -61,7 +63,9 @@ + + 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. diff --git a/modules/gltf/editor/editor_scene_importer_gltf.h b/modules/gltf/editor/editor_scene_importer_gltf.h index b17a1e4eaa2..edca038532b 100644 --- a/modules/gltf/editor/editor_scene_importer_gltf.h +++ b/modules/gltf/editor/editor_scene_importer_gltf.h @@ -33,9 +33,6 @@ #ifdef TOOLS_ENABLED -#include "../gltf_document_extension.h" -#include "../gltf_state.h" - #include "editor/import/resource_importer_scene.h" class Animation; diff --git a/modules/gltf/gltf_document_extension.cpp b/modules/gltf/extensions/gltf_document_extension.cpp similarity index 96% rename from modules/gltf/gltf_document_extension.cpp rename to modules/gltf/extensions/gltf_document_extension.cpp index 713779712cb..56519f70d38 100644 --- a/modules/gltf/gltf_document_extension.cpp +++ b/modules/gltf/extensions/gltf_document_extension.cpp @@ -32,7 +32,7 @@ void GLTFDocumentExtension::_bind_methods() { GDVIRTUAL_BIND(_get_supported_extensions); - GDVIRTUAL_BIND(_import_preflight, "state"); + GDVIRTUAL_BIND(_import_preflight, "state", "extensions"); GDVIRTUAL_BIND(_import_post_parse, "state"); GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node"); GDVIRTUAL_BIND(_import_post, "state", "root"); @@ -55,10 +55,10 @@ Error GLTFDocumentExtension::import_post(Ref p_state, Node *p_root) { return Error(err); } -Error GLTFDocumentExtension::import_preflight(Ref p_state) { +Error GLTFDocumentExtension::import_preflight(Ref p_state, Vector p_extensions) { ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER); int err = OK; - GDVIRTUAL_CALL(_import_preflight, p_state, err); + GDVIRTUAL_CALL(_import_preflight, p_state, p_extensions, err); return Error(err); } diff --git a/modules/gltf/gltf_document_extension.h b/modules/gltf/extensions/gltf_document_extension.h similarity index 94% rename from modules/gltf/gltf_document_extension.h rename to modules/gltf/extensions/gltf_document_extension.h index d4bb3993dcd..43e29ea0ab3 100644 --- a/modules/gltf/gltf_document_extension.h +++ b/modules/gltf/extensions/gltf_document_extension.h @@ -31,8 +31,7 @@ #ifndef GLTF_DOCUMENT_EXTENSION_H #define GLTF_DOCUMENT_EXTENSION_H -#include "gltf_state.h" -#include "structures/gltf_node.h" +#include "../gltf_state.h" class GLTFDocumentExtension : public Resource { GDCLASS(GLTFDocumentExtension, Resource); @@ -42,7 +41,7 @@ protected: public: virtual Vector get_supported_extensions(); - virtual Error import_preflight(Ref p_state); + virtual Error import_preflight(Ref p_state, Vector p_extensions); virtual Error import_post_parse(Ref p_state); virtual Error export_post(Ref p_state); virtual Error import_post(Ref p_state, Node *p_node); @@ -50,7 +49,7 @@ public: virtual Error import_node(Ref p_state, Ref p_gltf_node, Dictionary &r_json, Node *p_node); virtual Error export_node(Ref p_state, Ref p_gltf_node, Dictionary &r_json, Node *p_node); GDVIRTUAL0R(Vector, _get_supported_extensions); - GDVIRTUAL1R(int, _import_preflight, Ref); + GDVIRTUAL2R(int, _import_preflight, Ref, Vector); GDVIRTUAL1R(int, _import_post_parse, Ref); GDVIRTUAL4R(int, _import_node, Ref, Ref, Dictionary, Node *); GDVIRTUAL2R(int, _import_post, Ref, Node *); diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp similarity index 99% rename from modules/gltf/gltf_document_extension_convert_importer_mesh.cpp rename to modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp index 1620900a04e..49496afb62f 100644 --- a/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp +++ b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp @@ -30,7 +30,7 @@ #include "gltf_document_extension_convert_importer_mesh.h" -#include "gltf_state.h" +#include "../gltf_state.h" #include "core/error/error_macros.h" #include "scene/3d/mesh_instance_3d.h" diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.h b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.h similarity index 100% rename from modules/gltf/gltf_document_extension_convert_importer_mesh.h rename to modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.h diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 99803ed05d5..49797bb8fac 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -31,8 +31,6 @@ #include "gltf_document.h" #include "extensions/gltf_spec_gloss.h" -#include "gltf_document_extension.h" -#include "gltf_document_extension_convert_importer_mesh.h" #include "gltf_state.h" #include "core/crypto/crypto_core.h" @@ -215,8 +213,7 @@ Error GLTFDocument::_serialize(Ref state, const String &p_path) { return Error::FAILED; } - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref ext = document_extensions[ext_i]; + for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); err = ext->export_post(state); ERR_FAIL_COND_V(err != OK, err); @@ -454,8 +451,7 @@ Error GLTFDocument::_serialize_nodes(Ref state) { node["children"] = children; } - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref ext = document_extensions[ext_i]; + for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); ERR_CONTINUE(!state->scene_nodes.find(i)); Error err = ext->export_node(state, gltf_node, node, state->scene_nodes[i]); @@ -6586,11 +6582,13 @@ Error GLTFDocument::_parse(Ref state, String p_path, Ref state->major_version = version.get_slice(".", 0).to_int(); state->minor_version = version.get_slice(".", 1).to_int(); - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref ext = document_extensions[ext_i]; + document_extensions.clear(); + for (Ref ext : all_document_extensions) { ERR_CONTINUE(ext.is_null()); - err = ext->import_preflight(state); - ERR_FAIL_COND_V(err != OK, err); + err = ext->import_preflight(state, state->json["extensionsUsed"]); + if (err == OK) { + document_extensions.push_back(ext); + } } err = _parse_gltf_state(state, p_path, p_bake_fps); @@ -6728,14 +6726,8 @@ void GLTFDocument::_bind_methods() { ClassDB::bind_method(D_METHOD("write_to_filesystem", "state", "path"), &GLTFDocument::write_to_filesystem); - ClassDB::bind_method(D_METHOD("set_extensions", "extensions"), - &GLTFDocument::set_extensions); - ClassDB::bind_method(D_METHOD("get_extensions"), - &GLTFDocument::get_extensions); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "extensions", PROPERTY_HINT_ARRAY_TYPE, - vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "GLTFDocumentExtension"), - PROPERTY_USAGE_DEFAULT), - "set_extensions", "get_extensions"); + ClassDB::bind_static_method("GLTFDocument", D_METHOD("register_gltf_document_extension", "extension", "first_priority"), + &GLTFDocument::register_gltf_document_extension, DEFVAL(false)); } void GLTFDocument::_build_parent_hierachy(Ref state) { @@ -6752,22 +6744,20 @@ void GLTFDocument::_build_parent_hierachy(Ref state) { } } -void GLTFDocument::set_extensions(TypedArray p_extensions) { - document_extensions = p_extensions; -} +Vector> GLTFDocument::all_document_extensions; -TypedArray GLTFDocument::get_extensions() const { - return document_extensions; -} - -GLTFDocument::GLTFDocument() { - bool is_editor = ::Engine::get_singleton()->is_editor_hint(); - if (is_editor) { - return; +void GLTFDocument::register_gltf_document_extension(Ref p_extension, bool p_first_priority) { + if (all_document_extensions.find(p_extension) == -1) { + if (p_first_priority) { + all_document_extensions.insert(0, p_extension); + } else { + all_document_extensions.push_back(p_extension); + } } - Ref extension_editor; - extension_editor.instantiate(); - document_extensions.push_back(extension_editor); +} + +void GLTFDocument::unregister_all_gltf_document_extensions() { + all_document_extensions.clear(); } PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref state, Error *r_err) { @@ -6852,8 +6842,7 @@ Node *GLTFDocument::generate_scene(Ref state, int32_t p_bake_fps) { } for (KeyValue E : state->scene_nodes) { ERR_CONTINUE(!E.value); - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref ext = document_extensions[ext_i]; + for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); ERR_CONTINUE(!state->json.has("nodes")); Array nodes = state->json["nodes"]; @@ -6865,8 +6854,7 @@ Node *GLTFDocument::generate_scene(Ref state, int32_t p_bake_fps) { ERR_CONTINUE(err != OK); } } - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref ext = document_extensions[ext_i]; + for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); err = ext->import_post(state, root); ERR_CONTINUE(err != OK); @@ -6880,11 +6868,13 @@ Error GLTFDocument::append_from_scene(Node *p_node, Ref state, uint32 state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS; state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS; - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref ext = document_extensions[ext_i]; + document_extensions.clear(); + for (Ref ext : all_document_extensions) { ERR_CONTINUE(ext.is_null()); Error err = ext->export_preflight(p_node); - ERR_FAIL_COND_V(err != OK, FAILED); + if (err == OK) { + document_extensions.push_back(ext); + } } _convert_scene_node(state, p_node, -1, -1); if (!state->buffers.size()) { @@ -6906,8 +6896,7 @@ Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_pa state->base_path = p_base_path.get_base_dir(); err = _parse(state, state->base_path, file_access, p_bake_fps); ERR_FAIL_COND_V(err != OK, err); - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref ext = document_extensions[ext_i]; + for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); err = ext->import_post_parse(state); ERR_FAIL_COND_V(err != OK, err); @@ -7030,8 +7019,7 @@ Error GLTFDocument::append_from_file(String p_path, Ref r_state, uint r_state->base_path = base_path; err = _parse(r_state, base_path, f, p_bake_fps); ERR_FAIL_COND_V(err != OK, err); - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref ext = document_extensions[ext_i]; + for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); err = ext->import_post_parse(r_state); ERR_FAIL_COND_V(err != OK, err); @@ -7053,8 +7041,7 @@ Error GLTFDocument::_parse_gltf_extensions(Ref state) { supported_extensions.insert("KHR_lights_punctual"); supported_extensions.insert("KHR_materials_pbrSpecularGlossiness"); supported_extensions.insert("KHR_texture_transform"); - for (int ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref ext = document_extensions[ext_i]; + for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); Vector ext_supported_extensions = ext->get_supported_extensions(); for (int i = 0; i < ext_supported_extensions.size(); ++i) { diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 62b6e29fe08..15099efe33e 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -31,7 +31,7 @@ #ifndef GLTF_DOCUMENT_H #define GLTF_DOCUMENT_H -#include "gltf_defines.h" +#include "extensions/gltf_document_extension.h" #include "structures/gltf_animation.h" #include "scene/3d/bone_attachment_3d.h" @@ -44,13 +44,13 @@ class GLTFDocument : public Resource { GDCLASS(GLTFDocument, Resource); - TypedArray document_extensions; + static Vector> all_document_extensions; + Vector> document_extensions; private: const float BAKE_FPS = 30.0f; public: - GLTFDocument(); const int32_t JOINT_GROUP_SIZE = 4; enum { @@ -76,8 +76,8 @@ protected: static void _bind_methods(); public: - void set_extensions(TypedArray p_extensions); - TypedArray get_extensions() const; + static void register_gltf_document_extension(Ref p_extension, bool p_first_priority = false); + static void unregister_all_gltf_document_extensions(); private: void _build_parent_hierachy(Ref state); diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index b9027f6e3de..a7abf256ce3 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -32,11 +32,10 @@ #ifndef _3D_DISABLED +#include "extensions/gltf_document_extension_convert_importer_mesh.h" #include "extensions/gltf_light.h" #include "extensions/gltf_spec_gloss.h" #include "gltf_document.h" -#include "gltf_document_extension.h" -#include "gltf_document_extension_convert_importer_mesh.h" #include "gltf_state.h" #include "structures/gltf_accessor.h" #include "structures/gltf_animation.h" @@ -109,6 +108,11 @@ static void _editor_init() { } #endif // TOOLS_ENABLED +#define GLTF_REGISTER_DOCUMENT_EXTENSION(m_doc_ext_class) \ + Ref extension_##m_doc_ext_class; \ + extension_##m_doc_ext_class.instantiate(); \ + GLTFDocument::register_gltf_document_extension(extension_##m_doc_ext_class); + void initialize_gltf_module(ModuleInitializationLevel p_level) { if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { // glTF API available at runtime. @@ -128,6 +132,11 @@ void initialize_gltf_module(ModuleInitializationLevel p_level) { GDREGISTER_CLASS(GLTFState); GDREGISTER_CLASS(GLTFTexture); GDREGISTER_CLASS(GLTFTextureSampler); + // Register GLTFDocumentExtension classes with GLTFDocument. + bool is_editor = ::Engine::get_singleton()->is_editor_hint(); + if (!is_editor) { + GLTF_REGISTER_DOCUMENT_EXTENSION(GLTFDocumentExtensionConvertImporterMesh); + } } #ifdef TOOLS_ENABLED @@ -161,6 +170,7 @@ void uninitialize_gltf_module(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } + GLTFDocument::unregister_all_gltf_document_extensions(); } #endif // _3D_DISABLED diff --git a/modules/gltf/structures/gltf_buffer_view.cpp b/modules/gltf/structures/gltf_buffer_view.cpp index ba19ed86280..a15141225bc 100644 --- a/modules/gltf/structures/gltf_buffer_view.cpp +++ b/modules/gltf/structures/gltf_buffer_view.cpp @@ -30,8 +30,6 @@ #include "gltf_buffer_view.h" -#include "../gltf_document_extension.h" - void GLTFBufferView::_bind_methods() { ClassDB::bind_method(D_METHOD("get_buffer"), &GLTFBufferView::get_buffer); ClassDB::bind_method(D_METHOD("set_buffer", "buffer"), &GLTFBufferView::set_buffer);