StarArawn / bevy_ecs_tilemap

A tilemap rendering crate for bevy which is more ECS friendly.
MIT License
949 stars 197 forks source link

Error in 3d_iso example on mouse to tile #415

Open MonforteAdrian opened 1 year ago

MonforteAdrian commented 1 year ago

Trying to add the mouse_to_tile example to the 3d_iso. The detection works and change the tile but the area of detection is moved half of the tile. When changed the tileheight to 64 in iso_map.tmx the detection works better(not as good as the mouse_to_tile) but the iso representation is not correct. Here we can see the correct view of the 3d_iso with the problem in the area of detection 1 Here we can see the incorrect view of the 3d_is with the better area of detection 2

StarArawn commented 1 year ago

Stacked or 3d isometric tile picking is not an easy thing to solve. I recommend implementing your own solution as we currently do not support it.

MonforteAdrian commented 1 year ago

After playing a bit with this I found that if we change the DIAMOND_BASIS in the src/helpers/square_grid/diamond.rs to work with 64x64 instead of 64x32 we can get the 3d view and almost the from_worl_pos working. The only trouble is, when you go up or down in the screen, it doesn't work well, meaning that as further you go up more big is the error. I don't have the knowledge to fix this quick. Maybe we can add an option were we specify if it's the full block or just the top and have both config in the diamond.rs.

tguichaoua commented 1 year ago

I fix it by applying a delta to the cursor position before computing the TilePos.

for (map_size, grid_size, map_type, tile_storage, map_transform) in tilemap_q.iter() {
    // We need to make sure that the cursor's world position is correct relative to the map
    // due to any map transformation.
    let cursor_in_map_pos: Vec2 = {
        // Extend the cursor_pos vec3 by 0.0 and 1.0
        let cursor_pos = Vec4::from((cursor_position, 0.0, 1.0));
        let cursor_in_map_pos = map_transform.compute_matrix().inverse() * cursor_pos;
        cursor_in_map_pos.xy()
    };

    // Fix the gap due the dimond grid.
    let cursor_in_map_pos = cursor_in_map_pos - Vec2::new(0.0, grid_size.y / 2.0); // <----------- Here

    // Once we have a world position we can transform it into a possible tile position.
    if let Some(tile_pos) =
        TilePos::from_world_pos(&cursor_in_map_pos, map_size, grid_size, map_type)
    {
        if let Some(tile_entity) = tile_storage.get(&tile_pos) {
           /* ... */
        }
    }
}
StarArawn commented 9 months ago

Useful resource: https://stackoverflow.com/questions/21842814/mouse-position-to-isometric-tile-including-height