Lerping between points on an isometric map
Asked Answered
G

5

0

Hello, I am using an isometric TileMap that fakes 3D space by using layers as an up/down axis, and by offsetting tiles in higher layers upwards so that they appear above the layers below.

I also have an AStar3D for calculating paths between tiles on the TileMap.

I want to animate a sprite following this path, and I think this requires me to translate a given AStar3D position into a TileMap tile+layer coordinate, into the tile's local position on the map, into a global position to give the sprite to use for position lerps.

I am having trouble with TileMap's map_to_local() method because it only returns the local position of the tile's center, but I want to be able to get local positions offset from the tile center too, since sprites might not always be initiating paths from the center of a tile. map_to_local() expects a Vector2i, but I want to be able to input a Vector2.

Is there a better way of doing what I'm trying to do? Thanks!

Gina answered 22/3 at 8:18 Comment(0)
B
0

Gina In which form you keep the position of your object/sprite within the isometric world?

Borrero answered 22/3 at 13:22 Comment(0)
G
0

I'm using navigation graph position as its 'real' 3D position in the map, and then using the TileMap.map_to_local to get a screenspace 2D position that accounts for the isometric skew/rotation. The 2D position is only used for setting the sprite's position on the screen, all distance/direction calculations use the 3D position.

Thanks for the response!

Gina answered 22/3 at 15:23 Comment(0)
B
0

Gina Since you have the "real" coordinates, simply multiply x and z coordinates with x and z (or y) isometric basis vectors and add the results. This should give you the screen space position.

Borrero answered 22/3 at 19:12 Comment(0)
G
0

i seeee, I'll try that out, thanks!

Gina answered 22/3 at 22:12 Comment(0)
G
0

I was able to get the Navigation Position to World Position working!

Though, it's been a while since Linear Algebra and I hardly understand how the transformation matrix works, haha.

I also used this as a reference for the math.

Here's my method:
(I divide my pos.z by 2 because each layer can contain tiles of either half height or full height. It was my work around for Godot's TileMap not supporting layer offsets)

func get_tile_world_transform(pos: Vector3):
	pos.x += 1
	var layer = int(pos.z)/2
	
	var matrix = Transform3D()
	var tile_length = map.tile_set.tile_size.x/2
	matrix.basis.x = tile_length * Vector3(1.0, -1.0/2.0, -1.0/2.0/sqrt(2.0))
	matrix.basis.y = tile_length * Vector3(-1.0, -1.0/2.0, -1.0/2.0/sqrt(2.0))
	matrix.basis.z = tile_length * Vector3(0.0, 1.0, -1.0/2.0/sqrt(2.0))/2
	matrix.origin = Vector3.ZERO
	
	var world_pos = matrix * pos
	world_pos.y *= -1
	
	world_pos = map.to_global(Vector2(world_pos.x, world_pos.y))
		
	return Vector3(world_pos.x,world_pos.y,map.get_layer_z_index(layer))

Though for some reason I need to offset the original Navigation Graph position by +1 in the X axis; I'm not sure why. Maybe some integer division I missed somewhere? Otherwise, it seems to be working as intended. Thanks for all the help!

But would you happen to know why I'm needing to add that pos.x offset?

Gina answered 23/3 at 2:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.