1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//! Tile mesh generation for GPU rendering.
use crate::gpu::vertex::TileVertex;
use glam::DVec3;
use rustial_engine::{tile_bounds_world, TileId};
/// Generated mesh data for a single tile quad.
pub struct TileMesh {
/// Four quad vertices in CCW order (bottom-left, bottom-right,
/// top-right, top-left) in camera-relative world space.
pub vertices: [TileVertex; 4],
/// Triangle-list indices for the quad (`0,1,2` and `0,2,3`).
pub indices: [u16; 6],
}
/// Build a tile quad mesh in world space, then offset relative to a camera origin
/// to avoid floating-point precision issues far from the origin.
pub fn build_tile_mesh(tile: &TileId, camera_origin: DVec3) -> TileMesh {
let bounds = tile_bounds_world(tile);
let min = bounds.min.position - camera_origin;
let max = bounds.max.position - camera_origin;
let vertices = [
TileVertex {
position: [min.x as f32, min.y as f32, 0.0],
uv: [0.0, 1.0],
opacity: 1.0,
},
TileVertex {
position: [max.x as f32, min.y as f32, 0.0],
uv: [1.0, 1.0],
opacity: 1.0,
},
TileVertex {
position: [max.x as f32, max.y as f32, 0.0],
uv: [1.0, 0.0],
opacity: 1.0,
},
TileVertex {
position: [min.x as f32, max.y as f32, 0.0],
uv: [0.0, 0.0],
opacity: 1.0,
},
];
let indices = [0, 1, 2, 0, 2, 3];
TileMesh { vertices, indices }
}