Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the way GLTFDocumentExtension classes are registered #66026

Merged
merged 1 commit into from
Nov 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions modules/gltf/doc_classes/GLTFDocument.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand All @@ -58,8 +67,4 @@
</description>
</method>
</methods>
<members>
<member name="extensions" type="GLTFDocumentExtension[]" setter="set_extensions" getter="get_extensions" default="[]">
</member>
</members>
</class>
4 changes: 4 additions & 0 deletions modules/gltf/doc_classes/GLTFDocumentExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
3 changes: 0 additions & 3 deletions modules/gltf/editor/editor_scene_importer_gltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -42,15 +41,15 @@ class GLTFDocumentExtension : public Resource {

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);
virtual Error export_preflight(Node *p_state);
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 *);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
75 changes: 31 additions & 44 deletions modules/gltf/gltf_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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]);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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"];
Expand All @@ -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);
Expand All @@ -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()) {
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand Down
10 changes: 5 additions & 5 deletions modules/gltf/gltf_document.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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;
Copy link
Member

@fire fire Oct 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We devised this way to implement the two lists of extensions. Active vs all.


private:
const float BAKE_FPS = 30.0f;

public:
GLTFDocument();
const int32_t JOINT_GROUP_SIZE = 4;

enum {
Expand All @@ -76,8 +76,8 @@ class GLTFDocument : public Resource {
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);
Expand Down
14 changes: 12 additions & 2 deletions modules/gltf/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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
2 changes: 0 additions & 2 deletions modules/gltf/structures/gltf_buffer_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down