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 map_to_world and world_to_map do not account for TileMap node positions that are not at (0,0) #37394

Closed
jeremyhofer opened this issue Mar 28, 2020 · 2 comments

Comments

@jeremyhofer
Copy link

jeremyhofer commented Mar 28, 2020

Godot version:
3.2.1.stable.custom_build

OS/device including version:
Linux version 5.5.11-arch1-1 (linux@archlinux) (gcc version 9.3.0 (Arch Linux 9.3.0-1)) #1 SMP PREEMPT Sun, 22 Mar 2020 16:33:15 +0000

Issue description:
When a TileMap's node position is altered from (0, 0) the map_to_world and world_to_map functions do not account for the node position. This causes incorrect world and map positions to be returned, respectively.

For example, in my current project I have a TileMap as a child of a Node. The project has a screen size of 1920x1080. The TileMap is set to isometric with tile sizes of 96x49. The TileMap position was changed to (960, 294). This correlates to a map position of (0, 0) at a world position of (960, 294). However, when this position is converted with world_to_map it returns a map position of (16, -4) which is what the position would be if the TileMap position was (0, 0).

To get the proper positions for world_to_map the function must first subtract the TileMap's position vector from the world position vector prior to performing the world_to_map transformation.

To get the proper positions for map_to_world the function must add the TileMap's position vector to the world position vector returned by the map_to_world transformation.

GDScript fix example:

extends TileMap

func world_to_map(w_pos):
	# godot does not handle world_to_map transformation correctly when
	# the tilemap's position is not at (0, 0). We must offset our point
	# by the position of the tilemap
	return .world_to_map(w_pos - position)
	
func map_to_world(m_pos, ignore_half_ofs=false):
	# godot does not handle map_to_world transformation correctly when
	# the tilemap's position is not at (0, 0). We must offset our point
	# by the position of the tilemap
	return .map_to_world(m_pos, ignore_half_ofs) + position

Minimal reproduction project:

  1. Create a new 2D scene with a Node as root. My project is also using a screen size of 1920x1080.
  2. Add a TileMap node as a child of the root. Configure to be isometric with cells of 96x49.
  3. Alter the TileMap node position to be something other than (0, 0), for example (960, 294).
  4. Try to programmatically obtain the map position of any tile, for example the top most tile. The position returned will still reflect a TileMap node position at (0, 0).
@zzz-assault
Copy link
Contributor

Based on the PR #38551 to fix this potential bug, it was decided, that the local transform is correct and the documentation needs to be changed (to clearly state local transform / coords).

If you need global data simply use the node2d functions "to_global" for output of map_to_world and "to_local" for input of world_to_map.

From my point of view, this issue can be closed, after the official API documentation was corrected.

@akien-mga
Copy link
Member

Fixed by #45919.

@akien-mga akien-mga modified the milestones: 4.0, 3.2 Feb 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants