Merge pull request #71335 from groud/fix_atlas_merging

Fixes TileSet atlas merging not working correctly
This commit is contained in:
Rémi Verschelde 2023-01-13 18:03:53 +01:00
commit 3e5ee12555
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 52 additions and 24 deletions

View File

@ -56,7 +56,7 @@ void AtlasMergingDialog::_generate_merged(Vector<Ref<TileSetAtlasSource>> 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<Ref<TileSetAtlasSource>> 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<PropertyInfo> properties;
original_tile_data->get_property_list(&properties);
for (List<PropertyInfo>::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<Ref<TileSetAtlasSource>> 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<Ref<TileSetAtlasSource>> 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<TileSetAtlasSource> atlas_source = p_atlas_sources[source_index];
for (KeyValue<Vector2i, Vector2i> 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<PropertyInfo> 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<ImageTexture> output_image_texture = merged->get_texture();
output_image_texture->get_image()->save_png(p_path);
ResourceLoader::import(p_path);
Ref<Texture2D> 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<TileSet> p_tile_set) {
ERR_FAIL_COND(!p_tile_set.is_valid());
tile_set = p_tile_set;

View File

@ -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<TileSet> p_tile_set);