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 misaligned with odd numbers #62911

Closed
GarethSomers opened this issue Jul 11, 2022 · 5 comments · Fixed by #74814
Closed

TileMap misaligned with odd numbers #62911

GarethSomers opened this issue Jul 11, 2022 · 5 comments · Fixed by #74814

Comments

@GarethSomers
Copy link

Godot version

4.0.alpha11.official

System information

Windows 10, GLES3, GTX3080

Issue description

TileMap's that use a Tile Size with an odd y px and/or an odd Texture Region Size have their textures offset by half a pixel.

It's possible to correct this by offsetting the transform but physics shapes are not corrected.

Steps to reproduce

Create a TileMap
Set the Tile Size x and y to 12px and 9px
Create a TileSet with any texture
Set the Atlas Properties Texture Region Size to 12px and 9px
Create a tile.

(_) RetirementHome tscn - Zombie - Godot Engine 11_07_2022 11_28_23 PM

Minimal reproduction project

No response

@Calinou
Copy link
Member

Calinou commented Jul 11, 2022

@GarethSomers Please upload a minimal reproduction project to make this easier to troubleshoot.

@GarethSomers
Copy link
Author

github-issue-godot-4-tilemap-offset.zip

So the tile is 0.5px below where it's supposed to be, and it's collision shape is in the correct position.

example tscn - Github Issue Godot 4 Tilemap Offset - Godot Engine 12_07_2022 10_31_42 PM

@groud groud self-assigned this Jul 26, 2022
@mikhaelmartin
Copy link

bug still exists on godot 4.0.rc2. tested on fedora linux. the tile is misaligned 0.5 px down and 0.5px right

image

@kleonc
Copy link
Member

kleonc commented Mar 11, 2023

@groud This seems to fix (edit: not fully though, see #74773 (comment)) the TileMap rendering part (it makes Vector2::operator-(const Vector2 &p_v) be used instead of Vector2i::operator-(const Vector2i &p_v) so the half size is not truncated to ints):

diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 11e59d9858..0924303d5b 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1432,7 +1432,7 @@ void TileMap::draw_tile(RID p_canvas_item, const Vector2i &p_position, const Ref
                Color modulate = tile_data->get_modulate() * p_modulation;

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

                // Get destination rect.
                Rect2 dest_rect;
@@ -1442,9 +1442,9 @@ void TileMap::draw_tile(RID p_canvas_item, const Vector2i &p_position, const Ref

                bool transpose = tile_data->get_transpose();
                if (transpose) {
-                       dest_rect.position = (p_position - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset);
+                       dest_rect.position = (Vector2(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);
+                       dest_rect.position = (Vector2(p_position) - dest_rect.size / 2 - tile_offset);
                }

                if (tile_data->get_flip_h()) {

But in editor stuff is still broken. In some places e.g. Rect2i::get_center() is used which returns Vector2i instead of Vector2, so not an actual center for odd sizes. With:

diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index 43c6d1a48b..2b42e41e73 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -247,7 +247,7 @@ void TileAtlasView::_draw_base_tiles() {
                        for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(atlas_coords); frame++) {
                                // Update the y to max value.
                                Rect2i base_frame_rect = tile_set_atlas_source->get_tile_texture_region(atlas_coords, frame);
-                               Vector2i offset_pos = base_frame_rect.get_center() + tile_set_atlas_source->get_tile_data(atlas_coords, 0)->get_texture_origin();
+                               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(base_tiles_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, 0, frame);
@@ -331,7 +331,7 @@ void TileAtlasView::_draw_base_tiles_shape_grid() {
                                }
                                Rect2i texture_region = tile_set_atlas_source->get_tile_texture_region(tile_id, frame);
                                Transform2D tile_xform;
-                               tile_xform.set_origin(texture_region.get_center() + in_tile_base_offset);
+                               tile_xform.set_origin(Rect2(texture_region).get_center() + in_tile_base_offset);
                                tile_xform.set_scale(tile_shape_size);
                                tile_set->draw_tile_shape(base_tiles_shape_grid, tile_xform, color);
                        }

it's:
vz0NXZUXBu
Not sure where exactly all the relevant parts affecting these are, leaving it for you. 🙂

@Portponky
Copy link

Hi, I made a PR which fixes this for the scene and the editor. The drawing code does not need to be changed, but it needs to be given data correctly rounded to integer to prevent the small offset happening.

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