瀏覽代碼

Merge pull request #57660 from V-Sekai/gltf-extension-fixes

Rémi Verschelde 3 年之前
父節點
當前提交
410893ad0f

+ 28 - 41
modules/gltf/doc_classes/GLTFDocumentExtension.xml

@@ -7,65 +7,52 @@
 	<tutorials>
 	</tutorials>
 	<methods>
-		<method name="export_post">
-			<return type="int" enum="Error" />
-			<argument index="0" name="document" type="GLTFDocument" />
+		<method name="_export_node" qualifiers="virtual">
+			<return type="int" />
+			<argument index="0" name="state" type="GLTFState" />
+			<argument index="1" name="gltf_node" type="GLTFNode" />
+			<argument index="2" name="json" type="Dictionary" />
+			<argument index="3" name="node" type="Node" />
 			<description>
 			</description>
 		</method>
-		<method name="export_preflight">
-			<return type="int" enum="Error" />
-			<argument index="0" name="document" type="GLTFDocument" />
-			<argument index="1" name="node" type="Node" />
+		<method name="_export_post" qualifiers="virtual">
+			<return type="int" />
+			<argument index="0" name="state" type="GLTFState" />
 			<description>
 			</description>
 		</method>
-		<method name="get_export_setting" qualifiers="const">
-			<return type="Variant" />
-			<argument index="0" name="key" type="StringName" />
+		<method name="_export_preflight" qualifiers="virtual">
+			<return type="int" />
+			<argument index="0" name="root" type="Node" />
 			<description>
 			</description>
 		</method>
-		<method name="get_export_setting_keys" qualifiers="const">
-			<return type="Array" />
+		<method name="_import_node" qualifiers="virtual">
+			<return type="int" />
+			<argument index="0" name="state" type="GLTFState" />
+			<argument index="1" name="gltf_node" type="GLTFNode" />
+			<argument index="2" name="json" type="Dictionary" />
+			<argument index="3" name="node" type="Node" />
 			<description>
 			</description>
 		</method>
-		<method name="get_import_setting" qualifiers="const">
-			<return type="Variant" />
-			<argument index="0" name="key" type="StringName" />
+		<method name="_import_post" qualifiers="virtual">
+			<return type="int" />
+			<argument index="0" name="state" type="GLTFState" />
+			<argument index="1" name="root" type="Node" />
 			<description>
 			</description>
 		</method>
-		<method name="get_import_setting_keys" qualifiers="const">
-			<return type="Array" />
+		<method name="_import_post_parse" qualifiers="virtual">
+			<return type="int" />
+			<argument index="0" name="state" type="GLTFState" />
 			<description>
 			</description>
 		</method>
-		<method name="import_post">
-			<return type="int" enum="Error" />
-			<argument index="0" name="document" type="GLTFDocument" />
-			<argument index="1" name="node" type="Node" />
-			<description>
-			</description>
-		</method>
-		<method name="import_preflight">
-			<return type="int" enum="Error" />
-			<argument index="0" name="document" type="GLTFDocument" />
-			<description>
-			</description>
-		</method>
-		<method name="set_export_setting">
-			<return type="void" />
-			<argument index="0" name="key" type="StringName" />
-			<argument index="1" name="value" type="Variant" />
-			<description>
-			</description>
-		</method>
-		<method name="set_import_setting">
-			<return type="void" />
-			<argument index="0" name="key" type="StringName" />
-			<argument index="1" name="value" type="Variant" />
+		<method name="_import_preflight" qualifiers="virtual">
+			<return type="int" />
+			<argument index="0" name="state" type="GLTFState" />
 			<description>
 			</description>
 		</method>

+ 2 - 0
modules/gltf/doc_classes/GLTFState.xml

@@ -192,6 +192,8 @@
 		</method>
 	</methods>
 	<members>
