diff --git a/modules/fbx/fbx_document.cpp b/modules/fbx/fbx_document.cpp index bdd9f057a98e..cf2d21f31952 100644 --- a/modules/fbx/fbx_document.cpp +++ b/modules/fbx/fbx_document.cpp @@ -1048,7 +1048,7 @@ GLTFImageIndex FBXDocument::_parse_image_save_image(Ref p_state, const return p_state->images.size() - 1; } -Error FBXDocument::_parse_images(Ref p_state, const String &p_base_path) { +Error FBXDocument::_parse_images(Ref p_state) { ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER); const ufbx_scene *fbx_scene = p_state->scene.get(); @@ -1059,8 +1059,8 @@ Error FBXDocument::_parse_images(Ref p_state, const String &p_base_pat if (path.is_absolute_path()) { path = path.get_file(); } - if (!p_base_path.is_empty()) { - path = p_base_path.path_join(path); + if (!p_state->base_path.is_empty()) { + path = p_state->base_path.path_join(path); } path = path.simplify_path(); Vector data; @@ -2018,7 +2018,7 @@ void FBXDocument::_process_mesh_instances(Ref p_state, Node *p_scene_r } } -Error FBXDocument::_parse(Ref p_state, const String &p_path, Ref p_file) { +Error FBXDocument::_parse(Ref p_state, Ref p_file) { p_state->scene.reset(); Error err = ERR_INVALID_DATA; @@ -2109,7 +2109,7 @@ Error FBXDocument::_parse(Ref p_state, const String &p_path, Refopen_custom(p_bytes.ptr(), p_bytes.size()); state->base_path = p_base_path.get_base_dir(); - err = _parse(state, state->base_path, file_access); + err = _parse(state, file_access); ERR_FAIL_COND_V(err != OK, err); for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); @@ -2183,7 +2183,7 @@ Error FBXDocument::append_from_buffer(const PackedByteArray &p_bytes, const Stri return OK; } -Error FBXDocument::_parse_fbx_state(Ref p_state, const String &p_search_path) { +Error FBXDocument::_parse_fbx_state(Ref p_state) { Error err; // Abort parsing if the scene is not loaded. @@ -2199,7 +2199,7 @@ Error FBXDocument::_parse_fbx_state(Ref p_state, const String &p_searc if (!p_state->discard_meshes_and_materials) { /* PARSE IMAGES */ - err = _parse_images(p_state, p_search_path); + err = _parse_images(p_state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); @@ -2263,7 +2263,7 @@ Error FBXDocument::append_from_file(const String &p_path, Ref p_state if (p_state == Ref()) { p_state.instantiate(); } - state->filename = p_path.get_file().get_basename(); + state->filename = p_path.get_file(); state->use_named_skin_binds = p_flags & GLTFDocument::ImportFlags::IMPORT_FLAG_USE_NAMED_SKIN_BINDS; state->discard_meshes_and_materials = p_flags & GLTFDocument::ImportFlags::IMPORT_FLAG_DISCARD_MESHES_AND_MATERIALS; Error err; @@ -2275,7 +2275,7 @@ Error FBXDocument::append_from_file(const String &p_path, Ref p_state base_path = p_path.get_base_dir(); } state->base_path = base_path; - err = _parse(p_state, base_path, file); + err = _parse(p_state, file); ERR_FAIL_COND_V(err != OK, err); for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); diff --git a/modules/fbx/fbx_document.h b/modules/fbx/fbx_document.h index c2dcfd1e2f14..d8667dda724b 100644 --- a/modules/fbx/fbx_document.h +++ b/modules/fbx/fbx_document.h @@ -78,7 +78,7 @@ class FBXDocument : public GLTFDocument { Error _parse_meshes(Ref p_state); Ref _parse_image_bytes_into_image(Ref p_state, const Vector &p_bytes, const String &p_filename, int p_index); GLTFImageIndex _parse_image_save_image(Ref p_state, const Vector &p_bytes, const String &p_file_extension, int p_index, Ref p_image); - Error _parse_images(Ref p_state, const String &p_base_path); + Error _parse_images(Ref p_state); Error _parse_materials(Ref p_state); Error _parse_skins(Ref p_state); Error _parse_animations(Ref p_state); @@ -95,11 +95,11 @@ class FBXDocument : public GLTFDocument { Error _parse_lights(Ref p_state); public: - Error _parse_fbx_state(Ref p_state, const String &p_search_path); + Error _parse_fbx_state(Ref p_state); void _process_mesh_instances(Ref p_state, Node *p_scene_root); void _generate_scene_node(Ref p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root); void _generate_skeleton_bone_node(Ref p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root); void _import_animation(Ref p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const bool p_trimming, const bool p_remove_immutable_tracks); - Error _parse(Ref p_state, const String &p_path, Ref p_file); + Error _parse(Ref p_state, Ref p_file); }; diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 5d2bc1bae04e..7565acbbc6cc 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -242,29 +242,6 @@ Error GLTFDocument::_serialize_scenes(Ref p_state) { return OK; } -Error GLTFDocument::_parse_json(const String &p_path, Ref p_state) { - Error err; - Ref file = FileAccess::open(p_path, FileAccess::READ, &err); - if (file.is_null()) { - return err; - } - - Vector array; - array.resize(file->get_length()); - file->get_buffer(array.ptrw(), array.size()); - String text = String::utf8((const char *)array.ptr(), array.size()); - - JSON json; - 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); - return err; - } - p_state->json = json.get_data(); - - return OK; -} - Error GLTFDocument::_parse_glb(Ref p_file, Ref p_state) { ERR_FAIL_COND_V(p_file.is_null(), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER); @@ -701,90 +678,70 @@ static inline bool _all_buffers_empty(const Vector> &p_buffers, return true; } -Error GLTFDocument::_encode_buffer_glb(Ref p_state, const String &p_path) { - print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size())); - - if (p_state->buffers.is_empty() || _all_buffers_empty(p_state->buffers)) { - ERR_FAIL_COND_V_MSG(!p_state->buffer_views.is_empty(), ERR_INVALID_DATA, "glTF: Buffer views are present, but buffers are empty."); - return OK; - } - Array buffers; - Dictionary first_buffer; - - first_buffer["byteLength"] = p_state->buffers[0].size(); - buffers.push_back(first_buffer); - - for (GLTFBufferIndex i = 1; i < p_state->buffers.size(); i++) { - const Vector &buffer_data = p_state->buffers[i]; - Dictionary gltf_buffer; - if (buffer_data.is_empty()) { - if (i < p_state->buffers.size() - 1 && !_all_buffers_empty(p_state->buffers, i + 1)) { - // Have to push back an empty buffer to avoid changing the buffer index, even though this is against spec. - WARN_PRINT("glTF: Buffer " + itos(i) + " is empty, but there are non-empty subsequent buffers."); - gltf_buffer["byteLength"] = 0; - buffers.push_back(gltf_buffer); - } - continue; - } - String filename = p_path.get_basename().get_file() + itos(i) + ".bin"; - String path = p_path.get_base_dir() + "/" + filename; - Error err; - Ref file = FileAccess::open(path, FileAccess::WRITE, &err); - if (file.is_null()) { - return err; - } - file->create(FileAccess::ACCESS_RESOURCES); - file->store_buffer(buffer_data.ptr(), buffer_data.size()); - gltf_buffer["uri"] = filename; - gltf_buffer["byteLength"] = buffer_data.size(); - buffers.push_back(gltf_buffer); - } - p_state->json["buffers"] = buffers; - - return OK; -} - -Error GLTFDocument::_encode_buffer_bins(Ref p_state, const String &p_path) { - print_verbose("glTF: Total buffers: " + itos(p_state->buffers.size())); - - if (p_state->buffers.is_empty() || _all_buffers_empty(p_state->buffers)) { +Error GLTFDocument::_export_encode_buffers(Ref p_state, bool p_separate_buffers_into_files) { + const int64_t buffer_count = p_state->buffers.size(); + print_verbose("glTF: Total buffers: " + itos(buffer_count)); + if (buffer_count == 0 || _all_buffers_empty(p_state->buffers)) { ERR_FAIL_COND_V_MSG(!p_state->buffer_views.is_empty(), ERR_INVALID_DATA, "glTF: Buffer views are present, but buffers are empty."); return OK; } - Array buffers; - - for (GLTFBufferIndex i = 0; i < p_state->buffers.size(); i++) { - const Vector &buffer_data = p_state->buffers[i]; - Dictionary gltf_buffer; - if (buffer_data.is_empty()) { - if (i < p_state->buffers.size() - 1 && !_all_buffers_empty(p_state->buffers, i + 1)) { + Array buffer_dicts; + buffer_dicts.resize(buffer_count); + // Separate buffers into files if the caller requested it and the base path is available. + const bool should_separate_into_files = p_separate_buffers_into_files && !p_state->base_path.is_empty(); + // Check if the buffer at index 0 should be used as a GLB buffer. + GLTFBufferIndex loop_start_index; + if (should_separate_into_files || p_state->is_text_file()) { + loop_start_index = 0; // Encode all buffers with URIs, don't use a GLB buffer. + } else { + loop_start_index = 1; // Encode buffers starting at index 1 with URIs, use buffer 0 as a GLB buffer. + const PackedByteArray buffer_data = p_state->buffers[0]; + const int64_t buffer_byte_length = buffer_data.size(); + if (buffer_byte_length == 0) { + // If this buffer is empty and the others were too, this would've returned at the top of the function. + ERR_PRINT("glTF export: Buffer 0 is empty, but there are non-empty subsequent buffers. Writing it anyway to preserve buffer indices."); + } + Dictionary first_gltf_buffer_dict; + first_gltf_buffer_dict["byteLength"] = buffer_byte_length; + buffer_dicts[0] = first_gltf_buffer_dict; + } + // Encode the rest of the buffers. + for (GLTFBufferIndex buffer_index = loop_start_index; buffer_index < buffer_count; buffer_index++) { + const PackedByteArray &buffer_data = p_state->buffers[buffer_index]; + const int64_t buffer_byte_length = buffer_data.size(); + Dictionary gltf_buffer_dict; + gltf_buffer_dict["byteLength"] = buffer_byte_length; + if (buffer_byte_length == 0) { + if (buffer_index < buffer_count - 1 && !_all_buffers_empty(p_state->buffers, buffer_index + 1)) { // Have to push back an empty buffer to avoid changing the buffer index, even though this is against spec. - WARN_PRINT("glTF: Buffer " + itos(i) + " is empty, but there are non-empty subsequent buffers."); - gltf_buffer["byteLength"] = 0; - buffers.push_back(gltf_buffer); + WARN_PRINT("glTF: Buffer " + itos(buffer_index) + " is empty, but there are non-empty subsequent buffers."); + buffer_dicts[buffer_index] = gltf_buffer_dict; } continue; } - String filename = p_path.get_basename().get_file() + itos(i) + ".bin"; - String path = p_path.get_base_dir() + "/" + filename; - Error err; - Ref file = FileAccess::open(path, FileAccess::WRITE, &err); - if (file.is_null()) { - return err; + if (should_separate_into_files) { + // Encode the buffer as a separate file. + const String bin_filename = p_state->filename.get_basename() + itos(buffer_index) + ".bin"; + const String bin_path = p_state->base_path.path_join(bin_filename); + Error err; + Ref file = FileAccess::open(bin_path, FileAccess::WRITE, &err); + if (file.is_null()) { + return err; + } + file->store_buffer(buffer_data.ptr(), buffer_byte_length); + gltf_buffer_dict["uri"] = bin_filename; + } else { + // Encode the buffer as a base64 data URI. + const String base64_data = CryptoCore::b64_encode_str(buffer_data.ptr(), buffer_byte_length); + gltf_buffer_dict["uri"] = "data:application/octet-stream;base64," + base64_data; } - file->store_buffer(buffer_data.ptr(), buffer_data.size()); - gltf_buffer["uri"] = filename; - gltf_buffer["byteLength"] = buffer_data.size(); - buffers.push_back(gltf_buffer); + buffer_dicts[buffer_index] = gltf_buffer_dict; } - if (!buffers.is_empty()) { - p_state->json["buffers"] = buffers; - } - + p_state->json["buffers"] = buffer_dicts; return OK; } -Error GLTFDocument::_parse_buffers(Ref p_state, const String &p_base_path) { +Error GLTFDocument::_parse_buffers(Ref p_state) { if (!p_state->json.has("buffers")) { return OK; } @@ -804,9 +761,9 @@ Error GLTFDocument::_parse_buffers(Ref p_state, const String &p_base_ } 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); + ERR_FAIL_COND_V(p_state->base_path.is_empty(), ERR_INVALID_PARAMETER); uri = uri.uri_file_decode(); - uri = p_base_path.path_join(uri).replace_char('\\', '/'); // Fix for Windows. + uri = p_state->base_path.path_join(uri).replace_char('\\', '/'); // Fix for Windows. ERR_FAIL_COND_V_MSG(!FileAccess::exists(uri), ERR_FILE_NOT_FOUND, "glTF: Binary file not found: " + uri); buffer_data = FileAccess::get_file_as_bytes(uri); ERR_FAIL_COND_V_MSG(buffer_data.is_empty(), ERR_PARSE_ERROR, "glTF: Couldn't load binary file as an array: " + uri); @@ -2123,7 +2080,7 @@ Dictionary GLTFDocument::_serialize_image(Ref p_state, Ref p_i ERR_FAIL_COND_V_MSG(p_image->is_compressed(), image_dict, "glTF: Image was compressed, but could not be decompressed."); } - if (p_state->filename.to_lower().ends_with("gltf")) { + if (p_state->is_text_file()) { String relative_texture_dir = "textures"; String full_texture_dir = p_state->base_path.path_join(relative_texture_dir); Ref da = DirAccess::open(p_state->base_path); @@ -2148,6 +2105,8 @@ Dictionary GLTFDocument::_serialize_image(Ref p_state, Ref p_i } image_dict["uri"] = relative_texture_dir.path_join(image_file_name).uri_encode(); } else { + // Else, such as if this is a `.glb`, a byte array in memory, or an + // embedded `.gltf`, we need to serialize the image into a buffer view. GLTFBufferViewIndex bvi; Ref bv; @@ -2338,7 +2297,7 @@ void GLTFDocument::_parse_image_save_image(Ref p_state, const Vector< p_state->source_images.push_back(p_image); } -Error GLTFDocument::_parse_images(Ref p_state, const String &p_base_path) { +Error GLTFDocument::_parse_images(Ref p_state) { ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER); if (!p_state->json.has("images")) { return OK; @@ -2398,9 +2357,9 @@ Error GLTFDocument::_parse_images(Ref p_state, const String &p_base_p mime_type = uri.substr(5, uri.find(";base64") - 5); } } else { // Relative path to an external image file. - ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(p_state->base_path.is_empty(), ERR_INVALID_PARAMETER); uri = uri.uri_file_decode(); - uri = p_base_path.path_join(uri).replace_char('\\', '/'); // Fix for Windows. + uri = p_state->base_path.path_join(uri).replace_char('\\', '/'); // Fix for Windows. resource_uri = uri.simplify_path(); // ResourceLoader will rely on the file extension to use the relevant loader. // The spec says that if mimeType is defined, it should take precedence (e.g. @@ -6716,7 +6675,7 @@ void GLTFDocument::_convert_animation(Ref p_state, AnimationPlayer *p } } -Error GLTFDocument::_parse(Ref p_state, const String &p_path, Ref p_file) { +Error GLTFDocument::_parse(Ref p_state, Ref p_file) { Error err; if (p_file.is_null()) { return FAILED; @@ -6756,7 +6715,7 @@ Error GLTFDocument::_parse(Ref p_state, const String &p_path, Ref p_state) { return OK; } -Error GLTFDocument::_serialize_file(Ref p_state, const String p_path) { - Error err = FAILED; - if (p_path.to_lower().ends_with("glb")) { - err = _encode_buffer_glb(p_state, p_path); - ERR_FAIL_COND_V(err != OK, err); - Ref file = FileAccess::open(p_path, FileAccess::WRITE, &err); - ERR_FAIL_COND_V(file.is_null(), FAILED); - +Error GLTFDocument::_serialize_file(Ref p_state) { + const String gltf_path = p_state->base_path.path_join(p_state->filename); + Error err = _export_encode_buffers(p_state, p_state->is_text_file()); + ERR_FAIL_COND_V_MSG(err != OK, err, "glTF: Failed to encode buffers for file: " + gltf_path); + Ref file = FileAccess::open(gltf_path, FileAccess::WRITE, &err); + ERR_FAIL_COND_V(file.is_null(), FAILED); + if (p_state->is_text_file()) { + String json = JSON::stringify(p_state->json, "", true, true); + file->store_string(json); + } else { + // Serialize binary glTF (GLB) file. constexpr uint64_t header_size = 12; constexpr uint64_t chunk_header_size = 8; constexpr uint32_t magic = 0x46546C67; // The byte sequence "glTF" as little-endian. @@ -6847,7 +6809,7 @@ Error GLTFDocument::_serialize_file(Ref p_state, const String p_path) // Check if the file length with the buffer is greater than glTF's maximum of 4 GiB. // If it is, we can't write the buffer into the file, but can write it separately. if (unlikely(file_length_with_buffer > (uint64_t)UINT32_MAX)) { - err = _encode_buffer_bins(p_state, p_path); + err = _export_encode_buffers(p_state, true); ERR_FAIL_COND_V(err != OK, err); // Since the buffer bins were re-encoded, we need to re-convert the JSON to string. json_string = JSON::stringify(p_state->json, "", true, true); @@ -6885,14 +6847,6 @@ Error GLTFDocument::_serialize_file(Ref p_state, const String p_path) file->store_8(0); } } - } else { - err = _encode_buffer_bins(p_state, p_path); - ERR_FAIL_COND_V(err != OK, err); - Ref file = FileAccess::open(p_path, FileAccess::WRITE, &err); - ERR_FAIL_COND_V(file.is_null(), FAILED); - - String json = JSON::stringify(p_state->json, "", true, true); - file->store_string(json); } return err; } @@ -7036,7 +6990,7 @@ HashSet GLTFDocument::get_supported_gltf_extensions_hashset() { } PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref p_state, Error *r_err) { - Error err = _encode_buffer_glb(p_state, ""); + Error err = _export_encode_buffers(p_state, false); if (r_err) { *r_err = err; } @@ -7061,7 +7015,7 @@ PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref p_state, Erro total_file_length = file_length_with_buffer; } ERR_FAIL_COND_V_MSG(total_file_length > (uint64_t)UINT32_MAX, PackedByteArray(), - "glTF: File size exceeds glTF Binary's maximum of 4 GiB. Cannot serialize as a single GLB in-memory buffer."); + "glTF: File size exceeds glTF Binary's maximum of 4 GiB. Cannot serialize as a single GLB byte array in memory."); const uint32_t binary_chunk_length = binary_data_length; Ref buffer; @@ -7151,11 +7105,11 @@ Error GLTFDocument::_parse_asset_header(Ref p_state) { return OK; } -Error GLTFDocument::_parse_gltf_state(Ref p_state, const String &p_search_path) { +Error GLTFDocument::_parse_gltf_state(Ref p_state) { Error err; /* PARSE BUFFERS */ - err = _parse_buffers(p_state, p_search_path); + err = _parse_buffers(p_state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); /* PARSE BUFFER VIEWS */ @@ -7180,7 +7134,7 @@ Error GLTFDocument::_parse_gltf_state(Ref p_state, const String &p_se if (!p_state->discard_meshes_and_materials) { /* PARSE IMAGES */ - err = _parse_images(p_state, p_search_path); + err = _parse_images(p_state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); @@ -7255,7 +7209,7 @@ Error GLTFDocument::write_to_filesystem(Ref p_state, const String &p_ if (err != OK) { return err; } - err = _serialize_file(p_state, p_path); + err = _serialize_file(p_state); if (err != OK) { return Error::FAILED; } @@ -7371,7 +7325,7 @@ Error GLTFDocument::append_from_buffer(const PackedByteArray &p_bytes, const Str file_access.instantiate(); file_access->open_custom(p_bytes.ptr(), p_bytes.size()); p_state->set_base_path(p_base_path.get_base_dir()); - err = _parse(p_state, p_state->base_path, file_access); + err = _parse(p_state, file_access); ERR_FAIL_COND_V(err != OK, err); for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); @@ -7399,7 +7353,7 @@ Error GLTFDocument::append_from_file(const String &p_path, Ref p_stat base_path = p_path.get_base_dir(); } p_state->set_base_path(base_path); - err = _parse(p_state, base_path, file); + err = _parse(p_state, file); ERR_FAIL_COND_V(err != OK, err); for (Ref ext : document_extensions) { ERR_CONTINUE(ext.is_null()); diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index bba726f8b263..125f35b53e3f 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -139,10 +139,9 @@ class GLTFDocument : public Resource { StandardMaterial3D::TextureFilter p_filter_mode, bool p_repeats); Ref _get_sampler_for_texture(Ref p_state, const GLTFTextureIndex p_texture); - Error _parse_json(const String &p_path, Ref p_state); Error _parse_glb(Ref p_file, Ref p_state); void _compute_node_heights(Ref p_state); - Error _parse_buffers(Ref p_state, const String &p_base_path); + Error _parse_buffers(Ref p_state); Error _parse_buffer_views(Ref p_state); Error _parse_accessors(Ref p_state); template @@ -164,7 +163,7 @@ class GLTFDocument : public Resource { Error _serialize_lights(Ref p_state); Ref _parse_image_bytes_into_image(Ref p_state, const Vector &p_bytes, const String &p_mime_type, int p_index, String &r_file_extension); void _parse_image_save_image(Ref p_state, const Vector &p_bytes, const String &p_resource_uri, const String &p_file_extension, int p_index, Ref p_image); - Error _parse_images(Ref p_state, const String &p_base_path); + Error _parse_images(Ref p_state); Error _parse_textures(Ref p_state); Error _parse_texture_samplers(Ref p_state); Error _parse_materials(Ref p_state); @@ -206,13 +205,12 @@ class GLTFDocument : public Resource { Error _serialize_nodes(Ref p_state); Error _serialize_scenes(Ref p_state); String interpolation_to_string(const GLTFAnimation::Interpolation p_interp); - Error _encode_buffer_bins(Ref p_state, const String &p_path); - Error _encode_buffer_glb(Ref p_state, const String &p_path); + Error _export_encode_buffers(Ref p_state, bool p_separate_buffers_into_files); PackedByteArray _serialize_glb_buffer(Ref p_state, Error *r_err); Dictionary _serialize_texture_transform_uv1(const Ref &p_material); Dictionary _serialize_texture_transform_uv2(const Ref &p_material); Error _serialize_asset_header(Ref p_state); - Error _serialize_file(Ref p_state, const String p_path); + Error _serialize_file(Ref p_state); Error _serialize_gltf_extensions(Ref p_state) const; public: @@ -241,7 +239,7 @@ class GLTFDocument : public Resource { virtual Error write_to_filesystem(Ref p_state, const String &p_path); public: - Error _parse_gltf_state(Ref p_state, const String &p_search_path); + Error _parse_gltf_state(Ref p_state); Error _parse_asset_header(Ref p_state); Error _parse_gltf_extensions(Ref p_state); void _process_mesh_instances(Ref p_state, Node *p_scene_root); @@ -302,7 +300,7 @@ class GLTFDocument : public Resource { void _convert_animation(Ref p_state, AnimationPlayer *p_animation_player, const String &p_animation_track_name); Error _serialize(Ref p_state); - Error _parse(Ref p_state, const String &p_path, Ref p_file); + Error _parse(Ref p_state, Ref p_file); }; VARIANT_ENUM_CAST(GLTFDocument::RootNodeMode); diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index 667b5e5c89d3..94f046a6971c 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -445,6 +445,10 @@ void GLTFState::set_filename(const String &p_filename) { } } +bool GLTFState::is_text_file() const { + return filename.to_lower().ends_with(".gltf"); +} + Variant GLTFState::get_additional_data(const StringName &p_extension_name) const { return additional_data.get(p_extension_name, Variant()); } diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 39664bc88425..71ceeb4aa50b 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -255,6 +255,7 @@ class GLTFState : public Resource { String get_filename() const; void set_filename(const String &p_filename); + bool is_text_file() const; PackedInt32Array get_root_nodes() const; void set_root_nodes(const PackedInt32Array &p_root_nodes);