From 28f6fcd68f3886f2844a4972b199437e963e823d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gilles=20Roudi=C3=A8re?= Date: Fri, 13 Jan 2023 16:50:12 +0100 Subject: [PATCH] Fixes TileSet atlas merging not working correctly --- editor/plugins/tiles/atlas_merging_dialog.cpp | 74 +++++++++++++------ editor/plugins/tiles/atlas_merging_dialog.h | 2 + 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp index deb1df42d35..4128029fc66 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.cpp +++ b/editor/plugins/tiles/atlas_merging_dialog.cpp @@ -56,7 +56,7 @@ void AtlasMergingDialog::_generate_merged(Vector> p_atla new_texture_region_size = new_texture_region_size.max(atlas_source->get_texture_region_size()); } - // Generate the merged TileSetAtlasSource. + // Generate the new texture. Vector2i atlas_offset; int line_height = 0; for (int source_index = 0; source_index < p_atlas_sources.size(); source_index++) { @@ -72,28 +72,6 @@ void AtlasMergingDialog::_generate_merged(Vector> p_atla Rect2i new_tile_rect_in_altas = Rect2i(atlas_offset + tile_id, atlas_source->get_tile_size_in_atlas(tile_id)); - // Create tiles and alternatives, then copy their properties. - for (int alternative_index = 0; alternative_index < atlas_source->get_alternative_tiles_count(tile_id); alternative_index++) { - int alternative_id = atlas_source->get_alternative_tile_id(tile_id, alternative_index); - if (alternative_id == 0) { - merged->create_tile(new_tile_rect_in_altas.position, new_tile_rect_in_altas.size); - } else { - merged->create_alternative_tile(new_tile_rect_in_altas.position, alternative_index); - } - - // Copy the properties. - TileData *original_tile_data = atlas_source->get_tile_data(tile_id, alternative_id); - List properties; - original_tile_data->get_property_list(&properties); - for (List::Element *E = properties.front(); E; E = E->next()) { - const StringName &property_name = E->get().name; - merged->set(property_name, original_tile_data->get(property_name)); - } - - // Add to the mapping. - merged_mapping[source_index][tile_id] = new_tile_rect_in_altas.position; - } - // Copy the texture. for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(tile_id); frame++) { Rect2i src_rect = atlas_source->get_tile_texture_region(tile_id, frame); @@ -103,6 +81,9 @@ void AtlasMergingDialog::_generate_merged(Vector> p_atla } output_image->blit_rect(atlas_source->get_texture()->get_image(), src_rect, dst_rect_wide.get_center() - src_rect.size / 2); } + + // Add to the mapping. + merged_mapping[source_index][tile_id] = new_tile_rect_in_altas.position; } // Compute the atlas offset. @@ -115,8 +96,43 @@ void AtlasMergingDialog::_generate_merged(Vector> p_atla } } - merged->set_name(p_atlas_sources[0]->get_name()); merged->set_texture(ImageTexture::create_from_image(output_image)); + + // Copy the tiles to the merged TileSetAtlasSource. + for (int source_index = 0; source_index < p_atlas_sources.size(); source_index++) { + Ref atlas_source = p_atlas_sources[source_index]; + for (KeyValue tile_mapping : merged_mapping[source_index]) { + // Create tiles and alternatives, then copy their properties. + for (int alternative_index = 0; alternative_index < atlas_source->get_alternative_tiles_count(tile_mapping.key); alternative_index++) { + int alternative_id = atlas_source->get_alternative_tile_id(tile_mapping.key, alternative_index); + if (alternative_id == 0) { + merged->create_tile(tile_mapping.value, atlas_source->get_tile_size_in_atlas(tile_mapping.key)); + } else { + merged->create_alternative_tile(tile_mapping.value, alternative_index); + } + + // Copy the properties. + TileData *src_tile_data = atlas_source->get_tile_data(tile_mapping.key, alternative_id); + List properties; + src_tile_data->get_property_list(&properties); + + TileData *dst_tile_data = merged->get_tile_data(tile_mapping.value, alternative_id); + for (PropertyInfo property : properties) { + if (!(property.usage & PROPERTY_USAGE_STORAGE)) { + continue; + } + Variant value = src_tile_data->get(property.name); + Variant default_value = ClassDB::class_get_default_property_value("TileData", property.name); + if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) { + continue; + } + dst_tile_data->set(property.name, value); + } + } + } + } + + merged->set_name(p_atlas_sources[0]->get_name()); merged->set_texture_region_size(new_texture_region_size); } } @@ -151,6 +167,8 @@ void AtlasMergingDialog::_merge_confirmed(String p_path) { Ref output_image_texture = merged->get_texture(); output_image_texture->get_image()->save_png(p_path); + ResourceLoader::import(p_path); + Ref new_texture_resource = ResourceLoader::load(p_path, "Texture2D"); merged->set_texture(new_texture_resource); @@ -225,6 +243,14 @@ bool AtlasMergingDialog::_get(const StringName &p_name, Variant &r_ret) const { return false; } +void AtlasMergingDialog::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_VISIBILITY_CHANGED: { + _update_texture(); + } break; + } +} + void AtlasMergingDialog::update_tile_set(Ref p_tile_set) { ERR_FAIL_COND(!p_tile_set.is_valid()); tile_set = p_tile_set; diff --git a/editor/plugins/tiles/atlas_merging_dialog.h b/editor/plugins/tiles/atlas_merging_dialog.h index 032541c90e3..bf1b56894f5 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.h +++ b/editor/plugins/tiles/atlas_merging_dialog.h @@ -75,6 +75,8 @@ protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; + void _notification(int p_what); + public: void update_tile_set(Ref p_tile_set);