diff options
Diffstat (limited to 'modules/gltf/gltf_document.cpp')
-rw-r--r-- | modules/gltf/gltf_document.cpp | 73 |
1 files changed, 38 insertions, 35 deletions
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 660c2ab305..be44f66423 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -29,9 +29,7 @@ /*************************************************************************/ #include "gltf_document.h" -#include "core/error/error_list.h" -#include "core/error/error_macros.h" -#include "core/variant/variant.h" + #include "gltf_accessor.h" #include "gltf_animation.h" #include "gltf_camera.h" @@ -44,35 +42,33 @@ #include "gltf_state.h" #include "gltf_texture.h" -#include <stdio.h> -#include <stdlib.h> - -#include "core/core_bind.h" #include "core/crypto/crypto_core.h" +#include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/io/json.h" #include "core/math/disjoint_set.h" #include "core/variant/typed_array.h" +#include "core/variant/variant.h" #include "core/version.h" #include "core/version_hash.gen.h" #include "drivers/png/png_driver_common.h" #include "editor/import/resource_importer_scene.h" +#include "scene/2d/node_2d.h" +#include "scene/3d/camera_3d.h" +#include "scene/3d/multimesh_instance_3d.h" +#include "scene/animation/animation_player.h" +#include "scene/resources/surface_tool.h" + +#include "modules/modules_enabled.gen.h" #ifdef MODULE_CSG_ENABLED #include "modules/csg/csg_shape.h" #endif // MODULE_CSG_ENABLED #ifdef MODULE_GRIDMAP_ENABLED #include "modules/gridmap/grid_map.h" #endif // MODULE_GRIDMAP_ENABLED -#include "scene/2d/node_2d.h" -#include "scene/3d/bone_attachment_3d.h" -#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/3d/skeleton_3d.h" -#include "scene/animation/animation_player.h" -#include "scene/main/node.h" -#include "scene/resources/surface_tool.h" + +#include <stdio.h> +#include <stdlib.h> #include <limits> Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &p_path) { @@ -2800,7 +2796,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) { mat = mat3d; } - import_mesh->add_surface(primitive, array, morphs, Dictionary(), mat); + import_mesh->add_surface(primitive, array, morphs, Dictionary(), mat, mat.is_valid() ? mat->get_name() : String()); } Vector<float> blend_weights; @@ -2873,16 +2869,13 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path name = itos(i); } name = _gen_unique_name(state, name); - name = name.pad_zeros(3); - Ref<_Directory> dir; - dir.instantiate(); + name = name.pad_zeros(3) + ".png"; String texture_dir = "textures"; String new_texture_dir = p_path.get_base_dir() + "/" + texture_dir; - dir->open(p_path.get_base_dir()); - if (!dir->dir_exists(new_texture_dir)) { - dir->make_dir(new_texture_dir); + DirAccessRef da = DirAccess::open(p_path.get_base_dir()); + if (!da->dir_exists(new_texture_dir)) { + da->make_dir(new_texture_dir); } - name = name + ".png"; image->save_png(new_texture_dir.plus_file(name)); d["uri"] = texture_dir.plus_file(name); } @@ -3009,24 +3002,31 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat Ref<Image> img; + // First we honor the mime types if they were defined. if (mimetype == "image/png") { // Load buffer as PNG. ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, ERR_UNAVAILABLE); img = Image::_png_mem_loader_func(data_ptr, data_size); } else if (mimetype == "image/jpeg") { // Loader buffer as JPEG. ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE); img = Image::_jpg_mem_loader_func(data_ptr, data_size); - } else { - // We can land here if we got an URI with base64-encoded data with application/* MIME type, - // and the optional mimeType property was not defined to tell us how to handle this data (or was invalid). - // So let's try PNG first, then JPEG. + } + + // If we didn't pass the above tests, we attempt loading as PNG and then + // JPEG directly. + // This covers URIs with base64-encoded data with application/* type but + // no optional mimeType property, or bufferViews with a bogus mimeType + // (e.g. `image/jpeg` but the data is actually PNG). + // That's not *exactly* what the spec mandates but this lets us be + // lenient with bogus glb files which do exist in production. + if (img.is_null()) { // Try PNG first. ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, ERR_UNAVAILABLE); img = Image::_png_mem_loader_func(data_ptr, data_size); - if (img.is_null()) { - ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE); - img = Image::_jpg_mem_loader_func(data_ptr, data_size); - } } - + if (img.is_null()) { // And then JPEG. + ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE); + img = Image::_jpg_mem_loader_func(data_ptr, data_size); + } + // Now we've done our best, fix your scenes. if (img.is_null()) { ERR_PRINT(vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", i, mimetype)); state->images.push_back(Ref<Texture2D>()); @@ -5538,7 +5538,10 @@ struct EditorSceneImporterGLTFInterpolate<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) { ERR_FAIL_COND_V(!p_values.size(), T()); - ERR_FAIL_COND_V(p_times.size() != p_values.size(), p_values[0]); + if (p_times.size() != p_values.size()) { + ERR_PRINT_ONCE("The interpolated values are not corresponding to its times."); + return p_values[0]; + } //could use binary search, worth it? int idx = -1; for (int i = 0; i < p_times.size(); i++) { |