diff options
Diffstat (limited to 'scene/2d/tile_map.cpp')
| -rw-r--r-- | scene/2d/tile_map.cpp | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index b6da4d5082..1f70d4b558 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -472,7 +472,13 @@ void TileMapLayer::_rendering_quadrants_update_cell(CellData &r_cell_data, SelfL TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source && atlas_source->has_tile(r_cell_data.cell.get_atlas_coords()) && atlas_source->has_alternative_tile(r_cell_data.cell.get_atlas_coords(), r_cell_data.cell.alternative_tile)) { is_valid = true; - tile_y_sort_origin = atlas_source->get_tile_data(r_cell_data.cell.get_atlas_coords(), r_cell_data.cell.alternative_tile)->get_y_sort_origin(); + const TileData *tile_data; + if (r_cell_data.runtime_tile_data_cache) { + tile_data = r_cell_data.runtime_tile_data_cache; + } else { + tile_data = atlas_source->get_tile_data(r_cell_data.cell.get_atlas_coords(), r_cell_data.cell.alternative_tile); + } + tile_y_sort_origin = tile_data->get_y_sort_origin(); } } @@ -652,7 +658,7 @@ void TileMapLayer::_physics_update() { const Ref<TileSet> &tile_set = tile_map_node->get_tileset(); // Check if we should cleanup everything. - bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid() || !tile_map_node->is_visible_in_tree(); + bool forced_cleanup = in_destructor || !enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid(); if (forced_cleanup) { // Clean everything. for (KeyValue<Vector2i, CellData> &kv : tile_map) { @@ -902,7 +908,7 @@ void TileMapLayer::_navigation_update() { NavigationServer2D *ns = NavigationServer2D::get_singleton(); // Check if we should cleanup everything. - bool forced_cleanup = in_destructor || !enabled || !navigation_enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid() || !tile_map_node->is_visible_in_tree(); + bool forced_cleanup = in_destructor || !enabled || !navigation_enabled || !tile_map_node->is_inside_tree() || !tile_set.is_valid(); // ----------- Layer level processing ----------- if (forced_cleanup) { @@ -2294,11 +2300,12 @@ void TileMapLayer::set_cells_terrain_path(TypedArray<Vector2i> p_path, int p_ter TypedArray<Vector2i> TileMapLayer::get_used_cells() const { // Returns the cells used in the tilemap. TypedArray<Vector2i> a; - a.resize(tile_map.size()); - int i = 0; for (const KeyValue<Vector2i, CellData> &E : tile_map) { - Vector2i p(E.key.x, E.key.y); - a[i++] = p; + const TileMapCell &c = E.value.cell; + if (c.source_id == TileSet::INVALID_SOURCE) { + continue; + } + a.push_back(E.key); } return a; @@ -2308,9 +2315,13 @@ TypedArray<Vector2i> TileMapLayer::get_used_cells_by_id(int p_source_id, const V // Returns the cells used in the tilemap. TypedArray<Vector2i> a; for (const KeyValue<Vector2i, CellData> &E : tile_map) { - if ((p_source_id == TileSet::INVALID_SOURCE || p_source_id == E.value.cell.source_id) && - (p_atlas_coords == TileSetSource::INVALID_ATLAS_COORDS || p_atlas_coords == E.value.cell.get_atlas_coords()) && - (p_alternative_tile == TileSetSource::INVALID_TILE_ALTERNATIVE || p_alternative_tile == E.value.cell.alternative_tile)) { + const TileMapCell &c = E.value.cell; + if (c.source_id == TileSet::INVALID_SOURCE) { + continue; + } + if ((p_source_id == TileSet::INVALID_SOURCE || p_source_id == c.source_id) && + (p_atlas_coords == TileSetSource::INVALID_ATLAS_COORDS || p_atlas_coords == c.get_atlas_coords()) && + (p_alternative_tile == TileSetSource::INVALID_TILE_ALTERNATIVE || p_alternative_tile == c.alternative_tile)) { a.push_back(E.key); } } @@ -2323,13 +2334,23 @@ Rect2i TileMapLayer::get_used_rect() const { if (used_rect_cache_dirty) { used_rect_cache = Rect2i(); - if (tile_map.size() > 0) { - used_rect_cache = Rect2i(tile_map.begin()->key.x, tile_map.begin()->key.y, 0, 0); - - for (const KeyValue<Vector2i, CellData> &E : tile_map) { + bool first = true; + for (const KeyValue<Vector2i, CellData> &E : tile_map) { + const TileMapCell &c = E.value.cell; + if (c.source_id == TileSet::INVALID_SOURCE) { + continue; + } + if (first) { + used_rect_cache = Rect2i(E.key.x, E.key.y, 0, 0); + first = false; + } else { used_rect_cache.expand_to(E.key); } - used_rect_cache.size += Vector2i(1, 1); // The cache expands to top-left coordinate, so we add one full tile. + } + if (!first) { + // Only if we have at least one cell. + // The cache expands to top-left coordinate, so we add one full tile. + used_rect_cache.size += Vector2i(1, 1); } used_rect_cache_dirty = false; } @@ -3051,8 +3072,12 @@ void TileMap::_internal_update() { return; } + // FIXME: This should only clear polygons that are no longer going to be used, but since it's difficult to determine, + // the cache is never cleared at runtime to prevent invalidating used polygons. + if (Engine::get_singleton()->is_editor_hint()) { + polygon_cache.clear(); + } // Update dirty quadrants on layers. - polygon_cache.clear(); for (Ref<TileMapLayer> &layer : layers) { layer->internal_update(); } |
