From 73c673a614b47716ce467cd43adf770505c016cd Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Sun, 18 Sep 2022 20:35:13 -0500 Subject: Change the way GLTFDocumentExtension classes are registered Also move GLTFDocumentExtension into the extensions folder --- modules/gltf/doc_classes/GLTFDocument.xml | 13 ++- modules/gltf/doc_classes/GLTFDocumentExtension.xml | 4 + modules/gltf/editor/editor_scene_importer_gltf.h | 3 - .../gltf/extensions/gltf_document_extension.cpp | 101 +++++++++++++++++++++ modules/gltf/extensions/gltf_document_extension.h | 61 +++++++++++++ ...tf_document_extension_convert_importer_mesh.cpp | 81 +++++++++++++++++ ...gltf_document_extension_convert_importer_mesh.h | 50 ++++++++++ modules/gltf/gltf_document.cpp | 75 +++++++-------- modules/gltf/gltf_document.h | 10 +- modules/gltf/gltf_document_extension.cpp | 101 --------------------- modules/gltf/gltf_document_extension.h | 62 ------------- ...tf_document_extension_convert_importer_mesh.cpp | 81 ----------------- ...gltf_document_extension_convert_importer_mesh.h | 50 ---------- modules/gltf/register_types.cpp | 14 ++- modules/gltf/structures/gltf_buffer_view.cpp | 2 - 15 files changed, 354 insertions(+), 354 deletions(-) create mode 100644 modules/gltf/extensions/gltf_document_extension.cpp create mode 100644 modules/gltf/extensions/gltf_document_extension.h create mode 100644 modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp create mode 100644 modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.h delete mode 100644 modules/gltf/gltf_document_extension.cpp delete mode 100644 modules/gltf/gltf_document_extension.h delete mode 100644 modules/gltf/gltf_document_extension_convert_importer_mesh.cpp delete mode 100644 modules/gltf/gltf_document_extension_convert_importer_mesh.h diff --git a/modules/gltf/doc_classes/GLTFDocument.xml b/modules/gltf/doc_classes/GLTFDocument.xml index 3cd0f5c0f9..57727a7416 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 936794976d..adc32df8dc 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 b17a1e4eaa..edca038532 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/extensions/gltf_document_extension.cpp b/modules/gltf/extensions/gltf_document_extension.cpp new file mode 100644 index 0000000000..56519f70d3 --- /dev/null +++ b/modules/gltf/extensions/gltf_document_extension.cpp @@ -0,0 +1,101 @@ +/*************************************************************************/ +/* gltf_document_extension.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "gltf_document_extension.h" + +void GLTFDocumentExtension::_bind_methods() { + GDVIRTUAL_BIND(_get_supported_extensions); + 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"); + GDVIRTUAL_BIND(_export_preflight, "root"); + GDVIRTUAL_BIND(_export_node, "state", "gltf_node", "json", "node"); + GDVIRTUAL_BIND(_export_post, "state"); +} + +Vector GLTFDocumentExtension::get_supported_extensions() { + Vector ret; + GDVIRTUAL_CALL(_get_supported_extensions, ret); + return ret; +} + +Error GLTFDocumentExtension::import_post(Ref 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); +} + +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, p_extensions, err); + return Error(err); +} + +Error GLTFDocumentExtension::import_post_parse(Ref p_state) { + ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER); + int err = OK; + GDVIRTUAL_CALL(_import_post_parse, p_state, err); + return Error(err); +} + +Error GLTFDocumentExtension::export_post(Ref 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 p_state, Ref 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); + ERR_FAIL_NULL_V(p_node, ERR_INVALID_PARAMETER); + int err = OK; + GDVIRTUAL_CALL(_import_node, p_state, p_gltf_node, r_dict, p_node, err); + return Error(err); +} + +Error GLTFDocumentExtension::export_node(Ref p_state, Ref 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); + ERR_FAIL_NULL_V(p_node, ERR_INVALID_PARAMETER); + int err = OK; + GDVIRTUAL_CALL(_export_node, p_state, p_gltf_node, r_dict, p_node, err); + return Error(err); +} diff --git a/modules/gltf/extensions/gltf_document_extension.h b/modules/gltf/extensions/gltf_document_extension.h new file mode 100644 index 0000000000..43e29ea0ab --- /dev/null +++ b/modules/gltf/extensions/gltf_document_extension.h @@ -0,0 +1,61 @@ +/*************************************************************************/ +/* gltf_document_extension.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GLTF_DOCUMENT_EXTENSION_H +#define GLTF_DOCUMENT_EXTENSION_H + +#include "../gltf_state.h" + +class GLTFDocumentExtension : public Resource { + GDCLASS(GLTFDocumentExtension, Resource); + +protected: + static void _bind_methods(); + +public: + virtual Vector get_supported_extensions(); + 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); + virtual Error export_preflight(Node *p_state); + 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); + 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 *); + GDVIRTUAL1R(int, _export_preflight, Node *); + GDVIRTUAL4R(int, _export_node, Ref, Ref, Dictionary, Node *); + GDVIRTUAL1R(int, _export_post, Ref); +}; + +#endif // GLTF_DOCUMENT_EXTENSION_H diff --git a/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp new file mode 100644 index 0000000000..49496afb62 --- /dev/null +++ b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp @@ -0,0 +1,81 @@ +/*************************************************************************/ +/* gltf_document_extension_convert_importer_mesh.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "gltf_document_extension_convert_importer_mesh.h" + +#include "../gltf_state.h" + +#include "core/error/error_macros.h" +#include "scene/3d/mesh_instance_3d.h" +#include "scene/resources/importer_mesh.h" + +void GLTFDocumentExtensionConvertImporterMesh::_bind_methods() { +} + +Error GLTFDocumentExtensionConvertImporterMesh::import_post(Ref p_state, Node *p_root) { + ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER); + ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER); + List queue; + queue.push_back(p_root); + List delete_queue; + while (!queue.is_empty()) { + List::Element *E = queue.front(); + Node *node = E->get(); + ImporterMeshInstance3D *mesh_3d = cast_to(node); + if (mesh_3d) { + MeshInstance3D *mesh_instance_node_3d = memnew(MeshInstance3D); + Ref mesh = mesh_3d->get_mesh(); + if (mesh.is_valid()) { + Ref array_mesh = mesh->get_mesh(); + mesh_instance_node_3d->set_name(node->get_name()); + mesh_instance_node_3d->set_transform(mesh_3d->get_transform()); + mesh_instance_node_3d->set_mesh(array_mesh); + mesh_instance_node_3d->set_skin(mesh_3d->get_skin()); + mesh_instance_node_3d->set_skeleton_path(mesh_3d->get_skeleton_path()); + node->replace_by(mesh_instance_node_3d); + delete_queue.push_back(node); + } else { + memdelete(mesh_instance_node_3d); + } + } + int child_count = node->get_child_count(); + for (int i = 0; i < child_count; i++) { + queue.push_back(node->get_child(i)); + } + queue.pop_front(); + } + while (!queue.is_empty()) { + List::Element *E = delete_queue.front(); + Node *node = E->get(); + memdelete(node); + delete_queue.pop_front(); + } + return OK; +} diff --git a/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.h b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.h new file mode 100644 index 0000000000..00e664e73f --- /dev/null +++ b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.h @@ -0,0 +1,50 @@ +/*************************************************************************/ +/* gltf_document_extension_convert_importer_mesh.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GLTF_DOCUMENT_EXTENSION_CONVERT_IMPORTER_MESH_H +#define GLTF_DOCUMENT_EXTENSION_CONVERT_IMPORTER_MESH_H + +#include "gltf_document_extension.h" + +#include "scene/3d/importer_mesh_instance_3d.h" +#include "scene/3d/mesh_instance_3d.h" +#include "scene/resources/importer_mesh.h" + +class GLTFDocumentExtensionConvertImporterMesh : public GLTFDocumentExtension { + GDCLASS(GLTFDocumentExtensionConvertImporterMesh, GLTFDocumentExtension); + +protected: + static void _bind_methods(); + +public: + Error import_post(Ref p_state, Node *p_root) override; +}; + +#endif // GLTF_DOCUMENT_EXTENSION_CONVERT_IMPORTER_MESH_H diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 99803ed05d..49797bb8fa 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; +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); + } + } } -GLTFDocument::GLTFDocument() { - bool is_editor = ::Engine::get_singleton()->is_editor_hint(); - if (is_editor) { - return; - } - 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 62b6e29fe0..15099efe33 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/gltf_document_extension.cpp b/modules/gltf/gltf_document_extension.cpp deleted file mode 100644 index 713779712c..0000000000 --- a/modules/gltf/gltf_document_extension.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************/ -/* gltf_document_extension.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "gltf_document_extension.h" - -void GLTFDocumentExtension::_bind_methods() { - GDVIRTUAL_BIND(_get_supported_extensions); - GDVIRTUAL_BIND(_import_preflight, "state"); - GDVIRTUAL_BIND(_import_post_parse, "state"); - GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node"); - GDVIRTUAL_BIND(_import_post, "state", "root"); - GDVIRTUAL_BIND(_export_preflight, "root"); - GDVIRTUAL_BIND(_export_node, "state", "gltf_node", "json", "node"); - GDVIRTUAL_BIND(_export_post, "state"); -} - -Vector GLTFDocumentExtension::get_supported_extensions() { - Vector ret; - GDVIRTUAL_CALL(_get_supported_extensions, ret); - return ret; -} - -Error GLTFDocumentExtension::import_post(Ref 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); -} - -Error GLTFDocumentExtension::import_preflight(Ref p_state) { - ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER); - int err = OK; - GDVIRTUAL_CALL(_import_preflight, p_state, err); - return Error(err); -} - -Error GLTFDocumentExtension::import_post_parse(Ref p_state) { - ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER); - int err = OK; - GDVIRTUAL_CALL(_import_post_parse, p_state, err); - return Error(err); -} - -Error GLTFDocumentExtension::export_post(Ref 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 p_state, Ref 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); - ERR_FAIL_NULL_V(p_node, ERR_INVALID_PARAMETER); - int err = OK; - GDVIRTUAL_CALL(_import_node, p_state, p_gltf_node, r_dict, p_node, err); - return Error(err); -} - -Error GLTFDocumentExtension::export_node(Ref p_state, Ref 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); - ERR_FAIL_NULL_V(p_node, ERR_INVALID_PARAMETER); - int err = OK; - GDVIRTUAL_CALL(_export_node, p_state, p_gltf_node, r_dict, p_node, err); - return Error(err); -} diff --git a/modules/gltf/gltf_document_extension.h b/modules/gltf/gltf_document_extension.h deleted file mode 100644 index d4bb3993dc..0000000000 --- a/modules/gltf/gltf_document_extension.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ -/* gltf_document_extension.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GLTF_DOCUMENT_EXTENSION_H -#define GLTF_DOCUMENT_EXTENSION_H - -#include "gltf_state.h" -#include "structures/gltf_node.h" - -class GLTFDocumentExtension : public Resource { - GDCLASS(GLTFDocumentExtension, Resource); - -protected: - static void _bind_methods(); - -public: - virtual Vector get_supported_extensions(); - virtual Error import_preflight(Ref p_state); - 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); - virtual Error export_preflight(Node *p_state); - 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); - GDVIRTUAL1R(int, _import_post_parse, Ref); - GDVIRTUAL4R(int, _import_node, Ref, Ref, Dictionary, Node *); - GDVIRTUAL2R(int, _import_post, Ref, Node *); - GDVIRTUAL1R(int, _export_preflight, Node *); - GDVIRTUAL4R(int, _export_node, Ref, Ref, Dictionary, Node *); - GDVIRTUAL1R(int, _export_post, Ref); -}; - -#endif // GLTF_DOCUMENT_EXTENSION_H diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp b/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp deleted file mode 100644 index 1620900a04..0000000000 --- a/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************/ -/* gltf_document_extension_convert_importer_mesh.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "gltf_document_extension_convert_importer_mesh.h" - -#include "gltf_state.h" - -#include "core/error/error_macros.h" -#include "scene/3d/mesh_instance_3d.h" -#include "scene/resources/importer_mesh.h" - -void GLTFDocumentExtensionConvertImporterMesh::_bind_methods() { -} - -Error GLTFDocumentExtensionConvertImporterMesh::import_post(Ref p_state, Node *p_root) { - ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER); - ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER); - List queue; - queue.push_back(p_root); - List delete_queue; - while (!queue.is_empty()) { - List::Element *E = queue.front(); - Node *node = E->get(); - ImporterMeshInstance3D *mesh_3d = cast_to(node); - if (mesh_3d) { - MeshInstance3D *mesh_instance_node_3d = memnew(MeshInstance3D); - Ref mesh = mesh_3d->get_mesh(); - if (mesh.is_valid()) { - Ref array_mesh = mesh->get_mesh(); - mesh_instance_node_3d->set_name(node->get_name()); - mesh_instance_node_3d->set_transform(mesh_3d->get_transform()); - mesh_instance_node_3d->set_mesh(array_mesh); - mesh_instance_node_3d->set_skin(mesh_3d->get_skin()); - mesh_instance_node_3d->set_skeleton_path(mesh_3d->get_skeleton_path()); - node->replace_by(mesh_instance_node_3d); - delete_queue.push_back(node); - } else { - memdelete(mesh_instance_node_3d); - } - } - int child_count = node->get_child_count(); - for (int i = 0; i < child_count; i++) { - queue.push_back(node->get_child(i)); - } - queue.pop_front(); - } - while (!queue.is_empty()) { - List::Element *E = delete_queue.front(); - Node *node = E->get(); - memdelete(node); - delete_queue.pop_front(); - } - return OK; -} diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.h b/modules/gltf/gltf_document_extension_convert_importer_mesh.h deleted file mode 100644 index 00e664e73f..0000000000 --- a/modules/gltf/gltf_document_extension_convert_importer_mesh.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************/ -/* gltf_document_extension_convert_importer_mesh.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GLTF_DOCUMENT_EXTENSION_CONVERT_IMPORTER_MESH_H -#define GLTF_DOCUMENT_EXTENSION_CONVERT_IMPORTER_MESH_H - -#include "gltf_document_extension.h" - -#include "scene/3d/importer_mesh_instance_3d.h" -#include "scene/3d/mesh_instance_3d.h" -#include "scene/resources/importer_mesh.h" - -class GLTFDocumentExtensionConvertImporterMesh : public GLTFDocumentExtension { - GDCLASS(GLTFDocumentExtensionConvertImporterMesh, GLTFDocumentExtension); - -protected: - static void _bind_methods(); - -public: - Error import_post(Ref p_state, Node *p_root) override; -}; - -#endif // GLTF_DOCUMENT_EXTENSION_CONVERT_IMPORTER_MESH_H diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index b9027f6e3d..a7abf256ce 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 ba19ed8628..a15141225b 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); -- cgit v1.2.3