Merge pull request #66026 from aaronfranke/gltf-extension
Change the way GLTFDocumentExtension classes are registered
This commit is contained in:
commit
d5d83eefd3
11 changed files with 69 additions and 69 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 *);
|
|
@ -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"
|
|
@ -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;
|
||||
}
|
||||
|
||||
GLTFDocument::GLTFDocument() {
|
||||
bool is_editor = ::Engine::get_singleton()->is_editor_hint();
|
||||
if (is_editor) {
|
||||
return;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue