summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorGilles Roudière <gilles.roudiere@gmail.com>2021-06-30 12:03:22 +0200
committerGilles Roudière <gilles.roudiere@gmail.com>2021-07-21 12:29:51 +0200
commit047e9b19f80e1f65d207d163c9c67574f7484ade (patch)
treee948216522e1cf717f56c377d0b62e7b2312db13 /scene
parent88bf6e1c6d3e711976304bb16ac51719e8e82f72 (diff)
Import old tiles in SINGLE_TILE mode as atlases
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/tile_map.cpp21
-rw-r--r--scene/resources/tile_set.cpp159
-rw-r--r--scene/resources/tile_set.h30
3 files changed, 175 insertions, 35 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 6d1e27bf1b..beb7b31ea2 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -805,19 +805,16 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) {
if (format == FORMAT_3) {
uint16_t source_id = decode_uint16(&local[4]);
uint16_t atlas_coords_x = decode_uint16(&local[6]);
- uint16_t atlas_coords_y = decode_uint32(&local[8]);
+ uint16_t atlas_coords_y = decode_uint16(&local[8]);
uint16_t alternative_tile = decode_uint16(&local[10]);
set_cell(Vector2i(x, y), source_id, Vector2i(atlas_coords_x, atlas_coords_y), alternative_tile);
} else {
#ifndef DISABLE_DEPRECATED
uint32_t v = decode_uint32(&local[4]);
- v &= (1 << 29) - 1;
-
- // We generate an alternative tile number out of the the flags
- // An option should create the alternative in the tileset for compatibility
bool flip_h = v & (1 << 29);
bool flip_v = v & (1 << 30);
bool transpose = v & (1 << 31);
+ v &= (1 << 29) - 1;
int16_t coord_x = 0;
int16_t coord_y = 0;
if (format == FORMAT_2) {
@@ -825,13 +822,17 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) {
coord_y = decode_uint16(&local[10]);
}
- int compatibility_alternative_tile = ((int)flip_h) + ((int)flip_v << 1) + ((int)transpose << 2);
-
if (tile_set.is_valid()) {
- v = tile_set->compatibility_get_source_for_tile_id(v);
+ Array a = tile_set->compatibility_tilemap_map(v, Vector2i(coord_x, coord_y), flip_h, flip_v, transpose);
+ if (a.size() == 3) {
+ set_cell(Vector2i(x, y), a[0], a[1], a[2]);
+ } else {
+ ERR_PRINT(vformat("No valid tile in Tileset for: tile:%s coords:%s flip_h:%s flip_v:%s transpose:%s", v, Vector2i(coord_x, coord_y), flip_h, flip_v, transpose));
+ }
+ } else {
+ int compatibility_alternative_tile = ((int)flip_h) + ((int)flip_v << 1) + ((int)transpose << 2);
+ set_cell(Vector2i(x, y), v, Vector2i(coord_x, coord_y), compatibility_alternative_tile);
}
-
- set_cell(Vector2i(x, y), v, Vector2i(coord_x, coord_y), compatibility_alternative_tile);
#endif
}
}
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index deb5a50eb2..b00d05c17c 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -1539,7 +1539,7 @@ const Vector2i TileSetSource::INVALID_ATLAS_COORDS = Vector2i(-1, -1);
const int TileSetSource::INVALID_TILE_ALTERNATIVE = -1;
#ifndef DISABLE_DEPRECATED
-void TileSet::compatibility_conversion() {
+void TileSet::_compatibility_conversion() {
for (Map<int, CompatibilityTileData *>::Element *E = compatibility_data.front(); E; E = E->next()) {
CompatibilityTileData *ctd = E->value();
@@ -1551,13 +1551,94 @@ void TileSet::compatibility_conversion() {
// Handle each tile as a new source. Not optimal but at least it should stay compatible.
switch (ctd->tile_mode) {
- case 0: // SINGLE_TILE
- // TODO
- break;
- case 1: // AUTO_TILE
+ case COMPATIBILITY_TILE_MODE_SINGLE_TILE: {
+ atlas_source->set_margins(ctd->region.get_position());
+ atlas_source->set_texture_region_size(ctd->region.get_size());
+
+ Vector2i coords = Vector2i(0, 0);
+ for (int flags = 0; flags < 8; flags++) {
+ bool flip_h = flags & 1;
+ bool flip_v = flags & 2;
+ bool transpose = flags & 4;
+
+ int alternative_tile = 0;
+ if (!atlas_source->has_tile(coords)) {
+ atlas_source->create_tile(coords);
+ } else {
+ alternative_tile = atlas_source->create_alternative_tile(coords);
+ }
+
+ // Add to the mapping.
+ Array key_array;
+ key_array.push_back(flip_h);
+ key_array.push_back(flip_v);
+ key_array.push_back(transpose);
+
+ Array value_array;
+ value_array.push_back(source_id);
+ value_array.push_back(coords);
+ value_array.push_back(alternative_tile);
+
+ if (!compatibility_tilemap_mapping.has(E->key())) {
+ compatibility_tilemap_mapping[E->key()] = Map<Array, Array>();
+ }
+ compatibility_tilemap_mapping[E->key()][key_array] = value_array;
+ compatibility_tilemap_mapping_tile_modes[E->key()] = COMPATIBILITY_TILE_MODE_SINGLE_TILE;
+ print_line(vformat("Added conversion from:%s to%s", key_array, value_array));
+
+ TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(coords, alternative_tile));
+
+ tile_data->set_flip_h(flip_h);
+ tile_data->set_flip_v(flip_v);
+ tile_data->set_transpose(transpose);
+ tile_data->tile_set_material(ctd->material);
+ tile_data->set_modulate(ctd->modulate);
+ tile_data->set_z_index(ctd->z_index);
+
+ if (ctd->occluder.is_valid()) {
+ if (get_occlusion_layers_count() < 1) {
+ set_occlusion_layers_count(1);
+ }
+ tile_data->set_occluder(0, ctd->occluder);
+ }
+ if (ctd->navigation.is_valid()) {
+ if (get_navigation_layers_count() < 1) {
+ set_navigation_layers_count(1);
+ }
+ tile_data->set_navigation_polygon(0, ctd->autotile_navpoly_map[coords]);
+ }
+
+ tile_data->set_z_index(ctd->z_index);
+
+ // Add the shapes.
+ if (ctd->shapes.size() > 0) {
+ if (get_physics_layers_count() < 1) {
+ set_physics_layers_count(1);
+ }
+ }
+ for (int k = 0; k < ctd->shapes.size(); k++) {
+ CompatibilityShapeData csd = ctd->shapes[k];
+ if (csd.autotile_coords == coords) {
+ Ref<ConvexPolygonShape2D> convex_shape = csd.shape; // Only ConvexPolygonShape2D are supported, which is the default type used by the 3.x editor
+ if (convex_shape.is_valid()) {
+ Vector<Vector2> polygon = convex_shape->get_points();
+ for (int point_index = 0; point_index < polygon.size(); point_index++) {
+ polygon.write[point_index] = csd.transform.xform(polygon[point_index]);
+ }
+ tile_data->set_collision_polygons_count(0, tile_data->get_collision_polygons_count(0) + 1);
+ int index = tile_data->get_collision_polygons_count(0) - 1;
+ tile_data->set_collision_polygon_one_way(0, index, csd.one_way);
+ tile_data->set_collision_polygon_one_way_margin(0, index, csd.one_way_margin);
+ tile_data->set_collision_polygon_points(0, index, polygon);
+ }
+ }
+ }
+ }
+ } break;
+ case COMPATIBILITY_TILE_MODE_AUTO_TILE: {
// TODO
- break;
- case 2: // ATLAS_TILE
+ } break;
+ case COMPATIBILITY_TILE_MODE_ATLAS_TILE: {
atlas_source->set_margins(ctd->region.get_position());
atlas_source->set_separation(Vector2i(ctd->autotile_spacing, ctd->autotile_spacing));
atlas_source->set_texture_region_size(ctd->autotile_tile_size);
@@ -1578,6 +1659,26 @@ void TileSet::compatibility_conversion() {
} else {
alternative_tile = atlas_source->create_alternative_tile(coords);
}
+
+ // Add to the mapping.
+ Array key_array;
+ key_array.push_back(coords);
+ key_array.push_back(flip_h);
+ key_array.push_back(flip_v);
+ key_array.push_back(transpose);
+
+ Array value_array;
+ value_array.push_back(source_id);
+ value_array.push_back(coords);
+ value_array.push_back(alternative_tile);
+
+ if (!compatibility_tilemap_mapping.has(E->key())) {
+ compatibility_tilemap_mapping[E->key()] = Map<Array, Array>();
+ }
+ compatibility_tilemap_mapping[E->key()][key_array] = value_array;
+ compatibility_tilemap_mapping_tile_modes[E->key()] = COMPATIBILITY_TILE_MODE_ATLAS_TILE;
+ print_line(vformat("Added conversion from:%s to%s", key_array, value_array));
+
TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(coords, alternative_tile));
tile_data->set_flip_h(flip_h);
@@ -1641,7 +1742,7 @@ void TileSet::compatibility_conversion() {
}
}
}
- break;
+ } break;
}
// Offset all shapes
@@ -1655,9 +1756,6 @@ void TileSet::compatibility_conversion() {
convex->set_points(points);
}
}
-
- // Add the mapping to the map
- compatibility_source_mapping.insert(E->key(), source_id);
}
// Reset compatibility data
@@ -1666,6 +1764,43 @@ void TileSet::compatibility_conversion() {
}
compatibility_data = Map<int, CompatibilityTileData *>();
}
+
+Array TileSet::compatibility_tilemap_map(int p_tile_id, Vector2i p_coords, bool p_flip_h, bool p_flip_v, bool p_transpose) {
+ Array cannot_convert_array;
+ cannot_convert_array.push_back(-1);
+ cannot_convert_array.push_back(TileSetAtlasSource::INVALID_ATLAS_COORDS);
+ cannot_convert_array.push_back(TileSetAtlasSource::INVALID_TILE_ALTERNATIVE);
+
+ if (!compatibility_tilemap_mapping.has(p_tile_id)) {
+ return cannot_convert_array;
+ }
+
+ int tile_mode = compatibility_tilemap_mapping_tile_modes[p_tile_id];
+ switch (tile_mode) {
+ case COMPATIBILITY_TILE_MODE_SINGLE_TILE: {
+ Array a;
+ a.push_back(p_flip_h);
+ a.push_back(p_flip_v);
+ a.push_back(p_transpose);
+ return compatibility_tilemap_mapping[p_tile_id][a];
+ }
+ case COMPATIBILITY_TILE_MODE_AUTO_TILE:
+ return cannot_convert_array;
+ break;
+ case COMPATIBILITY_TILE_MODE_ATLAS_TILE: {
+ Array a;
+ a.push_back(p_coords);
+ a.push_back(p_flip_h);
+ a.push_back(p_flip_v);
+ a.push_back(p_transpose);
+ return compatibility_tilemap_mapping[p_tile_id][a];
+ }
+ default:
+ return cannot_convert_array;
+ break;
+ }
+};
+
#endif // DISABLE_DEPRECATED
bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
@@ -1831,7 +1966,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
ctd->z_index = p_value;
// TODO: remove the conversion from here, it's not where it should be done
- compatibility_conversion();
+ _compatibility_conversion();
} else {
return false;
}
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index dbf6dbabe6..4dcde52098 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -79,15 +79,15 @@ private:
Vector2 tex_offset;
Ref<ShaderMaterial> material;
Rect2 region;
- int tile_mode;
- Color modulate;
+ int tile_mode = 0;
+ Color modulate = Color(1, 1, 1);
// Atlas or autotiles data
- int autotile_bitmask_mode;
+ int autotile_bitmask_mode = 0;
Vector2 autotile_icon_coordinate;
Size2i autotile_tile_size = Size2i(16, 16);
- int autotile_spacing;
+ int autotile_spacing = 0;
Map<Vector2i, int> autotile_bitmask_flags;
Map<Vector2i, Ref<OccluderPolygon2D>> autotile_occluder_map;
Map<Vector2i, Ref<NavigationPolygon>> autotile_navpoly_map;
@@ -99,20 +99,24 @@ private:
Vector2 occluder_offset;
Ref<NavigationPolygon> navigation;
Vector2 navigation_offset;
- int z_index;
+ int z_index = 0;
};
- Map<int, CompatibilityTileData *> compatibility_data = Map<int, CompatibilityTileData *>();
- Map<int, int> compatibility_source_mapping = Map<int, int>();
+ enum CompatibilityTileMode {
+ COMPATIBILITY_TILE_MODE_SINGLE_TILE = 0,
+ COMPATIBILITY_TILE_MODE_AUTO_TILE,
+ COMPATIBILITY_TILE_MODE_ATLAS_TILE,
+ };
-private:
- void compatibility_conversion();
+ Map<int, CompatibilityTileData *> compatibility_data;
+ Map<int, int> compatibility_tilemap_mapping_tile_modes;
+ Map<int, Map<Array, Array>> compatibility_tilemap_mapping;
-public:
- int compatibility_get_source_for_tile_id(int p_old_source) {
- return compatibility_source_mapping[p_old_source];
- };
+ void _compatibility_conversion();
+public:
+ // Format of output array [source_id, atlas_coords, alternative]
+ Array compatibility_tilemap_map(int p_tile_id, Vector2i p_coords, bool p_flip_h, bool p_flip_v, bool p_transpose);
#endif // DISABLE_DEPRECATED
public: