mirror of
https://github.com/godotengine/godot.git
synced 2024-11-15 00:23:27 +00:00
Merge pull request #72440 from V-Sekai/gltf_embed_as_uncompressed
gltf: Add GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_UNCOMPRESSED
This commit is contained in:
commit
c40020513a
@ -2289,7 +2289,14 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashM
|
||||
ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
|
||||
|
||||
Error err = OK;
|
||||
Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, p_options, nullptr, &err);
|
||||
HashMap<StringName, Variant> options_dupe = p_options;
|
||||
|
||||
// By default, the GLTF importer will extract embedded images into files on disk
|
||||
// However, we do not want the advanced settings dialog to be able to write files on disk.
|
||||
// To avoid this and also avoid compressing to basis every time, we are using the uncompressed option.
|
||||
options_dupe["gltf/embedded_image_handling"] = 3; // Embed as Uncompressed defined in GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_UNCOMPRESSED
|
||||
|
||||
Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, options_dupe, nullptr, &err);
|
||||
if (!scene || err != OK) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -264,10 +264,16 @@
|
||||
</members>
|
||||
<constants>
|
||||
<constant name="HANDLE_BINARY_DISCARD_TEXTURES" value="0">
|
||||
Discards all embedded textures and uses untextured materials.
|
||||
</constant>
|
||||
<constant name="HANDLE_BINARY_EXTRACT_TEXTURES" value="1">
|
||||
Extracts embedded textures to be reimported and compressed. Editor only. Acts as uncompressed at runtime.
|
||||
</constant>
|
||||
<constant name="HANDLE_BINARY_EMBED_AS_BASISU" value="2">
|
||||
Embeds textures VRAM compressed with Basis Universal into the generated scene.
|
||||
</constant>
|
||||
<constant name="HANDLE_BINARY_EMBED_AS_UNCOMPRESSED" value="3">
|
||||
Embeds textures compressed losslessly into the generated scene, matching old behavior.
|
||||
</constant>
|
||||
</constants>
|
||||
</class>
|
||||
|
@ -51,8 +51,8 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t
|
||||
doc.instantiate();
|
||||
Ref<GLTFState> state;
|
||||
state.instantiate();
|
||||
if (p_options.has("meshes/handle_gltf_embedded_images")) {
|
||||
int32_t enum_option = p_options["meshes/handle_gltf_embedded_images"];
|
||||
if (p_options.has("gltf/embedded_image_handling")) {
|
||||
int32_t enum_option = p_options["gltf/embedded_image_handling"];
|
||||
state->set_handle_binary_image(enum_option);
|
||||
}
|
||||
Error err = doc->append_from_file(p_path, state, p_flags);
|
||||
@ -87,7 +87,7 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t
|
||||
|
||||
void EditorSceneFormatImporterGLTF::get_import_options(const String &p_path,
|
||||
List<ResourceImporter::ImportOption> *r_options) {
|
||||
r_options->push_back(ResourceImporterScene::ImportOption(PropertyInfo(Variant::INT, "meshes/handle_gltf_embedded_images", PROPERTY_HINT_ENUM, "Discard All Textures,Extract Textures,Embed As Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), GLTFState::HANDLE_BINARY_EXTRACT_TEXTURES));
|
||||
r_options->push_back(ResourceImporterScene::ImportOption(PropertyInfo(Variant::INT, "gltf/embedded_image_handling", PROPERTY_HINT_ENUM, "Discard All Textures,Extract Textures,Embed As Basis Universal,Embed as Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), GLTFState::HANDLE_BINARY_EXTRACT_TEXTURES));
|
||||
}
|
||||
|
||||
#endif // TOOLS_ENABLED
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "extensions/gltf_spec_gloss.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/crypto/crypto_core.h"
|
||||
#include "core/io/config_file.h"
|
||||
#include "core/io/dir_access.h"
|
||||
@ -3220,8 +3221,8 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
|
||||
if (GLTFState::GLTFHandleBinary(p_state->handle_binary_image) == GLTFState::GLTFHandleBinary::HANDLE_BINARY_DISCARD_TEXTURES) {
|
||||
p_state->images.push_back(Ref<Texture2D>());
|
||||
p_state->source_images.push_back(Ref<Image>());
|
||||
continue;
|
||||
} else if (GLTFState::GLTFHandleBinary(p_state->handle_binary_image) == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EXTRACT_TEXTURES) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
} else if (Engine::get_singleton()->is_editor_hint() && GLTFState::GLTFHandleBinary(p_state->handle_binary_image) == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EXTRACT_TEXTURES) {
|
||||
if (p_state->base_path.is_empty()) {
|
||||
p_state->images.push_back(Ref<Texture2D>());
|
||||
p_state->source_images.push_back(Ref<Image>());
|
||||
@ -3230,26 +3231,56 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
|
||||
p_state->images.push_back(Ref<Texture2D>());
|
||||
p_state->source_images.push_back(Ref<Image>());
|
||||
} else {
|
||||
String file_path = p_state->get_base_path() + "/" + p_state->filename.get_basename() + "_" + img->get_name() + ".png";
|
||||
Ref<ConfigFile> config;
|
||||
config.instantiate();
|
||||
if (FileAccess::exists(file_path + ".import")) {
|
||||
config->load(file_path + ".import");
|
||||
}
|
||||
config->set_value("remap", "importer", "texture");
|
||||
config->set_value("remap", "type", "Texture2D");
|
||||
if (!config->has_section_key("params", "compress/mode")) {
|
||||
config->set_value("remap", "compress/mode", 2); //user may want another compression, so leave it bes
|
||||
}
|
||||
if (!config->has_section_key("params", "mipmaps/generate")) {
|
||||
config->set_value("params", "mipmaps/generate", true);
|
||||
}
|
||||
Error err = OK;
|
||||
err = config->save(file_path + ".import");
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
img->save_png(file_path);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
ResourceLoader::import(file_path);
|
||||
bool must_import = false;
|
||||
String file_path = p_state->get_base_path() + "/" + p_state->filename.get_basename() + "_" + img->get_name() + ".png";
|
||||
if (!FileAccess::exists(file_path + ".import")) {
|
||||
Ref<ConfigFile> config;
|
||||
config.instantiate();
|
||||
config->set_value("remap", "importer", "texture");
|
||||
config->set_value("remap", "type", "Texture2D");
|
||||
// Currently, it will likely use project defaults of Detect 3D, so textures will be reimported again.
|
||||
if (!config->has_section_key("params", "mipmaps/generate")) {
|
||||
config->set_value("params", "mipmaps/generate", true);
|
||||
}
|
||||
|
||||
if (ProjectSettings::get_singleton()->has_setting("importer_defaults/texture")) {
|
||||
//use defaults if exist
|
||||
Dictionary importer_defaults = GLOBAL_GET("importer_defaults/texture");
|
||||
List<Variant> importer_def_keys;
|
||||
importer_defaults.get_key_list(&importer_def_keys);
|
||||
for (const Variant &key : importer_def_keys) {
|
||||
if (!config->has_section_key("params", (String)key)) {
|
||||
config->set_value("params", (String)key, importer_defaults[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
err = config->save(file_path + ".import");
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
must_import = true;
|
||||
}
|
||||
Vector<uint8_t> png_buffer = img->save_png_to_buffer();
|
||||
if (ResourceLoader::exists(file_path)) {
|
||||
Ref<FileAccess> file = FileAccess::open(file_path, FileAccess::READ, &err);
|
||||
if (err == OK && file.is_valid()) {
|
||||
Vector<uint8_t> orig_png_buffer = file->get_buffer(file->get_length());
|
||||
if (png_buffer != orig_png_buffer) {
|
||||
must_import = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
must_import = true;
|
||||
}
|
||||
if (must_import) {
|
||||
Ref<FileAccess> file = FileAccess::open(file_path, FileAccess::WRITE, &err);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
ERR_FAIL_COND_V(file.is_null(), FAILED);
|
||||
file->store_buffer(png_buffer);
|
||||
file->flush();
|
||||
file.unref();
|
||||
// ResourceLoader::import will crash if not is_editor_hint(), so this case is protected above and will fall through to uncompressed.
|
||||
ResourceLoader::import(file_path);
|
||||
}
|
||||
Ref<Texture2D> saved_image = ResourceLoader::load(file_path, "Texture2D");
|
||||
if (saved_image.is_valid()) {
|
||||
p_state->images.push_back(saved_image);
|
||||
@ -3261,7 +3292,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
|
||||
p_state->source_images.push_back(Ref<Image>());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
#endif
|
||||
} else if (GLTFState::GLTFHandleBinary(p_state->handle_binary_image) == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_BASISU) {
|
||||
Ref<PortableCompressedTexture2D> tex;
|
||||
tex.instantiate();
|
||||
@ -3271,11 +3302,15 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
|
||||
tex->create_from_image(img, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL);
|
||||
p_state->images.push_back(tex);
|
||||
p_state->source_images.push_back(img);
|
||||
continue;
|
||||
} else {
|
||||
// This handles two cases: if editor hint and HANDLE_BINARY_EXTRACT_TEXTURES; or if HANDLE_BINARY_EMBED_AS_UNCOMPRESSED
|
||||
Ref<ImageTexture> tex;
|
||||
tex.instantiate();
|
||||
tex->set_name(img->get_name());
|
||||
tex->set_image(img);
|
||||
p_state->images.push_back(tex);
|
||||
p_state->source_images.push_back(img);
|
||||
}
|
||||
|
||||
p_state->images.push_back(Ref<Texture2D>());
|
||||
p_state->source_images.push_back(Ref<Image>());
|
||||
}
|
||||
|
||||
print_verbose("glTF: Total images: " + itos(p_state->images.size()));
|
||||
|
@ -120,11 +120,12 @@ void GLTFState::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "skeleton_to_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_skeleton_to_node", "get_skeleton_to_node"); // RBMap<GLTFSkeletonIndex,
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "create_animations"), "set_create_animations", "get_create_animations"); // bool
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_animations", "get_animations"); // Vector<Ref<GLTFAnimation>>
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "handle_binary_image", PROPERTY_HINT_ENUM, "Discard All Textures,Extract Textures,Embed As Basis Universal", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_handle_binary_image", "get_handle_binary_image"); // enum
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "handle_binary_image", PROPERTY_HINT_ENUM, "Discard All Textures,Extract Textures,Embed As Basis Universal,Embed as Uncompressed", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_handle_binary_image", "get_handle_binary_image"); // enum
|
||||
|
||||
BIND_CONSTANT(HANDLE_BINARY_DISCARD_TEXTURES);
|
||||
BIND_CONSTANT(HANDLE_BINARY_EXTRACT_TEXTURES);
|
||||
BIND_CONSTANT(HANDLE_BINARY_EMBED_AS_BASISU);
|
||||
BIND_CONSTANT(HANDLE_BINARY_EMBED_AS_UNCOMPRESSED);
|
||||
}
|
||||
|
||||
void GLTFState::add_used_extension(const String &p_extension_name, bool p_required) {
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
HANDLE_BINARY_DISCARD_TEXTURES = 0,
|
||||
HANDLE_BINARY_EXTRACT_TEXTURES,
|
||||
HANDLE_BINARY_EMBED_AS_BASISU,
|
||||
HANDLE_BINARY_EMBED_AS_UNCOMPRESSED, // if this value changes from 3, ResourceImporterScene::pre_import must be changed as well.
|
||||
};
|
||||
int32_t get_handle_binary_image() {
|
||||
return handle_binary_image;
|
||||
|
Loading…
Reference in New Issue
Block a user