+		<member name="base_path" type="String" setter="set_base_path" getter="get_base_path" default="&quot;&quot;">
+		</member>
 		<member name="buffers" type="Array" setter="set_buffers" getter="get_buffers" default="[]">
 		</member>
 		<member name="glb_data" type="PackedByteArray" setter="set_glb_data" getter="get_glb_data" default="PackedByteArray()">

+ 0 - 1
modules/gltf/editor/editor_scene_importer_gltf.cpp

@@ -35,7 +35,6 @@
 #include "../gltf_document.h"
 #include "../gltf_state.h"
 
-#include "scene/main/node.h"
 #include "scene/resources/animation.h"
 
 uint32_t EditorSceneFormatImporterGLTF::get_import_flags() const {

+ 3 - 0
modules/gltf/editor/editor_scene_importer_gltf.h

@@ -33,6 +33,9 @@
 
 #ifdef TOOLS_ENABLED
 
+#include "../gltf_document_extension.h"
+#include "../gltf_state.h"
+
 #include "editor/import/resource_importer_scene.h"
 
 class Animation;

+ 0 - 1
modules/gltf/gltf_accessor.h

@@ -34,7 +34,6 @@
 #include "core/io/resource.h"
 
 #include "gltf_document.h"
-#include "gltf_document_extension.h"
 
 struct GLTFAccessor : public Resource {
 	GDCLASS(GLTFAccessor, Resource);

+ 85 - 31
modules/gltf/gltf_document.cpp

@@ -128,10 +128,10 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) {
 		state->buffers.push_back(Vector<uint8_t>());
 	}
 
-	/* STEP 1 CONVERT MESH INSTANCES */
+	/* STEP CONVERT MESH INSTANCES */
 	_convert_mesh_instances(state);
 
-	/* STEP 2 SERIALIZE CAMERAS */
+	/* STEP SERIALIZE CAMERAS */
 	Error err = _serialize_cameras(state);
 	if (err != OK) {
 		return Error::FAILED;
@@ -143,37 +143,37 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) {
 		return Error::FAILED;
 	}
 
-	/* STEP 5 SERIALIZE MESHES (we have enough info now) */
+	/* STEP SERIALIZE MESHES (we have enough info now) */
 	err = _serialize_meshes(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 6 SERIALIZE TEXTURES */
+	/* STEP SERIALIZE TEXTURES */
 	err = _serialize_materials(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 7 SERIALIZE ANIMATIONS */
+	/* STEP SERIALIZE ANIMATIONS */
 	err = _serialize_animations(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 8 SERIALIZE ACCESSORS */
+	/* STEP SERIALIZE ACCESSORS */
 	err = _encode_accessors(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 9 SERIALIZE IMAGES */
+	/* STEP SERIALIZE IMAGES */
 	err = _serialize_images(state, p_path);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 10 SERIALIZE TEXTURES */
+	/* STEP SERIALIZE TEXTURES */
 	err = _serialize_textures(state);
 	if (err != OK) {
 		return Error::FAILED;
@@ -183,42 +183,49 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) {
 		state->buffer_views.write[i]->buffer = 0;
 	}
 
-	/* STEP 11 SERIALIZE BUFFER VIEWS */
+	/* STEP SERIALIZE BUFFER VIEWS */
 	err = _encode_buffer_views(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 12 SERIALIZE NODES */
+	/* STEP SERIALIZE NODES */
 	err = _serialize_nodes(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 13 SERIALIZE SCENE */
+	/* STEP SERIALIZE SCENE */
 	err = _serialize_scenes(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 14 SERIALIZE SCENE */
+	/* STEP SERIALIZE SCENE */
 	err = _serialize_lights(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 15 SERIALIZE EXTENSIONS */
+	/* STEP SERIALIZE EXTENSIONS */
 	err = _serialize_extensions(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
-	/* STEP 16 SERIALIZE VERSION */
+	/* STEP SERIALIZE VERSION */
 	err = _serialize_version(state);
 	if (err != OK) {
 		return Error::FAILED;
 	}
 
+	for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
+		Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
+		ERR_CONTINUE(ext.is_null());
+		err = ext->export_post(state);
+		ERR_FAIL_COND_V(err != OK, err);
+	}
+
 	return OK;
 }
 
@@ -442,6 +449,15 @@ 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];
+			ERR_CONTINUE(ext.is_null());
+			ERR_CONTINUE(!state->scene_nodes.find(i));
+			Error err = ext->export_node(state, n, state->json, state->scene_nodes[i]);
+			ERR_CONTINUE(err != OK);
+		}
+
 		nodes.push_back(node);
 	}
 	state->json["nodes"] = nodes;
@@ -5658,7 +5674,7 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent
 	if (!current_node) {
 		current_node = _generate_spatial(state, node_index);
 	}
-	scene_parent->add_child(current_node);
+	scene_parent->add_child(current_node, true);
 	if (current_node != scene_root) {
 		current_node->set_owner(scene_root);
 	}
@@ -6642,8 +6658,8 @@ Error GLTFDocument::_parse(Ref<GLTFState> state, String p_path, Ref<FileAccess>
 	for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
 		Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
 		ERR_CONTINUE(ext.is_null());
-		err = ext->import_preflight(this);
-		ERR_FAIL_COND_V(err != OK, FAILED);
+		err = ext->import_preflight(state);
+		ERR_FAIL_COND_V(err != OK, err);
 	}
 	err = _parse_gltf_state(state, p_path, p_bake_fps);
 	ERR_FAIL_COND_V(err != OK, err);
@@ -6870,12 +6886,10 @@ PackedByteArray GLTFDocument::generate_buffer(Ref<GLTFState> state) {
 
 Error GLTFDocument::write_to_filesystem(Ref<GLTFState> state, const String &p_path) {
 	ERR_FAIL_NULL_V(state, ERR_INVALID_PARAMETER);
-
 	Error err = _serialize(state, p_path);
 	if (err != OK) {
 		return err;
 	}
-
 	err = _serialize_file(state, p_path);
 	if (err != OK) {
 		return Error::FAILED;
@@ -6886,6 +6900,7 @@ Error GLTFDocument::write_to_filesystem(Ref<GLTFState> state, const String &p_pa
 Node *GLTFDocument::generate_scene(Ref<GLTFState> state, int32_t p_bake_fps) {
 	ERR_FAIL_NULL_V(state, nullptr);
 	ERR_FAIL_INDEX_V(0, state->root_nodes.size(), nullptr);
+	Error err = OK;
 	GLTFNodeIndex gltf_root = state->root_nodes.write[0];
 	Node *gltf_root_node = state->get_scene_node(gltf_root);
 	Node *root = gltf_root_node->get_parent();
@@ -6899,12 +6914,26 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> state, int32_t p_bake_fps) {
 			_import_animation(state, ap, i, 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];
+			ERR_CONTINUE(ext.is_null());
+			ERR_CONTINUE(!state->json.has("nodes"));
+			Array nodes = state->json["nodes"];
+			ERR_CONTINUE(E.key >= nodes.size());
+			ERR_CONTINUE(E.key < 0);
+			Dictionary node_json = nodes[E.key];
+			Ref<GLTFNode> gltf_node = state->nodes[E.key];
+			err = ext->import_node(state, gltf_node, node_json, E.value);
+			ERR_CONTINUE(err != OK);
+		}
+	}
 	for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
 		Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
 		ERR_CONTINUE(ext.is_null());
-		Error err = ext->import_post(this, root);
-		ERR_FAIL_COND_V(err != OK, nullptr);
+		err = ext->import_post(state, root);
+		ERR_CONTINUE(err != OK);
 	}
 	ERR_FAIL_NULL_V(root, nullptr);
 	return root;
@@ -6919,13 +6948,23 @@ Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> state, uint32
 	if (!state->buffers.size()) {
 		state->buffers.push_back(Vector<uint8_t>());
 	}
+	for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
+		Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
+		ERR_CONTINUE(ext.is_null());
+	}
 
-	/* STEP 1 CONVERT MESH INSTANCES */
-	_convert_mesh_instances(state);
+	for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
+		Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
+		ERR_CONTINUE(ext.is_null());
+		Error err = ext->export_preflight(p_node);
+		ERR_FAIL_COND_V(err != OK, FAILED);
+	}
+	_convert_scene_node(state, p_node, -1, -1);
+	if (!state->buffers.size()) {
+		state->buffers.push_back(Vector<uint8_t>());
+	}
 
-	/* STEP 2 CREATE SKINS */
-	Error err = _serialize_skins(state);
-	return err;
+	return OK;
 }
 
 Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> state, uint32_t p_flags, int32_t p_bake_fps) {
@@ -6938,8 +6977,15 @@ Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_pa
 	Ref<FileAccessMemory> file_access;
 	file_access.instantiate();
 	file_access->open_custom(p_bytes.ptr(), p_bytes.size());
-	err = _parse(state, p_base_path.get_base_dir(), file_access, p_bake_fps);
-	ERR_FAIL_COND_V(err != OK, FAILED);
+	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];
+		ERR_CONTINUE(ext.is_null());
+		err = ext->import_post_parse(state);
+		ERR_FAIL_COND_V(err != OK, err);
+	}
 	return OK;
 }
 
@@ -7030,6 +7076,7 @@ Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> state, const String &p_sear
 	for (int32_t root_i = 0; root_i < state->root_nodes.size(); root_i++) {
 		_generate_scene_node(state, root, root, state->root_nodes[root_i]);
 	}
+
 	return OK;
 }
 
