Skip to content

Commit

Permalink
Merge pull request #62499 from fire/gltf-binary-img-compression
Browse files Browse the repository at this point in the history
Handle gltf binary images
  • Loading branch information
akien-mga committed Jan 27, 2023
2 parents 8b662c7 + 39922d7 commit 9d555f5
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 55 deletions.
20 changes: 19 additions & 1 deletion core/string/ustring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4342,6 +4342,9 @@ bool String::is_valid_html_color() const {
return Color::html_is_valid(*this);
}

// Changes made to the set of invalid filename characters must also be reflected in the String documentation for is_valid_filename.
static const char *invalid_filename_characters = ": / \\ ? * \" | % < >";

bool String::is_valid_filename() const {
String stripped = strip_edges();
if (*this != stripped) {
Expand All @@ -4352,7 +4355,22 @@ bool String::is_valid_filename() const {
return false;
}

return !(find(":") != -1 || find("/") != -1 || find("\\") != -1 || find("?") != -1 || find("*") != -1 || find("\"") != -1 || find("|") != -1 || find("%") != -1 || find("<") != -1 || find(">") != -1);
Vector<String> chars = String(invalid_filename_characters).split(" ");
for (const String &ch : chars) {
if (contains(ch)) {
return false;
}
}
return true;
}

String String::validate_filename() const {
Vector<String> chars = String(invalid_filename_characters).split(" ");
String name = strip_edges();
for (int i = 0; i < chars.size(); i++) {
name = name.replace(chars[i], "_");
}
return name;
}

bool String::is_valid_ip_address() const {
Expand Down
1 change: 1 addition & 0 deletions core/string/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ class String {
static const String invalid_node_name_characters;
String validate_node_name() const;
String validate_identifier() const;
String validate_filename() const;

bool is_valid_identifier() const;
bool is_valid_int() const;
Expand Down
1 change: 1 addition & 0 deletions core/variant/variant_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,7 @@ static void _register_variant_builtin_methods() {
bind_string_method(json_escape, sarray(), varray());

bind_string_method(validate_node_name, sarray(), varray());
bind_string_method(validate_filename, sarray(), varray());

bind_string_method(is_valid_identifier, sarray(), varray());
bind_string_method(is_valid_int, sarray(), varray());
Expand Down
6 changes: 6 additions & 0 deletions doc/classes/String.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,12 @@
[/codeblocks]
</description>
</method>
<method name="validate_filename" qualifiers="const">
<return type="String" />
<description>
Replace all characters that are not allowed in [method is_valid_filename] with underscores.
</description>
</method>
<method name="validate_node_name" qualifiers="const">
<return type="String" />
<description>
Expand Down
16 changes: 6 additions & 10 deletions editor/import/resource_importer_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,11 @@ void ResourceImporterTexture::save_to_ctex_format(Ref<FileAccess> f, const Ref<I
f->store_16(p_image->get_height());
f->store_32(p_image->get_mipmap_count());
f->store_32(p_image->get_format());

for (int i = 0; i < p_image->get_mipmap_count() + 1; i++) {
Vector<uint8_t> data = Image::basis_universal_packer(p_image->get_image_from_mipmap(i), p_channels);
int data_len = data.size();
f->store_32(data_len);

const uint8_t *r = data.ptr();
f->store_buffer(r, data_len);
}
Vector<uint8_t> data = Image::basis_universal_packer(p_image, p_channels);
int data_len = data.size();
f->store_32(data_len);
const uint8_t *r = data.ptr();
f->store_buffer(r, data_len);
} break;
}
}
Expand Down Expand Up @@ -387,7 +383,7 @@ void ResourceImporterTexture::_save_ctex(const Ref<Image> &p_image, const String

Ref<Image> image = p_image->duplicate();

if (((p_compress_mode == COMPRESS_BASIS_UNIVERSAL) || (p_compress_mode == COMPRESS_VRAM_COMPRESSED && p_force_po2_for_compressed)) && p_mipmaps) {
if (p_force_po2_for_compressed && p_mipmaps && ((p_compress_mode == COMPRESS_BASIS_UNIVERSAL) || (p_compress_mode == COMPRESS_VRAM_COMPRESSED))) {
image->resize_to_po2();
}

Expand Down
53 changes: 29 additions & 24 deletions modules/basis_universal/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,44 +52,50 @@ enum BasisDecompressFormat {
#ifdef TOOLS_ENABLED
static Vector<uint8_t> basis_universal_packer(const Ref<Image> &p_image, Image::UsedChannels p_channels) {
Vector<uint8_t> budata;

{
basisu::basis_compressor_params params;
Ref<Image> image = p_image->duplicate();

// unfortunately, basis universal does not support compressing supplied mipmaps,
// so for the time being, only compressing individual images will have to do.

if (image->has_mipmaps()) {
image->clear_mipmaps();
}
if (image->get_format() != Image::FORMAT_RGBA8) {
image->convert(Image::FORMAT_RGBA8);
}

basisu::image buimg(image->get_width(), image->get_height());

Ref<Image> image_single = image->duplicate();
{
Vector<uint8_t> vec = image->get_data();
if (image_single->has_mipmaps()) {
image_single->clear_mipmaps();
}
basisu::image buimg(image_single->get_width(), image_single->get_height());
Vector<uint8_t> vec = image_single->get_data();
const uint8_t *r = vec.ptr();

memcpy(buimg.get_ptr(), r, vec.size());
params.m_source_images.push_back(buimg);
}
basisu::vector<basisu::image> source_images;
for (int32_t mipmap_i = 1; mipmap_i < image->get_mipmap_count(); mipmap_i++) {
Ref<Image> mip = image->get_image_from_mipmap(mipmap_i);
basisu::image buimg(mip->get_width(), mip->get_height());
Vector<uint8_t> vec = mip->get_data();
const uint8_t *r = vec.ptr();
memcpy(buimg.get_ptr(), r, vec.size());
source_images.push_back(buimg);
}

basisu::basis_compressor_params params;
params.m_uastc = true;
params.m_max_endpoint_clusters = 512;
params.m_max_selector_clusters = 512;
params.m_quality_level = basisu::BASISU_QUALITY_MIN;

params.m_pack_uastc_flags &= ~basisu::cPackUASTCLevelMask;

static const uint32_t s_level_flags[basisu::TOTAL_PACK_UASTC_LEVELS] = { basisu::cPackUASTCLevelFastest, basisu::cPackUASTCLevelFaster, basisu::cPackUASTCLevelDefault, basisu::cPackUASTCLevelSlower, basisu::cPackUASTCLevelVerySlow };
params.m_pack_uastc_flags |= s_level_flags[0];
params.m_rdo_uastc = 0.0f;
params.m_rdo_uastc_quality_scalar = 0.0f;
params.m_rdo_uastc_dict_size = 1024;

params.m_mip_fast = true;
params.m_multithreading = true;
//params.m_quality_level = 0;
//params.m_disable_hierarchical_endpoint_codebooks = true;
//params.m_no_selector_rdo = true;

basisu::job_pool jpool(OS::get_singleton()->get_processor_count());
params.m_pJob_pool = &jpool;

params.m_mip_gen = false; //sorry, please some day support provided mipmaps.
params.m_source_images.push_back(buimg);

BasisDecompressFormat decompress_format = BASIS_DECOMPRESS_RG;
params.m_check_for_alpha = false;

Expand Down Expand Up @@ -252,8 +258,7 @@ static Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size
};
};

image.instantiate();
image->set_data(info.m_width, info.m_height, info.m_total_levels > 1, imgfmt, gpudata);
image = Image::create_from_data(info.m_width, info.m_height, info.m_total_levels > 1, imgfmt, gpudata);

return image;
}
Expand Down
11 changes: 11 additions & 0 deletions modules/gltf/doc_classes/GLTFState.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@
<description>
</description>
</method>
<method name="get_handle_binary_image">
<return type="int" />
<description>
</description>
</method>
<method name="get_images">
<return type="Texture2D[]" />
<description>
Expand Down Expand Up @@ -155,6 +160,12 @@
<description>
</description>
</method>
<method name="set_handle_binary_image">
<return type="void" />
<param index="0" name="method" type="int" />
<description>
</description>
</method>
<method name="set_images">
<return type="void" />
<param index="0" name="images" type="Texture2D[]" />
Expand Down
6 changes: 2 additions & 4 deletions modules/gltf/editor/editor_scene_importer_blend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#ifdef TOOLS_ENABLED

#include "../gltf_defines.h"
#include "../gltf_document.h"

#include "core/config/project_settings.h"
Expand All @@ -43,7 +44,6 @@
#include "scene/gui/line_edit.h"

#ifdef WINDOWS_ENABLED
// Code by Pedro Estebanez (https://github.com/godotengine/godot/pull/59766)
#include <shlwapi.h>
#endif

Expand Down Expand Up @@ -221,6 +221,7 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_
gltf.instantiate();
Ref<GLTFState> state;
state.instantiate();

String base_dir;
if (p_options.has(SNAME("blender/materials/unpack_enabled")) && p_options[SNAME("blender/materials/unpack_enabled")]) {
base_dir = sink.get_base_dir();
Expand Down Expand Up @@ -274,9 +275,6 @@ void EditorSceneFormatImporterBlend::get_import_options(const String &p_path, Li
ADD_OPTION_BOOL("blender/animation/limit_playback", true);
ADD_OPTION_BOOL("blender/animation/always_sample", true);
ADD_OPTION_BOOL("blender/animation/group_tracks", true);

#undef ADD_OPTION_BOOL
#undef ADD_OPTION_ENUM
}

///////////////////////////
Expand Down
10 changes: 10 additions & 0 deletions modules/gltf/editor/editor_scene_importer_gltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include "editor_scene_importer_gltf.h"

#include "../gltf_defines.h"
#include "../gltf_document.h"

uint32_t EditorSceneFormatImporterGLTF::get_import_flags() const {
Expand All @@ -50,6 +51,10 @@ 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"];
state->set_handle_binary_image(enum_option);
}
Error err = doc->append_from_file(p_path, state, p_flags);
if (err != OK) {
if (r_err) {
Expand All @@ -68,4 +73,9 @@ 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));
}

#endif // TOOLS_ENABLED
2 changes: 2 additions & 0 deletions modules/gltf/editor/editor_scene_importer_gltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class EditorSceneFormatImporterGLTF : public EditorSceneFormatImporter {
virtual Node *import_scene(const String &p_path, uint32_t p_flags,
const HashMap<StringName, Variant> &p_options,
List<String> *r_missing_deps, Error *r_err = nullptr) override;
virtual void get_import_options(const String &p_path,
List<ResourceImporter::ImportOption> *r_options) override;
};

#endif // TOOLS_ENABLED
Expand Down
Loading

0 comments on commit 9d555f5

Please sign in to comment.