Skip to main content

rustial_renderer_wgpu/gpu/
mesh.rs

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