@@ -7049,9 +7096,16 @@ Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> r_state, uint
 	if (base_path.is_empty()) {
 		base_path = p_path.get_base_dir();
 	}
+	r_state->base_path = base_path;
 	err = _parse(r_state, base_path, f, p_bake_fps);
-	ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
-	return err;
+	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];
+		ERR_CONTINUE(ext.is_null());
+		err = ext->import_post_parse(r_state);
+		ERR_FAIL_COND_V(err != OK, err);
+	}
+	return OK;
 }
 
 Error GLTFDocument::_parse_gltf_extensions(Ref<GLTFState> state) {

+ 0 - 7
modules/gltf/gltf_document.h

@@ -33,19 +33,12 @@
 
 #include "gltf_animation.h"
 
-#include "core/error/error_list.h"
-#include "core/variant/dictionary.h"
-#include "core/variant/variant.h"
-#include "gltf_document_extension_convert_importer_mesh.h"
 #include "scene/3d/bone_attachment_3d.h"
 #include "scene/3d/importer_mesh_instance_3d.h"
 #include "scene/3d/light_3d.h"
 #include "scene/3d/mesh_instance_3d.h"
-#include "scene/3d/node_3d.h"
-#include "scene/3d/skeleton_3d.h"
 #include "scene/animation/animation_player.h"
 #include "scene/resources/material.h"
-#include "scene/resources/texture.h"
 
 #include "modules/modules_enabled.gen.h" // For csg, gridmap.
 

+ 60 - 40
modules/gltf/gltf_document_extension.cpp

@@ -30,59 +30,79 @@
 
 #include "gltf_document_extension.h"
 
-#include "gltf_document.h"
-
 void GLTFDocumentExtension::_bind_methods() {
-	// Import
-	ClassDB::bind_method(D_METHOD("get_import_setting_keys"),
-			&GLTFDocumentExtension::get_import_setting_keys);
-	ClassDB::bind_method(D_METHOD("import_preflight", "document"),
-			&GLTFDocumentExtension::import_preflight);
-	ClassDB::bind_method(D_METHOD("get_import_setting", "key"),
-			&GLTFDocumentExtension::get_import_setting);
-	ClassDB::bind_method(D_METHOD("set_import_setting", "key", "value"),
-			&GLTFDocumentExtension::set_import_setting);
-	ClassDB::bind_method(D_METHOD("import_post", "document", "node"),
-			&GLTFDocumentExtension::import_post);
-	// Export
-	ClassDB::bind_method(D_METHOD("get_export_setting_keys"),
-			&GLTFDocumentExtension::get_export_setting_keys);
-	ClassDB::bind_method(D_METHOD("get_export_setting", "key"),
-			&GLTFDocumentExtension::get_export_setting);
-	ClassDB::bind_method(D_METHOD("set_export_setting", "key", "value"),
-			&GLTFDocumentExtension::set_export_setting);
-	ClassDB::bind_method(D_METHOD("export_preflight", "document", "node"),
-			&GLTFDocumentExtension::export_preflight);
-	ClassDB::bind_method(D_METHOD("export_post", "document"),
-			&GLTFDocumentExtension::export_post);
+	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");
 }
 
-Array GLTFDocumentExtension::get_import_setting_keys() const {
-	return import_settings.keys();
+Error GLTFDocumentExtension::import_post(Ref<GLTFState> 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;
+	if (GDVIRTUAL_CALL(_import_post, p_state, p_root, err)) {
+		return Error(err);
+	}
+	return OK;
 }
 
-Variant GLTFDocumentExtension::get_import_setting(const StringName &p_key) const {
-	if (!import_settings.has(p_key)) {
-		return Variant();
+Error GLTFDocumentExtension::import_preflight(Ref<GLTFState> p_state) {
+	ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
+	int err = OK;
+	if (GDVIRTUAL_CALL(_import_preflight, p_state, err)) {
+		return Error(err);
 	}
-	return import_settings[p_key];
+	return OK;
 }
 
-void GLTFDocumentExtension::set_import_setting(const StringName &p_key, Variant p_var) {
-	import_settings[p_key] = p_var;
+Error GLTFDocumentExtension::import_post_parse(Ref<GLTFState> p_state) {
+	ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
+	int err = OK;
+	if (GDVIRTUAL_CALL(_import_post_parse, p_state, err)) {
+		return Error(err);
+	}
+	return OK;
 }
 
-Array GLTFDocumentExtension::get_export_setting_keys() const {
-	return import_settings.keys();
+Error GLTFDocumentExtension::export_post(Ref<GLTFState> p_state) {
+	ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
+	int err = OK;
+	if (GDVIRTUAL_CALL(_export_post, p_state, err)) {
+		return Error(err);
+	}
+	return OK;
+}
+Error GLTFDocumentExtension::export_preflight(Node *p_root) {
+	ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
+	int err = OK;
+	if (GDVIRTUAL_CALL(_export_preflight, p_root, err)) {
+		return Error(err);
+	}
+	return OK;
 }
 
-Variant GLTFDocumentExtension::get_export_setting(const StringName &p_key) const {
-	if (!import_settings.has(p_key)) {
-		return Variant();
+Error GLTFDocumentExtension::import_node(Ref<GLTFState> p_state, Ref<GLTFNode> 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;
+	if (GDVIRTUAL_CALL(_import_node, p_state, p_gltf_node, r_dict, p_node, err)) {
+		return Error(err);
 	}
-	return import_settings[p_key];
+	return OK;
 }
 
-void GLTFDocumentExtension::set_export_setting(const StringName &p_key, Variant p_var) {
-	import_settings[p_key] = p_var;
+Error GLTFDocumentExtension::export_node(Ref<GLTFState> p_state, Ref<GLTFNode> 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;
+	if (GDVIRTUAL_CALL(_export_node, p_state, p_gltf_node, r_dict, p_node, err)) {
+		return Error(err);
+	}
+	return OK;
 }

+ 18 - 20
modules/gltf/gltf_document_extension.h

@@ -31,33 +31,31 @@
 #ifndef GLTF_DOCUMENT_EXTENSION_H
 #define GLTF_DOCUMENT_EXTENSION_H
 
-#include "core/io/resource.h"
-#include "core/variant/dictionary.h"
-#include "core/variant/typed_array.h"
-#include "core/variant/variant.h"
-class GLTFDocument;
+#include "gltf_accessor.h"
+#include "gltf_node.h"
+#include "gltf_state.h"
+
 class GLTFDocumentExtension : public Resource {
 	GDCLASS(GLTFDocumentExtension, Resource);
 
-	Dictionary import_settings;
-	Dictionary export_settings;
-
 protected:
 	static void _bind_methods();
 
 public:
-	virtual Array get_import_setting_keys() const;
-	virtual Variant get_import_setting(const StringName &p_key) const;
-	virtual void set_import_setting(const StringName &p_key, Variant p_var);
-	virtual Error import_preflight(Ref<GLTFDocument> p_document) { return OK; }
-	virtual Error import_post(Ref<GLTFDocument> p_document, Node *p_node) { return OK; }
-
-public:
-	virtual Array get_export_setting_keys() const;
-	virtual Variant get_export_setting(const StringName &p_key) const;
-	virtual void set_export_setting(const StringName &p_key, Variant p_var);
-	virtual Error export_preflight(Ref<GLTFDocument> p_document, Node *p_node) { return OK; }
-	virtual Error export_post(Ref<GLTFDocument> p_document) { return OK; }
+	virtual Error import_preflight(Ref<GLTFState> p_state);
+	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);
+	GDVIRTUAL1R(int, _import_preflight, Ref<GLTFState>);
+	GDVIRTUAL1R(int, _import_post_parse, Ref<GLTFState>);
+	GDVIRTUAL4R(int, _import_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
+	GDVIRTUAL2R(int, _import_post, Ref<GLTFState>, Node *);
+	GDVIRTUAL1R(int, _export_preflight, Node *);
+	GDVIRTUAL4R(int, _export_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
+	GDVIRTUAL1R(int, _export_post, Ref<GLTFState>);
 };
 
 #endif // GLTF_DOCUMENT_EXTENSION_H

+ 22 - 23
modules/gltf/gltf_document_extension_convert_importer_mesh.cpp

@@ -29,41 +29,40 @@
 /*************************************************************************/
 
 #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"
 
-#include <cstddef>
-
 void GLTFDocumentExtensionConvertImporterMesh::_bind_methods() {
 }
 
-Error GLTFDocumentExtensionConvertImporterMesh::import_post(Ref<GLTFDocument> p_document, Node *p_node) {
-	ERR_FAIL_NULL_V(p_document, ERR_INVALID_PARAMETER);
-	ERR_FAIL_NULL_V(p_node, ERR_INVALID_PARAMETER);
+Error GLTFDocumentExtensionConvertImporterMesh::import_post(Ref<GLTFState> p_state, Node *p_root) {
+	ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
+	ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
 	List<Node *> queue;
-	queue.push_back(p_node);
+	queue.push_back(p_root);
 	List<Node *> delete_queue;
 	while (!queue.is_empty()) {
 		List<Node *>::Element *E = queue.front();
 		Node *node = E->get();
-		{
-			ImporterMeshInstance3D *mesh_3d = cast_to<ImporterMeshInstance3D>(node);
-			if (mesh_3d) {
-				MeshInstance3D *mesh_instance_node_3d = memnew(MeshInstance3D);
-				Ref<ImporterMesh> mesh = mesh_3d->get_mesh();
-				if (mesh.is_valid()) {
-					Ref<ArrayMesh> 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);
-				}
+		ImporterMeshInstance3D *mesh_3d = cast_to<ImporterMeshInstance3D>(node);
+		if (mesh_3d) {
+			MeshInstance3D *mesh_instance_node_3d = memnew(MeshInstance3D);
+			Ref<ImporterMesh> mesh = mesh_3d->get_mesh();
+			if (mesh.is_valid()) {
+				Ref<ArrayMesh> 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();

+ 2 - 6
modules/gltf/gltf_document_extension_convert_importer_mesh.h

@@ -31,14 +31,10 @@
 #ifndef GLTF_EXTENSION_EDITOR_H
 #define GLTF_EXTENSION_EDITOR_H
 
-#include "core/io/resource.h"
-#include "core/variant/dictionary.h"
-
-#include "gltf_document.h"
 #include "gltf_document_extension.h"
+
 #include "scene/3d/importer_mesh_instance_3d.h"
 #include "scene/3d/mesh_instance_3d.h"
-#include "scene/main/node.h"
 #include "scene/resources/importer_mesh.h"
 
 class GLTFDocumentExtension;
@@ -50,6 +46,6 @@ protected:
 	static void _bind_methods();
 
 public:
-	Error import_post(Ref<GLTFDocument> p_document, Node *p_node) override;
+	Error import_post(Ref<GLTFState> p_state, Node *p_root) override;
 };
 #endif // GLTF_EXTENSION_EDITOR_H

+ 11 - 0
modules/gltf/gltf_state.cpp

@@ -57,6 +57,8 @@ void GLTFState::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_materials", "materials"), &GLTFState::set_materials);
 	ClassDB::bind_method(D_METHOD("get_scene_name"), &GLTFState::get_scene_name);
 	ClassDB::bind_method(D_METHOD("set_scene_name", "scene_name"), &GLTFState::set_scene_name);
+	ClassDB::bind_method(D_METHOD("get_base_path"), &GLTFState::get_base_path);
+	ClassDB::bind_method(D_METHOD("set_base_path", "base_path"), &GLTFState::set_base_path);
 	ClassDB::bind_method(D_METHOD("get_root_nodes"), &GLTFState::get_root_nodes);
 	ClassDB::bind_method(D_METHOD("set_root_nodes", "root_nodes"), &GLTFState::set_root_nodes);
 	ClassDB::bind_method(D_METHOD("get_textures"), &GLTFState::get_textures);
@@ -93,6 +95,7 @@ void GLTFState::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "meshes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_meshes", "get_meshes"); // Vector<Ref<GLTFMesh>>
 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "materials", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_materials", "get_materials"); // Vector<Ref<Material>
 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "scene_name"), "set_scene_name", "get_scene_name"); // String
+	ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_path"), "set_base_path", "get_base_path"); // String
 	ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "root_nodes"), "set_root_nodes", "get_root_nodes"); // Vector<int>
 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "textures", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_textures", "get_textures"); // Vector<Ref<GLTFTexture>>
 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_images", "get_images"); // Vector<Ref<Texture>
@@ -313,3 +316,11 @@ void GLTFState::set_discard_meshes_and_materials(bool p_discard_meshes_and_mater
 bool GLTFState::get_discard_meshes_and_materials() {
 	return discard_meshes_and_materials;
 }
+
+String GLTFState::get_base_path() {
+	return base_path;
+}
+
+void GLTFState::set_base_path(String p_base_path) {
+	base_path = p_base_path;
+}

+ 4 - 3
modules/gltf/gltf_state.h

@@ -44,10 +44,7 @@
 #include "gltf_skin.h"
 #include "gltf_texture.h"
 
-#include "core/io/resource.h"
-#include "core/templates/pair.h"
 #include "core/templates/rb_map.h"
-#include "core/templates/vector.h"
 #include "scene/animation/animation_player.h"
 #include "scene/resources/texture.h"
 
@@ -56,6 +53,7 @@ class GLTFState : public Resource {
 	friend class GLTFDocument;
 
 	String filename;
+	String base_path;
 	Dictionary json;
 	int major_version = 0;
 	int minor_version = 0;
@@ -137,6 +135,9 @@ public:
 	String get_scene_name();
 	void set_scene_name(String p_scene_name);
 
+	String get_base_path();
+	void set_base_path(String p_base_path);
+
 	Array get_root_nodes();
 	void set_root_nodes(Array p_root_nodes);