|
41 | 41 | #include "editor/themes/editor_theme_manager.h" |
42 | 42 | #include "scene/resources/compressed_texture.h" |
43 | 43 |
|
| 44 | +Variant EditorTextureImportPlugin::get_option_value(const StringName &p_name) const { |
| 45 | + ERR_FAIL_COND_V_MSG(current_options == nullptr, Variant(), "get_option_value() called from a function where option values are not available."); |
| 46 | + ERR_FAIL_COND_V_MSG(!current_options->has(p_name), Variant(), "get_option_value() called with unexisting option argument: " + String(p_name)); |
| 47 | + return (*current_options)[p_name]; |
| 48 | +} |
| 49 | + |
| 50 | +void EditorTextureImportPlugin::add_import_option(const String &p_name, const Variant &p_default_value) { |
| 51 | + ERR_FAIL_NULL_MSG(current_option_list, "add_import_option() can only be called from get_import_options()."); |
| 52 | + add_import_option_advanced(p_default_value.get_type(), p_name, p_default_value); |
| 53 | +} |
| 54 | + |
| 55 | +void EditorTextureImportPlugin::add_import_option_advanced(Variant::Type p_type, const String &p_name, const Variant &p_default_value, PropertyHint p_hint, const String &p_hint_string, int p_usage_flags) { |
| 56 | + ERR_FAIL_NULL_MSG(current_option_list, "add_import_option_advanced() can only be called from get_import_options()."); |
| 57 | + current_option_list->push_back(ResourceImporter::ImportOption(PropertyInfo(p_type, p_name, p_hint, p_hint_string, p_usage_flags), p_default_value)); |
| 58 | +} |
| 59 | + |
| 60 | +void EditorTextureImportPlugin::get_recognized_extensions(List<String> *p_extensions) const { |
| 61 | + Vector<String> extensions; |
| 62 | + GDVIRTUAL_CALL(_get_recognized_extensions, extensions); |
| 63 | + for (int i = 0; i < extensions.size(); i++) { |
| 64 | + p_extensions->push_back(extensions[i]); |
| 65 | + } |
| 66 | +} |
| 67 | + |
| 68 | +void EditorTextureImportPlugin::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options, Preset p_preset) const { |
| 69 | + current_option_list = r_options; |
| 70 | + GDVIRTUAL_CALL(_get_import_options, p_path, p_preset); |
| 71 | + current_option_list = nullptr; |
| 72 | +} |
| 73 | + |
| 74 | +Variant EditorTextureImportPlugin::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const { |
| 75 | + current_options = &p_options; |
| 76 | + Variant ret; |
| 77 | + GDVIRTUAL_CALL(_get_option_visibility, p_path, p_option, ret); |
| 78 | + current_options = nullptr; |
| 79 | + return ret; |
| 80 | +} |
| 81 | + |
| 82 | +Error EditorTextureImportPlugin::load_image(Ref<Image> p_image, bool *r_use_custom_loader, const HashMap<StringName, Variant> &p_options) const { |
| 83 | + Error err = OK; |
| 84 | + current_options = &p_options; |
| 85 | + bool custom_loader = GDVIRTUAL_CALL(_load_image, p_image, err); |
| 86 | + current_options = nullptr; |
| 87 | + if (r_use_custom_loader) { |
| 88 | + *r_use_custom_loader = custom_loader; |
| 89 | + } |
| 90 | + return err; |
| 91 | +} |
| 92 | + |
| 93 | +Ref<Image> EditorTextureImportPlugin::pre_process(Ref<Image> p_image, const HashMap<StringName, Variant> &p_options) const { |
| 94 | + Ref<Image> image = p_image; |
| 95 | + current_options = &p_options; |
| 96 | + GDVIRTUAL_CALL(_pre_process, p_image, image); |
| 97 | + current_options = nullptr; |
| 98 | + return image; |
| 99 | +} |
| 100 | + |
| 101 | +Ref<Image> EditorTextureImportPlugin::post_process(Ref<Image> p_image, const HashMap<StringName, Variant> &p_options) const { |
| 102 | + Ref<Image> image = p_image; |
| 103 | + current_options = &p_options; |
| 104 | + GDVIRTUAL_CALL(_post_process, p_image, image); |
| 105 | + current_options = nullptr; |
| 106 | + return image; |
| 107 | +} |
| 108 | + |
| 109 | +void EditorTextureImportPlugin::_bind_methods() { |
| 110 | + ClassDB::bind_method(D_METHOD("get_option_value", "name"), &EditorTextureImportPlugin::get_option_value); |
| 111 | + ClassDB::bind_method(D_METHOD("add_import_option", "name", "value"), &EditorTextureImportPlugin::add_import_option); |
| 112 | + ClassDB::bind_method(D_METHOD("add_import_option_advanced", "type", "name", "default_value", "hint", "hint_string", "usage_flags"), &EditorTextureImportPlugin::add_import_option_advanced, DEFVAL(PROPERTY_HINT_NONE), DEFVAL(""), DEFVAL(PROPERTY_USAGE_DEFAULT)); |
| 113 | + |
| 114 | + BIND_ENUM_CONSTANT(PRESET_DETECT); |
| 115 | + BIND_ENUM_CONSTANT(PRESET_2D); |
| 116 | + BIND_ENUM_CONSTANT(PRESET_3D); |
| 117 | + |
| 118 | + GDVIRTUAL_BIND(_get_recognized_extensions); |
| 119 | + GDVIRTUAL_BIND(_get_import_options, "path", "preset_index"); |
| 120 | + GDVIRTUAL_BIND(_get_option_visibility, "path", "option"); |
| 121 | + GDVIRTUAL_BIND(_load_image, "image"); |
| 122 | + GDVIRTUAL_BIND(_pre_process, "image"); |
| 123 | + GDVIRTUAL_BIND(_post_process, "image"); |
| 124 | +} |
| 125 | + |
| 126 | +/////////////////////////////////////////////////////// |
| 127 | + |
44 | 128 | void ResourceImporterTexture::_texture_reimport_roughness(const Ref<CompressedTexture2D> &p_tex, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_channel) { |
45 | 129 | ERR_FAIL_COND(p_tex.is_null()); |
46 | 130 |
|
@@ -170,6 +254,9 @@ String ResourceImporterTexture::get_visible_name() const { |
170 | 254 |
|
171 | 255 | void ResourceImporterTexture::get_recognized_extensions(List<String> *p_extensions) const { |
172 | 256 | ImageLoader::get_recognized_extensions(p_extensions); |
| 257 | + for (const Ref<EditorTextureImportPlugin> &plugin : texture_import_plugins) { |
| 258 | + plugin->get_recognized_extensions(p_extensions); |
| 259 | + } |
173 | 260 | } |
174 | 261 |
|
175 | 262 | String ResourceImporterTexture::get_save_extension() const { |
@@ -209,6 +296,13 @@ bool ResourceImporterTexture::get_option_visibility(const String &p_path, const |
209 | 296 | return p_options["mipmaps/generate"]; |
210 | 297 | } |
211 | 298 |
|
| 299 | + for (const Ref<EditorTextureImportPlugin> &plugin : texture_import_plugins) { |
| 300 | + Variant ret = plugin->get_option_visibility(p_path, p_option, p_options); |
| 301 | + if (ret.get_type() == Variant::BOOL && !ret) { |
| 302 | + return false; |
| 303 | + } |
| 304 | + } |
| 305 | + |
212 | 306 | return true; |
213 | 307 | } |
214 | 308 |
|
@@ -256,6 +350,10 @@ void ResourceImporterTexture::get_import_options(const String &p_path, List<Impo |
256 | 350 | r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "editor/scale_with_editor_scale"), false)); |
257 | 351 | r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "editor/convert_colors_with_editor_theme"), false)); |
258 | 352 | } |
| 353 | + |
| 354 | + for (const Ref<EditorTextureImportPlugin> &plugin : texture_import_plugins) { |
| 355 | + plugin->get_import_options(p_path, r_options); |
| 356 | + } |
259 | 357 | } |
260 | 358 |
|
261 | 359 | void ResourceImporterTexture::save_to_ctex_format(Ref<FileAccess> f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality) { |
@@ -338,6 +436,23 @@ void ResourceImporterTexture::save_to_ctex_format(Ref<FileAccess> f, const Ref<I |
338 | 436 | } |
339 | 437 | } |
340 | 438 |
|
| 439 | +void ResourceImporterTexture::add_texture_import_plugin(Ref<EditorTextureImportPlugin> p_plugin, bool p_first_priority) { |
| 440 | + ERR_FAIL_COND(p_plugin.is_null()); |
| 441 | + if (p_first_priority) { |
| 442 | + texture_import_plugins.insert(0, p_plugin); |
| 443 | + } else { |
| 444 | + texture_import_plugins.push_back(p_plugin); |
| 445 | + } |
| 446 | +} |
| 447 | + |
| 448 | +void ResourceImporterTexture::remove_texture_import_plugin(Ref<EditorTextureImportPlugin> p_importer) { |
| 449 | + texture_import_plugins.erase(p_importer); |
| 450 | +} |
| 451 | + |
| 452 | +void ResourceImporterTexture::clean_up_importer_plugins() { |
| 453 | + texture_import_plugins.clear(); |
| 454 | +} |
| 455 | + |
341 | 456 | void ResourceImporterTexture::_save_ctex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_roughness, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel) { |
342 | 457 | Ref<FileAccess> f = FileAccess::open(p_to_path, FileAccess::WRITE); |
343 | 458 | ERR_FAIL_COND(f.is_null()); |
@@ -559,10 +674,25 @@ Error ResourceImporterTexture::import(ResourceUID::ID p_source_id, const String |
559 | 674 | // Load the main image. |
560 | 675 | Ref<Image> image; |
561 | 676 | image.instantiate(); |
562 | | - Error err = ImageLoader::load_image(p_source_file, image, nullptr, loader_flags, scale); |
563 | | - if (err != OK) { |
564 | | - return err; |
| 677 | + Error err = OK; |
| 678 | + bool use_custom_loader = false; |
| 679 | + |
| 680 | + for (const Ref<EditorTextureImportPlugin> &plugin : texture_import_plugins) { |
| 681 | + err = plugin->load_image(image, &use_custom_loader, p_options); |
| 682 | + } |
| 683 | + ERR_FAIL_COND_V_MSG(image.is_null(), ERR_INVALID_DATA, "The returned image of _load_image() is null."); |
| 684 | + ERR_FAIL_COND_V(use_custom_loader && err != OK, err); |
| 685 | + |
| 686 | + if (!use_custom_loader) { |
| 687 | + err = ImageLoader::load_image(p_source_file, image, nullptr, loader_flags, scale); |
| 688 | + ERR_FAIL_COND_V(err != OK, err); |
565 | 689 | } |
| 690 | + |
| 691 | + for (const Ref<EditorTextureImportPlugin> &plugin : texture_import_plugins) { |
| 692 | + image = plugin->pre_process(image, p_options); |
| 693 | + } |
| 694 | + ERR_FAIL_COND_V_MSG(image.is_null(), ERR_INVALID_DATA, "The returned image of _pre_process() is null."); |
| 695 | + |
566 | 696 | images_imported.push_back(image); |
567 | 697 |
|
568 | 698 | // Load the editor-only image. |
@@ -636,6 +766,11 @@ Error ResourceImporterTexture::import(ResourceUID::ID p_source_id, const String |
636 | 766 | } |
637 | 767 | } |
638 | 768 |
|
| 769 | + for (const Ref<EditorTextureImportPlugin> &plugin : texture_import_plugins) { |
| 770 | + image = plugin->post_process(image, p_options); |
| 771 | + } |
| 772 | + ERR_FAIL_COND_V_MSG(image.is_null(), ERR_INVALID_DATA, "The returned image of _post_process() is null."); |
| 773 | + |
639 | 774 | bool detect_3d = int(p_options["detect_3d/compress_to"]) > 0; |
640 | 775 | bool detect_roughness = roughness == 0; |
641 | 776 | bool detect_normal = normal == 0; |
@@ -837,6 +972,7 @@ bool ResourceImporterTexture::are_import_settings_valid(const String &p_path, co |
837 | 972 | } |
838 | 973 |
|
839 | 974 | ResourceImporterTexture *ResourceImporterTexture::singleton = nullptr; |
| 975 | +Vector<Ref<EditorTextureImportPlugin>> ResourceImporterTexture::texture_import_plugins; |
840 | 976 |
|
841 | 977 | ResourceImporterTexture::ResourceImporterTexture(bool p_singleton) { |
842 | 978 | // This should only be set through the EditorNode. |
|
0 commit comments