Skip to content

Commit

Permalink
Merge pull request #92194 from KoBeWi/TileMap_is_dead
Browse files Browse the repository at this point in the history
Remove some TileMap dependencies from TileMapLayer
  • Loading branch information
akien-mga committed May 21, 2024
2 parents d916423 + 6559bb6 commit 7ecf3eb
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 96 deletions.
4 changes: 2 additions & 2 deletions editor/plugins/tiles/tile_atlas_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ void TileAtlasView::_draw_base_tiles() {
Vector2 offset_pos = Rect2(base_frame_rect).get_center() + Vector2(tile_set_atlas_source->get_tile_data(atlas_coords, 0)->get_texture_origin());

// Draw the tile.
TileMap::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, 0, frame);
TileMapLayer::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, 0, frame);
}
}

Expand Down Expand Up @@ -411,7 +411,7 @@ void TileAtlasView::_draw_alternatives() {
}

// Draw the tile.
TileMap::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, alternative_id);
TileMapLayer::draw_tile(ci_rid, offset_pos, tile_set, source_id, atlas_coords, alternative_id);

// Increment the x position.
current_pos.x += transposed ? texture_region_size.y : texture_region_size.x;
Expand Down
85 changes: 0 additions & 85 deletions scene/2d/tile_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,91 +225,6 @@ int TileMap::get_rendering_quadrant_size() const {
return rendering_quadrant_size;
}

void TileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_normalized_animation_offset) {
ERR_FAIL_COND(!p_tile_set.is_valid());
ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id));
ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords));
ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_alternative_tile(p_atlas_coords, p_alternative_tile));
TileSetSource *source = *p_tile_set->get_source(p_atlas_source_id);
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source) {
// Check for the frame.
if (p_frame >= 0) {
ERR_FAIL_INDEX(p_frame, atlas_source->get_tile_animation_frames_count(p_atlas_coords));
}

// Get the texture.
Ref<Texture2D> tex = atlas_source->get_runtime_texture();
if (!tex.is_valid()) {
return;
}

// Check if we are in the texture, return otherwise.
Vector2i grid_size = atlas_source->get_atlas_grid_size();
if (p_atlas_coords.x >= grid_size.x || p_atlas_coords.y >= grid_size.y) {
return;
}

// Get tile data.
const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile);

// Get the tile modulation.
Color modulate = tile_data->get_modulate() * p_modulation;

// Compute the offset.
Vector2 tile_offset = tile_data->get_texture_origin();

// Get destination rect.
Rect2 dest_rect;
dest_rect.size = atlas_source->get_runtime_tile_texture_region(p_atlas_coords).size;
dest_rect.size.x += FP_ADJUST;
dest_rect.size.y += FP_ADJUST;

bool transpose = tile_data->get_transpose() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
if (transpose) {
dest_rect.position = (p_position - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset);
} else {
dest_rect.position = (p_position - dest_rect.size / 2 - tile_offset);
}

if (tile_data->get_flip_h() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H)) {
dest_rect.size.x = -dest_rect.size.x;
}

if (tile_data->get_flip_v() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V)) {
dest_rect.size.y = -dest_rect.size.y;
}

// Draw the tile.
if (p_frame >= 0) {
Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, p_frame);
tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
} else if (atlas_source->get_tile_animation_frames_count(p_atlas_coords) == 1) {
Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, 0);
tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
} else {
real_t speed = atlas_source->get_tile_animation_speed(p_atlas_coords);
real_t animation_duration = atlas_source->get_tile_animation_total_duration(p_atlas_coords) / speed;
real_t animation_offset = p_normalized_animation_offset * animation_duration;
// Accumulate durations unaffected by the speed to avoid accumulating floating point division errors.
// Aka do `sum(duration[i]) / speed` instead of `sum(duration[i] / speed)`.
real_t time_unscaled = 0.0;
for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) {
real_t frame_duration_unscaled = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame);
real_t slice_start = time_unscaled / speed;
real_t slice_end = (time_unscaled + frame_duration_unscaled) / speed;
RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, slice_start, slice_end, animation_offset);

Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame);
tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());

time_unscaled += frame_duration_unscaled;
}
RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, 1.0, 0.0, 1.0, 0.0);
}
}
}

void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
if (p_tileset == tile_set) {
return;
Expand Down
4 changes: 0 additions & 4 deletions scene/2d/tile_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ class TileMap : public Node2D {
// A compatibility enum to specify how is the data if formatted.
mutable TileMapDataFormat format = TileMapDataFormat::TILE_MAP_DATA_FORMAT_3;

static constexpr float FP_ADJUST = 0.00001;

// Properties.
Ref<TileSet> tile_set;
int rendering_quadrant_size = 16;
Expand Down Expand Up @@ -123,8 +121,6 @@ class TileMap : public Node2D {
void set_rendering_quadrant_size(int p_size);
int get_rendering_quadrant_size() const;

static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_normalized_animation_offset = 0.0);

// Accessors.
void set_tileset(const Ref<TileSet> &p_tileset);
Ref<TileSet> get_tileset() const;
Expand Down
95 changes: 90 additions & 5 deletions scene/2d/tile_map_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
}

// Drawing the tile in the canvas item.
TileMap::draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset);
draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset);
}

