From 1463fc889b65524794f2f7d9cf661aa673d58e06 Mon Sep 17 00:00:00 2001 From: "K. S. Ernest (iFire) Lee" Date: Mon, 20 Sep 2021 18:24:31 -0700 Subject: GLTF for game templates. Convert GLTF Document to use ImporterMeshInstance3D. Add a GLTFDocument extension list and an extension for converting the importer mesh instance 3d to mesh instance 3d. Use GLTF module when the editor tools are disabled. Modified the render server to be less restrictive on matching blend arrays and have more logging. Misc bugs with multimesh. Always index the meshes. --- modules/fbx/data/fbx_mesh_data.cpp | 7 +- modules/fbx/data/fbx_mesh_data.h | 6 +- modules/fbx/editor_scene_importer_fbx.cpp | 6 +- modules/gltf/config.py | 4 +- modules/gltf/doc_classes/GLTFDocument.xml | 4 + modules/gltf/doc_classes/GLTFDocumentExtension.xml | 73 +++++ .../GLTFDocumentExtensionConvertImporterMesh.xml | 9 + modules/gltf/doc_classes/GLTFMesh.xml | 2 +- modules/gltf/editor_scene_exporter_gltf_plugin.cpp | 3 + modules/gltf/editor_scene_exporter_gltf_plugin.h | 4 +- modules/gltf/editor_scene_importer_gltf.cpp | 3 + modules/gltf/editor_scene_importer_gltf.h | 7 +- modules/gltf/gltf_accessor.cpp | 2 + modules/gltf/gltf_accessor.h | 2 + modules/gltf/gltf_buffer_view.cpp | 2 + modules/gltf/gltf_document.cpp | 321 +++++++++++++-------- modules/gltf/gltf_document.h | 24 +- modules/gltf/gltf_document_extension.cpp | 88 ++++++ modules/gltf/gltf_document_extension.h | 63 ++++ ...tf_document_extension_convert_importer_mesh.cpp | 79 +++++ ...gltf_document_extension_convert_importer_mesh.h | 55 ++++ modules/gltf/gltf_mesh.cpp | 6 +- modules/gltf/gltf_mesh.h | 9 +- modules/gltf/gltf_state.h | 1 + modules/gltf/register_types.cpp | 4 + 25 files changed, 631 insertions(+), 153 deletions(-) create mode 100644 modules/gltf/doc_classes/GLTFDocumentExtension.xml create mode 100644 modules/gltf/doc_classes/GLTFDocumentExtensionConvertImporterMesh.xml create mode 100644 modules/gltf/gltf_document_extension.cpp create mode 100644 modules/gltf/gltf_document_extension.h create mode 100644 modules/gltf/gltf_document_extension_convert_importer_mesh.cpp create mode 100644 modules/gltf/gltf_document_extension_convert_importer_mesh.h (limited to 'modules') diff --git a/modules/fbx/data/fbx_mesh_data.cpp b/modules/fbx/data/fbx_mesh_data.cpp index dcea476275..7343bf87af 100644 --- a/modules/fbx/data/fbx_mesh_data.cpp +++ b/modules/fbx/data/fbx_mesh_data.cpp @@ -31,6 +31,7 @@ #include "fbx_mesh_data.h" #include "core/templates/local_vector.h" +#include "scene/resources/importer_mesh.h" #include "scene/resources/mesh.h" #include "scene/resources/surface_tool.h" @@ -101,7 +102,7 @@ HashMap collect_uv(const Vector> *p_data, Hash return collection; } -EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, bool use_compression) { +ImporterMeshInstance3D *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, bool use_compression) { mesh_geometry = p_mesh_geometry; // todo: make this just use a uint64_t FBX ID this is a copy of our original materials unfortunately. const std::vector &material_lookup = model->GetMaterials(); @@ -344,7 +345,7 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s } // Phase 6. Compose the mesh and return it. - Ref mesh; + Ref mesh; mesh.instantiate(); // Add blend shape info. @@ -380,7 +381,7 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s in_mesh_surface_id += 1; } - EditorSceneImporterMeshNode3D *godot_mesh = memnew(EditorSceneImporterMeshNode3D); + ImporterMeshInstance3D *godot_mesh = memnew(ImporterMeshInstance3D); godot_mesh->set_mesh(mesh); const String name = ImportUtils::FBXNodeToName(model->Name()); godot_mesh->set_name(name); // hurry up compiling >.< diff --git a/modules/fbx/data/fbx_mesh_data.h b/modules/fbx/data/fbx_mesh_data.h index 24db4a5469..eec7f38cd6 100644 --- a/modules/fbx/data/fbx_mesh_data.h +++ b/modules/fbx/data/fbx_mesh_data.h @@ -35,7 +35,7 @@ #include "core/templates/local_vector.h" #include "core/templates/ordered_hash_map.h" #include "editor/import/resource_importer_scene.h" -#include "editor/import/scene_importer_mesh_node_3d.h" +#include "scene/3d/importer_mesh_instance_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/resources/surface_tool.h" @@ -98,7 +98,7 @@ struct FBXMeshData : RefCounted { // translate fbx mesh data from document context to FBX Mesh Geometry Context bool valid_weight_indexes = false; - EditorSceneImporterMeshNode3D *create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, bool use_compression); + ImporterMeshInstance3D *create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, bool use_compression); void gen_weight_info(Ref st, int vertex_id) const; @@ -107,7 +107,7 @@ struct FBXMeshData : RefCounted { int max_weight_count = 0; uint64_t armature_id = 0; bool valid_armature_id = false; - EditorSceneImporterMeshNode3D *godot_mesh_instance = nullptr; + ImporterMeshInstance3D *godot_mesh_instance = nullptr; private: void sanitize_vertex_weights(const ImportState &state); diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index e0663ab49d..e4de204cf1 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -40,9 +40,9 @@ #include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/import/resource_importer_scene.h" -#include "editor/import/scene_importer_mesh_node_3d.h" #include "scene/3d/bone_attachment_3d.h" #include "scene/3d/camera_3d.h" +#include "scene/3d/importer_mesh_instance_3d.h" #include "scene/3d/light_3d.h" #include "scene/main/node.h" #include "scene/resources/material.h" @@ -627,7 +627,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( node_element; node_element = node_element->next()) { Ref fbx_node = node_element->get(); - EditorSceneImporterMeshNode3D *mesh_node = nullptr; + ImporterMeshInstance3D *mesh_node = nullptr; Ref mesh_data_precached; // check for valid geometry @@ -768,7 +768,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( for (KeyValue> &mesh_data : state.renderer_mesh_data) { Ref mesh = mesh_data.value; const uint64_t mesh_id = mesh_data.key; - EditorSceneImporterMeshNode3D *mesh_instance = mesh->godot_mesh_instance; + ImporterMeshInstance3D *mesh_instance = mesh->godot_mesh_instance; const int mesh_weights = mesh->max_weight_count; Ref skeleton; const bool valid_armature = mesh->valid_armature_id; diff --git a/modules/gltf/config.py b/modules/gltf/config.py index 52a97c93aa..a4736321fa 100644 --- a/modules/gltf/config.py +++ b/modules/gltf/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return env["tools"] and not env["disable_3d"] + return not env["disable_3d"] def configure(env): @@ -22,6 +22,8 @@ def get_doc_classes(): "GLTFSpecGloss", "GLTFState", "GLTFTexture", + "GLTFDocumentExtension", + "GLTFDocumentExtensionConvertImporterMesh", ] diff --git a/modules/gltf/doc_classes/GLTFDocument.xml b/modules/gltf/doc_classes/GLTFDocument.xml index 16e649f390..77c45da34d 100644 --- a/modules/gltf/doc_classes/GLTFDocument.xml +++ b/modules/gltf/doc_classes/GLTFDocument.xml @@ -30,4 +30,8 @@ + + + + diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml new file mode 100644 index 0000000000..390bd3b30b --- /dev/null +++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/gltf/doc_classes/GLTFDocumentExtensionConvertImporterMesh.xml b/modules/gltf/doc_classes/GLTFDocumentExtensionConvertImporterMesh.xml new file mode 100644 index 0000000000..452eec5f4f --- /dev/null +++ b/modules/gltf/doc_classes/GLTFDocumentExtensionConvertImporterMesh.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/gltf/doc_classes/GLTFMesh.xml b/modules/gltf/doc_classes/GLTFMesh.xml index 51e9fc032a..1e7199d229 100644 --- a/modules/gltf/doc_classes/GLTFMesh.xml +++ b/modules/gltf/doc_classes/GLTFMesh.xml @@ -9,7 +9,7 @@ - + diff --git a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp index 3ce5ea23dc..25fda7ef3b 100644 --- a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp +++ b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#if TOOLS_ENABLED #include "editor_scene_exporter_gltf_plugin.h" #include "core/config/project_settings.h" #include "core/error/error_list.h" @@ -93,3 +94,5 @@ void SceneExporterGLTFPlugin::convert_scene_to_gltf2() { file_export_lib->set_current_file(filename + String(".gltf")); file_export_lib->popup_centered_ratio(); } + +#endif // TOOLS_ENABLED diff --git a/modules/gltf/editor_scene_exporter_gltf_plugin.h b/modules/gltf/editor_scene_exporter_gltf_plugin.h index c4f277fca2..89a8e27053 100644 --- a/modules/gltf/editor_scene_exporter_gltf_plugin.h +++ b/modules/gltf/editor_scene_exporter_gltf_plugin.h @@ -31,7 +31,9 @@ #ifndef EDITOR_SCENE_EXPORTER_GLTF_PLUGIN_H #define EDITOR_SCENE_EXPORTER_GLTF_PLUGIN_H +#if TOOLS_ENABLED #include "editor/editor_plugin.h" + #include "editor_scene_importer_gltf.h" class SceneExporterGLTFPlugin : public EditorPlugin { @@ -47,5 +49,5 @@ public: bool has_main_screen() const override; SceneExporterGLTFPlugin(class EditorNode *p_node); }; - +#endif // TOOLS_ENABLED #endif // EDITOR_SCENE_EXPORTER_GLTF_PLUGIN_H diff --git a/modules/gltf/editor_scene_importer_gltf.cpp b/modules/gltf/editor_scene_importer_gltf.cpp index 12796c41d7..25875e7396 100644 --- a/modules/gltf/editor_scene_importer_gltf.cpp +++ b/modules/gltf/editor_scene_importer_gltf.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#if TOOLS_ENABLED #include "editor_scene_importer_gltf.h" #include "gltf_document.h" @@ -60,3 +61,5 @@ Ref EditorSceneImporterGLTF::import_animation(const String &p_path, int p_bake_fps) { return Ref(); } + +#endif // TOOLS_ENABLED diff --git a/modules/gltf/editor_scene_importer_gltf.h b/modules/gltf/editor_scene_importer_gltf.h index eb8775b137..90663612a1 100644 --- a/modules/gltf/editor_scene_importer_gltf.h +++ b/modules/gltf/editor_scene_importer_gltf.h @@ -30,16 +30,17 @@ #ifndef EDITOR_SCENE_IMPORTER_GLTF_H #define EDITOR_SCENE_IMPORTER_GLTF_H - +#ifdef TOOLS_ENABLED #include "gltf_state.h" +#include "gltf_document_extension.h" + #include "editor/import/resource_importer_scene.h" #include "scene/main/node.h" #include "scene/resources/packed_scene.h" class Animation; -#ifdef TOOLS_ENABLED class EditorSceneImporterGLTF : public EditorSceneImporter { GDCLASS(EditorSceneImporterGLTF, EditorSceneImporter); @@ -50,5 +51,5 @@ public: virtual Ref import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) override; }; -#endif +#endif // TOOLS_ENABLED #endif // EDITOR_SCENE_IMPORTER_GLTF_H diff --git a/modules/gltf/gltf_accessor.cpp b/modules/gltf/gltf_accessor.cpp index daeb084916..85cec3fec4 100644 --- a/modules/gltf/gltf_accessor.cpp +++ b/modules/gltf/gltf_accessor.cpp @@ -30,6 +30,8 @@ #include "gltf_accessor.h" +#include "gltf_document_extension.h" + void GLTFAccessor::_bind_methods() { ClassDB::bind_method(D_METHOD("get_buffer_view"), &GLTFAccessor::get_buffer_view); ClassDB::bind_method(D_METHOD("set_buffer_view", "buffer_view"), &GLTFAccessor::set_buffer_view); diff --git a/modules/gltf/gltf_accessor.h b/modules/gltf/gltf_accessor.h index 57aea1026c..bec511f974 100644 --- a/modules/gltf/gltf_accessor.h +++ b/modules/gltf/gltf_accessor.h @@ -32,7 +32,9 @@ #define GLTF_ACCESSOR_H #include "core/io/resource.h" + #include "gltf_document.h" +#include "gltf_document_extension.h" struct GLTFAccessor : public Resource { GDCLASS(GLTFAccessor, Resource); diff --git a/modules/gltf/gltf_buffer_view.cpp b/modules/gltf/gltf_buffer_view.cpp index ba38a11c4c..d00e0f040f 100644 --- a/modules/gltf/gltf_buffer_view.cpp +++ b/modules/gltf/gltf_buffer_view.cpp @@ -30,6 +30,8 @@ #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); diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 3f1f218e78..c7818e7e86 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -33,6 +33,8 @@ #include "gltf_accessor.h" #include "gltf_animation.h" #include "gltf_camera.h" +#include "gltf_document_extension.h" +#include "gltf_document_extension_convert_importer_mesh.h" #include "gltf_light.h" #include "gltf_mesh.h" #include "gltf_node.h" @@ -49,6 +51,7 @@ #include "core/io/json.h" #include "core/math/disjoint_set.h" #include "core/math/vector2.h" +#include "core/variant/dictionary.h" #include "core/variant/typed_array.h" #include "core/variant/variant.h" #include "core/version.h" @@ -57,8 +60,12 @@ #include "editor/import/resource_importer_scene.h" #include "scene/2d/node_2d.h" #include "scene/3d/camera_3d.h" +#include "scene/3d/mesh_instance_3d.h" #include "scene/3d/multimesh_instance_3d.h" #include "scene/animation/animation_player.h" +#include "scene/resources/importer_mesh.h" +#include "scene/resources/mesh.h" +#include "scene/resources/multimesh.h" #include "scene/resources/surface_tool.h" #include "modules/modules_enabled.gen.h" @@ -2101,7 +2108,7 @@ Error GLTFDocument::_serialize_meshes(Ref state) { Array meshes; for (GLTFMeshIndex gltf_mesh_i = 0; gltf_mesh_i < state->meshes.size(); gltf_mesh_i++) { print_verbose("glTF: Serializing mesh: " + itos(gltf_mesh_i)); - Ref import_mesh = state->meshes.write[gltf_mesh_i]->get_mesh(); + Ref import_mesh = state->meshes.write[gltf_mesh_i]->get_mesh(); if (import_mesh.is_null()) { continue; } @@ -2493,7 +2500,7 @@ Error GLTFDocument::_parse_meshes(Ref state) { Array primitives = d["primitives"]; const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] : Dictionary(); - Ref import_mesh; + Ref import_mesh; import_mesh.instantiate(); String mesh_name = "mesh"; if (d.has("name") && !String(d["name"]).is_empty()) { @@ -2732,17 +2739,18 @@ Error GLTFDocument::_parse_meshes(Ref state) { bool generate_tangents = (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("TEXCOORD_0") && a.has("NORMAL")); + Ref mesh_surface_tool; + mesh_surface_tool.instantiate(); + mesh_surface_tool->create_from_triangle_arrays(array); + if (a.has("JOINTS_0") && a.has("JOINTS_1")) { + mesh_surface_tool->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS); + } + mesh_surface_tool->index(); if (generate_tangents) { //must generate mikktspace tangents.. ergh.. - Ref st; - st.instantiate(); - st->create_from_triangle_arrays(array); - if (a.has("JOINTS_0") && a.has("JOINTS_1")) { - st->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS); - } - st->generate_tangents(); - array = st->commit_to_arrays(); + mesh_surface_tool->generate_tangents(); } + array = mesh_surface_tool->commit_to_arrays(); Array morphs; //blend shapes @@ -2772,8 +2780,6 @@ Error GLTFDocument::_parse_meshes(Ref state) { array_copy[l] = array[l]; } - array_copy[Mesh::ARRAY_INDEX] = Variant(); - if (t.has("POSITION")) { Vector varr = _decode_accessor_as_vec3(state, t["POSITION"], true); const Vector src_varr = array[Mesh::ARRAY_VERTEX]; @@ -2852,17 +2858,17 @@ Error GLTFDocument::_parse_meshes(Ref state) { array_copy[Mesh::ARRAY_TANGENT] = tangents_v4; } + Ref blend_surface_tool; + blend_surface_tool.instantiate(); + blend_surface_tool->create_from_triangle_arrays(array_copy); + if (a.has("JOINTS_0") && a.has("JOINTS_1")) { + blend_surface_tool->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS); + } + blend_surface_tool->index(); if (generate_tangents) { - Ref st; - st.instantiate(); - st->create_from_triangle_arrays(array_copy); - if (a.has("JOINTS_0") && a.has("JOINTS_1")) { - st->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS); - } - st->deindex(); - st->generate_tangents(); - array_copy = st->commit_to_arrays(); + blend_surface_tool->generate_tangents(); } + array_copy = blend_surface_tool->commit_to_arrays(); morphs.push_back(array_copy); } @@ -2875,19 +2881,23 @@ Error GLTFDocument::_parse_meshes(Ref state) { const int material = p["material"]; ERR_FAIL_INDEX_V(material, state->materials.size(), ERR_FILE_CORRUPT); Ref mat3d = state->materials[material]; + ERR_FAIL_NULL_V(mat3d, ERR_FILE_CORRUPT); if (has_vertex_color) { mat3d->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); } mat = mat3d; - } else if (has_vertex_color) { + } else { Ref mat3d; mat3d.instantiate(); - mat3d->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + if (has_vertex_color) { + mat3d->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + } mat = mat3d; } - - import_mesh->add_surface(primitive, array, morphs, Dictionary(), mat, mat.is_valid() ? mat->get_name() : String(), flags); + ERR_FAIL_NULL_V(mat, ERR_FILE_CORRUPT); + import_mesh->add_surface(primitive, array, morphs, + Dictionary(), mat, mat->get_name(), flags); } Vector blend_weights; @@ -3610,7 +3620,6 @@ Error GLTFDocument::_parse_materials(Ref state) { material->set_cull_mode(BaseMaterial3D::CULL_DISABLED); } } - if (d.has("alphaMode")) { const String &am = d["alphaMode"]; if (am == "BLEND") { @@ -5007,72 +5016,65 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref state, MeshInst if (p_mesh_instance->get_mesh().is_null()) { return -1; } - Ref import_mesh; - import_mesh.instantiate(); - Ref godot_mesh = p_mesh_instance->get_mesh(); - if (godot_mesh.is_null()) { - return -1; - } + Ref current_mesh; + current_mesh.instantiate(); Vector blend_weights; - Vector blend_names; - int32_t blend_count = godot_mesh->get_blend_shape_count(); - blend_names.resize(blend_count); - blend_weights.resize(blend_count); - for (int32_t blend_i = 0; blend_i < godot_mesh->get_blend_shape_count(); blend_i++) { - String blend_name = godot_mesh->get_blend_shape_name(blend_i); - blend_names.write[blend_i] = blend_name; - import_mesh->add_blend_shape(blend_name); - } - for (int32_t surface_i = 0; surface_i < godot_mesh->get_surface_count(); surface_i++) { - Mesh::PrimitiveType primitive_type = godot_mesh->surface_get_primitive_type(surface_i); - Array arrays = godot_mesh->surface_get_arrays(surface_i); - Array blend_shape_arrays = godot_mesh->surface_get_blend_shape_arrays(surface_i); - Ref mat = godot_mesh->surface_get_material(surface_i); - Ref godot_array_mesh = godot_mesh; - String surface_name; - if (godot_array_mesh.is_valid()) { - surface_name = godot_array_mesh->surface_get_name(surface_i); - } - if (p_mesh_instance->get_surface_override_material(surface_i).is_valid()) { - mat = p_mesh_instance->get_surface_override_material(surface_i); - } - if (p_mesh_instance->get_material_override().is_valid()) { - mat = p_mesh_instance->get_material_override(); - } - import_mesh->add_surface(primitive_type, arrays, blend_shape_arrays, Dictionary(), mat, surface_name, godot_mesh->surface_get_format(surface_i)); - } - for (int32_t blend_i = 0; blend_i < blend_count; blend_i++) { - blend_weights.write[blend_i] = 0.0f; + { + Ref import_mesh = p_mesh_instance->get_mesh(); + Ref import_array_mesh = p_mesh_instance->get_mesh(); + if (import_mesh->get_blend_shape_count()) { + ArrayMesh::BlendShapeMode shape_mode = ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED; + if (import_array_mesh.is_valid()) { + shape_mode = import_array_mesh->get_blend_shape_mode(); + } + current_mesh->set_blend_shape_mode(shape_mode); + for (int morph_i = 0; morph_i < import_mesh->get_blend_shape_count(); morph_i++) { + current_mesh->add_blend_shape(import_mesh->get_blend_shape_name(morph_i)); + } + } + for (int32_t surface_i = 0; surface_i < import_mesh->get_surface_count(); surface_i++) { + Array array = import_mesh->surface_get_arrays(surface_i); + Ref mat = import_mesh->surface_get_material(surface_i); + String mat_name; + if (mat.is_valid()) { + mat_name = mat->get_name(); + } + current_mesh->add_surface(import_mesh->surface_get_primitive_type(surface_i), + array, import_mesh->surface_get_blend_shape_arrays(surface_i), import_mesh->surface_get_lods(surface_i), mat, + mat_name, import_mesh->surface_get_format(surface_i)); + } + int32_t blend_count = import_mesh->get_blend_shape_count(); + blend_weights.resize(blend_count); + for (int32_t blend_i = 0; blend_i < blend_count; blend_i++) { + blend_weights.write[blend_i] = 0.0f; + } } Ref gltf_mesh; gltf_mesh.instantiate(); - gltf_mesh->set_mesh(import_mesh); + gltf_mesh->set_mesh(current_mesh); gltf_mesh->set_blend_weights(blend_weights); GLTFMeshIndex mesh_i = state->meshes.size(); state->meshes.push_back(gltf_mesh); return mesh_i; } -EditorSceneImporterMeshNode3D *GLTFDocument::_generate_mesh_instance(Ref state, Node *scene_parent, const GLTFNodeIndex node_index) { +ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref state, Node *parent_node, const GLTFNodeIndex node_index) { Ref gltf_node = state->nodes[node_index]; ERR_FAIL_INDEX_V(gltf_node->mesh, state->meshes.size(), nullptr); - EditorSceneImporterMeshNode3D *mi = memnew(EditorSceneImporterMeshNode3D); + ImporterMeshInstance3D *mi = memnew(ImporterMeshInstance3D); print_verbose("glTF: Creating mesh for: " + gltf_node->get_name()); Ref mesh = state->meshes.write[gltf_node->mesh]; if (mesh.is_null()) { return mi; } - Ref import_mesh = mesh->get_mesh(); + Ref import_mesh = mesh->get_mesh(); if (import_mesh.is_null()) { return mi; } mi->set_mesh(import_mesh); - for (int i = 0; i < mesh->get_blend_weights().size(); i++) { - mi->set("blend_shapes/" + mesh->get_mesh()->get_blend_shape_name(i), mesh->get_blend_weights()[i]); - } return mi; } @@ -5241,7 +5243,7 @@ void GLTFDocument::_convert_scene_node(Ref state, Node *p_current, co return; } else if (cast_to(p_current)) { MultiMeshInstance3D *multi = cast_to(p_current); - _convert_mult_mesh_instance_to_gltf(multi, p_gltf_parent, p_gltf_root, gltf_node, state); + _convert_multi_mesh_instance_to_gltf(multi, p_gltf_parent, p_gltf_root, gltf_node, state); #ifdef MODULE_CSG_ENABLED } else if (cast_to(p_current)) { CSGShape3D *shape = cast_to(p_current); @@ -5292,13 +5294,8 @@ void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeInd } Ref gltf_mesh; gltf_mesh.instantiate(); - Ref import_mesh; - import_mesh.instantiate(); - Ref array_mesh = csg->get_meshes()[1]; - for (int32_t surface_i = 0; surface_i < array_mesh->get_surface_count(); surface_i++) { - import_mesh->add_surface(Mesh::PrimitiveType::PRIMITIVE_TRIANGLES, array_mesh->surface_get_arrays(surface_i), Array(), Dictionary(), mat, array_mesh->surface_get_name(surface_i)); - } - gltf_mesh->set_mesh(import_mesh); + Ref array_mesh = csg->get_meshes()[1]; + gltf_mesh->set_mesh(array_mesh); GLTFMeshIndex mesh_i = state->meshes.size(); state->meshes.push_back(gltf_mesh); gltf_node->mesh = mesh_i; @@ -5364,7 +5361,7 @@ void GLTFDocument::_convert_grid_map_to_gltf(GridMap *p_grid_map, GLTFNodeIndex Vector3 cell_location = cells[k]; int32_t cell = p_grid_map->get_cell_item( Vector3(cell_location.x, cell_location.y, cell_location.z)); - EditorSceneImporterMeshNode3D *import_mesh_node = memnew(EditorSceneImporterMeshNode3D); + ImporterMeshInstance3D *import_mesh_node = memnew(ImporterMeshInstance3D); import_mesh_node->set_mesh(p_grid_map->get_mesh_library()->get_item_mesh(cell)); Transform3D cell_xform; cell_xform.basis.set_orthogonal_index( @@ -5386,49 +5383,72 @@ void GLTFDocument::_convert_grid_map_to_gltf(GridMap *p_grid_map, GLTFNodeIndex } #endif // MODULE_GRIDMAP_ENABLED -void GLTFDocument::_convert_mult_mesh_instance_to_gltf(MultiMeshInstance3D *p_multi_mesh_instance, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_node_index, Ref gltf_node, Ref state) { +void GLTFDocument::_convert_multi_mesh_instance_to_gltf( + MultiMeshInstance3D *p_multi_mesh_instance, + GLTFNodeIndex p_parent_node_index, + GLTFNodeIndex p_root_node_index, + Ref gltf_node, Ref state) { + ERR_FAIL_COND(!p_multi_mesh_instance); Ref multi_mesh = p_multi_mesh_instance->get_multimesh(); - if (multi_mesh.is_valid()) { - for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count(); - instance_i++) { - GLTFNode *new_gltf_node = memnew(GLTFNode); - Transform3D transform; - if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_2D) { - Transform2D xform_2d = multi_mesh->get_instance_transform_2d(instance_i); - transform.origin = - Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y); - real_t rotation = xform_2d.get_rotation(); - Quaternion quaternion(Vector3(0, 1, 0), rotation); - Size2 scale = xform_2d.get_scale(); - transform.basis.set_quaternion_scale(quaternion, - Vector3(scale.x, 0, scale.y)); - transform = - p_multi_mesh_instance->get_transform() * transform; - } else if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_3D) { - transform = p_multi_mesh_instance->get_transform() * - multi_mesh->get_instance_transform(instance_i); - } - Ref mm = multi_mesh->get_mesh(); - if (mm.is_valid()) { - Ref mesh; - mesh.instantiate(); - for (int32_t surface_i = 0; surface_i < mm->get_surface_count(); surface_i++) { - Array surface = mm->surface_get_arrays(surface_i); - mesh->add_surface(mm->surface_get_primitive_type(surface_i), surface, Array(), Dictionary(), - mm->surface_get_material(surface_i), mm->get_name()); - } - Ref gltf_mesh; - gltf_mesh.instantiate(); - gltf_mesh->set_name(multi_mesh->get_name()); - gltf_mesh->set_mesh(mesh); - new_gltf_node->mesh = state->meshes.size(); - state->meshes.push_back(gltf_mesh); - } - new_gltf_node->xform = transform; - new_gltf_node->set_name(_gen_unique_name(state, p_multi_mesh_instance->get_name())); - gltf_node->children.push_back(state->nodes.size()); - state->nodes.push_back(new_gltf_node); + if (multi_mesh.is_null()) { + return; + } + Ref gltf_mesh; + gltf_mesh.instantiate(); + Ref mesh = multi_mesh->get_mesh(); + if (mesh.is_null()) { + return; + } + gltf_mesh->set_name(multi_mesh->get_name()); + Ref importer_mesh; + importer_mesh.instantiate(); + Ref array_mesh = multi_mesh->get_mesh(); + if (array_mesh.is_valid()) { + importer_mesh->set_blend_shape_mode(array_mesh->get_blend_shape_mode()); + for (int32_t blend_i = 0; blend_i < array_mesh->get_blend_shape_count(); blend_i++) { + importer_mesh->add_blend_shape(array_mesh->get_blend_shape_name(blend_i)); + } + } + for (int32_t surface_i = 0; surface_i < mesh->get_surface_count(); surface_i++) { + Ref mat = mesh->surface_get_material(surface_i); + String material_name; + if (mat.is_valid()) { + material_name = mat->get_name(); } + Array blend_arrays; + if (array_mesh.is_valid()) { + blend_arrays = array_mesh->surface_get_blend_shape_arrays(surface_i); + } + importer_mesh->add_surface(mesh->surface_get_primitive_type(surface_i), mesh->surface_get_arrays(surface_i), + blend_arrays, mesh->surface_get_lods(surface_i), mat, material_name, mesh->surface_get_format(surface_i)); + } + gltf_mesh->set_mesh(importer_mesh); + GLTFMeshIndex mesh_index = state->meshes.size(); + state->meshes.push_back(gltf_mesh); + for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count(); + instance_i++) { + Transform3D transform; + if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_2D) { + Transform2D xform_2d = multi_mesh->get_instance_transform_2d(instance_i); + transform.origin = + Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y); + real_t rotation = xform_2d.get_rotation(); + Quaternion quaternion(Vector3(0, 1, 0), rotation); + Size2 scale = xform_2d.get_scale(); + transform.basis.set_quaternion_scale(quaternion, + Vector3(scale.x, 0, scale.y)); + transform = p_multi_mesh_instance->get_transform() * transform; + } else if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_3D) { + transform = p_multi_mesh_instance->get_transform() * + multi_mesh->get_instance_transform(instance_i); + } + Ref new_gltf_node; + new_gltf_node.instantiate(); + new_gltf_node->mesh = mesh_index; + new_gltf_node->xform = transform; + new_gltf_node->set_name(_gen_unique_name(state, p_multi_mesh_instance->get_name())); + gltf_node->children.push_back(state->nodes.size()); + state->nodes.push_back(new_gltf_node); } } @@ -6106,8 +6126,8 @@ void GLTFDocument::_process_mesh_instances(Ref state, Node *scene_roo Map::Element *mi_element = state->scene_nodes.find(node_i); ERR_CONTINUE_MSG(mi_element == nullptr, vformat("Unable to find node %d", node_i)); - EditorSceneImporterMeshNode3D *mi = Object::cast_to(mi_element->get()); - ERR_CONTINUE_MSG(mi == nullptr, vformat("Unable to cast node %d of type %s to EditorSceneImporterMeshNode3D", node_i, mi_element->get()->get_class_name())); + ImporterMeshInstance3D *mi = Object::cast_to(mi_element->get()); + ERR_CONTINUE_MSG(mi == nullptr, vformat("Unable to cast node %d of type %s to ImporterMeshInstance3D", node_i, mi_element->get()->get_class_name())); const GLTFSkeletonIndex skel_i = state->skins.write[node->skin]->skeleton; Ref gltf_skeleton = state->skeletons.write[skel_i]; @@ -6748,10 +6768,25 @@ Error GLTFDocument::save_scene(Node *p_node, const String &p_path, Ref gltf_document; gltf_document.instantiate(); + for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { + Ref ext = document_extensions[ext_i]; + ERR_CONTINUE(ext.is_null()); + Error err = ext->export_preflight(this, p_node); + ERR_FAIL_COND_V(err != OK, err); + } + if (r_state == Ref()) { r_state.instantiate(); } - return gltf_document->serialize(r_state, p_node, p_path); + Error err = gltf_document->serialize(r_state, p_node, p_path); + 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]; + ERR_CONTINUE(ext.is_null()); + err = ext->export_post(this); + ERR_FAIL_COND_V(err != OK, err); + } + return OK; } Node *GLTFDocument::import_scene_gltf(const String &p_path, uint32_t p_flags, int32_t p_bake_fps, Ref r_state, List *r_missing_deps, Error *r_err) { @@ -6764,6 +6799,15 @@ Node *GLTFDocument::import_scene_gltf(const String &p_path, uint32_t p_flags, in Ref gltf_document; gltf_document.instantiate(); + for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { + Ref ext = document_extensions[ext_i]; + ERR_CONTINUE(ext.is_null()); + Error err = ext->import_preflight(this); + if (r_err) { + *r_err = err; + } + ERR_FAIL_COND_V(err != OK, nullptr); + } Error err = gltf_document->parse(r_state, p_path); if (r_err) { *r_err = err; @@ -6783,7 +6827,15 @@ Node *GLTFDocument::import_scene_gltf(const String &p_path, uint32_t p_flags, in gltf_document->_import_animation(r_state, ap, i, p_bake_fps); } } - + for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { + Ref ext = document_extensions[ext_i]; + ERR_CONTINUE(ext.is_null()); + err = ext->import_post(this, root); + if (r_err) { + *r_err = err; + } + ERR_FAIL_COND_V(err != OK, nullptr); + } return root; } @@ -6792,6 +6844,14 @@ void GLTFDocument::_bind_methods() { &GLTFDocument::save_scene, DEFVAL(0), DEFVAL(30), DEFVAL(Ref())); ClassDB::bind_method(D_METHOD("import_scene", "path", "flags", "bake_fps", "state"), &GLTFDocument::import_scene, DEFVAL(0), DEFVAL(30), DEFVAL(Ref())); + 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"); } void GLTFDocument::_build_parent_hierachy(Ref state) { @@ -6817,3 +6877,20 @@ Node *GLTFDocument::import_scene(const String &p_path, uint32_t p_flags, int32_t } return node; } + +void GLTFDocument::set_extensions(TypedArray p_extensions) { + document_extensions = p_extensions; +} + +TypedArray GLTFDocument::get_extensions() const { + return document_extensions; +} + +GLTFDocument::GLTFDocument() { + if (!::Engine::get_singleton()->is_editor_hint()) { + return; + } + Ref extension_editor; + extension_editor.instantiate(); + document_extensions.push_back(extension_editor); +} diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 18aeb81bc0..7317c6a9a3 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -33,8 +33,11 @@ #include "gltf_animation.h" -#include "editor/import/scene_importer_mesh_node_3d.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" @@ -54,6 +57,7 @@ class GLTFSkeleton; class CSGShape3D; class GridMap; class MultiMeshInstance3D; +class GLTFDocumentExtension; using GLTFAccessorIndex = int; using GLTFAnimationIndex = int; @@ -74,11 +78,13 @@ class GLTFDocument : public Resource { friend class GLTFState; friend class GLTFSkin; friend class GLTFSkeleton; + TypedArray document_extensions; private: const float BAKE_FPS = 30.0f; public: + GLTFDocument(); const int32_t JOINT_GROUP_SIZE = 4; enum GLTFType { TYPE_SCALAR, @@ -118,6 +124,8 @@ public: Error save_scene(Node *p_node, const String &p_path, const String &p_src_path, uint32_t p_flags, float p_bake_fps, Ref r_state); + void set_extensions(TypedArray p_extensions); + TypedArray get_extensions() const; private: template @@ -280,12 +288,10 @@ private: Skeleton3D *skeleton, const GLTFNodeIndex node_index, const GLTFNodeIndex bone_index); - EditorSceneImporterMeshNode3D *_generate_mesh_instance(Ref state, Node *scene_parent, const GLTFNodeIndex node_index); - Camera3D *_generate_camera(Ref state, Node *scene_parent, - const GLTFNodeIndex node_index); - Node3D *_generate_light(Ref state, Node *scene_parent, const GLTFNodeIndex node_index); - Node3D *_generate_spatial(Ref state, Node *scene_parent, - const GLTFNodeIndex node_index); + ImporterMeshInstance3D *_generate_mesh_instance(Ref state, Node *parent_node, const GLTFNodeIndex node_index); + Camera3D *_generate_camera(Ref state, Node *parent_node, const GLTFNodeIndex node_index); + Node3D *_generate_light(Ref state, Node *parent_node, const GLTFNodeIndex node_index); + Node3D *_generate_spatial(Ref state, Node *parent_node, const GLTFNodeIndex node_index); void _assign_scene_names(Ref state); template T _interpolate_track(const Vector &p_times, const Vector &p_values, @@ -420,8 +426,8 @@ public: GLTFNodeIndex p_root_node_index, Ref gltf_node, Ref state); #endif // MODULE_GRIDMAP_ENABLED - void _convert_mult_mesh_instance_to_gltf( - MultiMeshInstance3D *p_scene_parent, + void _convert_multi_mesh_instance_to_gltf( + MultiMeshInstance3D *p_multi_mesh_instance, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_node_index, Ref gltf_node, Ref state); diff --git a/modules/gltf/gltf_document_extension.cpp b/modules/gltf/gltf_document_extension.cpp new file mode 100644 index 0000000000..a423059a9c --- /dev/null +++ b/modules/gltf/gltf_document_extension.cpp @@ -0,0 +1,88 @@ +/*************************************************************************/ +/* gltf_document_extension.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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" + +#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); +} + +Array GLTFDocumentExtension::get_import_setting_keys() const { + return import_settings.keys(); +} + +Variant GLTFDocumentExtension::get_import_setting(const StringName &p_key) const { + if (!import_settings.has(p_key)) { + return Variant(); + } + return import_settings[p_key]; +} + +void GLTFDocumentExtension::set_import_setting(const StringName &p_key, Variant p_var) { + import_settings[p_key] = p_var; +} + +Array GLTFDocumentExtension::get_export_setting_keys() const { + return import_settings.keys(); +} + +Variant GLTFDocumentExtension::get_export_setting(const StringName &p_key) const { + if (!import_settings.has(p_key)) { + return Variant(); + } + return import_settings[p_key]; +} + +void GLTFDocumentExtension::set_export_setting(const StringName &p_key, Variant p_var) { + import_settings[p_key] = p_var; +} diff --git a/modules/gltf/gltf_document_extension.h b/modules/gltf/gltf_document_extension.h new file mode 100644 index 0000000000..622a65708c --- /dev/null +++ b/modules/gltf/gltf_document_extension.h @@ -0,0 +1,63 @@ +/*************************************************************************/ +/* gltf_document_extension.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 "core/io/resource.h" +#include "core/variant/dictionary.h" +#include "core/variant/typed_array.h" +#include "core/variant/variant.h" +class GLTFDocument; +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 p_document) { return OK; } + virtual Error import_post(Ref 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 p_document, Node *p_node) { return OK; } + virtual Error export_post(Ref p_document) { return OK; } +}; + +#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 new file mode 100644 index 0000000000..78a98dfa3e --- /dev/null +++ b/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* gltf_document_extension_convert_importer_mesh.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 "scene/3d/mesh_instance_3d.h" +#include "scene/resources/importer_mesh.h" + +#include + +void GLTFDocumentExtensionConvertImporterMesh::_bind_methods() { +} + +Error GLTFDocumentExtensionConvertImporterMesh::import_post(Ref p_document, Node *p_node) { + List queue; + queue.push_back(p_node); + 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 new file mode 100644 index 0000000000..85ddb4d250 --- /dev/null +++ b/modules/gltf/gltf_document_extension_convert_importer_mesh.h @@ -0,0 +1,55 @@ +/*************************************************************************/ +/* gltf_document_extension_convert_importer_mesh.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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_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; +class GLTFDocument; +class GLTFDocumentExtensionConvertImporterMesh : public GLTFDocumentExtension { + GDCLASS(GLTFDocumentExtensionConvertImporterMesh, GLTFDocumentExtension); + +protected: + static void _bind_methods(); + +public: + Error import_post(Ref p_document, Node *p_node) override; +}; +#endif // GLTF_EXTENSION_EDITOR_H diff --git a/modules/gltf/gltf_mesh.cpp b/modules/gltf/gltf_mesh.cpp index 8c10e42c89..747820521a 100644 --- a/modules/gltf/gltf_mesh.cpp +++ b/modules/gltf/gltf_mesh.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "gltf_mesh.h" -#include "editor/import/scene_importer_mesh.h" +#include "scene/resources/importer_mesh.h" void GLTFMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_mesh"), &GLTFMesh::get_mesh); @@ -41,11 +41,11 @@ void GLTFMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "blend_weights"), "set_blend_weights", "get_blend_weights"); // Vector } -Ref GLTFMesh::get_mesh() { +Ref GLTFMesh::get_mesh() { return mesh; } -void GLTFMesh::set_mesh(Ref p_mesh) { +void GLTFMesh::set_mesh(Ref p_mesh) { mesh = p_mesh; } diff --git a/modules/gltf/gltf_mesh.h b/modules/gltf/gltf_mesh.h index 0fc750fc9f..3aba0ede32 100644 --- a/modules/gltf/gltf_mesh.h +++ b/modules/gltf/gltf_mesh.h @@ -33,22 +33,23 @@ #include "core/io/resource.h" #include "editor/import/resource_importer_scene.h" -#include "editor/import/scene_importer_mesh.h" +#include "scene/3d/importer_mesh_instance_3d.h" +#include "scene/resources/importer_mesh.h" #include "scene/resources/mesh.h" class GLTFMesh : public Resource { GDCLASS(GLTFMesh, Resource); private: - Ref mesh; + Ref mesh; Vector blend_weights; protected: static void _bind_methods(); public: - Ref get_mesh(); - void set_mesh(Ref p_mesh); + Ref get_mesh(); + void set_mesh(Ref p_mesh); Vector get_blend_weights(); void set_blend_weights(Vector p_blend_weights); }; diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index d6614da804..61faba0dc5 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -36,6 +36,7 @@ #include "gltf_buffer_view.h" #include "gltf_camera.h" #include "gltf_document.h" +#include "gltf_document_extension.h" #include "gltf_light.h" #include "gltf_mesh.h" #include "gltf_node.h" diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index d6020f50f0..0aceb838f7 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -38,6 +38,8 @@ #include "gltf_buffer_view.h" #include "gltf_camera.h" #include "gltf_document.h" +#include "gltf_document_extension.h" +#include "gltf_document_extension_convert_importer_mesh.h" #include "gltf_light.h" #include "gltf_mesh.h" #include "gltf_node.h" @@ -79,6 +81,8 @@ void register_gltf_types() { GDREGISTER_CLASS(GLTFCamera); GDREGISTER_CLASS(GLTFLight); GDREGISTER_CLASS(GLTFState); + GDREGISTER_CLASS(GLTFDocumentExtensionConvertImporterMesh); + GDREGISTER_CLASS(GLTFDocumentExtension); GDREGISTER_CLASS(GLTFDocument); #endif } -- cgit v1.2.3