Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TileMap Fix rendering odd-sized tiles #74814

Merged

Conversation

kleonc
Copy link
Member

@kleonc kleonc commented Mar 12, 2023

Each TileMapQuadrant was storing local positions within the map_to_local/local_to_map maps cached for rendering as Vector2is instead of Vector2s. This is incorrect, local positions can be non-int. Using float vectors for keys is fine in here, as what's being used for these are the results of TileMap::map_to_local(cell_map_coords) calls which are per-cell unique and always the same for each cell.

Cells are rendered relative to the per quadrant CanvasItem(s) (ci below; E_cell.key - tile_position being the relative position):

godot/scene/2d/tile_map.cpp

Lines 1284 to 1285 in 550a779

// Drawing the tile in the canvas item.
draw_tile(ci, E_cell.key - tile_position, tile_set, c.source_id, c.get_atlas_coords(), c.alternative_tile, -1, get_self_modulate(), tile_data);

and quadrant's own position can also be non-int: it's calculated as the position of its first cell's position (its center and hence can be non-int), possibly offsetted according to the Y-sorting:

godot/scene/2d/tile_map.cpp

Lines 1241 to 1246 in 550a779

// Quandrant pos.
Vector2 tile_position = map_to_local(q.coords * get_effective_quadrant_size(q.layer));
if (is_y_sort_enabled() && layers[q.layer].y_sort_enabled) {
// When Y-sorting, the quandrant size is sure to be 1, we can thus offset the CanvasItem.
tile_position.y += layers[q.layer].y_sort_origin + tile_data->get_y_sort_origin();
}

Meaning the relative cell-in-quadrant position (E_cell.key - tile_position) can be non-int, hence this PR changes draw_tile to take in Vector2 instead of Vector2i to avoid truncating such passed relative positions to ints.

On top of the above fixes the in-editor plugin rendering as in some places Rect2i::get_center() was used which returns a center truncated to ints (a Vector2i) instead of an actual center which is needed. This resulted in another possible misalignment by half unit.

Fixes #62911.
Supersedes #74773. Thanks @Portponky for pointing at the cause

Before After
Godot_v4 0-stable_win64_I8ezii2ASO qSVdRHhfFS
YSxB2iPHX3 Qdui5T2PmK
FMGxXxrnyH mqIVM94mGc
17T8sbsJBS godot windows editor dev x86_64_YMsmDOG03M

@kleonc kleonc added this to the 4.1 milestone Mar 12, 2023
@kleonc kleonc requested a review from groud March 12, 2023 11:58
@kleonc kleonc requested a review from a team as a code owner March 12, 2023 11:58
@kleonc kleonc force-pushed the tilemap-fix-rendering-odd-sized-tiles branch from 45217d2 to c49a7fe Compare March 12, 2023 15:21
@kleonc
Copy link
Member Author

kleonc commented Mar 12, 2023

Rechecked and updated as I've missed changing TileMapQuadrant.CoordsWorldComparator to non-ints before.

Copy link
Member

@KoBeWi KoBeWi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still needs a check from @groud probably.

@YuriSizov YuriSizov merged commit 9e6b680 into godotengine:master Apr 18, 2023
@YuriSizov
Copy link
Contributor

Thanks!

@kleonc kleonc deleted the tilemap-fix-rendering-odd-sized-tiles branch April 18, 2023 14:51
@YuriSizov
Copy link
Contributor

Cherry-picked for 4.0.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TileMap misaligned with odd numbers
4 participants