summaryrefslogtreecommitdiff
path: root/modules/gltf
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2022-11-20 11:44:05 +0100
committerRémi Verschelde <rverschelde@gmail.com>2022-11-20 11:44:05 +0100
commitd5d83eefd30b42fa5e2ace98bf3990aba575b2ac (patch)
treec708169e8956532b46f277c45a1dbbc65e7810d6 /modules/gltf
parent5ba216e428ff058a1b8b1b94565c331c59225891 (diff)
parent73c673a614b47716ce467cd43adf770505c016cd (diff)
Merge pull request #66026 from aaronfranke/gltf-extension
Change the way GLTFDocumentExtension classes are registered
Diffstat (limited to 'modules/gltf')
-rw-r--r--modules/gltf/doc_classes/GLTFDocument.xml13
-rw-r--r--modules/gltf/doc_classes/GLTFDocumentExtension.xml4
-rw-r--r--modules/gltf/editor/editor_scene_importer_gltf.h3
-rw-r--r--modules/gltf/extensions/gltf_document_extension.cpp (renamed from modules/gltf/gltf_document_extension.cpp)6
-rw-r--r--modules/gltf/extensions/gltf_document_extension.h (renamed from modules/gltf/gltf_document_extension.h)7
-rw-r--r--modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp (renamed from modules/gltf/gltf_document_extension_convert_importer_mesh.cpp)2
-rw-r--r--modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.h (renamed from modules/gltf/gltf_document_extension_convert_importer_mesh.h)0
-rw-r--r--modules/gltf/gltf_document.cpp75
-rw-r--r--modules/gltf/gltf_document.h10
-rw-r--r--modules/gltf/register_types.cpp14
-rw-r--r--modules/gltf/structures/gltf_buffer_view.cpp2
11 files changed, 68 insertions, 68 deletions
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 @@
<description>
</description>
</method>
+ <method name="register_gltf_document_extension" qualifiers="static">
+ <return type="void" />
+ <param index="0" name="extension" type="GLTFDocumentExtension" />
+ <param index="1" name="first_priority" type="bool" default="false" />
+ <description>
+ 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].
+ </description>
+ </method>
<method name="write_to_filesystem">
<return type="int" enum="Error" />
<param index="0" name="state" type="GLTFState" />
@@ -58,8 +67,4 @@
</description>
</method>
</methods>
- <members>
- <member name="extensions" type="GLTFDocumentExtension[]" setter="set_extensions" getter="get_extensions" default="[]">
- </member>
- </members>
</class>
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 @@
</brief_description>
<description>
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].
</description>
<tutorials>
</tutorials>
@@ -61,7 +63,9 @@
<method name="_import_preflight" qualifiers="virtual">
<return type="int" />
<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.
</description>
</method>
</methods>
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/gltf_document_extension.cpp b/modules/gltf/extensions/gltf_document_extension.cpp
index 713779712c..56519f70d3 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<GLTFState> p_state, Node *p_root) {
return Error(err);
}
-Error GLTFDocumentExtension::import_preflight(Ref<GLTFState> p_state) {
+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, 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
index d4bb3993dc..43e29ea0ab 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<String> get_supported_extensions();
- virtual Error import_preflight(Ref<GLTFState> p_state);
+ virtual Error import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions);
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);
@@ -50,7 +49,7 @@ public:
virtual Error import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_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);
- GDVIRTUAL1R(int, _import_preflight, Ref<GLTFState>);
+ GDVIRTUAL2R(int, _import_preflight, Ref<GLTFState>, Vector<String>);
GDVIRTUAL1R(int, _import_post_parse, Ref<GLTFState>);
GDVIRTUAL4R(int, _import_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
GDVIRTUAL2R(int, _import_post, Ref<GLTFState>, Node *);
diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp
index 1620900a04..49496afb62 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
index 00e664e73f..00e664e73f 100644
--- a/modules/gltf/gltf_document_extension_convert_importer_mesh.h
+++ b/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 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<GLTFState> state, const String &p_path) {
return Error::FAILED;
}
- for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
- Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ for (Ref<GLTFDocumentExtension> 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<GLTFState> state) {
node["children"] = children;
}
- for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
- Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ for (Ref<GLTFDocumentExtension> 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<GLTFState> state, String p_path, Ref<FileAccess>
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<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ document_extensions.clear();
+ for (Ref<GLTFDocumentExtension> 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<GLTFState> state) {
@@ -6752,22 +6744,20 @@ void GLTFDocument::_build_parent_hierachy(Ref<GLTFState> state) {
}
}
-void GLTFDocument::set_extensions(TypedArray<GLTFDocumentExtension> p_extensions) {
- document_extensions = p_extensions;
-}
+Vector<Ref<GLTFDocumentExtension>> GLTFDocument::all_document_extensions;
-TypedArray<GLTFDocumentExtension> GLTFDocument::get_extensions() const {
- return document_extensions;
+void GLTFDocument::register_gltf_document_extension(Ref<GLTFDocumentExtension> 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<GLTFDocumentExtensionConvertImporterMesh> 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<GLTFState> state, Error *r_err) {
@@ -6852,8 +6842,7 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> state, int32_t p_bake_fps) {
}
for (KeyValue<GLTFNodeIndex, Node *> E : state->scene_nodes) {
ERR_CONTINUE(!E.value);
- for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
- Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ for (Ref<GLTFDocumentExtension> 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<GLTFState> state, int32_t p_bake_fps) {
ERR_CONTINUE(err != OK);
}
}
- for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
- Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ for (Ref<GLTFDocumentExtension> 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<GLTFState> 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<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ document_extensions.clear();
+ for (Ref<GLTFDocumentExtension> 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<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ for (Ref<GLTFDocumentExtension> 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<GLTFState> 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<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ for (Ref<GLTFDocumentExtension> 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<GLTFState> 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<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ for (Ref<GLTFDocumentExtension> ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
Vector<String> 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<GLTFDocumentExtension> document_extensions;
+ static Vector<Ref<GLTFDocumentExtension>> all_document_extensions;
+ Vector<Ref<GLTFDocumentExtension>> 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<GLTFDocumentExtension> p_extensions);
- TypedArray<GLTFDocumentExtension> get_extensions() const;
+ static void register_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension, bool p_first_priority = false);
+ static void unregister_all_gltf_document_extensions();
private:
void _build_parent_hierachy(Ref<GLTFState> state);
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<m_doc_ext_class> 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);