From 101442ced9f266eca289cb3ad61dc7f8756ecbd0 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Tue, 18 Jul 2023 14:28:09 -0500 Subject: [PATCH 1/2] Expose filename in GLTFState --- modules/gltf/doc_classes/GLTFState.xml | 4 ++++ modules/gltf/gltf_state.cpp | 15 +++++++++++++-- modules/gltf/gltf_state.h | 9 ++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml index 44b0d124e71d..db468e2994e7 100644 --- a/modules/gltf/doc_classes/GLTFState.xml +++ b/modules/gltf/doc_classes/GLTFState.xml @@ -267,6 +267,7 @@ + The folder path associated with this GLTF data. This is used to find other files the GLTF file references, like images or binary buffers. This will be set during import when appending from a file. @@ -275,6 +276,9 @@ + + The file name associated with this GLTF data. If it ends with [code].gltf[/code], this is text-based GLTF, otherwise this is binary GLB. This will be set during import when appending from a file. + diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index 87d15066f015..c0ec004fd631 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -64,6 +64,8 @@ void GLTFState::_bind_methods() { ClassDB::bind_method(D_METHOD("set_scene_name", "scene_name"), &GLTFState::set_scene_name); ClassDB::bind_method(D_METHOD("get_base_path"), &GLTFState::get_base_path); ClassDB::bind_method(D_METHOD("set_base_path", "base_path"), &GLTFState::set_base_path); + ClassDB::bind_method(D_METHOD("get_filename"), &GLTFState::get_filename); + ClassDB::bind_method(D_METHOD("set_filename", "filename"), &GLTFState::set_filename); ClassDB::bind_method(D_METHOD("get_root_nodes"), &GLTFState::get_root_nodes); ClassDB::bind_method(D_METHOD("set_root_nodes", "root_nodes"), &GLTFState::set_root_nodes); ClassDB::bind_method(D_METHOD("get_textures"), &GLTFState::get_textures); @@ -109,6 +111,7 @@ void GLTFState::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "materials", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_materials", "get_materials"); // Vector ADD_PROPERTY(PropertyInfo(Variant::STRING, "scene_name"), "set_scene_name", "get_scene_name"); // String ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_path"), "set_base_path", "get_base_path"); // String + ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename"), "set_filename", "get_filename"); // String ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "root_nodes"), "set_root_nodes", "get_root_nodes"); // Vector ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "textures", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_textures", "get_textures"); // Vector> ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "texture_samplers", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_texture_samplers", "get_texture_samplers"); //Vector> @@ -164,11 +167,11 @@ void GLTFState::set_minor_version(int p_minor_version) { minor_version = p_minor_version; } -String GLTFState::get_copyright() { +String GLTFState::get_copyright() const { return copyright; } -void GLTFState::set_copyright(String p_copyright) { +void GLTFState::set_copyright(const String &p_copyright) { copyright = p_copyright; } @@ -381,6 +384,14 @@ void GLTFState::set_base_path(String p_base_path) { base_path = p_base_path; } +String GLTFState::get_filename() const { + return filename; +} + +void GLTFState::set_filename(const String &p_filename) { + filename = p_filename; +} + Variant GLTFState::get_additional_data(const StringName &p_extension_name) { return additional_data[p_extension_name]; } diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index d122049c0bb8..91af8f91a4e1 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -47,8 +47,8 @@ class GLTFState : public Resource { GDCLASS(GLTFState, Resource); friend class GLTFDocument; - String filename; String base_path; + String filename; Dictionary json; int major_version = 0; int minor_version = 0; @@ -126,8 +126,8 @@ class GLTFState : public Resource { int get_minor_version(); void set_minor_version(int p_minor_version); - String get_copyright(); - void set_copyright(String p_copyright); + String get_copyright() const; + void set_copyright(const String &p_copyright); Vector get_glb_data(); void set_glb_data(Vector p_glb_data); @@ -171,6 +171,9 @@ class GLTFState : public Resource { String get_base_path(); void set_base_path(String p_base_path); + String get_filename() const; + void set_filename(const String &p_filename); + PackedInt32Array get_root_nodes(); void set_root_nodes(PackedInt32Array p_root_nodes); From 2970839085b82e80b5d167c1f9222d71bdc5f422 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Tue, 18 Jul 2023 14:42:22 -0500 Subject: [PATCH 2/2] Set base_path and filename during export --- modules/gltf/doc_classes/GLTFState.xml | 4 +-- modules/gltf/gltf_document.cpp | 49 ++++++++++++++------------ modules/gltf/gltf_document.h | 4 +-- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml index db468e2994e7..ba1c531283b7 100644 --- a/modules/gltf/doc_classes/GLTFState.xml +++ b/modules/gltf/doc_classes/GLTFState.xml @@ -267,7 +267,7 @@ - The folder path associated with this GLTF data. This is used to find other files the GLTF file references, like images or binary buffers. This will be set during import when appending from a file. + The folder path associated with this GLTF data. This is used to find other files the GLTF file references, like images or binary buffers. This will be set during import when appending from a file, and will be set during export when writing to a file. @@ -277,7 +277,7 @@ - The file name associated with this GLTF data. If it ends with [code].gltf[/code], this is text-based GLTF, otherwise this is binary GLB. This will be set during import when appending from a file. + The file name associated with this GLTF data. If it ends with [code].gltf[/code], this is text-based GLTF, otherwise this is binary GLB. This will be set during import when appending from a file, and will be set during export when writing to a file. If writing to a buffer, this will be an empty string. diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index d23b22049bd2..572ef4487661 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -110,7 +110,7 @@ static Ref _mesh_to_importer_mesh(Ref p_mesh) { return importer_mesh; } -Error GLTFDocument::_serialize(Ref p_state, const String &p_path) { +Error GLTFDocument::_serialize(Ref p_state) { if (!p_state->buffers.size()) { p_state->buffers.push_back(Vector()); } @@ -167,7 +167,7 @@ Error GLTFDocument::_serialize(Ref p_state, const String &p_path) { } /* STEP SERIALIZE IMAGES */ - err = _serialize_images(p_state, p_path); + err = _serialize_images(p_state); if (err != OK) { return Error::FAILED; } @@ -3001,7 +3001,7 @@ Error GLTFDocument::_parse_meshes(Ref p_state) { return OK; } -Error GLTFDocument::_serialize_images(Ref p_state, const String &p_path) { +Error GLTFDocument::_serialize_images(Ref p_state) { Array images; for (int i = 0; i < p_state->images.size(); i++) { Dictionary image_dict; @@ -3011,7 +3011,22 @@ Error GLTFDocument::_serialize_images(Ref p_state, const String &p_pa Ref image = p_state->images[i]->get_image(); ERR_CONTINUE(image.is_null()); - if (p_path.to_lower().ends_with("glb") || p_path.is_empty()) { + if (p_state->filename.to_lower().ends_with("gltf")) { + String img_name = p_state->images[i]->get_name(); + if (img_name.is_empty()) { + img_name = itos(i); + } + img_name = _gen_unique_name(p_state, img_name); + img_name = img_name.pad_zeros(3) + ".png"; + 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); + if (!da->dir_exists(full_texture_dir)) { + da->make_dir(full_texture_dir); + } + image->save_png(full_texture_dir.path_join(img_name)); + image_dict["uri"] = relative_texture_dir.path_join(img_name).uri_encode(); + } else { GLTFBufferViewIndex bvi; Ref bv; @@ -3039,23 +3054,6 @@ Error GLTFDocument::_serialize_images(Ref p_state, const String &p_pa bvi = p_state->buffer_views.size() - 1; image_dict["bufferView"] = bvi; image_dict["mimeType"] = "image/png"; - } else { - ERR_FAIL_COND_V(p_path.is_empty(), ERR_INVALID_PARAMETER); - String img_name = p_state->images[i]->get_name(); - if (img_name.is_empty()) { - img_name = itos(i); - } - img_name = _gen_unique_name(p_state, img_name); - img_name = img_name.pad_zeros(3) + ".png"; - String relative_texture_dir = "textures"; - String parent_path = p_path.get_base_dir(); - String full_texture_dir = parent_path + "/" + relative_texture_dir; - Ref da = DirAccess::open(parent_path); - if (!da->dir_exists(full_texture_dir)) { - da->make_dir(full_texture_dir); - } - image->save_png(full_texture_dir.path_join(img_name)); - image_dict["uri"] = relative_texture_dir.path_join(img_name).uri_encode(); } images.push_back(image_dict); } @@ -7241,7 +7239,10 @@ PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref p_state, Erro PackedByteArray GLTFDocument::generate_buffer(Ref p_state) { ERR_FAIL_NULL_V(p_state, PackedByteArray()); - Error err = _serialize(p_state, ""); + // For buffers, set the state filename to an empty string, but + // don't touch the base path, in case the user set it manually. + p_state->filename = ""; + Error err = _serialize(p_state); ERR_FAIL_COND_V(err != OK, PackedByteArray()); PackedByteArray bytes = _serialize_glb_buffer(p_state, &err); return bytes; @@ -7249,7 +7250,9 @@ PackedByteArray GLTFDocument::generate_buffer(Ref p_state) { Error GLTFDocument::write_to_filesystem(Ref p_state, const String &p_path) { ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER); - Error err = _serialize(p_state, p_path); + p_state->base_path = p_path.get_base_dir(); + p_state->filename = p_path.get_file(); + Error err = _serialize(p_state); if (err != OK) { return err; } diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index f8bd156feb4f..f2e36a045761 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -149,7 +149,7 @@ class GLTFDocument : public Resource { Error _parse_meshes(Ref p_state); Error _serialize_textures(Ref p_state); Error _serialize_texture_samplers(Ref p_state); - Error _serialize_images(Ref p_state, const String &p_path); + Error _serialize_images(Ref p_state); 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_file_extension, int p_index, Ref p_image); @@ -366,7 +366,7 @@ class GLTFDocument : public Resource { GLTFMeshIndex _convert_mesh_to_gltf(Ref p_state, MeshInstance3D *p_mesh_instance); void _convert_animation(Ref p_state, AnimationPlayer *p_animation_player, String p_animation_track_name); - Error _serialize(Ref p_state, const String &p_path); + Error _serialize(Ref p_state); Error _parse(Ref p_state, String p_path, Ref p_file); };