diff options
Diffstat (limited to 'modules/gltf')
37 files changed, 525 insertions, 429 deletions
diff --git a/modules/gltf/doc_classes/GLTFDocument.xml b/modules/gltf/doc_classes/GLTFDocument.xml index 8d8e25e8b3..ed7c018cb9 100644 --- a/modules/gltf/doc_classes/GLTFDocument.xml +++ b/modules/gltf/doc_classes/GLTFDocument.xml @@ -3,30 +3,57 @@ <brief_description> </brief_description> <description> + Append a glTF2 3d format from a file, buffer or scene and then write to the filesystem, buffer or scene. </description> <tutorials> </tutorials> <methods> - <method name="import_scene"> - <return type="Node" /> + <method name="append_from_buffer"> + <return type="int" enum="Error" /> + <argument index="0" name="bytes" type="PackedByteArray" /> + <argument index="1" name="base_path" type="String" /> + <argument index="2" name="state" type="GLTFState" /> + <argument index="3" name="flags" type="int" default="0" /> + <argument index="4" name="bake_fps" type="int" default="30" /> + <description> + </description> + </method> + <method name="append_from_file"> + <return type="int" enum="Error" /> <argument index="0" name="path" type="String" /> - <argument index="1" name="flags" type="int" default="0" /> - <argument index="2" name="bake_fps" type="int" default="30" /> - <argument index="3" name="state" type="GLTFState" default="null" /> + <argument index="1" name="state" type="GLTFState" /> + <argument index="2" name="flags" type="int" default="0" /> + <argument index="3" name="bake_fps" type="int" default="30" /> <description> - Import a scene from glTF2 ".gltf" or ".glb" file. </description> </method> - <method name="save_scene"> + <method name="append_from_scene"> <return type="int" enum="Error" /> <argument index="0" name="node" type="Node" /> + <argument index="1" name="state" type="GLTFState" /> + <argument index="2" name="flags" type="int" default="0" /> + <argument index="3" name="bake_fps" type="int" default="30" /> + <description> + </description> + </method> + <method name="generate_buffer"> + <return type="PackedByteArray" /> + <argument index="0" name="state" type="GLTFState" /> + <description> + </description> + </method> + <method name="generate_scene"> + <return type="Node" /> + <argument index="0" name="state" type="GLTFState" /> + <argument index="1" name="bake_fps" type="int" default="30" /> + <description> + </description> + </method> + <method name="write_to_filesystem"> + <return type="int" enum="Error" /> + <argument index="0" name="state" type="GLTFState" /> <argument index="1" name="path" type="String" /> - <argument index="2" name="src_path" type="String" /> - <argument index="3" name="flags" type="int" default="0" /> - <argument index="4" name="bake_fps" type="float" default="30" /> - <argument index="5" name="state" type="GLTFState" default="null" /> <description> - Save a scene as a glTF2 ".glb" or ".gltf" file. </description> </method> </methods> diff --git a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp index 25fda7ef3b..fd5741605c 100644 --- a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp +++ b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -36,6 +36,7 @@ #include "core/templates/vector.h" #include "editor/editor_file_system.h" #include "gltf_document.h" +#include "gltf_state.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/gui/check_box.h" #include "scene/main/node.h" @@ -75,7 +76,15 @@ void SceneExporterGLTFPlugin::_gltf2_dialog_action(String p_file) { List<String> deps; Ref<GLTFDocument> doc; doc.instantiate(); - Error err = doc->save_scene(root, p_file, p_file, 0, 30.0f, Ref<GLTFState>()); + Ref<GLTFState> state; + state.instantiate(); + int32_t flags = 0; + flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; + Error err = doc->append_from_scene(root, state, flags, 30.0f); + if (err != OK) { + ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err))); + } + err = doc->write_to_filesystem(state, p_file); if (err != OK) { ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err))); } diff --git a/modules/gltf/editor_scene_exporter_gltf_plugin.h b/modules/gltf/editor_scene_exporter_gltf_plugin.h index 89a8e27053..e6b15e73c4 100644 --- a/modules/gltf/editor_scene_exporter_gltf_plugin.h +++ b/modules/gltf/editor_scene_exporter_gltf_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/editor_scene_importer_gltf.cpp b/modules/gltf/editor_scene_importer_gltf.cpp index 1a172877a0..f063cc1e2b 100644 --- a/modules/gltf/editor_scene_importer_gltf.cpp +++ b/modules/gltf/editor_scene_importer_gltf.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -48,16 +48,24 @@ void EditorSceneFormatImporterGLTF::get_extensions(List<String> *r_extensions) c } Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, - uint32_t p_flags, int p_bake_fps, + uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { Ref<GLTFDocument> doc; doc.instantiate(); - return doc->import_scene_gltf(p_path, p_flags, p_bake_fps, Ref<GLTFState>(), r_missing_deps, r_err); + Ref<GLTFState> state; + state.instantiate(); + Error err = doc->append_from_file(p_path, state, p_flags, p_bake_fps); + if (err != OK) { + *r_err = err; + return nullptr; + } + Node *root = doc->generate_scene(state, p_bake_fps); + return root; } Ref<Animation> EditorSceneFormatImporterGLTF::import_animation(const String &p_path, - uint32_t p_flags, + uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) { return Ref<Animation>(); } diff --git a/modules/gltf/editor_scene_importer_gltf.h b/modules/gltf/editor_scene_importer_gltf.h index 28963adc28..4410559b3d 100644 --- a/modules/gltf/editor_scene_importer_gltf.h +++ b/modules/gltf/editor_scene_importer_gltf.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -47,9 +47,9 @@ class EditorSceneFormatImporterGLTF : public EditorSceneFormatImporter { public: virtual uint32_t get_import_flags() const override; virtual void get_extensions(List<String> *r_extensions) const override; - virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; + virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; virtual Ref<Animation> import_animation(const String &p_path, - uint32_t p_flags, int p_bake_fps) override; + uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) override; }; #endif // TOOLS_ENABLED #endif // EDITOR_SCENE_IMPORTER_GLTF_H diff --git a/modules/gltf/gltf_accessor.cpp b/modules/gltf/gltf_accessor.cpp index 85cec3fec4..1daf2f90a7 100644 --- a/modules/gltf/gltf_accessor.cpp +++ b/modules/gltf/gltf_accessor.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_accessor.h b/modules/gltf/gltf_accessor.h index bec511f974..6bf1bf543a 100644 --- a/modules/gltf/gltf_accessor.h +++ b/modules/gltf/gltf_accessor.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_animation.cpp b/modules/gltf/gltf_animation.cpp index 889a8e8870..c857be4b2c 100644 --- a/modules/gltf/gltf_animation.cpp +++ b/modules/gltf/gltf_animation.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_animation.h b/modules/gltf/gltf_animation.h index be0ed2d4c6..ba8ae8a273 100644 --- a/modules/gltf/gltf_animation.h +++ b/modules/gltf/gltf_animation.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -50,7 +50,7 @@ public: template <class T> struct Channel { Interpolation interpolation; - Vector<float> times; + Vector<real_t> times; Vector<T> values; }; @@ -58,7 +58,7 @@ public: Channel<Vector3> position_track; Channel<Quaternion> rotation_track; Channel<Vector3> scale_track; - Vector<Channel<float>> weight_tracks; + Vector<Channel<real_t>> weight_tracks; }; public: diff --git a/modules/gltf/gltf_buffer_view.cpp b/modules/gltf/gltf_buffer_view.cpp index d00e0f040f..fc467367c6 100644 --- a/modules/gltf/gltf_buffer_view.cpp +++ b/modules/gltf/gltf_buffer_view.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_buffer_view.h b/modules/gltf/gltf_buffer_view.h index 63af5e7c0d..560d56f35c 100644 --- a/modules/gltf/gltf_buffer_view.h +++ b/modules/gltf/gltf_buffer_view.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_camera.cpp b/modules/gltf/gltf_camera.cpp index 0f895fb989..f3ea6a1c4c 100644 --- a/modules/gltf/gltf_camera.cpp +++ b/modules/gltf/gltf_camera.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_camera.h b/modules/gltf/gltf_camera.h index 843ff417a4..c696d4cc6b 100644 --- a/modules/gltf/gltf_camera.h +++ b/modules/gltf/gltf_camera.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 0b2854e731..5a931ed839 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -48,6 +48,7 @@ #include "core/error/error_macros.h" #include "core/io/dir_access.h" #include "core/io/file_access.h" +#include "core/io/file_access_memory.h" #include "core/io/json.h" #include "core/math/disjoint_set.h" #include "core/math/vector2.h" @@ -62,13 +63,14 @@ #include "scene/3d/camera_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/multimesh_instance_3d.h" +#include "scene/3d/node_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" +#include "modules/modules_enabled.gen.h" // For csg, gridmap. #ifdef MODULE_CSG_ENABLED #include "modules/csg/csg_shape.h" @@ -82,13 +84,7 @@ #include <cstdint> #include <limits> -Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &p_path) { - uint64_t begin_time = OS::get_singleton()->get_ticks_usec(); - - state->skeleton3d_to_gltf_skeleton.clear(); - state->skin_and_skeleton3d_to_gltf_skin.clear(); - - _convert_scene_node(state, p_root, -1, -1); +Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) { if (!state->buffers.size()) { state->buffers.push_back(Vector<uint8_t>()); } @@ -184,16 +180,6 @@ Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String & return Error::FAILED; } - /* STEP 17 SERIALIZE FILE */ - err = _serialize_file(state, p_path); - if (err != OK) { - return Error::FAILED; - } - uint64_t elapsed = OS::get_singleton()->get_ticks_usec() - begin_time; - float elapsed_sec = double(elapsed) / 1000000.0; - elapsed_sec = Math::snapped(elapsed_sec, 0.01f); - print_line("glTF: Export time elapsed seconds " + rtos(elapsed_sec).pad_decimals(2)); - return OK; } @@ -255,18 +241,14 @@ Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> state) { return OK; } -Error GLTFDocument::_parse_glb(const String &p_path, Ref<GLTFState> state) { - Error err; - FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err); - if (!f) { - return err; - } - +Error GLTFDocument::_parse_glb(FileAccess *f, Ref<GLTFState> state) { + ERR_FAIL_NULL_V(f, ERR_INVALID_PARAMETER); + ERR_FAIL_NULL_V(state, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(f->get_position() != 0, ERR_FILE_CANT_READ); uint32_t magic = f->get_32(); ERR_FAIL_COND_V(magic != 0x46546C67, ERR_FILE_UNRECOGNIZED); //glTF f->get_32(); // version f->get_32(); // length - uint32_t chunk_length = f->get_32(); uint32_t chunk_type = f->get_32(); @@ -280,9 +262,9 @@ Error GLTFDocument::_parse_glb(const String &p_path, Ref<GLTFState> state) { text.parse_utf8((const char *)json_data.ptr(), json_data.size()); JSON json; - err = json.parse(text); + Error err = json.parse(text); if (err != OK) { - _err_print_error("", p_path.utf8().get_data(), json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); + _err_print_error("", "", json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); return err; } @@ -753,6 +735,8 @@ Error GLTFDocument::_parse_buffers(Ref<GLTFState> state, const String &p_base_pa } buffer_data = _parse_base64_uri(uri); } else { // Relative path to an external image file. + ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER); + uri = uri.uri_decode(); uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows. buffer_data = FileAccess::get_file_as_array(uri); ERR_FAIL_COND_V_MSG(buffer.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load binary file as an array: " + uri); @@ -2539,14 +2523,16 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) { if (p.has("mode")) { const int mode = p["mode"]; ERR_FAIL_INDEX_V(mode, 7, ERR_FILE_CORRUPT); + // Convert mesh.primitive.mode to Godot Mesh enum. See: + // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode static const Mesh::PrimitiveType primitives2[7] = { - Mesh::PRIMITIVE_POINTS, - Mesh::PRIMITIVE_LINES, - Mesh::PRIMITIVE_LINES, //loop not supported, should ce converted - Mesh::PRIMITIVE_LINES, - Mesh::PRIMITIVE_TRIANGLES, - Mesh::PRIMITIVE_TRIANGLE_STRIP, - Mesh::PRIMITIVE_TRIANGLES, //fan not supported, should be converted + Mesh::PRIMITIVE_POINTS, // 0 POINTS + Mesh::PRIMITIVE_LINES, // 1 LINES + Mesh::PRIMITIVE_LINES, // 2 LINE_LOOP; loop not supported, should be converted + Mesh::PRIMITIVE_LINE_STRIP, // 3 LINE_STRIP + Mesh::PRIMITIVE_TRIANGLES, // 4 TRIANGLES + Mesh::PRIMITIVE_TRIANGLE_STRIP, // 5 TRIANGLE_STRIP + Mesh::PRIMITIVE_TRIANGLES, // 6 TRIANGLE_FAN fan not supported, should be converted #ifndef _MSC_VER #warning line loop and triangle fan are not supported and need to be converted to lines and triangles #endif @@ -2952,7 +2938,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path Ref<Image> image = state->images[i]->get_image(); ERR_CONTINUE(image.is_null()); - if (p_path.to_lower().ends_with("glb")) { + if (p_path.to_lower().ends_with("glb") || p_path.is_empty()) { GLTFBufferViewIndex bvi; Ref<GLTFBufferView> bv; @@ -2981,6 +2967,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path d["bufferView"] = bvi; d["mimeType"] = "image/png"; } else { + ERR_FAIL_COND_V(p_path.is_empty(), ERR_INVALID_PARAMETER); String name = state->images[i]->get_name(); if (name.is_empty()) { name = itos(i); @@ -2988,13 +2975,14 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path name = _gen_unique_name(state, name); name = name.pad_zeros(3) + ".png"; String texture_dir = "textures"; - String new_texture_dir = p_path.get_base_dir() + "/" + texture_dir; - DirAccessRef da = DirAccess::open(p_path.get_base_dir()); + String path = p_path.get_base_dir(); + String new_texture_dir = path + "/" + texture_dir; + DirAccessRef da = DirAccess::open(path); if (!da->dir_exists(new_texture_dir)) { da->make_dir(new_texture_dir); } image->save_png(new_texture_dir.plus_file(name)); - d["uri"] = texture_dir.plus_file(name); + d["uri"] = texture_dir.plus_file(name).uri_encode(); } images.push_back(d); } @@ -3010,6 +2998,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path } Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_path) { + ERR_FAIL_NULL_V(state, ERR_INVALID_PARAMETER); if (!state->json.has("images")) { return OK; } @@ -3069,6 +3058,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat } } } else { // Relative path to an external image file. + ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER); uri = uri.uri_decode(); uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows. // ResourceLoader will rely on the file extension to use the relevant loader. @@ -3402,29 +3392,32 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { tex.instantiate(); { Ref<Texture2D> normal_texture = material->get_texture(BaseMaterial3D::TEXTURE_NORMAL); - // Code for uncompressing RG normal maps - Ref<Image> img = normal_texture->get_image(); - Ref<ImageTexture> img_tex = img; - if (img_tex.is_valid()) { - img = img_tex->get_image(); - } - img->decompress(); - img->convert(Image::FORMAT_RGBA8); - img->convert_ra_rgba8_to_rg(); - for (int32_t y = 0; y < img->get_height(); y++) { - for (int32_t x = 0; x < img->get_width(); x++) { - Color c = img->get_pixel(x, y); - Vector2 red_green = Vector2(c.r, c.g); - red_green = red_green * Vector2(2.0f, 2.0f) - Vector2(1.0f, 1.0f); - float blue = 1.0f - red_green.dot(red_green); - blue = MAX(0.0f, blue); - c.b = Math::sqrt(blue); - img->set_pixel(x, y, c); + if (normal_texture.is_valid()) { + // Code for uncompressing RG normal maps + Ref<Image> img = normal_texture->get_image(); + if (img.is_valid()) { + Ref<ImageTexture> img_tex = img; + if (img_tex.is_valid()) { + img = img_tex->get_image(); + } + img->decompress(); + img->convert(Image::FORMAT_RGBA8); + img->convert_ra_rgba8_to_rg(); + for (int32_t y = 0; y < img->get_height(); y++) { + for (int32_t x = 0; x < img->get_width(); x++) { + Color c = img->get_pixel(x, y); + Vector2 red_green = Vector2(c.r, c.g); + red_green = red_green * Vector2(2.0f, 2.0f) - Vector2(1.0f, 1.0f); + float blue = 1.0f - red_green.dot(red_green); + blue = MAX(0.0f, blue); + c.b = Math::sqrt(blue); + img->set_pixel(x, y, c); + } + } + tex->create_from_image(img); } } - tex->create_from_image(img); } - Ref<Texture2D> normal_texture = material->get_texture(BaseMaterial3D::TEXTURE_NORMAL); GLTFTextureIndex gltf_texture_index = -1; if (tex.is_valid() && tex->get_image().is_valid()) { tex->set_name(material->get_name() + "_normal"); @@ -4606,7 +4599,7 @@ Error GLTFDocument::_parse_lights(Ref<GLTFState> state) { light->outer_cone_angle = spot["outerConeAngle"]; ERR_CONTINUE_MSG(light->inner_cone_angle >= light->outer_cone_angle, "The inner angle must be smaller than the outer angle."); } else if (type != "point" && type != "directional") { - ERR_CONTINUE_MSG(ERR_PARSE_ERROR, "Light type is unknown."); + ERR_CONTINUE_MSG(true, "Light type is unknown."); } state->lights.push_back(light); @@ -4804,7 +4797,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { bool last = false; Vector<real_t> weight_track; while (true) { - float weight = _interpolate_track<float>(track.weight_tracks[track_idx].times, + float weight = _interpolate_track<real_t>(track.weight_tracks[track_idx].times, track.weight_tracks[track_idx].values, time, track.weight_tracks[track_idx].interpolation); @@ -4828,7 +4821,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { int32_t weight_tracks_size = track.weight_tracks.size(); all_track_values.resize(weight_tracks_size * values_size); for (int k = 0; k < track.weight_tracks.size(); k++) { - Vector<float> wdata = track.weight_tracks[k].values; + Vector<real_t> wdata = track.weight_tracks[k].values; for (int l = 0; l < wdata.size(); l++) { int32_t index = l * weight_tracks_size + k; ERR_BREAK(index >= all_track_values.size()); @@ -4979,10 +4972,10 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) { const int wlen = weights.size() / wc; for (int k = 0; k < wc; k++) { //separate tracks, having them together is not such a good idea - GLTFAnimation::Channel<float> cf; + GLTFAnimation::Channel<real_t> cf; cf.interpolation = interp; cf.times = Variant(times); - Vector<float> wdata; + Vector<real_t> wdata; wdata.resize(wlen); for (int l = 0; l < wlen; l++) { wdata.write[l] = weights[l * wc + k]; @@ -5099,7 +5092,7 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> state, MeshInst return mesh_i; } -ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index) { +ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> state, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; ERR_FAIL_INDEX_V(gltf_node->mesh, state->meshes.size(), nullptr); @@ -5119,7 +5112,7 @@ ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> sta return mi; } -Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) { +Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; ERR_FAIL_INDEX_V(gltf_node->light, state->lights.size(), nullptr); @@ -5171,7 +5164,7 @@ Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, Node *scene_parent, return memnew(Node3D); } -Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) { +Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> state, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; ERR_FAIL_INDEX_V(gltf_node->camera, state->cameras.size(), nullptr); @@ -5249,7 +5242,7 @@ void GLTFDocument::_convert_spatial(Ref<GLTFState> state, Node3D *p_spatial, Ref p_node->position = xform.origin; } -Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) { +Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> state, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; Node3D *spatial = memnew(Node3D); @@ -5616,19 +5609,18 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent scene_parent = bone_attachment; } if (gltf_node->mesh >= 0) { - current_node = _generate_mesh_instance(state, scene_parent, node_index); + current_node = _generate_mesh_instance(state, node_index); } else if (gltf_node->camera >= 0) { - current_node = _generate_camera(state, scene_parent, node_index); + current_node = _generate_camera(state, node_index); } else if (gltf_node->light >= 0) { - current_node = _generate_light(state, scene_parent, node_index); + current_node = _generate_light(state, node_index); } // We still have not managed to make a node. if (!current_node) { - current_node = _generate_spatial(state, scene_parent, node_index); + current_node = _generate_spatial(state, node_index); } - - scene_parent->add_child(current_node, true); + scene_parent->add_child(current_node); if (current_node != scene_root) { current_node->set_owner(scene_root); } @@ -5699,11 +5691,11 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> state, Node *scen // We still have not managed to make a node if (gltf_node->mesh >= 0) { - current_node = _generate_mesh_instance(state, scene_parent, node_index); + current_node = _generate_mesh_instance(state, node_index); } else if (gltf_node->camera >= 0) { - current_node = _generate_camera(state, scene_parent, node_index); + current_node = _generate_camera(state, node_index); } else if (gltf_node->light >= 0) { - current_node = _generate_light(state, scene_parent, node_index); + current_node = _generate_light(state, node_index); } scene_parent->add_child(current_node, true); @@ -5772,7 +5764,7 @@ struct EditorSceneFormatImporterGLTFInterpolate<Quaternion> { }; template <class T> -T GLTFDocument::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) { +T GLTFDocument::_interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) { ERR_FAIL_COND_V(!p_values.size(), T()); if (p_times.size() != (p_values.size() / (p_interp == GLTFAnimation::INTERP_CUBIC_SPLINE ? 3 : 1))) { ERR_PRINT_ONCE("The interpolated values are not corresponding to its times."); @@ -6052,7 +6044,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, double time = 0.0; bool last = false; while (true) { - float blend = _interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp); + real_t blend = _interpolate_track<real_t>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp); animation->blend_shape_track_insert_key(track_idx, time, blend); if (last) { break; @@ -6084,7 +6076,9 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { continue; } MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(mi_element->get()); - ERR_CONTINUE(!mi); + if (!mi) { + continue; + } Transform3D mi_xform = mi->get_transform(); node->scale = mi_xform.basis.get_scale(); node->rotation = mi_xform.basis.get_rotation_quaternion(); @@ -6115,7 +6109,10 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { int bone_cnt = skeleton->get_bone_count(); ERR_FAIL_COND(bone_cnt != gltf_skeleton->joints.size()); - ObjectID gltf_skin_key = skin->get_instance_id(); + ObjectID gltf_skin_key; + if (skin.is_valid()) { + gltf_skin_key = skin->get_instance_id(); + } ObjectID gltf_skel_key = godot_skeleton->get_instance_id(); GLTFSkinIndex skin_gltf_i = -1; GLTFNodeIndex root_gltf_i = -1; @@ -6243,7 +6240,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state } Animation::TrackType track_type = p_animation->track_get_type(p_track_i); int32_t key_count = p_animation->track_get_key_count(p_track_i); - Vector<float> times; + Vector<real_t> times; times.resize(key_count); String path = p_animation->track_get_path(p_track_i); for (int32_t key_i = 0; key_i < key_count; key_i++) { @@ -6279,39 +6276,8 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state ERR_CONTINUE(err != OK); p_track.rotation_track.values.write[key_i] = rotation; } - } else if (path.find(":transform") != -1) { - p_track.position_track.times = times; - p_track.position_track.interpolation = gltf_interpolation; - p_track.rotation_track.times = times; - p_track.rotation_track.interpolation = gltf_interpolation; - p_track.scale_track.times = times; - p_track.scale_track.interpolation = gltf_interpolation; - - p_track.scale_track.values.resize(key_count); - p_track.scale_track.interpolation = gltf_interpolation; - p_track.position_track.values.resize(key_count); - p_track.position_track.interpolation = gltf_interpolation; - p_track.rotation_track.values.resize(key_count); - p_track.rotation_track.interpolation = gltf_interpolation; - for (int32_t key_i = 0; key_i < key_count; key_i++) { - Transform3D xform = p_animation->track_get_key_value(p_track_i, key_i); - p_track.position_track.values.write[key_i] = xform.get_origin(); - p_track.rotation_track.values.write[key_i] = xform.basis.get_rotation_quaternion(); - p_track.scale_track.values.write[key_i] = xform.basis.get_scale(); - } } else if (track_type == Animation::TYPE_VALUE) { - if (path.find("/rotation_quat") != -1) { - p_track.rotation_track.times = times; - p_track.rotation_track.interpolation = gltf_interpolation; - - p_track.rotation_track.values.resize(key_count); - p_track.rotation_track.interpolation = gltf_interpolation; - - for (int32_t key_i = 0; key_i < key_count; key_i++) { - Quaternion rotation_track = p_animation->track_get_key_value(p_track_i, key_i); - p_track.rotation_track.values.write[key_i] = rotation_track; - } - } else if (path.find(":position") != -1) { + if (path.find(":position") != -1) { p_track.position_track.times = times; p_track.position_track.interpolation = gltf_interpolation; @@ -6349,7 +6315,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state if (path.find("/scale") != -1) { const int32_t keys = p_animation->track_get_key_time(p_track_i, key_count - 1) * BAKE_FPS; if (!p_track.scale_track.times.size()) { - Vector<float> new_times; + Vector<real_t> new_times; new_times.resize(keys); for (int32_t key_i = 0; key_i < keys; key_i++) { new_times.write[key_i] = key_i / BAKE_FPS; @@ -6379,7 +6345,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state } else if (path.find("/position") != -1) { const int32_t keys = p_animation->track_get_key_time(p_track_i, key_count - 1) * BAKE_FPS; if (!p_track.position_track.times.size()) { - Vector<float> new_times; + Vector<real_t> new_times; new_times.resize(keys); for (int32_t key_i = 0; key_i < keys; key_i++) { new_times.write[key_i] = key_i / BAKE_FPS; @@ -6500,7 +6466,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, NodePath shape_path = String(path) + ":" + shape_name; int32_t shape_track_i = animation->find_track(shape_path, Animation::TYPE_BLEND_SHAPE); if (shape_track_i == -1) { - GLTFAnimation::Channel<float> weight; + GLTFAnimation::Channel<real_t> weight; weight.interpolation = GLTFAnimation::INTERP_LINEAR; weight.times.push_back(0.0f); weight.times.push_back(0.0f); @@ -6519,7 +6485,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, gltf_interpolation = GLTFAnimation::INTERP_CUBIC_SPLINE; } int32_t key_count = animation->track_get_key_count(shape_track_i); - GLTFAnimation::Channel<float> weight; + GLTFAnimation::Channel<real_t> weight; weight.interpolation = gltf_interpolation; weight.times.resize(key_count); for (int32_t time_i = 0; time_i < key_count; time_i++) { @@ -6586,142 +6552,57 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, } } -Error GLTFDocument::parse(Ref<GLTFState> state, String p_path, bool p_read_binary) { +Error GLTFDocument::_parse(Ref<GLTFState> state, String p_path, FileAccess *f, int p_bake_fps) { Error err; - FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err); if (!f) { - return err; + return FAILED; } + f->seek(0); uint32_t magic = f->get_32(); if (magic == 0x46546C67) { //binary file //text file - err = _parse_glb(p_path, state); - if (err) { - return FAILED; + f->seek(0); + err = _parse_glb(f, state); + if (err != OK) { + return err; } } else { - //text file - err = _parse_json(p_path, state); - if (err) { - return FAILED; + f->seek(0); + String text = f->get_as_utf8_string(); + JSON json; + err = json.parse(text); + if (err != OK) { + _err_print_error("", "", json.get_error_line(), json.get_error_message().utf8().get_data(), false, ERR_HANDLER_SCRIPT); } + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + state->json = json.get_data(); } f->close(); - // get file's name, use for scene name if none - state->filename = p_path.get_file().get_slice(".", 0); - - ERR_FAIL_COND_V(!state->json.has("asset"), Error::FAILED); + if (!state->json.has("asset")) { + return ERR_PARSE_ERROR; + } Dictionary asset = state->json["asset"]; - ERR_FAIL_COND_V(!asset.has("version"), Error::FAILED); + if (!asset.has("version")) { + return ERR_PARSE_ERROR; + } String version = asset["version"]; state->major_version = version.get_slice(".", 0).to_int(); state->minor_version = version.get_slice(".", 1).to_int(); - /* STEP 0 PARSE SCENE */ - err = _parse_scenes(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 1 PARSE NODES */ - err = _parse_nodes(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 2 PARSE BUFFERS */ - err = _parse_buffers(state, p_path.get_base_dir()); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 3 PARSE BUFFER VIEWS */ - err = _parse_buffer_views(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 4 PARSE ACCESSORS */ - err = _parse_accessors(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 5 PARSE IMAGES */ - err = _parse_images(state, p_path.get_base_dir()); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 6 PARSE TEXTURES */ - err = _parse_textures(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 7 PARSE TEXTURES */ - err = _parse_materials(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 9 PARSE SKINS */ - err = _parse_skins(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 10 DETERMINE SKELETONS */ - err = _determine_skeletons(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 11 CREATE SKELETONS */ - err = _create_skeletons(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 12 CREATE SKINS */ - err = _create_skins(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 13 PARSE MESHES (we have enough info now) */ - err = _parse_meshes(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 14 PARSE LIGHTS */ - err = _parse_lights(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 15 PARSE CAMERAS */ - err = _parse_cameras(state); - if (err != OK) { - return Error::FAILED; - } - - /* STEP 16 PARSE ANIMATIONS */ - err = _parse_animations(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->import_preflight(this); + ERR_FAIL_COND_V(err != OK, FAILED); } - - /* STEP 17 ASSIGN SCENE NAMES */ - _assign_scene_names(state); - + err = _parse_gltf_state(state, p_path, p_bake_fps); + ERR_FAIL_COND_V(err != OK, err); return OK; } @@ -6840,89 +6721,20 @@ Error GLTFDocument::_serialize_file(Ref<GLTFState> state, const String p_path) { return err; } -Error GLTFDocument::save_scene(Node *p_node, const String &p_path, - const String &p_src_path, uint32_t p_flags, - float p_bake_fps, Ref<GLTFState> r_state) { - ERR_FAIL_NULL_V(p_node, ERR_INVALID_PARAMETER); - - Ref<GLTFDocument> gltf_document; - gltf_document.instantiate(); - 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(this, p_node); - ERR_FAIL_COND_V(err != OK, err); - } - - if (r_state == Ref<GLTFState>()) { - r_state.instantiate(); - } - 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<GLTFDocumentExtension> 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<GLTFState> r_state, List<String> *r_missing_deps, Error *r_err) { - // TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire - if (r_state == Ref<GLTFState>()) { - r_state.instantiate(); - } - r_state->use_named_skin_binds = - p_flags & EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; - - Ref<GLTFDocument> gltf_document; - gltf_document.instantiate(); - 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_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; - } - ERR_FAIL_COND_V(err != Error::OK, nullptr); - - Node3D *root = memnew(Node3D); - for (int32_t root_i = 0; root_i < r_state->root_nodes.size(); root_i++) { - gltf_document->_generate_scene_node(r_state, root, root, r_state->root_nodes[root_i]); - } - gltf_document->_process_mesh_instances(r_state, root); - if (r_state->animations.size()) { - AnimationPlayer *ap = memnew(AnimationPlayer); - root->add_child(ap, true); - ap->set_owner(root); - for (int i = 0; i < r_state->animations.size(); i++) { - 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<GLTFDocumentExtension> 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; -} - void GLTFDocument::_bind_methods() { - ClassDB::bind_method(D_METHOD("save_scene", "node", "path", "src_path", "flags", "bake_fps", "state"), - &GLTFDocument::save_scene, DEFVAL(0), DEFVAL(30), DEFVAL(Ref<GLTFState>())); - ClassDB::bind_method(D_METHOD("import_scene", "path", "flags", "bake_fps", "state"), - &GLTFDocument::import_scene, DEFVAL(0), DEFVAL(30), DEFVAL(Ref<GLTFState>())); + ClassDB::bind_method(D_METHOD("append_from_file", "path", "state", "flags", "bake_fps"), + &GLTFDocument::append_from_file, DEFVAL(0), DEFVAL(30)); + ClassDB::bind_method(D_METHOD("append_from_buffer", "bytes", "base_path", "state", "flags", "bake_fps"), + &GLTFDocument::append_from_buffer, DEFVAL(0), DEFVAL(30)); + ClassDB::bind_method(D_METHOD("append_from_scene", "node", "state", "flags", "bake_fps"), + &GLTFDocument::append_from_scene, DEFVAL(0), DEFVAL(30)); + ClassDB::bind_method(D_METHOD("generate_scene", "state", "bake_fps"), + &GLTFDocument::generate_scene, DEFVAL(30)); + ClassDB::bind_method(D_METHOD("generate_buffer", "state"), + &GLTFDocument::generate_buffer); + 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"), @@ -6947,16 +6759,6 @@ void GLTFDocument::_build_parent_hierachy(Ref<GLTFState> state) { } } -Node *GLTFDocument::import_scene(const String &p_path, uint32_t p_flags, int32_t p_bake_fps, Ref<GLTFState> r_state) { - Error err = FAILED; - List<String> deps; - Node *node = import_scene_gltf(p_path, p_flags, p_bake_fps, r_state, &deps, &err); - if (err != OK) { - return nullptr; - } - return node; -} - void GLTFDocument::set_extensions(TypedArray<GLTFDocumentExtension> p_extensions) { document_extensions = p_extensions; } @@ -6974,3 +6776,243 @@ GLTFDocument::GLTFDocument() { extension_editor.instantiate(); document_extensions.push_back(extension_editor); } + +PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref<GLTFState> state, Error *r_err) { + Error err = _encode_buffer_glb(state, ""); + if (r_err) { + *r_err = err; + } + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + String json = Variant(state->json).to_json_string(); + + const uint32_t magic = 0x46546C67; // GLTF + const int32_t header_size = 12; + const int32_t chunk_header_size = 8; + + for (int32_t pad_i = 0; pad_i < (chunk_header_size + json.utf8().length()) % 4; pad_i++) { + json += " "; + } + CharString cs = json.utf8(); + const uint32_t text_chunk_length = cs.length(); + + const uint32_t text_chunk_type = 0x4E4F534A; //JSON + int32_t binary_data_length = 0; + if (state->buffers.size()) { + binary_data_length = state->buffers[0].size(); + } + const int32_t binary_chunk_length = binary_data_length; + const int32_t binary_chunk_type = 0x004E4942; //BIN + + Ref<StreamPeerBuffer> buffer; + buffer.instantiate(); + buffer->put_32(magic); + buffer->put_32(state->major_version); // version + buffer->put_32(header_size + chunk_header_size + text_chunk_length + chunk_header_size + binary_data_length); // length + buffer->put_32(text_chunk_length); + buffer->put_32(text_chunk_type); + buffer->put_data((uint8_t *)&cs[0], cs.length()); + if (binary_chunk_length) { + buffer->put_32(binary_chunk_length); + buffer->put_32(binary_chunk_type); + buffer->put_data(state->buffers[0].ptr(), binary_data_length); + } + return buffer->get_data_array(); +} + +PackedByteArray GLTFDocument::generate_buffer(Ref<GLTFState> state) { + ERR_FAIL_NULL_V(state, PackedByteArray()); + Error err = _serialize(state, ""); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + PackedByteArray bytes = _serialize_glb_buffer(state, &err); + return bytes; +} + +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; + } + return OK; +} + +Node *GLTFDocument::generate_scene(Ref<GLTFState> state, int32_t p_bake_fps) { + ERR_FAIL_INDEX_V(0, state->root_nodes.size(), nullptr); + 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(); + ERR_FAIL_NULL_V(root, nullptr); + _process_mesh_instances(state, root); + if (state->animations.size()) { + AnimationPlayer *ap = memnew(AnimationPlayer); + root->add_child(ap, true); + ap->set_owner(root); + for (int i = 0; i < state->animations.size(); i++) { + _import_animation(state, ap, i, p_bake_fps); + } + } + + 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_FAIL_NULL_V(root, nullptr); + return root; +} + +Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> state, uint32_t p_flags, int32_t p_bake_fps) { + ERR_FAIL_COND_V(state.is_null(), FAILED); + state->use_named_skin_binds = + p_flags & EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; + + _convert_scene_node(state, p_node, -1, -1); + if (!state->buffers.size()) { + state->buffers.push_back(Vector<uint8_t>()); + } + + /* STEP 1 CONVERT MESH INSTANCES */ + _convert_mesh_instances(state); + + /* STEP 2 CREATE SKINS */ + Error err = _serialize_skins(state); + return err; +} + +Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> state, uint32_t p_flags, int32_t p_bake_fps) { + ERR_FAIL_COND_V(state.is_null(), FAILED); + // TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire + Error err = FAILED; + state->use_named_skin_binds = + p_flags & EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; + FileAccessMemory *file_access = memnew(FileAccessMemory); + 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); + return OK; +} + +Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> state, const String &p_search_path, float p_bake_fps) { + Error err; + + /* PARSE EXTENSIONS */ + err = _parse_gltf_extensions(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE SCENE */ + err = _parse_scenes(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE NODES */ + err = _parse_nodes(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE BUFFERS */ + err = _parse_buffers(state, p_search_path); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE BUFFER VIEWS */ + err = _parse_buffer_views(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE ACCESSORS */ + err = _parse_accessors(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE IMAGES */ + err = _parse_images(state, p_search_path); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE TEXTURES */ + err = _parse_textures(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE TEXTURES */ + err = _parse_materials(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE SKINS */ + err = _parse_skins(state); + + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* DETERMINE SKELETONS */ + err = _determine_skeletons(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* CREATE SKELETONS */ + err = _create_skeletons(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* CREATE SKINS */ + err = _create_skins(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE MESHES (we have enough info now) */ + err = _parse_meshes(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE LIGHTS */ + err = _parse_lights(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE CAMERAS */ + err = _parse_cameras(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE ANIMATIONS */ + err = _parse_animations(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* ASSIGN SCENE NAMES */ + _assign_scene_names(state); + + Node3D *root = memnew(Node3D); + 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; +} + +Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> r_state, uint32_t p_flags, int32_t p_bake_fps) { + // TODO Add missing texture and missing .bin file paths to r_missing_deps 2021-09-10 fire + if (r_state == Ref<GLTFState>()) { + r_state.instantiate(); + } + r_state->filename = p_path.get_file().get_basename(); + r_state->use_named_skin_binds = + p_flags & EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; + Error err; + FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); + ERR_FAIL_COND_V(err != OK, ERR_FILE_CANT_OPEN); + ERR_FAIL_NULL_V(f, ERR_FILE_CANT_OPEN); + + err = _parse(r_state, p_path.get_base_dir(), f, p_bake_fps); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + return err; +} + +Error GLTFDocument::_parse_gltf_extensions(Ref<GLTFState> state) { + ERR_FAIL_NULL_V(state, ERR_PARSE_ERROR); + if (state->json.has("extensionsRequired") && state->json["extensionsRequired"].get_type() == Variant::ARRAY) { + Array extensions_required = state->json["extensionsRequired"]; + if (extensions_required.find("KHR_draco_mesh_compression") != -1) { + ERR_PRINT("glTF2 extension KHR_draco_mesh_compression is not supported."); + return ERR_UNAVAILABLE; + } + } + return OK; +} diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index f2f0b439a5..c0649e0129 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -33,6 +33,7 @@ #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" @@ -46,7 +47,8 @@ #include "scene/resources/material.h" #include "scene/resources/texture.h" -#include "modules/modules_enabled.gen.h" +#include "modules/modules_enabled.gen.h" // For csg, gridmap. + #include <cstdint> class GLTFState; @@ -119,11 +121,6 @@ protected: static void _bind_methods(); public: - Node *import_scene(const String &p_path, uint32_t p_flags, int32_t p_bake_fps, Ref<GLTFState> r_state); - Node *import_scene_gltf(const String &p_path, uint32_t p_flags, int32_t p_bake_fps, Ref<GLTFState> r_state, List<String> *r_missing_deps, Error *r_err = nullptr); - Error save_scene(Node *p_node, const String &p_path, - const String &p_src_path, uint32_t p_flags, - float p_bake_fps, Ref<GLTFState> r_state); void set_extensions(TypedArray<GLTFDocumentExtension> p_extensions); TypedArray<GLTFDocumentExtension> get_extensions() const; @@ -199,7 +196,7 @@ private: Ref<Texture2D> _get_texture(Ref<GLTFState> state, const GLTFTextureIndex p_texture); Error _parse_json(const String &p_path, Ref<GLTFState> state); - Error _parse_glb(const String &p_path, Ref<GLTFState> state); + Error _parse_glb(FileAccess *f, Ref<GLTFState> state); void _compute_node_heights(Ref<GLTFState> state); Error _parse_buffers(Ref<GLTFState> state, const String &p_base_path); Error _parse_buffer_views(Ref<GLTFState> state); @@ -286,13 +283,13 @@ private: Skeleton3D *skeleton, const GLTFNodeIndex node_index, const GLTFNodeIndex bone_index); - ImporterMeshInstance3D *_generate_mesh_instance(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index); - Camera3D *_generate_camera(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index); - Node3D *_generate_light(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index); - Node3D *_generate_spatial(Ref<GLTFState> state, Node *parent_node, const GLTFNodeIndex node_index); + ImporterMeshInstance3D *_generate_mesh_instance(Ref<GLTFState> state, const GLTFNodeIndex node_index); + Camera3D *_generate_camera(Ref<GLTFState> state, const GLTFNodeIndex node_index); + Node3D *_generate_light(Ref<GLTFState> state, const GLTFNodeIndex node_index); + Node3D *_generate_spatial(Ref<GLTFState> state, const GLTFNodeIndex node_index); void _assign_scene_names(Ref<GLTFState> state); template <class T> - T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, + T _interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp); GLTFAccessorIndex _encode_accessor_as_quaternions(Ref<GLTFState> state, @@ -360,6 +357,7 @@ private: GLTFNodeIndex p_node_i); Error _encode_buffer_bins(Ref<GLTFState> state, const String &p_path); Error _encode_buffer_glb(Ref<GLTFState> state, const String &p_path); + PackedByteArray _serialize_glb_buffer(Ref<GLTFState> state, Error *r_err); Dictionary _serialize_texture_transform_uv1(Ref<BaseMaterial3D> p_material); Dictionary _serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material); Error _serialize_version(Ref<GLTFState> state); @@ -383,6 +381,18 @@ private: static float get_max_component(const Color &p_color); public: + Error append_from_file(String p_path, Ref<GLTFState> r_state, uint32_t p_flags = 0, int32_t p_bake_fps = 30); + Error append_from_buffer(PackedByteArray p_bytes, String p_base_path, Ref<GLTFState> r_state, uint32_t p_flags = 0, int32_t p_bake_fps = 30); + Error append_from_scene(Node *p_node, Ref<GLTFState> r_state, uint32_t p_flags = 0, int32_t p_bake_fps = 30); + +public: + Node *generate_scene(Ref<GLTFState> state, int32_t p_bake_fps = 30.0f); + PackedByteArray generate_buffer(Ref<GLTFState> state); + Error write_to_filesystem(Ref<GLTFState> state, const String &p_path); + +public: + Error _parse_gltf_state(Ref<GLTFState> state, const String &p_search_path, float p_bake_fps); + Error _parse_gltf_extensions(Ref<GLTFState> state); void _process_mesh_instances(Ref<GLTFState> state, Node *scene_root); void _generate_scene_node(Ref<GLTFState> state, Node *scene_parent, Node3D *scene_root, @@ -446,8 +456,8 @@ public: MeshInstance3D *p_mesh_instance); void _convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, String p_animation_track_name); - Error serialize(Ref<GLTFState> state, Node *p_root, const String &p_path); - Error parse(Ref<GLTFState> state, String p_paths, bool p_read_binary = false); + Error _serialize(Ref<GLTFState> state, const String &p_path); + Error _parse(Ref<GLTFState> state, String p_path, FileAccess *f, int p_bake_fps); }; #endif // GLTF_DOCUMENT_H diff --git a/modules/gltf/gltf_document_extension.cpp b/modules/gltf/gltf_document_extension.cpp index a423059a9c..192a1d347c 100644 --- a/modules/gltf/gltf_document_extension.cpp +++ b/modules/gltf/gltf_document_extension.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_document_extension.h b/modules/gltf/gltf_document_extension.h index 622a65708c..f7a3531282 100644 --- a/modules/gltf/gltf_document_extension.h +++ b/modules/gltf/gltf_document_extension.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp b/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp index 56c8f5ca27..47a3e5598f 100644 --- a/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp +++ b/modules/gltf/gltf_document_extension_convert_importer_mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.h b/modules/gltf/gltf_document_extension_convert_importer_mesh.h index 85ddb4d250..2d51143140 100644 --- a/modules/gltf/gltf_document_extension_convert_importer_mesh.h +++ b/modules/gltf/gltf_document_extension_convert_importer_mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_light.cpp b/modules/gltf/gltf_light.cpp index c5aa8d5724..af21a4e804 100644 --- a/modules/gltf/gltf_light.cpp +++ b/modules/gltf/gltf_light.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_light.h b/modules/gltf/gltf_light.h index 62a20d2f16..25e0835a33 100644 --- a/modules/gltf/gltf_light.h +++ b/modules/gltf/gltf_light.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_mesh.cpp b/modules/gltf/gltf_mesh.cpp index 7134345b30..1251622642 100644 --- a/modules/gltf/gltf_mesh.cpp +++ b/modules/gltf/gltf_mesh.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_mesh.h b/modules/gltf/gltf_mesh.h index cc2be93c09..aeab1ad68f 100644 --- a/modules/gltf/gltf_mesh.h +++ b/modules/gltf/gltf_mesh.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_node.cpp b/modules/gltf/gltf_node.cpp index 9f925c7bbc..86280603fa 100644 --- a/modules/gltf/gltf_node.cpp +++ b/modules/gltf/gltf_node.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_node.h b/modules/gltf/gltf_node.h index 3b6e061449..929ad3eca0 100644 --- a/modules/gltf/gltf_node.h +++ b/modules/gltf/gltf_node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_skeleton.cpp b/modules/gltf/gltf_skeleton.cpp index d6c7a25eaf..e80376f130 100644 --- a/modules/gltf/gltf_skeleton.cpp +++ b/modules/gltf/gltf_skeleton.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_skeleton.h b/modules/gltf/gltf_skeleton.h index d6986eb35a..7d07d528cb 100644 --- a/modules/gltf/gltf_skeleton.h +++ b/modules/gltf/gltf_skeleton.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_skin.cpp b/modules/gltf/gltf_skin.cpp index 5cf17135ac..283fc34ff5 100644 --- a/modules/gltf/gltf_skin.cpp +++ b/modules/gltf/gltf_skin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_skin.h b/modules/gltf/gltf_skin.h index e32e2d397c..31cb892f19 100644 --- a/modules/gltf/gltf_skin.h +++ b/modules/gltf/gltf_skin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_spec_gloss.cpp b/modules/gltf/gltf_spec_gloss.cpp index 70b182da52..83af91bfcc 100644 --- a/modules/gltf/gltf_spec_gloss.cpp +++ b/modules/gltf/gltf_spec_gloss.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_spec_gloss.h b/modules/gltf/gltf_spec_gloss.h index 3cc6fb09ed..f8a431bdce 100644 --- a/modules/gltf/gltf_spec_gloss.h +++ b/modules/gltf/gltf_spec_gloss.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index ff9778e7d8..3f638bbca5 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 61faba0dc5..d03434d2f1 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_texture.cpp b/modules/gltf/gltf_texture.cpp index 0482c1064e..2a21cb3df8 100644 --- a/modules/gltf/gltf_texture.cpp +++ b/modules/gltf/gltf_texture.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/gltf_texture.h b/modules/gltf/gltf_texture.h index 4659725502..54dd61f9a5 100644 --- a/modules/gltf/gltf_texture.h +++ b/modules/gltf/gltf_texture.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index 5a60c2d328..6ab202096d 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/modules/gltf/register_types.h b/modules/gltf/register_types.h index fefacb1106..4a9c31241c 100644 --- a/modules/gltf/register_types.h +++ b/modules/gltf/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ |