diff options
Diffstat (limited to 'tools/editor/io_plugins')
16 files changed, 1258 insertions, 332 deletions
diff --git a/tools/editor/io_plugins/SCsub b/tools/editor/io_plugins/SCsub index b525fb3f75..363a2ce4c0 100644 --- a/tools/editor/io_plugins/SCsub +++ b/tools/editor/io_plugins/SCsub @@ -1,7 +1,3 @@ Import('env') Export('env') env.add_source_files(env.tool_sources,"*.cpp") - - - - diff --git a/tools/editor/io_plugins/editor_atlas.cpp b/tools/editor/io_plugins/editor_atlas.cpp index 4c716874ba..7e9acd193d 100644 --- a/tools/editor/io_plugins/editor_atlas.cpp +++ b/tools/editor/io_plugins/editor_atlas.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "editor_atlas.h" - +#include "print_string.h" struct _EditorAtlasWorkRect { @@ -83,6 +83,7 @@ void EditorAtlas::fit(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, S //place them int ofs=0; int limit_h=0; + for(int j=0;j<wrects.size();j++) { @@ -100,6 +101,9 @@ void EditorAtlas::fit(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, S wrects[j].p.x=ofs; wrects[j].p.y=from_y; + + + int end_h = from_y+wrects[j].s.height; int end_w = ofs+wrects[j].s.width; if (ofs==0) @@ -116,7 +120,7 @@ void EditorAtlas::fit(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, S if (end_w > max_w) max_w=end_w; - if (ofs==0 || end_h>limit_h ) //while h limit not reched, keep stacking + //if (ofs==0 || end_h>limit_h ) //while h limit not reched, keep stacking ofs+=wrects[j].s.width; } @@ -136,8 +140,8 @@ void EditorAtlas::fit(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, S for(int i=0;i<results.size();i++) { - float h = nearest_power_of_2(results[i].max_h); - float w = nearest_power_of_2(results[i].max_w); + float h = results[i].max_h; + float w = results[i].max_w; float aspect = h>w ? h/w : w/h; if (aspect < best_aspect) { best=i; diff --git a/tools/editor/io_plugins/editor_atlas.h b/tools/editor/io_plugins/editor_atlas.h index 685cf60c9d..716faff0c6 100644 --- a/tools/editor/io_plugins/editor_atlas.h +++ b/tools/editor/io_plugins/editor_atlas.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp index 064758f6cd..10a3877529 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +28,7 @@ /*************************************************************************/ #include "editor_font_import_plugin.h" #include "scene/gui/dialogs.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" #include "tools/editor/editor_node.h" #include "os/file_access.h" #include "editor_atlas.h" @@ -47,6 +47,12 @@ class _EditorFontImportOptions : public Object { OBJ_TYPE(_EditorFontImportOptions,Object); public: + enum FontMode { + + FONT_BITMAP, + FONT_DISTANCE_FIELD + }; + enum ColorType { COLOR_WHITE, COLOR_CUSTOM, @@ -69,6 +75,9 @@ public: CHARSET_CUSTOM_LATIN }; + + FontMode font_mode; + CharacterSet character_set; String custom_file; @@ -91,7 +100,6 @@ public: bool color_use_monochrome; String gradient_image; - bool disable_filter; bool round_advance; @@ -100,7 +108,10 @@ public: bool _set(const StringName& p_name, const Variant& p_value) { String n = p_name; - if (n=="extra_space/char") + if (n=="mode/mode") { + font_mode=FontMode(int(p_value)); + _change_notify(); + } else if (n=="extra_space/char") char_extra_spacing=p_value; else if (n=="extra_space/space") space_extra_spacing=p_value; @@ -169,7 +180,9 @@ public: bool _get(const StringName& p_name,Variant &r_ret) const{ String n = p_name; - if (n=="extra_space/char") + if (n=="mode/mode") + r_ret=font_mode; + else if (n=="extra_space/char") r_ret=char_extra_spacing; else if (n=="extra_space/space") r_ret=space_extra_spacing; @@ -231,6 +244,9 @@ public: void _get_property_list( List<PropertyInfo> *p_list) const{ + + p_list->push_back(PropertyInfo(Variant::INT,"mode/mode",PROPERTY_HINT_ENUM,"Bitmap,Distance Field")); + p_list->push_back(PropertyInfo(Variant::INT,"extra_space/char",PROPERTY_HINT_RANGE,"-64,64,1")); p_list->push_back(PropertyInfo(Variant::INT,"extra_space/space",PROPERTY_HINT_RANGE,"-64,64,1")); p_list->push_back(PropertyInfo(Variant::INT,"extra_space/top",PROPERTY_HINT_RANGE,"-64,64,1")); @@ -240,35 +256,45 @@ public: if (character_set>=CHARSET_CUSTOM) p_list->push_back(PropertyInfo(Variant::STRING,"character_set/custom",PROPERTY_HINT_FILE)); - p_list->push_back(PropertyInfo(Variant::BOOL,"shadow/enabled")); - if (shadow) { - p_list->push_back(PropertyInfo(Variant::INT,"shadow/radius",PROPERTY_HINT_RANGE,"-64,64,1")); - p_list->push_back(PropertyInfo(Variant::VECTOR2,"shadow/offset")); - p_list->push_back(PropertyInfo(Variant::COLOR,"shadow/color")); - p_list->push_back(PropertyInfo(Variant::REAL,"shadow/transition",PROPERTY_HINT_EXP_EASING)); - } + int usage = PROPERTY_USAGE_DEFAULT; - p_list->push_back(PropertyInfo(Variant::BOOL,"shadow2/enabled")); - if (shadow2) { - p_list->push_back(PropertyInfo(Variant::INT,"shadow2/radius",PROPERTY_HINT_RANGE,"-64,64,1")); - p_list->push_back(PropertyInfo(Variant::VECTOR2,"shadow2/offset")); - p_list->push_back(PropertyInfo(Variant::COLOR,"shadow2/color")); - p_list->push_back(PropertyInfo(Variant::REAL,"shadow2/transition",PROPERTY_HINT_EXP_EASING)); + if (font_mode==FONT_DISTANCE_FIELD) { + usage = PROPERTY_USAGE_NOEDITOR; } - p_list->push_back(PropertyInfo(Variant::INT,"color/mode",PROPERTY_HINT_ENUM,"White,Color,Gradient,Gradient Image")); - if (color_type==COLOR_CUSTOM) { - p_list->push_back(PropertyInfo(Variant::COLOR,"color/color")); + { + p_list->push_back(PropertyInfo(Variant::BOOL,"shadow/enabled",PROPERTY_HINT_NONE,"",usage)); + if (shadow) { + p_list->push_back(PropertyInfo(Variant::INT,"shadow/radius",PROPERTY_HINT_RANGE,"-64,64,1",usage)); + p_list->push_back(PropertyInfo(Variant::VECTOR2,"shadow/offset",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::COLOR,"shadow/color",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::REAL,"shadow/transition",PROPERTY_HINT_EXP_EASING,"",usage)); + } + + p_list->push_back(PropertyInfo(Variant::BOOL,"shadow2/enabled",PROPERTY_HINT_NONE,"",usage)); + if (shadow2) { + p_list->push_back(PropertyInfo(Variant::INT,"shadow2/radius",PROPERTY_HINT_RANGE,"-64,64,1",usage)); + p_list->push_back(PropertyInfo(Variant::VECTOR2,"shadow2/offset",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::COLOR,"shadow2/color",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::REAL,"shadow2/transition",PROPERTY_HINT_EXP_EASING,"",usage)); + } + + p_list->push_back(PropertyInfo(Variant::INT,"color/mode",PROPERTY_HINT_ENUM,"White,Color,Gradient,Gradient Image",usage)); + if (color_type==COLOR_CUSTOM) { + p_list->push_back(PropertyInfo(Variant::COLOR,"color/color",PROPERTY_HINT_NONE,"",usage)); + + } + if (color_type==COLOR_GRADIENT_RANGE) { + p_list->push_back(PropertyInfo(Variant::COLOR,"color/begin",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::COLOR,"color/end",PROPERTY_HINT_NONE,"",usage)); + } + if (color_type==COLOR_GRADIENT_IMAGE) { + p_list->push_back(PropertyInfo(Variant::STRING,"color/image",PROPERTY_HINT_FILE,"",usage)); + } + p_list->push_back(PropertyInfo(Variant::BOOL,"color/monochrome",PROPERTY_HINT_NONE,"",usage)); } - if (color_type==COLOR_GRADIENT_RANGE) { - p_list->push_back(PropertyInfo(Variant::COLOR,"color/begin")); - p_list->push_back(PropertyInfo(Variant::COLOR,"color/end")); - } - if (color_type==COLOR_GRADIENT_IMAGE) { - p_list->push_back(PropertyInfo(Variant::STRING,"color/image",PROPERTY_HINT_FILE)); - } - p_list->push_back(PropertyInfo(Variant::BOOL,"color/monochrome")); + p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/round_advance")); p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/disable_filter")); @@ -307,6 +333,7 @@ public: gradient_end=Color(0.5,0.5,0.5,1); color_use_monochrome=false; + font_mode=FONT_BITMAP; round_advance=true; disable_filter=false; @@ -314,6 +341,8 @@ public: _EditorFontImportOptions() { + font_mode=FONT_BITMAP; + char_extra_spacing=0; top_extra_spacing=0; bottom_extra_spacing=0; @@ -350,8 +379,8 @@ class EditorFontImportDialog : public ConfirmationDialog { OBJ_TYPE(EditorFontImportDialog, ConfirmationDialog); - LineEditFileChooser *source; - LineEditFileChooser *dest; + EditorLineEditFileChooser *source; + EditorLineEditFileChooser *dest; SpinBox *font_size; LineEdit *test_string; ColorPickerButton *test_color; @@ -377,7 +406,10 @@ class EditorFontImportDialog : public ConfirmationDialog { imd->set_option(opt,v); } - imd->add_source(EditorImportPlugin::validate_source_path(source->get_line_edit()->get_text())); + String src_path = EditorImportPlugin::validate_source_path(source->get_line_edit()->get_text()); + //print_line("pre src path "+source->get_line_edit()->get_text()); + //print_line("src path "+src_path); + imd->add_source(src_path); imd->set_option("font/size",font_size->get_val()); return imd; @@ -499,7 +531,7 @@ class EditorFontImportDialog : public ConfirmationDialog { Error err = plugin->import(dest->get_line_edit()->get_text(),rimd); if (err!=OK) { - error_dialog->set_text("Could't save font."); + error_dialog->set_text("Couldn't save font."); error_dialog->popup_centered(Size2(200,100)); return; } @@ -580,9 +612,9 @@ public: hbc->add_child(vbr); vbr->set_h_size_flags(SIZE_EXPAND_FILL); - source = memnew( LineEditFileChooser ); - source->get_file_dialog()->set_access(FileDialog::ACCESS_FILESYSTEM); - source->get_file_dialog()->set_mode(FileDialog::MODE_OPEN_FILE); + source = memnew( EditorLineEditFileChooser ); + source->get_file_dialog()->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + source->get_file_dialog()->set_mode(EditorFileDialog::MODE_OPEN_FILE); source->get_file_dialog()->add_filter("*.ttf;TrueType"); source->get_file_dialog()->add_filter("*.otf;OpenType"); source->get_line_edit()->connect("text_entered",this,"_src_changed"); @@ -594,7 +626,7 @@ public: font_size->set_max(256); font_size->set_val(16); font_size->connect("value_changed",this,"_font_size_changed"); - dest = memnew( LineEditFileChooser ); + dest = memnew( EditorLineEditFileChooser ); // List<String> fl; Ref<Font> font= memnew(Font); @@ -621,6 +653,7 @@ public: vbl->add_spacer(); vbl->add_margin_child("Test: ",testhb); + /* HBoxContainer *upd_hb = memnew( HBoxContainer ); // vbl->add_child(upd_hb); upd_hb->add_spacer(); @@ -628,7 +661,7 @@ public: upd_hb->add_child(update); update->set_text("Update"); update->connect("pressed",this,"_update"); - +*/ options = memnew( _EditorFontImportOptions ); prop_edit = memnew( PropertyEditor() ); vbr->add_margin_child("Options:",prop_edit,true); @@ -706,6 +739,137 @@ struct _EditorKerningKey { }; + +static unsigned char get_SDF_radial( + unsigned char *fontmap, + int w, int h, + int x, int y, + int max_radius ) +{ + // hideous brute force method + float d2 = max_radius*max_radius+1.0; + unsigned char v = fontmap[x+y*w]; + for( int radius = 1; (radius <= max_radius) && (radius*radius < d2); ++radius ) + { + int line, lo, hi; + // north + line = y - radius; + if( (line >= 0) && (line < h) ) + { + lo = x - radius; + hi = x + radius; + if( lo < 0 ) { lo = 0; } + if( hi >= w ) { hi = w-1; } + int idx = line * w + lo; + for( int i = lo; i <= hi; ++i ) + { + // check this pixel + if( fontmap[idx] != v ) + { + float nx = i - x; + float ny = line - y; + float nd2 = nx*nx+ny*ny; + if( nd2 < d2 ) + { + d2 = nd2; + } + } + // move on + ++idx; + } + } + // south + line = y + radius; + if( (line >= 0) && (line < h) ) + { + lo = x - radius; + hi = x + radius; + if( lo < 0 ) { lo = 0; } + if( hi >= w ) { hi = w-1; } + int idx = line * w + lo; + for( int i = lo; i <= hi; ++i ) + { + // check this pixel + if( fontmap[idx] != v ) + { + float nx = i - x; + float ny = line - y; + float nd2 = nx*nx+ny*ny; + if( nd2 < d2 ) + { + d2 = nd2; + } + } + // move on + ++idx; + } + } + // west + line = x - radius; + if( (line >= 0) && (line < w) ) + { + lo = y - radius + 1; + hi = y + radius - 1; + if( lo < 0 ) { lo = 0; } + if( hi >= h ) { hi = h-1; } + int idx = lo * w + line; + for( int i = lo; i <= hi; ++i ) + { + // check this pixel + if( fontmap[idx] != v ) + { + float nx = line - x; + float ny = i - y; + float nd2 = nx*nx+ny*ny; + if( nd2 < d2 ) + { + d2 = nd2; + } + } + // move on + idx += w; + } + } + // east + line = x + radius; + if( (line >= 0) && (line < w) ) + { + lo = y - radius + 1; + hi = y + radius - 1; + if( lo < 0 ) { lo = 0; } + if( hi >= h ) { hi = h-1; } + int idx = lo * w + line; + for( int i = lo; i <= hi; ++i ) + { + // check this pixel + if( fontmap[idx] != v ) + { + float nx = line - x; + float ny = i - y; + float nd2 = nx*nx+ny*ny; + if( nd2 < d2 ) + { + d2 = nd2; + } + } + // move on + idx += w; + } + } + } + d2 = sqrtf( d2 ); + if( v==0 ) + { + d2 = -d2; + } + d2 *= 127.5 / max_radius; + d2 += 127.5; + if( d2 < 0.0 ) d2 = 0.0; + if( d2 > 255.0 ) d2 = 255.0; + return (unsigned char)(d2 + 0.5); +} + + Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata>& p_from, const String &p_existing) { Ref<ResourceImportMetadata> from = p_from; @@ -754,7 +918,11 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata } - error = FT_Set_Pixel_Sizes(face,0,size); + int font_mode = from->get_option("mode/mode"); + + int scaler=(font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD)?16:1; + + error = FT_Set_Pixel_Sizes(face,0,size*scaler); FT_GlyphSlot slot = face->glyph; @@ -820,9 +988,9 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata { bool skip=false; - error = FT_Load_Char( face, charcode, FT_LOAD_RENDER ); + error = FT_Load_Char( face, charcode, font_mode==_EditorFontImportOptions::FONT_BITMAP?FT_LOAD_RENDER:FT_LOAD_MONOCHROME ); if (error) skip=true; - else error = FT_Render_Glyph( face->glyph, ft_render_mode_normal ); + else error = FT_Render_Glyph( face->glyph, font_mode==_EditorFontImportOptions::FONT_BITMAP?ft_render_mode_normal:ft_render_mode_mono ); if (error) { skip=true; } else if (!skip) { @@ -847,28 +1015,36 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata } _EditorFontData * fdata = memnew( _EditorFontData ); - fdata->bitmap.resize( slot->bitmap.width*slot->bitmap.rows ); - fdata->width=slot->bitmap.width; - fdata->height=slot->bitmap.rows; - fdata->character=charcode; - fdata->glyph=FT_Get_Char_Index(face,charcode); - if (charcode=='x') - xsize=slot->bitmap.width; - if (charcode<127) { - if (slot->bitmap_top>max_up) { + int w = slot->bitmap.width; + int h = slot->bitmap.rows; + int p = slot->bitmap.pitch; - max_up=slot->bitmap_top; - } + //print_line("W: "+itos(w)+" P: "+itos(slot->bitmap.pitch)); + if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { - if ( (slot->bitmap_top - fdata->height)<max_down ) { + // oversize the holding buffer so I can smooth it! + int sw = w + scaler * 4; + int sh = h + scaler * 4; + // do the SDF + int sdfw = sw / scaler; + int sdfh = sh / scaler; - max_down=slot->bitmap_top - fdata->height; - } + fdata->width=sdfw; + fdata->height=sdfh; + } else { + fdata->width=w; + fdata->height=h; } + fdata->character=charcode; + fdata->glyph=FT_Get_Char_Index(face,charcode); + if (charcode=='x') + xsize=w/scaler; + + fdata->valign=slot->bitmap_top; fdata->halign=slot->bitmap_left; @@ -878,12 +1054,85 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata else fdata->advance=slot->advance.x/float(1<<6); + if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { + + fdata->halign = fdata->halign / scaler - 1.5; + fdata->valign = fdata->valign / scaler + 1.5; + fdata->advance/=scaler; + + } + fdata->advance+=font_spacing; - for (int i=0;i<slot->bitmap.width;i++) { - for (int j=0;j<slot->bitmap.rows;j++) { - fdata->bitmap[j*slot->bitmap.width+i]=slot->bitmap.buffer[j*slot->bitmap.width+i]; + if (charcode<127) { + int top = fdata->valign; + int hmax = h/scaler; + + if (top>max_up) { + + max_up=top; + } + + + if ( (top - hmax)<max_down ) { + + max_down=top - hmax; + } + } + + if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { + + + // oversize the holding buffer so I can smooth it! + int sw = w + scaler * 4; + int sh = h + scaler * 4; + + unsigned char *smooth_buf = new unsigned char[sw*sh]; + + for( int i = 0; i < sw*sh; ++i ) { + smooth_buf[i] = 0; + } + + // copy the glyph into the buffer to be smoothed + unsigned char *buf = slot->bitmap.buffer; + for( int j = 0; j < h; ++j ) { + for( int i = 0; i < w; ++i ) { + smooth_buf[scaler*2+i+(j+scaler*2)*sw] = 255 * ((buf[j*p+(i>>3)] >> (7 - (i & 7))) & 1); + } + } + + // do the SDF + int sdfw = fdata->width; + int sdfh = fdata->height; + + fdata->bitmap.resize( sdfw*sdfh ); + + for( int j = 0; j < sdfh; ++j ) { + for( int i = 0; i < sdfw; ++i ) { + int pd_idx = j*sdfw+i; + + //fdata->bitmap[j*slot->bitmap.width+i]=slot->bitmap.buffer[j*slot->bitmap.width+i]; + + fdata->bitmap[pd_idx] = + //get_SDF + get_SDF_radial + ( smooth_buf, sw, sh, + i*scaler + (scaler >>1), j*scaler + (scaler >>1), + 2*scaler ); + + } + } + + delete [] smooth_buf; + + } else { + fdata->bitmap.resize( slot->bitmap.width*slot->bitmap.rows ); + for (int i=0;i<slot->bitmap.width;i++) { + for (int j=0;j<slot->bitmap.rows;j++) { + + fdata->bitmap[j*slot->bitmap.width+i]=slot->bitmap.buffer[j*slot->bitmap.width+i]; + } } } @@ -904,9 +1153,10 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata spd->ofs_x=0; spd->ofs_y=0; - if (!FT_Load_Char( face, ' ', FT_LOAD_RENDER ) && !FT_Render_Glyph( face->glyph, ft_render_mode_normal )) { + if (!FT_Load_Char( face, ' ', FT_LOAD_RENDER ) && !FT_Render_Glyph( face->glyph, font_mode==_EditorFontImportOptions::FONT_BITMAP?ft_render_mode_normal:ft_render_mode_mono )) { spd->advance = slot->advance.x>>6; //round to nearest or store as float + spd->advance/=scaler; spd->advance+=font_spacing; } else { @@ -955,7 +1205,7 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata if (kern==0) continue; - kerning_map[kpk]=kern; + kerning_map[kpk]=kern/scaler; } } } @@ -1079,7 +1329,7 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata pixels.resize(s.x*s.y*4); DVector<uint8_t>::Write w = pixels.write(); - print_line("val: "+itos(font_data_list[i]->valign)); + //print_line("val: "+itos(font_data_list[i]->valign)); for(int y=0;y<s.height;y++) { int yc=CLAMP(y-o.y+font_data_list[i]->valign,0,height-1); @@ -1284,6 +1534,7 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata font->clear(); font->set_height(height+bottom_space+top_space); font->set_ascent(ascent+top_space); + font->set_distance_field_hint(font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD); //register texures { diff --git a/tools/editor/io_plugins/editor_font_import_plugin.h b/tools/editor/io_plugins/editor_font_import_plugin.h index ac3b4eb0fe..451f01080e 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.h +++ b/tools/editor/io_plugins/editor_font_import_plugin.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp index 529ed3374b..d57cff850e 100644 --- a/tools/editor/io_plugins/editor_import_collada.cpp +++ b/tools/editor/io_plugins/editor_import_collada.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,6 +39,7 @@ #include "scene/resources/packed_scene.h" #include "os/os.h" #include "tools/editor/editor_node.h" +#include <iostream> struct ColladaImport { @@ -83,7 +84,7 @@ struct ColladaImport { Error _create_scene(Collada::Node *p_node, Spatial *p_parent); Error _create_resources(Collada::Node *p_node); Error _create_material(const String& p_material); - Error _create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data); + Error _create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data,Vector<Ref<Mesh> > p_morph_meshes=Vector<Ref<Mesh> >()); Error load(const String& p_path, int p_flags, bool p_force_make_tangents=false); void _fix_param_animation_tracks(); void create_animation(int p_clip,bool p_make_tracks_in_all_bones); @@ -285,13 +286,16 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) { case Collada::CameraData::MODE_ORTHOGONAL: { - if (cd.orthogonal.x_mag) { + if (cd.orthogonal.y_mag) { - camera->set_orthogonal(cd.orthogonal.x_mag,cd.z_near,cd.z_far); + camera->set_keep_aspect_mode(Camera::KEEP_HEIGHT); + camera->set_orthogonal(cd.orthogonal.y_mag*2.0 ,cd.z_near,cd.z_far); - } else if (!cd.orthogonal.x_mag && cd.orthogonal.y_mag) { + } else if (!cd.orthogonal.y_mag && cd.orthogonal.x_mag) { - camera->set_orthogonal(cd.orthogonal.y_mag * cd.aspect,cd.z_near,cd.z_far); + + camera->set_keep_aspect_mode(Camera::KEEP_WIDTH); + camera->set_orthogonal(cd.orthogonal.x_mag*2.0,cd.z_near,cd.z_far); } } break; @@ -585,7 +589,7 @@ static void _generate_tangents_and_binormals(const DVector<int>& p_indices,const } } -Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data) { +Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data,Vector<Ref<Mesh> > p_morph_meshes) { bool local_xform_mirror=p_local_xform.basis.determinant() < 0; @@ -706,10 +710,126 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co //find largest source.. + /************************/ + /* ADD WEIGHTS IF EXIST */ + /************************/ + + Map<int,Vector<Collada::Vertex::Weight> > pre_weights; + + bool has_weights=false; + + if (skin_controller) { + + const Collada::SkinControllerData::Source *weight_src=NULL; + int weight_ofs=0; + + if (skin_controller->weights.sources.has("WEIGHT")) { + + String weight_id = skin_controller->weights.sources["WEIGHT"].source; + weight_ofs = skin_controller->weights.sources["WEIGHT"].offset; + if (skin_controller->sources.has(weight_id)) { + + weight_src = &skin_controller->sources[weight_id]; + + } + } + + int joint_ofs=0; + + if (skin_controller->weights.sources.has("JOINT")) { + + joint_ofs = skin_controller->weights.sources["JOINT"].offset; + } + + //should be OK, given this was pre-checked. + + int index_ofs=0; + int wstride = skin_controller->weights.sources.size(); + for(int w_i=0;w_i<skin_controller->weights.sets.size();w_i++) { + + int amount = skin_controller->weights.sets[w_i]; + + Vector<Collada::Vertex::Weight> weights; + + for (int a_i=0;a_i<amount;a_i++) { + + Collada::Vertex::Weight w; + + int read_from = index_ofs+a_i*wstride; + ERR_FAIL_INDEX_V(read_from+wstride-1,skin_controller->weights.indices.size(),ERR_INVALID_DATA); + int weight_index = skin_controller->weights.indices[read_from+weight_ofs]; + ERR_FAIL_INDEX_V(weight_index,weight_src->array.size(),ERR_INVALID_DATA); + + w.weight = weight_src->array[weight_index]; + + int bone_index = skin_controller->weights.indices[read_from+joint_ofs]; + if (bone_index==-1) + continue; //ignore this weight (refers to bind shape) + ERR_FAIL_INDEX_V(bone_index,bone_remap.size(),ERR_INVALID_DATA); + + w.bone_idx=bone_remap[bone_index]; + + + weights.push_back(w); + } + + /* FIX WEIGHTS */ + + + + weights.sort(); + + if (weights.size()>4) { + //cap to 4 and make weights add up 1 + weights.resize(4); + + } + + //make sure weights allways add up to 1 + float total=0; + for(int i=0;i<weights.size();i++) + total+=weights[i].weight; + if (total) + for(int i=0;i<weights.size();i++) + weights[i].weight/=total; + + if (weights.size()==0 || total==0) { //if nothing, add a weight to bone 0 + //no weights assigned + Collada::Vertex::Weight w; + w.bone_idx=0; + w.weight=1.0; + weights.clear(); + weights.push_back(w); + + } + + pre_weights[w_i]=weights; + + /* + for(Set<int>::Element *E=vertex_map[w_i].front();E;E=E->next()) { + + int dst = E->get(); + ERR_EXPLAIN("invalid vertex index in array"); + ERR_FAIL_INDEX_V(dst,vertex_array.size(),ERR_INVALID_DATA); + vertex_array[dst].weights=weights; + + }*/ + + + + + index_ofs+=wstride*amount; + + } + + //vertices need to be localized + has_weights=true; + + } Set<Collada::Vertex> vertex_set; //vertex set will be the vertices List<int> indices_list; //indices will be the indices - Map<int,Set<int> > vertex_map; //map vertices (for setting skinning/morph) + //Map<int,Set<int> > vertex_map; //map vertices (for setting skinning/morph) /**************************/ /* CREATE PRIMITIVE ARRAY */ @@ -746,14 +866,19 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co ERR_FAIL_INDEX_V(src,p.indices.size(),ERR_INVALID_DATA); Collada::Vertex vertex; - if (p_morph_data) + if (!p_optimize) vertex.uid=vertidx++; + + int vertex_index=p.indices[src+vertex_ofs]; //used for index field (later used by controllers) int vertex_pos = (vertex_src->stride?vertex_src->stride:3) * vertex_index; ERR_FAIL_INDEX_V(vertex_pos,vertex_src->array.size(),ERR_INVALID_DATA); vertex.vertex=Vector3(vertex_src->array[vertex_pos+0],vertex_src->array[vertex_pos+1],vertex_src->array[vertex_pos+2]); + if (pre_weights.has(vertex_index)) { + vertex.weights=pre_weights[vertex_index]; + } if (normal_src) { @@ -832,9 +957,9 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co vertex_set.insert(vertex); } - if (!vertex_map.has(vertex_index)) + /* if (!vertex_map.has(vertex_index)) vertex_map[vertex_index]=Set<int>(); - vertex_map[vertex_index].insert(index); //should be outside.. + vertex_map[vertex_index].insert(index); //should be outside..*/ //build triangles if needed if (j==0) prev2[0]=index; @@ -870,120 +995,10 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co vertex_array[F->get().idx]=F->get(); } - /************************/ - /* ADD WEIGHTS IF EXIST */ - /************************/ - - - bool has_weights=false; - - if (skin_controller) { - - const Collada::SkinControllerData::Source *weight_src=NULL; - int weight_ofs=0; - if (skin_controller->weights.sources.has("WEIGHT")) { - - String weight_id = skin_controller->weights.sources["WEIGHT"].source; - weight_ofs = skin_controller->weights.sources["WEIGHT"].offset; - if (skin_controller->sources.has(weight_id)) { - - weight_src = &skin_controller->sources[weight_id]; - - } - } - - int joint_ofs=0; - - if (skin_controller->weights.sources.has("JOINT")) { - - joint_ofs = skin_controller->weights.sources["JOINT"].offset; - } - - //should be OK, given this was pre-checked. - - int index_ofs=0; - int wstride = skin_controller->weights.sources.size(); - for(int w_i=0;w_i<skin_controller->weights.sets.size();w_i++) { - - int amount = skin_controller->weights.sets[w_i]; - - if (vertex_map.has(w_i)) { //vertex may no longer be here, don't bother converting - - Vector<Collada::Vertex::Weight> weights; - - for (int a_i=0;a_i<amount;a_i++) { - - Collada::Vertex::Weight w; - - int read_from = index_ofs+a_i*wstride; - ERR_FAIL_INDEX_V(read_from+wstride-1,skin_controller->weights.indices.size(),ERR_INVALID_DATA); - int weight_index = skin_controller->weights.indices[read_from+weight_ofs]; - ERR_FAIL_INDEX_V(weight_index,weight_src->array.size(),ERR_INVALID_DATA); - - w.weight = weight_src->array[weight_index]; - - int bone_index = skin_controller->weights.indices[read_from+joint_ofs]; - if (bone_index==-1) - continue; //ignore this weight (refers to bind shape) - ERR_FAIL_INDEX_V(bone_index,bone_remap.size(),ERR_INVALID_DATA); - - w.bone_idx=bone_remap[bone_index]; - - - weights.push_back(w); - } - - /* FIX WEIGHTS */ - - - - weights.sort(); - - if (weights.size()>4) { - //cap to 4 and make weights add up 1 - weights.resize(4); - - } - - //make sure weights allways add up to 1 - float total=0; - for(int i=0;i<weights.size();i++) - total+=weights[i].weight; - if (total) - for(int i=0;i<weights.size();i++) - weights[i].weight/=total; - - if (weights.size()==0 || total==0) { //if nothing, add a weight to bone 0 - //no weights assigned - Collada::Vertex::Weight w; - w.bone_idx=0; - w.weight=1.0; - weights.clear(); - weights.push_back(w); - - } - - - for(Set<int>::Element *E=vertex_map[w_i].front();E;E=E->next()) { - - int dst = E->get(); - ERR_EXPLAIN("invalid vertex index in array"); - ERR_FAIL_INDEX_V(dst,vertex_array.size(),ERR_INVALID_DATA); - vertex_array[dst].weights=weights; - - } - - } else { - //zzprint_line("no vertex found for index "+itos(w_i)); - } - - index_ofs+=wstride*amount; - - } - - //vertices need to be localized + if (has_weights) { + //if skeleton, localize Transform local_xform = p_local_xform; for(int i=0;i<vertex_array.size();i++) { @@ -996,11 +1011,9 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co //vertex_array[i].tangent.normal*=-1.0; } } - - has_weights=true; - } + DVector<int> index_array; index_array.resize(indices_list.size()); DVector<int>::Write index_arrayw = index_array.write(); @@ -1272,7 +1285,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co //////////////////////////// // THEN THE MORPH TARGETS // //////////////////////////// - +#if 0 if (p_morph_data) { //add morphie target @@ -1354,8 +1367,63 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co vertw = DVector<Vector3>::Write(); DVector<Vector3> normals; DVector<float> tangents; + print_line("vertex source id: "+vertex_src_id); + if(md.vertices[vertex_src_id].sources.has("NORMAL")){ + //has normals + normals.resize(vlen); + //std::cout << "has normals" << std::endl; + String normal_src_id = md.vertices[vertex_src_id].sources["NORMAL"]; + //std::cout << "normals source: "<< normal_src_id.utf8().get_data() <<std::endl; + ERR_FAIL_COND_V(!md.sources.has(normal_src_id),ERR_INVALID_DATA); + + const Collada::MeshData::Source *m=&md.sources[normal_src_id]; + + ERR_FAIL_COND_V( m->array.size() != vertex_src->array.size(), ERR_INVALID_DATA); + int stride=m->stride; + if (stride==0) + stride=3; + + + //read normals from morph target + DVector<Vector3>::Write vertw = normals.write(); + + for(int m_i=0;m_i<m->array.size()/stride;m_i++) { + + int pos = m_i*stride; + Vector3 vtx( m->array[pos+0], m->array[pos+1], m->array[pos+2] ); + + #ifndef NO_UP_AXIS_SWAP + if (collada.state.up_axis==Vector3::AXIS_Z) { + + SWAP( vtx.z, vtx.y ); + vtx.z = -vtx.z; + + } + #endif + + Collada::Vertex vertex; + vertex.vertex=vtx; + vertex.fix_unit_scale(collada); + vtx=vertex.vertex; + + vtx = p_local_xform.xform(vtx); + - _generate_normals(index_array,vertices,normals); + if (vertex_map.has(m_i)) { //vertex may no longer be here, don't bother converting + + + for (Set<int> ::Element *E=vertex_map[m_i].front() ; E; E=E->next() ) { + + vertw[E->get()]=vtx; + } + } + } + + print_line("using built-in normals"); + }else{ + print_line("generating normals"); + _generate_normals(index_array,vertices,normals);//no normals + } if (final_tangent_array.size() && final_uv_array.size()) { _generate_tangents_and_binormals(index_array,vertices,final_uv_array,normals,tangents); @@ -1380,6 +1448,17 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co } +#endif + for(int mi=0;mi<p_morph_meshes.size();mi++) { + + // print_line("want surface "+itos(mi)+" has "+itos(p_morph_meshes[mi]->get_surface_count())); + Array a = p_morph_meshes[mi]->surface_get_arrays(surface); + a[Mesh::ARRAY_BONES]=Variant(); + a[Mesh::ARRAY_WEIGHTS]=Variant(); + a[Mesh::ARRAY_INDEX]=Variant(); + //a.resize(Mesh::ARRAY_MAX); //no need for index + mr.push_back(a); + } p_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,d,mr); @@ -1510,17 +1589,21 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) { String meshid; Transform apply_xform; Vector<int> bone_remap; + Vector<Ref<Mesh> > morphs; print_line("mesh: "+String(mi->get_name())); if (ng->controller) { print_line("has controller"); - if (collada.state.skin_controller_data_map.has(ng->source)) { + String ngsource = ng->source; - ERR_FAIL_COND_V(!collada.state.skin_controller_data_map.has(ng->source),ERR_INVALID_DATA); - skin=&collada.state.skin_controller_data_map[ng->source]; + if (collada.state.skin_controller_data_map.has(ngsource)) { + + + ERR_FAIL_COND_V(!collada.state.skin_controller_data_map.has(ngsource),ERR_INVALID_DATA); + skin=&collada.state.skin_controller_data_map[ngsource]; Vector<String> skeletons = ng->skeletons; @@ -1543,7 +1626,10 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) { if (collada.state.morph_controller_data_map.has(meshid)) { //it's a morph!! morph = &collada.state.morph_controller_data_map[meshid]; + ngsource=meshid; meshid=morph->mesh; + } else { + ngsource=""; } if (apply_mesh_xform_to_vertices) { @@ -1574,15 +1660,48 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) { ERR_FAIL_COND_V( !bone_remap_map.has(str), ERR_INVALID_DATA ); bone_remap[i]=bone_remap_map[str]; } - } else if (collada.state.morph_controller_data_map.has(ng->source)) { - print_line("is morph "+ng->source); + } + + if (collada.state.morph_controller_data_map.has(ngsource)) { + print_line("is morph "+ngsource); //it's a morph!! - morph = &collada.state.morph_controller_data_map[ng->source]; + morph = &collada.state.morph_controller_data_map[ngsource]; meshid=morph->mesh; printf("KKmorph: %p\n",morph); print_line("morph mshid: "+meshid); - } else { - ERR_EXPLAIN("Controller Instance Source '"+ng->source+"' is neither skin or morph!"); + + Vector<String> targets; + + morph->targets.has("MORPH_TARGET"); + String target = morph->targets["MORPH_TARGET"]; + bool valid=false; + if (morph->sources.has(target)) { + valid=true; + Vector<String> names = morph->sources[target].sarray; + for(int i=0;i<names.size();i++) { + + String meshid=names[i]; + if (collada.state.mesh_data_map.has(meshid)) { + Ref<Mesh> mesh=Ref<Mesh>(memnew( Mesh )); + const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; + Error err = _create_mesh_surfaces(false,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,NULL); + ERR_FAIL_COND_V(err,err); + + morphs.push_back(mesh); + } else { + valid=false; + } + } + } + + if (!valid) + morphs.clear(); + + ngsource=""; + } + + if (ngsource!=""){ + ERR_EXPLAIN("Controller Instance Source '"+ngsource+"' is neither skin or morph!"); ERR_FAIL_V( ERR_INVALID_DATA ); } @@ -1603,7 +1722,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) { mesh=Ref<Mesh>(memnew( Mesh )); const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; mesh->set_name( meshdata.name ); - Error err = _create_mesh_surfaces(mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,morph); + Error err = _create_mesh_surfaces(morphs.size()==0,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,morph,morphs); ERR_FAIL_COND_V(err,err); mesh_cache[meshid]=mesh; diff --git a/tools/editor/io_plugins/editor_import_collada.h b/tools/editor/io_plugins/editor_import_collada.h index ae4cedeff6..243cd043a0 100644 --- a/tools/editor/io_plugins/editor_import_collada.h +++ b/tools/editor/io_plugins/editor_import_collada.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp index 7d6f400ccc..2139513025 100644 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp @@ -1,6 +1,6 @@ #include "editor_mesh_import_plugin.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" #include "tools/editor/editor_dir_dialog.h" #include "tools/editor/editor_node.h" #include "tools/editor/property_editor.h" @@ -105,7 +105,7 @@ public: _EditorMeshImportOptions() { generate_tangents=true; - generate_normals=true; + generate_normals=false; flip_faces=false; smooth_shading=false; weld_vertices=true; @@ -126,7 +126,7 @@ class EditorMeshImportDialog : public ConfirmationDialog { LineEdit *import_path; LineEdit *save_path; - FileDialog *file_select; + EditorFileDialog *file_select; EditorDirDialog *save_select; ConfirmationDialog *error_dialog; PropertyEditor *option_editor; @@ -300,16 +300,16 @@ public: save_choose->connect("pressed", this,"_browse_target"); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILES); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); file_select->connect("files_selected", this,"_choose_files"); file_select->add_filter("*.obj ; Wavefront OBJ"); save_select = memnew( EditorDirDialog ); add_child(save_select); - // save_select->set_mode(FileDialog::MODE_OPEN_DIR); + // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); save_select->connect("dir_selected", this,"_choose_save_dir"); get_ok()->connect("pressed", this,"_import"); diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp index 377af8f179..7888246956 100644 --- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_sample_import_plugin.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "editor_sample_import_plugin.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" #include "tools/editor/editor_dir_dialog.h" #include "tools/editor/editor_node.h" #include "tools/editor/property_editor.h" @@ -35,6 +35,7 @@ #include "io/resource_saver.h" #include "os/file_access.h" #include "io/marshalls.h" +#include "tools/editor/editor_settings.h" class _EditorSampleImportOptions : public Object { @@ -156,7 +157,7 @@ public: edit_normalize=true; edit_loop=false; - compress_mode=COMPRESS_MODE_DISABLED; + compress_mode=COMPRESS_MODE_RAM; compress_bitrate=COMPRESS_128; } @@ -171,7 +172,7 @@ class EditorSampleImportDialog : public ConfirmationDialog { LineEdit *import_path; LineEdit *save_path; - FileDialog *file_select; + EditorFileDialog *file_select; EditorDirDialog *save_select; ConfirmationDialog *error_dialog; PropertyEditor *option_editor; @@ -254,6 +255,24 @@ public: error_dialog->popup_centered(Size2(200,100)); } + if (save_path->get_text().strip_edges()=="") { + error_dialog->set_text("Target path is empty."); + error_dialog->popup_centered_minsize(); + return; + } + + if (!save_path->get_text().begins_with("res://")) { + error_dialog->set_text("Target path must be full resource path."); + error_dialog->popup_centered_minsize(); + return; + } + + if (!DirAccess::exists(save_path->get_text())) { + error_dialog->set_text("Target path must exist."); + error_dialog->popup_centered_minsize(); + return; + } + for(int i=0;i<samples.size();i++) { Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); @@ -345,16 +364,16 @@ public: save_choose->connect("pressed", this,"_browse_target"); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILES); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); file_select->connect("files_selected", this,"_choose_files"); file_select->add_filter("*.wav ; MS Waveform"); save_select = memnew( EditorDirDialog ); add_child(save_select); - // save_select->set_mode(FileDialog::MODE_OPEN_DIR); + // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); save_select->connect("dir_selected", this,"_choose_save_dir"); get_ok()->connect("pressed", this,"_import"); @@ -562,8 +581,7 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI int compression = from->get_option("compress/mode"); bool force_mono = from->get_option("force/mono"); - if (compression==_EditorSampleImportOptions::COMPRESS_MODE_RAM) - force_mono=true; + if (force_mono && chans==2) { @@ -590,8 +608,47 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI if ( compression == _EditorSampleImportOptions::COMPRESS_MODE_RAM) { dst_format=Sample::FORMAT_IMA_ADPCM; + if (chans==1) { + _compress_ima_adpcm(data,dst_data); + } else { + + print_line("INTERLEAAVE!"); + + + + //byte interleave + Vector<float> left; + Vector<float> right; - _compress_ima_adpcm(data,dst_data); + int tlen = data.size()/2; + left.resize(tlen); + right.resize(tlen); + + for(int i=0;i<tlen;i++) { + left[i]=data[i*2+0]; + right[i]=data[i*2+1]; + } + + DVector<uint8_t> bleft; + DVector<uint8_t> bright; + + _compress_ima_adpcm(left,bleft); + _compress_ima_adpcm(right,bright); + + int dl = bleft.size(); + dst_data.resize( dl *2 ); + + DVector<uint8_t>::Write w=dst_data.write(); + DVector<uint8_t>::Read rl=bleft.read(); + DVector<uint8_t>::Read rr=bright.read(); + + for(int i=0;i<dl;i++) { + w[i*2+0]=rl[i]; + w[i*2+1]=rr[i]; + } + } + +// print_line("compressing ima-adpcm, resulting buffersize is "+itos(dst_data.size())+" from "+itos(data.size())); } else { @@ -691,7 +748,7 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D *(out++) =0; for (i=0;i<datalen;i++) { - int step,diff,vpdiff,signed_nibble,p,mask; + int step,diff,vpdiff,mask; uint8_t nibble; int16_t xm_sample; @@ -701,8 +758,8 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D xm_sample=CLAMP(in[i]*32767.0,-32768,32767); - if (xm_sample==32767 || xm_sample==-32768) - printf("clippy!\n",xm_sample); + //if (xm_sample==32767 || xm_sample==-32768) + // printf("clippy!\n",xm_sample); } // xm_sample=xm_sample+xm_prev; @@ -737,10 +794,10 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D prev+=vpdiff ; if (prev > 32767) { - printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev); + //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev); prev=32767; } else if (prev < -32768) { - printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev); + //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev); prev = -32768 ; } @@ -762,9 +819,54 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D } + +EditorSampleImportPlugin* EditorSampleImportPlugin::singleton=NULL; + + + EditorSampleImportPlugin::EditorSampleImportPlugin(EditorNode* p_editor) { + singleton=this; dialog = memnew( EditorSampleImportDialog(this)); p_editor->get_gui_base()->add_child(dialog); } +Vector<uint8_t> EditorSampleExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { + + + + if (EditorImportExport::get_singleton()->sample_get_action()==EditorImportExport::SAMPLE_ACTION_NONE || p_path.extension().to_lower()!="wav") { + + return Vector<uint8_t>(); + } + + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + + imd->add_source(EditorImportPlugin::validate_source_path(p_path)); + + imd->set_option("force/8_bit",false); + imd->set_option("force/mono",false); + imd->set_option("force/max_rate",true); + imd->set_option("force/max_rate_hz",EditorImportExport::get_singleton()->sample_get_max_hz()); + imd->set_option("edit/trim",EditorImportExport::get_singleton()->sample_get_trim()); + imd->set_option("edit/normalize",false); + imd->set_option("edit/loop",false); + imd->set_option("compress/mode",1); + + String savepath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/smpconv.smp"); + Error err = EditorSampleImportPlugin::singleton->import(savepath,imd); + + + ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); + + p_path=p_path.basename()+".smp"; + return FileAccess::get_file_as_array(savepath); + +} + + +EditorSampleExportPlugin::EditorSampleExportPlugin() { + +} + + diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.h b/tools/editor/io_plugins/editor_sample_import_plugin.h index 176dece0d5..89319affa0 100644 --- a/tools/editor/io_plugins/editor_sample_import_plugin.h +++ b/tools/editor/io_plugins/editor_sample_import_plugin.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -43,6 +43,8 @@ class EditorSampleImportPlugin : public EditorImportPlugin { void _compress_ima_adpcm(const Vector<float>& p_data,DVector<uint8_t>& dst_data); public: + static EditorSampleImportPlugin *singleton; + virtual String get_name() const; virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); @@ -52,4 +54,16 @@ public: EditorSampleImportPlugin(EditorNode* p_editor); }; +class EditorSampleExportPlugin : public EditorExportPlugin { + + OBJ_TYPE( EditorSampleExportPlugin, EditorExportPlugin); + + +public: + + virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform); + + EditorSampleExportPlugin(); +}; + #endif // EDITOR_SAMPLE_IMPORT_PLUGIN_H diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp index 06780e4d8a..ca44df269b 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -162,8 +162,8 @@ class EditorSceneImportDialog : public ConfirmationDialog { LineEdit *save_path; LineEdit *script_path; Tree *import_options; - FileDialog *file_select; - FileDialog *script_select; + EditorFileDialog *file_select; + EditorFileDialog *script_select; EditorDirDialog *save_select; OptionButton *texture_action; @@ -671,15 +671,28 @@ void EditorSceneImportDialog::_import(bool p_and_open) { wip_open=p_and_open; //' ImportMonitorBlock imb; - if (import_path->get_text()=="") { + + if (import_path->get_text().strip_edges()=="") { error_dialog->set_text("Source path is empty."); - error_dialog->popup_centered(Size2(200,100)); + error_dialog->popup_centered_minsize(); return; } - if (save_path->get_text()=="") { + if (save_path->get_text().strip_edges()=="") { error_dialog->set_text("Target path is empty."); - error_dialog->popup_centered(Size2(200,100)); + error_dialog->popup_centered_minsize(); + return; + } + + if (!save_path->get_text().begins_with("res://")) { + error_dialog->set_text("Target path must be full resource path."); + error_dialog->popup_centered_minsize(); + return; + } + + if (!DirAccess::exists(save_path->get_text())) { + error_dialog->set_text("Target path must exist."); + error_dialog->popup_centered_minsize(); return; } @@ -701,7 +714,8 @@ void EditorSceneImportDialog::_import(bool p_and_open) { } - Ref<EditorScenePostImport> pi; + + if (script_path->get_text()!="") { Ref<Script> scr = ResourceLoader::load(script_path->get_text()); @@ -711,7 +725,7 @@ void EditorSceneImportDialog::_import(bool p_and_open) { return; } - pi = Ref<EditorScenePostImport>( memnew( EditorScenePostImport ) ); + Ref<EditorScenePostImport> pi = Ref<EditorScenePostImport>( memnew( EditorScenePostImport ) ); pi->set_script(scr.get_ref_ptr()); if (!pi->get_script_instance()) { @@ -719,6 +733,7 @@ void EditorSceneImportDialog::_import(bool p_and_open) { error_dialog->popup_centered(Size2(200,100)); return; } + } @@ -747,7 +762,7 @@ void EditorSceneImportDialog::_import(bool p_and_open) { rim->set_option("animation_optimizer_max_angle",animation_options->get_optimize_max_angle()); rim->set_option("animation_filters",animation_options->get_filter()); rim->set_option("animation_clips",animation_options->get_clips()); - rim->set_option("post_import_script",script_path->get_text()!=String()?EditorImportPlugin::validate_source_path(script_path->get_text()):String()); + rim->set_option("post_import_script",script_path->get_text()); rim->set_option("import_this_time",this_import->get_selected()); rim->set_option("import_next_time",next_import->get_selected()); rim->set_option("reimport",true); @@ -893,6 +908,7 @@ void EditorSceneImportDialog::popup_import(const String &p_from) { if (rimd->has_option("animation_optimizer_max_angle")) animation_options->set_optimize_max_angle(rimd->get_option("animation_optimizer_max_angle")); + script_path->set_text(rimd->get_option("post_import_script")); if (rimd->has_option("import_this_time")) this_import->select(rimd->get_option("import_this_time")); @@ -1063,19 +1079,19 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce vbc->set_v_size_flags(SIZE_EXPAND_FILL); vbc->add_margin_child("Options:",import_options,true); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILE); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); file_select->connect("file_selected", this,"_choose_file"); save_select = memnew(EditorDirDialog); add_child(save_select); - //save_select->set_mode(FileDialog::MODE_SAVE_FILE); + //save_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); save_select->connect("dir_selected", this,"_choose_save_file"); get_ok()->connect("pressed", this,"_import"); @@ -1124,7 +1140,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce script_choose->connect("pressed", this,"_browse_script"); - script_select = memnew(FileDialog); + script_select = memnew(EditorFileDialog); add_child(script_select); for(int i=0;i<ScriptServer::get_language_count();i++) { @@ -1136,7 +1152,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce } - script_select->set_mode(FileDialog::MODE_OPEN_FILE); + script_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); script_select->connect("file_selected", this,"_choose_script"); @@ -1798,8 +1814,8 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> for(int i=0;i<portal_points.size()-1;i++) { - float a = portal_points[i].atan2(); - float b = portal_points[i+1].atan2(); + float a = portal_points[i].angle(); + float b = portal_points[i+1].angle(); if (a>b) { SWAP( portal_points[i], portal_points[i+1] ); @@ -2121,7 +2137,7 @@ void EditorSceneImportPlugin::_merge_existing_node(Node *p_node,Node *p_imported } -void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set<Node*> &checked_nodes) { +void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Node *p_existing_scene,Set<Node*> &checked_nodes) { for(int i=0;i<p_imported->get_child_count();i++) { @@ -2129,12 +2145,15 @@ void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node Node *imported_node = p_imported->get_child(i); - if (imported_node->get_owner()!=p_imported_scene) + if (imported_node->get_owner()!=p_imported_scene) { + // print_line("skipping because not imported at "+String(imported_node->get_name())); continue; //end of the road + } Vector<StringName> nn; nn.push_back(imported_node->get_name()); NodePath imported_path(nn,false); + //print_line("check for: "+String(imported_path)); if (!p_node->has_node(imported_path) && !checked_nodes.has(imported_node)) { //not there, re-add it @@ -2144,8 +2163,11 @@ void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node if (o) n=o->cast_to<Node>(); + //print_line("creating node of same type.."); + if (n) { + //print_line("copy props and add"); List<PropertyInfo> pl; imported_node->get_property_list(&pl); for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { @@ -2155,8 +2177,11 @@ void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node } p_node->add_child(n); + n->set_owner(p_existing_scene); } + } else { + //print_line("already exists"); } @@ -2164,7 +2189,7 @@ void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node Node *other_node = p_node->get_node(imported_path); - _add_new_nodes(other_node,imported_node,p_imported_scene,checked_nodes); + _add_new_nodes(other_node,imported_node,p_imported_scene,p_existing_scene,checked_nodes); } @@ -2177,7 +2202,7 @@ void EditorSceneImportPlugin::_merge_scenes(Node *p_node,Node *p_imported) { Set<Ref<Resource> > checked_resources; Set<Node*> checked_nodes; _merge_existing_node(p_node,p_imported,checked_resources,checked_nodes); - _add_new_nodes(p_node,p_imported,p_imported,checked_nodes); + _add_new_nodes(p_node,p_imported,p_imported,p_node,checked_nodes); //add existing.. ? } @@ -2214,27 +2239,33 @@ void EditorSceneImportPlugin::_scan_materials(Node*p_base,Node *p_node,Map<Strin void EditorSceneImportPlugin::_apply_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials,Set<Ref<Mesh> >& meshes_processed) { - if (!p_base && p_node->get_owner()!=p_base) + if (p_node!=p_base && p_node->get_owner()!=p_base) return; MeshInstance *mi=p_node->cast_to<MeshInstance>(); if (mi) { + print_line("is mesh "+String(p_node->get_name())); String path = p_base->get_path_to(p_node); - if (override_materials.has(path)) + if (override_materials.has(path)) { + print_line("is in material overrides"); mi->set_material_override(override_materials[path]); + } Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid() && !meshes_processed.has(mesh)) { + print_line("mesh was not processed"); meshes_processed.insert(mesh); for(int i=0;i<mesh->get_surface_count();i++) { String name = mesh->get_name()+":"+mesh->surface_get_name(i); + print_line("name for surface "+itos(i)+": "+name); if (mesh_materials.has(name)) { Ref<Material> mat = mesh_materials[name]; mesh->surface_set_material(i,mat); + print_line("overriding!"); } } } @@ -2251,9 +2282,19 @@ void EditorSceneImportPlugin::_merge_materials(Node *p_node,Node *p_imported) { Map<String,Ref<Material> > override_materials; _scan_materials(p_node,p_node,mesh_materials,override_materials); + + for (Map<String,Ref<Material> >::Element *E=mesh_materials.front();E;E=E->next()) { + print_line("Mats: "+String(E->key())); + } + + for (Map<String,Ref<Material> >::Element *E=override_materials.front();E;E=E->next()) { + print_line("Overrides: "+String(E->key())); + } + Set<Ref<Mesh> > mp; _apply_materials(p_imported,p_imported,mesh_materials,override_materials,mp); + } #if 0 @@ -2597,8 +2638,11 @@ void EditorSceneImportPlugin::_filter_tracks(Node *scene, const String& p_text) for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { keep.insert(F->get()); } - + print_line("FILTERING ANIM: "+String(E->get())); _filter_anim_tracks(anim->get_animation(name),keep); + } else { + print_line("NOT FILTERING ANIM: "+String(E->get())); + } } @@ -2687,7 +2731,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c Ref<EditorScenePostImport> post_import_script; if (post_import_script_path!="") { - post_import_script_path = EditorImportPlugin::expand_source_path(post_import_script_path); + post_import_script_path = post_import_script_path; Ref<Script> scr = ResourceLoader::load(post_import_script_path); if (!scr.is_valid()) { EditorNode::add_io_error("Couldn't load post-import script: '"+post_import_script_path); @@ -2709,8 +2753,11 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c EditorNode::add_io_error("Error running Post-Import script: '"+post_import_script_path); return err; } + + } + /// IMPORT IMAGES diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h index fa4730f7ee..71efab9503 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.h +++ b/tools/editor/io_plugins/editor_scene_import_plugin.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -113,7 +113,7 @@ class EditorSceneImportPlugin : public EditorImportPlugin { void _filter_tracks(Node *scene, const String& p_text); void _merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes); - void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set<Node*> &checked_nodes); + void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Node *p_existing_scene,Set<Node*> &checked_nodes); void _optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle); void _merge_scenes(Node *p_node, Node *p_imported); diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index b855b15b39..8d5a4f1dcf 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -51,6 +51,7 @@ static const char *flag_names[]={ NULL }; +#if 0 // not used static const char *flag_short_names[]={ "Stream", "FixBorder", @@ -65,6 +66,7 @@ static const char *flag_short_names[]={ "Anisoropic", NULL }; +#endif void EditorImportTextureOptions::set_format(EditorTextureImportPlugin::ImageFormat p_format) { @@ -142,6 +144,8 @@ void EditorImportTextureOptions::_changed() { void EditorImportTextureOptions::_bind_methods() { + print_line("bind toptions"); + ObjectTypeDB::bind_method("_changed",&EditorImportTextureOptions::_changed); ObjectTypeDB::bind_method("_changedp",&EditorImportTextureOptions::_changedp); @@ -217,7 +221,6 @@ EditorImportTextureOptions::EditorImportTextureOptions() { fname++; } - add_margin_child("Texture Options",flags,true); notice_for_2d = memnew( Label ); @@ -245,17 +248,20 @@ class EditorTextureImportDialog : public ConfirmationDialog { LineEdit *import_path; LineEdit *save_path; - FileDialog *file_select; - FileDialog *save_file_select; + EditorFileDialog *file_select; + EditorFileDialog *save_file_select; EditorDirDialog *save_select; OptionButton *texture_action; ConfirmationDialog *error_dialog; CheckButton *crop_source; + SpinBox *size; bool atlas; + bool large; EditorTextureImportPlugin *plugin; void _choose_files(const Vector<String>& p_path); + void _choose_file(const String& p_path); void _choose_save_dir(const String& p_path); void _browse(); void _browse_target(); @@ -270,7 +276,7 @@ public: 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,bool p_2d=false,bool p_atlas=false); + EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL,bool p_2d=false,bool p_atlas=false,bool p_large=false); }; @@ -299,6 +305,15 @@ void EditorTextureImportDialog::_choose_files(const Vector<String>& p_path) { 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); @@ -321,12 +336,23 @@ void EditorTextureImportDialog::_import() { String dst_path=save_path->get_text(); - if (dst_path.empty()) { + if (save_path->get_text().strip_edges()=="") { + error_dialog->set_text("Target path is empty."); + error_dialog->popup_centered_minsize(); + return; + } - error_dialog->set_text("Please specify a valid target import path!"); - error_dialog->popup_centered(Size2(200,100)); + if (!save_path->get_text().begins_with("res://")) { + error_dialog->set_text("Target path must be full resource path."); + error_dialog->popup_centered_minsize(); return; + } + + if (!atlas && !large && !DirAccess::exists(save_path->get_text())) { + error_dialog->set_text("Target path must exist."); + error_dialog->popup_centered_minsize(); + return; } if (atlas) { //atlas @@ -349,6 +375,8 @@ void EditorTextureImportDialog::_import() { 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_val())); + imd->set_option("large",false); imd->set_option("crop",crop_source->is_pressed()); Error err = plugin->import(dst_file,imd); @@ -359,7 +387,38 @@ void EditorTextureImportDialog::_import() { return; } + } else if (large) { //atlas + + if (files.size()!=1) { + + error_dialog->set_text("Only one file is required for large texture"); + error_dialog->popup_centered(Size2(200,100)); + return; + + } + String dst_file = dst_path; + //dst_file=dst_file.basename()+".tex"; + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + //imd->set_editor(); + for(int i=0;i<files.size();i++) { + 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",true); + imd->set_option("large_cell_size",int(size->get_val())); + imd->set_option("crop",crop_source->is_pressed()); + Error err = plugin->import(dst_file,imd); + if (err) { + + error_dialog->set_text("Error importing: "+dst_file.get_file()); + error_dialog->popup_centered(Size2(200,100)); + return; + + } } else { @@ -374,6 +433,8 @@ void EditorTextureImportDialog::_import() { 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); + Error err = plugin->import(dst_file,imd); if (err) { @@ -395,7 +456,7 @@ void EditorTextureImportDialog::_browse() { void EditorTextureImportDialog::_browse_target() { - if (atlas) { + if (atlas || large) { save_file_select->popup_centered_ratio(); } else { save_select->popup_centered_ratio(); @@ -411,7 +472,11 @@ void EditorTextureImportDialog::popup_import(const String& p_from) { Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); ERR_FAIL_COND(!rimd.is_valid()); - save_path->set_text(p_from.get_base_dir()); + if (plugin->get_mode()==EditorTextureImportPlugin::MODE_ATLAS || plugin->get_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")); @@ -457,6 +522,7 @@ void EditorTextureImportDialog::_bind_methods() { ObjectTypeDB::bind_method("_choose_files",&EditorTextureImportDialog::_choose_files); + ObjectTypeDB::bind_method("_choose_file",&EditorTextureImportDialog::_choose_file); ObjectTypeDB::bind_method("_choose_save_dir",&EditorTextureImportDialog::_choose_save_dir); ObjectTypeDB::bind_method("_import",&EditorTextureImportDialog::_import); ObjectTypeDB::bind_method("_browse",&EditorTextureImportDialog::_browse); @@ -464,21 +530,25 @@ void EditorTextureImportDialog::_bind_methods() { // ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); } -EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin, bool p_2d, bool p_atlas) { +EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin, bool p_2d, bool p_atlas,bool p_large) { atlas=p_atlas; + large=p_large; plugin=p_plugin; set_title("Import Textures"); - texture_options = memnew( EditorImportTextureOptions );; - VBoxContainer *vbc = texture_options; + + VBoxContainer *vbc = memnew(VBoxContainer); add_child(vbc); set_child_rect(vbc); VBoxContainer *source_vb=memnew(VBoxContainer); - vbc->add_margin_child("Source Texture(s):",source_vb); + if (large) + vbc->add_margin_child("Source Texture:",source_vb); + else + vbc->add_margin_child("Source Texture(s):",source_vb); HBoxContainer *hbc = memnew( HBoxContainer ); source_vb->add_child(hbc); @@ -493,6 +563,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* if (!p_atlas) crop_source->hide(); + Button * import_choose = memnew( Button ); import_choose->set_text(" .. "); hbc->add_child(import_choose); @@ -502,6 +573,19 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* hbc = memnew( HBoxContainer ); vbc->add_margin_child("Target Path:",hbc); + size = memnew( SpinBox ); + size->set_min(128); + size->set_max(16384); + + if (p_atlas) { + size->set_val(2048); + vbc->add_margin_child("Max Texture size:",size); + } else { + size->set_val(256); + vbc->add_margin_child("Cell Size:",size); + } + + save_path = memnew( LineEdit ); save_path->set_h_size_flags(SIZE_EXPAND_FILL); hbc->add_child(save_path); @@ -512,32 +596,39 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* save_choose->connect("pressed", this,"_browse_target"); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILES); + if (!large) + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); + else + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); file_select->connect("files_selected", this,"_choose_files"); + file_select->connect("file_selected", this,"_choose_file"); - save_file_select = memnew(FileDialog); - save_file_select->set_access(FileDialog::ACCESS_RESOURCES); + save_file_select = memnew(EditorFileDialog); + save_file_select->set_access(EditorFileDialog::ACCESS_RESOURCES); add_child(save_file_select); - save_file_select->set_mode(FileDialog::MODE_SAVE_FILE); + save_file_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); save_file_select->clear_filters(); - save_file_select->add_filter("*.tex;Base Atlas Texture"); + if (large) + save_file_select->add_filter("*.ltex;Large Texture"); + else + save_file_select->add_filter("*.tex;Base Atlas Texture"); save_file_select->connect("file_selected", this,"_choose_save_dir"); save_select = memnew( EditorDirDialog ); add_child(save_select); -// save_select->set_mode(FileDialog::MODE_OPEN_DIR); +// save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); save_select->connect("dir_selected", this,"_choose_save_dir"); get_ok()->connect("pressed", this,"_import"); get_ok()->set_text("Import"); //move stuff up - for(int i=0;i<4;i++) - vbc->move_child( vbc->get_child( vbc->get_child_count() -1), 0); + //for(int i=0;i<4;i++) + // vbc->move_child( vbc->get_child( vbc->get_child_count() -1), 0); error_dialog = memnew ( ConfirmationDialog ); add_child(error_dialog); @@ -546,13 +637,24 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* set_hide_on_ok(false); + texture_options = memnew( EditorImportTextureOptions );; + vbc->add_child(texture_options); + texture_options->set_v_size_flags(SIZE_EXPAND_FILL); + if (atlas) { 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); - texture_options->show_2d_notice(); + //texture_options->show_2d_notice(); set_title("Import Textures for Atlas (2D)"); + } else if (large) { + + 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); + texture_options->show_2d_notice(); + set_title("Import Large Textures (2D)"); } else if (p_2d) { @@ -598,12 +700,17 @@ String EditorTextureImportPlugin::get_name() const { return "texture_atlas"; } break; + case MODE_LARGE: { + + return "texture_large"; + } break; } return ""; } + String EditorTextureImportPlugin::get_visible_name() const { switch(mode) { @@ -618,7 +725,11 @@ String EditorTextureImportPlugin::get_visible_name() const { } break; case MODE_ATLAS: { - return "Atlas Texture"; + return "2D Atlas Texture"; + } break; + case MODE_LARGE: { + + return "2D Large Texture"; } break; } @@ -716,6 +827,135 @@ Error EditorTextureImportPlugin::import(const String& p_path, const Ref<Resource return import2(p_path,p_from,EditorExportPlatform::IMAGE_COMPRESSION_BC,false); } + +Error EditorTextureImportPlugin::_process_texture_data(Ref<ImageTexture> &texture,int format, float quality,int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink) { + + + if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS || format==IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { + + Image image=texture->get_data(); + ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); + + bool has_alpha=image.detect_alpha(); + if (!has_alpha && image.get_format()==Image::FORMAT_RGBA) { + + image.convert(Image::FORMAT_RGB); + + } + + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { + + image.fix_alpha_edges(); + } + + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); + } + + //if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { + + // image.srgb_to_linear(); + //} + + if (shrink>1) { + + int orig_w=image.get_width(); + int orig_h=image.get_height(); + image.resize(orig_w/shrink,orig_h/shrink,Image::INTERPOLATE_CUBIC); + texture->create_from_image(image,tex_flags); + texture->set_size_override(Size2(orig_w,orig_h)); + + + } else { + + texture->create_from_image(image,tex_flags); + } + + + if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS) { + texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSLESS); + } else { + texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY); + } + + + + texture->set_lossy_storage_quality(quality); + + + } else { + + + Image image=texture->get_data(); + ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); + + + bool has_alpha=image.detect_alpha(); + if (!has_alpha && image.get_format()==Image::FORMAT_RGBA) { + + image.convert(Image::FORMAT_RGB); + + } + + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { + + image.fix_alpha_edges(); + } + + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); + } + + //if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { +// + // print_line("CONVERT BECAUSE: "+itos(flags)); + // image.srgb_to_linear(); + //} + + int orig_w=image.get_width(); + int orig_h=image.get_height(); + + if (shrink>1) { + image.resize(orig_w/shrink,orig_h/shrink,Image::INTERPOLATE_CUBIC); + texture->create_from_image(image,tex_flags); + texture->set_size_override(Size2(orig_w,orig_h)); + } + + if (!(flags&IMAGE_FLAG_NO_MIPMAPS)) { + image.generate_mipmaps(); + + } + + if (format!=IMAGE_FORMAT_UNCOMPRESSED) { + + compress_image(p_compr,image,flags&IMAGE_FLAG_COMPRESS_EXTRA); + } + + + texture->create_from_image(image,tex_flags); + + + if (shrink>1 || (format!=IMAGE_FORMAT_UNCOMPRESSED && (image.get_width()!=orig_w || image.get_height()!=orig_h))) { + texture->set_size_override(Size2(orig_w,orig_h)); + } + + //uint32_t save_flags=ResourceSaver::FLAG_COMPRESS; + } + + return OK; +} + + Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<ResourceImportMetadata>& p_from,EditorExportPlatform::ImageCompression p_compr, bool p_external){ @@ -727,8 +967,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc Ref<ImageTexture> texture; Vector<Ref<AtlasTexture> > atlases; bool atlas = from->get_option("atlas"); + bool large = from->get_option("large"); int flags=from->get_option("flags"); + int format=from->get_option("format"); + float quality=from->get_option("quality"); uint32_t tex_flags=0; @@ -744,20 +987,95 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER; print_line("path: "+p_path+" flags: "+itos(tex_flags)); - int shrink=1; + float shrink=1; if (from->has_option("shrink")) shrink=from->get_option("shrink"); - if (atlas) { + if (large) { + ERR_FAIL_COND_V(from->get_source_count()!=1,ERR_INVALID_PARAMETER); + + String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); + + + int cell_size=from->get_option("large_cell_size"); + ERR_FAIL_COND_V(cell_size<128 || cell_size>16384,ERR_CANT_OPEN); + + EditorProgress pg("ltex","Import Large Texture",3); + + pg.step("Load Source Image",0); + Image img; + Error err = ImageLoader::load_image(src_path,&img); + if (err) { + return err; + } + + pg.step("Slicing",1); + + Map<Vector2,Image> pieces; + for(int i=0;i<img.get_width();i+=cell_size) { + int w = MIN(img.get_width()-i,cell_size); + for(int j=0;j<img.get_height();j+=cell_size) { + int h = MIN(img.get_height()-j,cell_size); + + Image piece(w,h,0,img.get_format()); + piece.blit_rect(img,Rect2(i,j,w,h),Point2(0,0)); + if (!piece.is_invisible()) { + pieces[Vector2(i,j)]=piece; + //print_line("ADDING PIECE AT "+Vector2(i,j)); + } + } + } + + Ref<LargeTexture> existing; + if (ResourceCache::has(p_path)) { + existing = ResourceCache::get(p_path); + } + + if (existing.is_valid()) { + existing->clear(); + } else { + existing = Ref<LargeTexture>(memnew( LargeTexture )); + } + + existing->set_size(Size2(img.get_width(),img.get_height())); + pg.step("Inserting",2); + + for (Map<Vector2,Image>::Element *E=pieces.front();E;E=E->next()) { + + Ref<ImageTexture> imgtex = Ref<ImageTexture>( memnew( ImageTexture ) ); + imgtex->create_from_image(E->get(),tex_flags); + _process_texture_data(imgtex,format,quality,flags,p_compr,tex_flags,shrink); + existing->add_piece(E->key(),imgtex); + } + + if (!p_external) { + from->set_editor(get_name()); + existing->set_path(p_path); + existing->set_import_metadata(from); + } + pg.step("Saving",3); + + err = ResourceSaver::save(p_path,existing); + if (err!=OK) { + EditorNode::add_io_error("Couldn't save large texture: "+p_path); + return err; + } + + return OK; + + + } else if (atlas) { //prepare atlas! Vector< Image > sources; + Vector< Image > tsources; bool alpha=false; bool crop = from->get_option("crop"); EditorProgress ep("make_atlas","Build Atlas For: "+p_path.get_file(),from->get_source_count()+3); print_line("sources: "+itos(from->get_source_count())); + for(int i=0;i<from->get_source_count();i++) { String path = EditorImportPlugin::expand_source_path(from->get_source_path(i)); @@ -775,17 +1093,57 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc if (src.detect_alpha()) alpha=true; - sources.push_back(src); + tsources.push_back(src); } ep.step("Converting Images",sources.size()); - for(int i=0;i<sources.size();i++) { + int base_index=0; + + + Map<uint64_t,int> source_md5; + Map<int,List<int> > source_map; + + for(int i=0;i<tsources.size();i++) { + + Image src = tsources[i]; if (alpha) { - sources[i].convert(Image::FORMAT_RGBA); + src.convert(Image::FORMAT_RGBA); + } else { + src.convert(Image::FORMAT_RGB); + } + + DVector<uint8_t> data = src.get_data(); + MD5_CTX md5; + DVector<uint8_t>::Read r=data.read(); + MD5Init(&md5); + int len=data.size(); + for(int j=0;j<len;j++) { + uint8_t b = r[j]; + b>>=2; //to aid in comparing + MD5Update(&md5,(unsigned char*)&b,1); + } + MD5Final(&md5); + uint64_t *cmp = (uint64_t*)md5.digest; //less bits, but still useful for this + + tsources[i]=Image(); //clear + + if (source_md5.has(*cmp)) { + int sidx=source_md5[*cmp]; + source_map[sidx].push_back(i); + print_line("REUSING "+from->get_source_path(i)); + } else { - sources[i].convert(Image::FORMAT_RGB); + int sidx=sources.size(); + source_md5[*cmp]=sidx; + sources.push_back(src); + List<int> sm; + sm.push_back(i); + source_map[sidx]=sm; + } + + } //texturepacker is not really good for optimizing, so.. @@ -822,31 +1180,59 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc ep.step("Blitting Images",sources.size()+2); + bool blit_to_po2=tex_flags&Texture::FLAG_MIPMAPS; + int atlas_w=dst_size.width; + int atlas_h=dst_size.height; + if (blit_to_po2) { + atlas_w=nearest_power_of_2(dst_size.width); + atlas_h=nearest_power_of_2(dst_size.height); + } Image atlas; - atlas.create(nearest_power_of_2(dst_size.width),nearest_power_of_2(dst_size.height),0,alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB); + atlas.create(atlas_w,atlas_h,0,alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB); + + + atlases.resize(from->get_source_count()); for(int i=0;i<sources.size();i++) { int x=dst_positions[i].x; int y=dst_positions[i].y; - Ref<AtlasTexture> at = memnew( AtlasTexture ); Size2 sz = Size2(sources[i].get_width(),sources[i].get_height()); + + Rect2 region; + Rect2 margin; + if (crop && sz!=crops[i].size) { Rect2 rect = crops[i]; rect.size=sz-rect.size; - at->set_region(Rect2(x+border,y+border,crops[i].size.width,crops[i].size.height)); - at->set_margin(rect); + region=Rect2(x+border,y+border,crops[i].size.width,crops[i].size.height); + margin=rect; atlas.blit_rect(sources[i],crops[i],Point2(x+border,y+border)); } else { - at->set_region(Rect2(x+border,y+border,sz.x,sz.y)); + region=Rect2(x+border,y+border,sz.x,sz.y); atlas.blit_rect(sources[i],Rect2(0,0,sources[i].get_width(),sources[i].get_height()),Point2(x+border,y+border)); } - String apath = p_path.get_base_dir().plus_file(from->get_source_path(i).get_file().basename()+".atex"); - print_line("Atlas Tex: "+apath); - at->set_path(apath); - atlases.push_back(at); + ERR_CONTINUE( !source_map.has(i) ); + for (List<int>::Element *E=source_map[i].front();E;E=E->next()) { + + String apath = p_path.get_base_dir().plus_file(from->get_source_path(E->get()).get_file().basename()+".atex"); + + Ref<AtlasTexture> at; + + if (ResourceCache::has(apath)) { + at = Ref<AtlasTexture>( ResourceCache::get(apath)->cast_to<AtlasTexture>() ); + } else { + + at = Ref<AtlasTexture>( memnew( AtlasTexture ) ); + } + at->set_region(region); + at->set_margin(margin); + at->set_path(apath); + atlases[E->get()]=at; + print_line("Atlas Tex: "+apath); + } } if (ResourceCache::has(p_path)) { texture = Ref<ImageTexture> ( ResourceCache::get(p_path)->cast_to<ImageTexture>() ); @@ -880,8 +1266,6 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc } - int format=from->get_option("format"); - float quality=from->get_option("quality"); if (!p_external) { from->set_editor(get_name()); @@ -915,7 +1299,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc } } + bool compress=false; +#if 1 + _process_texture_data(texture,format,quality,flags,p_compr,tex_flags,shrink); +#else if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS || format==IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { Image image=texture->get_data(); @@ -972,13 +1360,6 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc texture->set_lossy_storage_quality(quality); - Error err = ResourceSaver::save(p_path,texture); - - if (err!=OK) { - EditorNode::add_io_error("Couldn't save converted texture: "+p_path); - return err; - } - } else { @@ -1041,15 +1422,20 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc texture->set_size_override(Size2(orig_w,orig_h)); } - uint32_t save_flags=ResourceSaver::FLAG_COMPRESS; + compress=true; - Error err = ResourceSaver::save(p_path,texture,save_flags); - if (err!=OK) { - EditorNode::add_io_error("Couldn't save converted texture: "+p_path); - return err; - } } +#endif + uint32_t save_flags=0; + if (compress) + save_flags=ResourceSaver::FLAG_COMPRESS; + + Error err = ResourceSaver::save(p_path,texture,save_flags); + if (err!=OK) { + EditorNode::add_io_error("Couldn't save converted texture: "+p_path); + return err; + } return OK; } @@ -1098,6 +1484,9 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; } break; //use default + case EditorImportExport::IMAGE_ACTION_KEEP: { + return Vector<uint8_t>(); + } break; //use default } @@ -1238,14 +1627,14 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c } -EditorTextureImportPlugin *EditorTextureImportPlugin::singleton[3]={NULL,NULL,NULL}; +EditorTextureImportPlugin *EditorTextureImportPlugin::singleton[EditorTextureImportPlugin::MODE_MAX]={NULL,NULL,NULL,NULL}; EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor, Mode p_mode) { singleton[p_mode]=this; editor=p_editor; - mode=p_mode; - dialog = memnew( EditorTextureImportDialog(this,p_mode==MODE_TEXTURE_2D || p_mode==MODE_ATLAS,p_mode==MODE_ATLAS) ); + mode=p_mode; + dialog = memnew( EditorTextureImportDialog(this,p_mode==MODE_TEXTURE_2D || p_mode==MODE_ATLAS || p_mode==MODE_LARGE,p_mode==MODE_ATLAS,p_mode==MODE_LARGE) ); editor->get_gui_base()->add_child(dialog); } diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index d17b3c05c2..38fd671e9d 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -56,7 +56,9 @@ public: enum Mode { MODE_TEXTURE_2D, MODE_TEXTURE_3D, - MODE_ATLAS + MODE_ATLAS, + MODE_LARGE, + MODE_MAX }; @@ -65,10 +67,10 @@ private: Mode mode; EditorNode *editor; EditorTextureImportDialog *dialog; - static EditorTextureImportPlugin *singleton[3]; + static EditorTextureImportPlugin *singleton[MODE_MAX]; //used by other importers such as mesh - + Error _process_texture_data(Ref<ImageTexture> &texture, int format, float quality, int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink); void compress_image(EditorExportPlatform::ImageCompression p_mode,Image& image,bool p_smaller); public: @@ -98,6 +100,7 @@ public: IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear }; + Mode get_mode() const { return mode; } virtual String get_name() const; virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); @@ -120,6 +123,7 @@ public: virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform); EditorTextureExportPlugin(); }; + class EditorImportTextureOptions : public VBoxContainer { OBJ_TYPE( EditorImportTextureOptions, VBoxContainer ); diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.cpp b/tools/editor/io_plugins/editor_translation_import_plugin.cpp index 9540869789..d152d71af4 100644 --- a/tools/editor/io_plugins/editor_translation_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_translation_import_plugin.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -47,7 +47,7 @@ class EditorTranslationImportDialog : public ConfirmationDialog { LineEdit *import_path; LineEdit *save_path; - FileDialog *file_select; + EditorFileDialog *file_select; CheckButton *ignore_first; CheckButton *compress; CheckButton *add_to_project; @@ -347,16 +347,16 @@ public: add_to_project->set_text("Add to Project (engine.cfg)"); tcomp->add_child(add_to_project); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILE); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); file_select->connect("file_selected", this,"_choose_file"); file_select->add_filter("*.csv ; Translation CSV"); save_select = memnew( EditorDirDialog ); add_child(save_select); - // save_select->set_mode(FileDialog::MODE_OPEN_DIR); + // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); save_select->connect("dir_selected", this,"_choose_save_dir"); get_ok()->connect("pressed", this,"_import"); diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.h b/tools/editor/io_plugins/editor_translation_import_plugin.h index 8ea422c244..f3c2884534 100644 --- a/tools/editor/io_plugins/editor_translation_import_plugin.h +++ b/tools/editor/io_plugins/editor_translation_import_plugin.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ |