#[derive(Debug, Clone)]
pub struct Vertex {
pub position: [f64; 3],
pub normal: [f64; 3],
pub uv: [f64; 2],
pub tangent: [f64; 4],
}
pub struct TerrainMesh {
pub vertices: Vec<Vertex>,
pub indices: Vec<u32>,
}
impl TerrainMesh {
pub fn from_region(
lat_min: f64,
lat_max: f64,
lon_min: f64,
lon_max: f64,
subdivisions: usize,
) -> Self {
let n = subdivisions + 1;
let mut vertices = Vec::with_capacity(n * n);
let mut indices = Vec::with_capacity(subdivisions * subdivisions * 6);
for j in 0..n {
let v = j as f64 / subdivisions as f64;
let lat = lat_min + v * (lat_max - lat_min);
let lat_rad = lat.to_radians();
for i in 0..n {
let u = i as f64 / subdivisions as f64;
let lon = lon_min + u * (lon_max - lon_min);
let lon_rad = lon.to_radians();
let r = crate::MARS_RADIUS + super::heightmap::mars_elevation(lat, lon);
let (sin_lat, cos_lat) = lat_rad.sin_cos();
let (sin_lon, cos_lon) = lon_rad.sin_cos();
let px = r * cos_lat * cos_lon;
let py = r * cos_lat * sin_lon;
let pz = r * sin_lat;
let nx = cos_lat * cos_lon;
let ny = cos_lat * sin_lon;
let nz = sin_lat;
let tx = -sin_lon;
let ty = cos_lon;
vertices.push(Vertex {
position: [px, py, pz],
normal: [nx, ny, nz],
uv: [u, v],
tangent: [tx, ty, 0.0, 1.0],
});
}
}
for j in 0..subdivisions {
for i in 0..subdivisions {
let tl = (j * n + i) as u32;
let tr = tl + 1;
let bl = ((j + 1) * n + i) as u32;
let br = bl + 1;
indices.extend_from_slice(&[tl, bl, tr, tr, bl, br]);
}
}
Self { vertices, indices }
}
pub fn vertex_count(&self) -> usize {
self.vertices.len()
}
pub fn triangle_count(&self) -> usize {
self.indices.len() / 3
}
}