// Reset physics interpolation for any recreated canvas items.
Expand Down Expand Up @@ -1696,18 +1696,18 @@ void TileMapLayer::_notification(int p_what) {
_internal_update(true);
} break;

case TileMap::NOTIFICATION_ENTER_CANVAS: {
case NOTIFICATION_ENTER_CANVAS: {
dirty.flags[DIRTY_FLAGS_LAYER_IN_CANVAS] = true;
_queue_internal_update();
} break;

case TileMap::NOTIFICATION_EXIT_CANVAS: {
case NOTIFICATION_EXIT_CANVAS: {
dirty.flags[DIRTY_FLAGS_LAYER_IN_CANVAS] = true;
// Update immediately on exiting, and force cleanup.
_internal_update(true);
} break;

case TileMap::NOTIFICATION_VISIBILITY_CHANGED: {
case NOTIFICATION_VISIBILITY_CHANGED: {
dirty.flags[DIRTY_FLAGS_LAYER_VISIBILITY] = true;
_queue_internal_update();
} break;
Expand Down Expand Up @@ -2162,6 +2162,91 @@ TileMapCell TileMapLayer::get_cell(const Vector2i &p_coords) const {
}
}

void TileMapLayer::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_normalized_animation_offset) {
ERR_FAIL_COND(p_tile_set.is_null());
ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id));
ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords));
ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_alternative_tile(p_atlas_coords, p_alternative_tile));
TileSetSource *source = *p_tile_set->get_source(p_atlas_source_id);
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source) {
// Check for the frame.
if (p_frame >= 0) {
ERR_FAIL_INDEX(p_frame, atlas_source->get_tile_animation_frames_count(p_atlas_coords));
}

// Get the texture.
Ref<Texture2D> tex = atlas_source->get_runtime_texture();
if (tex.is_null()) {
return;
}

// Check if we are in the texture, return otherwise.
Vector2i grid_size = atlas_source->get_atlas_grid_size();
if (p_atlas_coords.x >= grid_size.x || p_atlas_coords.y >= grid_size.y) {
return;
}

// Get tile data.
const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile);

// Get the tile modulation.
Color modulate = tile_data->get_modulate() * p_modulation;

// Compute the offset.
Vector2 tile_offset = tile_data->get_texture_origin();

// Get destination rect.
Rect2 dest_rect;
dest_rect.size = atlas_source->get_runtime_tile_texture_region(p_atlas_coords).size;
dest_rect.size.x += FP_ADJUST;
dest_rect.size.y += FP_ADJUST;

bool transpose = tile_data->get_transpose() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
if (transpose) {
dest_rect.position = (p_position - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset);
} else {
dest_rect.position = (p_position - dest_rect.size / 2 - tile_offset);
}

if (tile_data->get_flip_h() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H)) {
dest_rect.size.x = -dest_rect.size.x;
}

if (tile_data->get_flip_v() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V)) {
dest_rect.size.y = -dest_rect.size.y;
}

// Draw the tile.
if (p_frame >= 0) {
Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, p_frame);
tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
} else if (atlas_source->get_tile_animation_frames_count(p_atlas_coords) == 1) {
Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, 0);
tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());
} else {
real_t speed = atlas_source->get_tile_animation_speed(p_atlas_coords);
real_t animation_duration = atlas_source->get_tile_animation_total_duration(p_atlas_coords) / speed;
real_t animation_offset = p_normalized_animation_offset * animation_duration;
// Accumulate durations unaffected by the speed to avoid accumulating floating point division errors.
// Aka do `sum(duration[i]) / speed` instead of `sum(duration[i] / speed)`.
real_t time_unscaled = 0.0;
for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) {
real_t frame_duration_unscaled = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame);
real_t slice_start = time_unscaled / speed;
real_t slice_end = (time_unscaled + frame_duration_unscaled) / speed;
RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, slice_start, slice_end, animation_offset);

Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame);
tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping());

time_unscaled += frame_duration_unscaled;
}
RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, 1.0, 0.0, 1.0, 0.0);
}
}
}

void TileMapLayer::set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile) {
// Set the current cell tile (using integer position).
Vector2i pk(p_coords);
Expand Down Expand Up @@ -2212,7 +2297,7 @@ void TileMapLayer::erase_cell(const Vector2i &p_coords) {
}

void TileMapLayer::fix_invalid_tiles() {
ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot call fix_invalid_tiles() on a TileMap without a valid TileSet.");
ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot call fix_invalid_tiles() on a TileMapLayer without a valid TileSet.");

RBSet<Vector2i> coords;
for (const KeyValue<Vector2i, CellData> &E : tile_map_layer_data) {
Expand Down
4 changes: 4 additions & 0 deletions scene/2d/tile_map_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ class TileMapLayer : public Node2D {
};

private:
static constexpr float FP_ADJUST = 0.00001;

// Properties.
HashMap<Vector2i, CellData> tile_map_layer_data;

Expand Down Expand Up @@ -407,6 +409,8 @@ class TileMapLayer : public Node2D {
// Not exposed to users.
TileMapCell get_cell(const Vector2i &p_coords) const;

static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_normalized_animation_offset = 0.0);

////////////// Exposed functions //////////////

// --- Cells manipulation ---
Expand Down

0 comments on commit 7ecf3eb

Please sign in to comment.