/*************************************************************************/ /* editor_texture_import_plugin.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "editor_texture_import_plugin.h" #if 0 #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor_atlas.h" #include "global_config.h" #include "io/image_loader.h" #include "io/marshalls.h" #include "io/resource_saver.h" #include "scene/gui/button_group.h" #include "scene/gui/check_button.h" #include "scene/gui/margin_container.h" #include "scene/io/resource_format_image.h" #include "thirdparty/misc/md5.h" static const char *flag_names[]={ ("Streaming Format"), ("Fix Border Alpha"), ("Alpha Bit Hint"), ("Compress Extra (PVRTC2)"), ("No MipMaps"), ("Repeat"), ("Filter (Magnifying)"), ("Premultiply Alpha"), ("Convert SRGB->Linear"), ("Convert NormalMap to XY"), ("Use Anisotropy"), NULL }; #if 0 // not used static const char *flag_short_names[]={ "Stream", "FixBorder", "AlphBit", "ExtComp", "NoMipMap", "Repeat", "Filter", "PMAlpha", "ToLinear", "ToRG", "Anisoropic", NULL }; #endif void EditorImportTextureOptions::set_format(EditorTextureImportPlugin::ImageFormat p_format) { updating=true; format->select(p_format); if (p_format==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { quality_vb->show(); } else { quality_vb->hide(); } updating=false; } EditorTextureImportPlugin::ImageFormat EditorImportTextureOptions::get_format() const{ return (EditorTextureImportPlugin::ImageFormat)format->get_selected(); } void EditorImportTextureOptions::set_flags(uint32_t p_flags){ updating=true; for(int i=0;iset_checked(0,p_flags&(1<set_value(p_quality); } float EditorImportTextureOptions::get_quality() const { return quality->get_value(); } uint32_t EditorImportTextureOptions::get_flags() const{ uint32_t f=0; for(int i=0;iis_checked(0)) f|=(1<get_selected()==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { quality_vb->show(); } else { quality_vb->hide(); } emit_signal("changed"); } void EditorImportTextureOptions::_bind_methods() { ClassDB::bind_method("_changed",&EditorImportTextureOptions::_changed); ClassDB::bind_method("_changedp",&EditorImportTextureOptions::_changedp); ADD_SIGNAL(MethodInfo("changed")); } void EditorImportTextureOptions::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { flags->connect("item_edited",this,"_changed"); format->connect("item_selected",this,"_changedp"); } } void EditorImportTextureOptions::show_2d_notice() { //notice_for_2d->show(); } EditorImportTextureOptions::EditorImportTextureOptions() { add_constant_override("separation",3); updating=false; format = memnew( OptionButton ); format->add_item(TTR("Uncompressed"),EditorTextureImportPlugin::IMAGE_FORMAT_UNCOMPRESSED); format->add_item(TTR("Compress Lossless (PNG)"),EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); format->add_item(TTR("Compress Lossy (WebP)"),EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); format->add_item(TTR("Compress (VRAM)"),EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); add_margin_child(TTR("Texture Format"),format); quality_vb = memnew( VBoxContainer ); HBoxContainer *quality_hb = memnew(HBoxContainer); HSlider *hs = memnew( HSlider ); hs->set_h_size_flags(SIZE_EXPAND_FILL); hs->set_stretch_ratio(0.8); quality_hb->add_child(hs); quality_hb->set_h_size_flags(SIZE_EXPAND_FILL); SpinBox *sb = memnew( SpinBox ); sb->set_h_size_flags(SIZE_EXPAND_FILL); sb->set_stretch_ratio(0.2); quality_hb->add_child(sb); sb->share(hs); hs->set_min(0); hs->set_max(1.0); hs->set_step(0.01); hs->set_value(0.7); quality=hs; quality_vb->add_margin_child(TTR("Texture Compression Quality (WebP):"),quality_hb); add_child(quality_vb); flags = memnew( Tree ); flags->set_hide_root(true); TreeItem *root = flags->create_item(); const char ** fname=flag_names; while( *fname ) { TreeItem*ti = flags->create_item(root); ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); ti->set_text(0,*fname); ti->set_editable(0,true); items.push_back(ti); fname++; } add_margin_child(TTR("Texture Options"),flags,true); } /////////////////////////////////////////////////////////// class EditorTextureImportDialog : public ConfirmationDialog { GDCLASS(EditorTextureImportDialog,ConfirmationDialog); HBoxContainer *mode_hb; CheckBox *mode_check[EditorTextureImportPlugin::MODE_MAX]; EditorImportTextureOptions *texture_options; EditorTextureImportPlugin::Mode mode; //EditorNode *editor; LineEdit *import_path; LineEdit *save_path; EditorFileDialog *file_select; EditorFileDialog *save_file_select; EditorDirDialog *save_select; OptionButton *texture_action; ConfirmationDialog *error_dialog; CheckButton *crop_source; SpinBox *size; MarginContainer *size_mc; Label* size_label; Label* source_label; Label *notice_for_2d; EditorTextureImportPlugin *plugin; void _mode_changed(int p_mode); void _choose_files(const Vector& p_path); void _choose_file(const String& p_path); void _choose_save_dir(const String& p_path); void _browse(); void _browse_target(); void _import(); protected: void _notification(int p_what); static void _bind_methods(); public: void setup_multiple_import_3d(const Vector& p_path,const String& p_dest) { _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_3D); _choose_files(p_path); _choose_save_dir(p_dest); } void add_sources_and_dest(const Vector& p_path,const String& p_dest) { _choose_files(p_path); _choose_save_dir(p_dest); } Error import(const String& p_from, const String& p_to, const String& p_preset); void popup_import(const String &p_from=String()); EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL); }; ///////////////////////////////////////////////////////// void EditorTextureImportDialog::_choose_files(const Vector& p_path) { String files; for(int i=0;i0) files+=","; files+=p_path[i]; } /* if (p_path.size()) { String srctex=p_path[0]; String ipath = EditorImportDB::get_singleton()->find_source_path(srctex); if (ipath!="") save_path->set_text(ipath.get_base_dir()); }*/ import_path->set_text(files); } void EditorTextureImportDialog::_choose_file(const String& p_path) { import_path->set_text(p_path); } void EditorTextureImportDialog::_choose_save_dir(const String& p_path) { save_path->set_text(p_path); } void EditorTextureImportDialog::_import() { //ImportMonitorBlock imb; Vector files=import_path->get_text().split(","); if (!files.size()) { error_dialog->set_text(TTR("Please specify some files!")); error_dialog->popup_centered(Size2(200,100)*EDSCALE); return; } String dst_path=save_path->get_text(); if (save_path->get_text().strip_edges()=="") { error_dialog->set_text(TTR("Target path is empty.")); error_dialog->popup_centered_minsize(); return; } if (!save_path->get_text().begins_with("res://")) { error_dialog->set_text(TTR("Target path must be a complete resource path.")); error_dialog->popup_centered_minsize(); return; } if (mode!=EditorTextureImportPlugin::MODE_ATLAS && mode!=EditorTextureImportPlugin::MODE_LARGE && !DirAccess::exists(save_path->get_text())) { error_dialog->set_text(TTR("Target path must exist.")); error_dialog->popup_centered_minsize(); return; } if (mode==EditorTextureImportPlugin::MODE_ATLAS) { //atlas if (files.size()==0) { error_dialog->set_text(TTR("At least one file needed for Atlas.")); error_dialog->popup_centered(Size2(200,100)*EDSCALE); return; } String dst_file = dst_path; //dst_file=dst_file.basename()+".tex"; Ref imd = memnew( ResourceImportMetadata ); //imd->set_editor(); for(int i=0;iadd_source(EditorImportPlugin::validate_source_path(files[i])); } imd->set_option("format",texture_options->get_format()); imd->set_option("flags",texture_options->get_flags()); imd->set_option("quality",texture_options->get_quality()); imd->set_option("atlas",true); imd->set_option("atlas_size",int(size->get_value())); imd->set_option("large",false); imd->set_option("crop",crop_source->is_pressed()); imd->set_option("mode",mode); Error err = plugin->import(dst_file,imd); if (err) { error_dialog->set_text(TTR("Error importing:")+" "+dst_file.get_file()); error_dialog->popup_centered(Size2(200,100)*EDSCALE); return; } } else if (mode==EditorTextureImportPlugin::MODE_LARGE) { //large if (files.size()!=1) { error_dialog->set_text(TTR("Only one file is required for large texture.")); error_dialog->popup_centered(Size2(200,100)*EDSCALE); return; } String dst_file = dst_path; //dst_file=dst_file.basename()+".tex"; Ref imd = memnew( ResourceImportMetadata ); //imd->set_editor(); for(int i=0;iadd_source(EditorImportPlugin::validate_source_path(files[i])); } imd->set_option("format",texture_options->get_format()); imd->set_option("flags",texture_options->get_flags()); imd->set_option("quality",texture_options->get_quality()); imd->set_option("atlas",false); imd->set_option("large",true); imd->set_option("large_cell_size",int(size->get_value())); imd->set_option("crop",crop_source->is_pressed()); imd->set_option("mode",mode); Error err = plugin->import(dst_file,imd); if (err) { error_dialog->set_text(TTR("Error importing:")+" "+dst_file.get_file()); error_dialog->popup_centered(Size2(200,100)*EDSCALE); return; } } else { for(int i=0;i imd = memnew( ResourceImportMetadata ); //imd->set_editor(); imd->add_source(EditorImportPlugin::validate_source_path(files[i])); imd->set_option("format",texture_options->get_format()); imd->set_option("flags",texture_options->get_flags()); imd->set_option("quality",texture_options->get_quality()); imd->set_option("atlas",false); imd->set_option("large",false); imd->set_option("mode",mode); Error err = plugin->import(dst_file,imd); if (err) { error_dialog->set_text(TTR("Error importing:")+" "+dst_file.get_file()); error_dialog->popup_centered(Size2(200,100)*EDSCALE); return; } } } hide(); } void EditorTextureImportDialog::_browse() { file_select->popup_centered_ratio(); } void EditorTextureImportDialog::_browse_target() { if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) { save_file_select->popup_centered_ratio(); } else { save_select->popup_centered_ratio(); } } void EditorTextureImportDialog::popup_import(const String& p_from) { popup_centered(Size2(600,500)*EDSCALE); if (p_from!="") { Ref rimd = ResourceLoader::load_import_metadata(p_from); ERR_FAIL_COND(!rimd.is_valid()); if (rimd->has_option("mode")) { //new imported stuff uses this option _mode_changed(rimd->get_option("mode")); } else { //this one is for compatibility, will have to guess it if (rimd->has_option("atlas") && rimd->get_option("atlas")) { _mode_changed(EditorTextureImportPlugin::MODE_ATLAS); } else if (rimd->has_option("large") && rimd->get_option("large")) { _mode_changed(EditorTextureImportPlugin::MODE_LARGE); } else { //guess by usage of mipmaps..? _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_2D); } } if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) save_path->set_text(p_from); else save_path->set_text(p_from.get_base_dir()); texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("format")))); texture_options->set_flags(rimd->get_option("flags")); texture_options->set_quality(rimd->get_option("quality")); String src = ""; for(int i=0;iget_source_count();i++) { if (i>0) src+=","; src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); } import_path->set_text(src); } } void EditorTextureImportDialog::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { List extensions; ImageLoader::get_recognized_extensions(&extensions); //ResourceLoader::get_recognized_extensions_for_type("PackedTexture",&extensions); file_select->clear_filters(); for(int i=0;iadd_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); } } } Error EditorTextureImportDialog::import(const String& p_from, const String& p_to, const String& p_preset) { import_path->set_text(p_from); save_path->set_text(p_to); _import(); return OK; } void EditorTextureImportDialog::_mode_changed(int p_mode) { mode = EditorTextureImportPlugin::Mode(p_mode); for(int i=0;iset_pressed(i==mode); } if (p_mode==EditorTextureImportPlugin::MODE_ATLAS) { size_label->set_text(TTR("Max Texture Size:")); size->set_value(2048); crop_source->show(); size_label->show(); size->show(); texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); texture_options->set_quality(0.7); texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); set_title(TTR("Import Textures for Atlas (2D)")); } else { crop_source->hide(); } if (p_mode==EditorTextureImportPlugin::MODE_LARGE) { size_label->set_text(TTR("Cell Size:")); size->set_value(256); size_label->show(); size->show(); file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); save_file_select->add_filter("*.ltex;"+TTR("Large Texture")); texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); texture_options->set_quality(0.7); texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); set_title(TTR("Import Large Textures (2D)")); source_label->set_text(TTR("Source Texture")); } else { file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); save_file_select->add_filter("*.tex;"+TTR("Base Atlas Texture")); source_label->set_text(TTR("Source Texture(s)")); } if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_2D) { size_label->hide(); size->hide(); texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); texture_options->set_quality(0.7); texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); notice_for_2d->show(); set_title(TTR("Import Textures for 2D")); } else { notice_for_2d->hide(); } if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_3D) { size_label->hide(); size->hide(); //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_); //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS); texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER|EditorTextureImportPlugin::IMAGE_FLAG_REPEAT); texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); set_title(TTR("Import Textures for 3D")); } } void EditorTextureImportDialog::_bind_methods() { ClassDB::bind_method("_choose_files",&EditorTextureImportDialog::_choose_files); ClassDB::bind_method("_choose_file",&EditorTextureImportDialog::_choose_file); ClassDB::bind_method("_choose_save_dir",&EditorTextureImportDialog::_choose_save_dir); ClassDB::bind_method("_import",&EditorTextureImportDialog::_import); ClassDB::bind_method("_browse",&EditorTextureImportDialog::_browse); ClassDB::bind_method("_browse_target",&EditorTextureImportDialog::_browse_target); ClassDB::bind_method("_mode_changed",&EditorTextureImportDialog::_mode_changed); //ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); } EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin) { plugin=p_plugin; set_title(TTR("Import Textures")); mode_hb = memnew( HBoxContainer ); add_child(mode_hb); //set_child_rect(mode_hb); VBoxContainer *vbcg = memnew( VBoxContainer); mode_hb->add_child(vbcg); mode_hb->add_constant_override("separation",15); VBoxContainer *bg = memnew( VBoxContainer ); vbcg->add_margin_child("Import Mode",bg); for(int i=0;iadd_child(mode_check[i]); mode_check[i]->set_text(mode_name[i]); mode_check[i]->connect("pressed",this,"_mode_changed",varray(i)); } VBoxContainer *vbc = memnew(VBoxContainer); mode_hb->add_child(vbc); vbc->set_h_size_flags(SIZE_EXPAND_FILL); vbc->add_constant_override("separation",4); notice_for_2d = memnew( Label ); notice_for_2d->set_text(TTR("NOTICE: Importing 2D textures is not mandatory. Just copy png/jpg files to the project.")); //notice_for_2d->set_custom_minimum_size(Size2(0,50)); notice_for_2d->set_autowrap(true); notice_for_2d->hide(); vbcg->add_child(notice_for_2d); notice_for_2d->set_v_size_flags(SIZE_EXPAND_FILL); notice_for_2d->set_valign(Label::VALIGN_BOTTOM); VBoxContainer *source_vb=memnew(VBoxContainer); MarginContainer *source_mc = vbc->add_margin_child(TTR("Source Texture(s):"),source_vb); source_label = vbc->get_child(source_mc->get_index()-1)->cast_to