mirror of
https://github.com/godotengine/godot.git
synced 2024-11-10 14:12:51 +00:00
Enable SpriteFramesEditor to guess the amount of rows and columns of a sprite sheet when loading it for the first time
This commit is contained in:
parent
88f3b5f9d5
commit
eccd1452fa
@ -504,6 +504,82 @@ void SpriteFramesEditor::_update_show_settings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpriteFramesEditor::_auto_slice_sprite_sheet() {
|
||||||
|
if (updating_split_settings) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updating_split_settings = true;
|
||||||
|
|
||||||
|
const Size2i size = split_sheet_preview->get_texture()->get_size();
|
||||||
|
|
||||||
|
const Size2i split_sheet = _estimate_sprite_sheet_size(split_sheet_preview->get_texture());
|
||||||
|
split_sheet_h->set_value(split_sheet.x);
|
||||||
|
split_sheet_v->set_value(split_sheet.y);
|
||||||
|
split_sheet_size_x->set_value(size.x / split_sheet.x);
|
||||||
|
split_sheet_size_y->set_value(size.y / split_sheet.y);
|
||||||
|
split_sheet_sep_x->set_value(0);
|
||||||
|
split_sheet_sep_y->set_value(0);
|
||||||
|
split_sheet_offset_x->set_value(0);
|
||||||
|
split_sheet_offset_y->set_value(0);
|
||||||
|
|
||||||
|
updating_split_settings = false;
|
||||||
|
|
||||||
|
frames_selected.clear();
|
||||||
|
selected_count = 0;
|
||||||
|
last_frame_selected = -1;
|
||||||
|
split_sheet_preview->queue_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpriteFramesEditor::_matches_background_color(const Color &p_background_color, const Color &p_pixel_color) {
|
||||||
|
if ((p_background_color.a == 0 && p_pixel_color.a == 0) || p_background_color.is_equal_approx(p_pixel_color)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color d = p_background_color - p_pixel_color;
|
||||||
|
// 0.04f is the threshold for how much a colour can deviate from background colour and still be considered a match. Arrived at through experimentation, can be tweaked.
|
||||||
|
return (d.r * d.r) + (d.g * d.g) + (d.b * d.b) + (d.a * d.a) < 0.04f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size2i SpriteFramesEditor::_estimate_sprite_sheet_size(const Ref<Texture2D> p_texture) {
|
||||||
|
Ref<Image> image = p_texture->get_image();
|
||||||
|
Size2i size = p_texture->get_size();
|
||||||
|
|
||||||
|
Color assumed_background_color = image->get_pixel(0, 0);
|
||||||
|
Size2i sheet_size;
|
||||||
|
|
||||||
|
bool previous_line_background = true;
|
||||||
|
for (int x = 0; x < size.x; x++) {
|
||||||
|
int y = 0;
|
||||||
|
while (y < size.y && _matches_background_color(assumed_background_color, image->get_pixel(x, y))) {
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
bool current_line_background = (y == size.y);
|
||||||
|
if (previous_line_background && !current_line_background) {
|
||||||
|
sheet_size.x++;
|
||||||
|
}
|
||||||
|
previous_line_background = current_line_background;
|
||||||
|
}
|
||||||
|
|
||||||
|
previous_line_background = true;
|
||||||
|
for (int y = 0; y < size.y; y++) {
|
||||||
|
int x = 0;
|
||||||
|
while (x < size.x && _matches_background_color(assumed_background_color, image->get_pixel(x, y))) {
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
bool current_line_background = (x == size.x);
|
||||||
|
if (previous_line_background && !current_line_background) {
|
||||||
|
sheet_size.y++;
|
||||||
|
}
|
||||||
|
previous_line_background = current_line_background;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sheet_size == Size2i(0, 0) || sheet_size == Size2i(1, 1)) {
|
||||||
|
sheet_size = Size2i(4, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sheet_size;
|
||||||
|
}
|
||||||
|
|
||||||
void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
|
void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
|
||||||
Ref<Texture2D> texture = ResourceLoader::load(p_file);
|
Ref<Texture2D> texture = ResourceLoader::load(p_file);
|
||||||
if (texture.is_null()) {
|
if (texture.is_null()) {
|
||||||
@ -530,10 +606,11 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
|
|||||||
// Different texture, reset to 4x4.
|
// Different texture, reset to 4x4.
|
||||||
dominant_param = PARAM_FRAME_COUNT;
|
dominant_param = PARAM_FRAME_COUNT;
|
||||||
updating_split_settings = true;
|
updating_split_settings = true;
|
||||||
split_sheet_h->set_value(4);
|
const Size2i split_sheet = Size2i(4, 4);
|
||||||
split_sheet_v->set_value(4);
|
split_sheet_h->set_value(split_sheet.x);
|
||||||
split_sheet_size_x->set_value(size.x / 4);
|
split_sheet_v->set_value(split_sheet.y);
|
||||||
split_sheet_size_y->set_value(size.y / 4);
|
split_sheet_size_x->set_value(size.x / split_sheet.x);
|
||||||
|
split_sheet_size_y->set_value(size.y / split_sheet.y);
|
||||||
split_sheet_sep_x->set_value(0);
|
split_sheet_sep_x->set_value(0);
|
||||||
split_sheet_sep_y->set_value(0);
|
split_sheet_sep_y->set_value(0);
|
||||||
split_sheet_offset_x->set_value(0);
|
split_sheet_offset_x->set_value(0);
|
||||||
@ -2290,6 +2367,11 @@ SpriteFramesEditor::SpriteFramesEditor() {
|
|||||||
split_sheet_offset_hb->add_child(split_sheet_offset_vb);
|
split_sheet_offset_hb->add_child(split_sheet_offset_vb);
|
||||||
split_sheet_settings_vb->add_child(split_sheet_offset_hb);
|
split_sheet_settings_vb->add_child(split_sheet_offset_hb);
|
||||||
|
|
||||||
|
Button *auto_slice = memnew(Button);
|
||||||
|
auto_slice->set_text(TTR("Auto Slice"));
|
||||||
|
auto_slice->connect(SceneStringName(pressed), callable_mp(this, &SpriteFramesEditor::_auto_slice_sprite_sheet));
|
||||||
|
split_sheet_settings_vb->add_child(auto_slice);
|
||||||
|
|
||||||
split_sheet_hb->add_child(split_sheet_settings_vb);
|
split_sheet_hb->add_child(split_sheet_settings_vb);
|
||||||
|
|
||||||
file_split_sheet = memnew(EditorFileDialog);
|
file_split_sheet = memnew(EditorFileDialog);
|
||||||
|
@ -234,6 +234,9 @@ class SpriteFramesEditor : public HSplitContainer {
|
|||||||
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
||||||
|
|
||||||
void _open_sprite_sheet();
|
void _open_sprite_sheet();
|
||||||
|
void _auto_slice_sprite_sheet();
|
||||||
|
bool _matches_background_color(const Color &p_background_color, const Color &p_pixel_color);
|
||||||
|
Size2i _estimate_sprite_sheet_size(const Ref<Texture2D> p_texture);
|
||||||
void _prepare_sprite_sheet(const String &p_file);
|
void _prepare_sprite_sheet(const String &p_file);
|
||||||
int _sheet_preview_position_to_frame_index(const Vector2 &p_position);
|
int _sheet_preview_position_to_frame_index(const Vector2 &p_position);
|
||||||
void _sheet_preview_draw();
|
void _sheet_preview_draw();
|
||||||
|
Loading…
Reference in New Issue
Block a user