use crate::physics::orbit::MERCURY_RADIUS;
#[derive(Debug, Clone, Copy)]
pub struct Vertex {
pub position: [f64; 3],
pub normal: [f64; 3],
pub uv: [f32; 2],
pub tangent: [f64; 3],
}
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: u32,
) -> Self {
let mut vertices = Vec::new();
let mut indices = Vec::new();
let rows = subdivisions + 1;
let cols = subdivisions + 1;
for j in 0..rows {
for i in 0..cols {
let u = i as f64 / subdivisions as f64;
let v = j as f64 / subdivisions as f64;
let lat = lat_min + v * (lat_max - lat_min);
let lon = lon_min + u * (lon_max - lon_min);
let lat_rad = lat.to_radians();
let lon_rad = lon.to_radians();
let r = MERCURY_RADIUS;
let x = r * lat_rad.cos() * lon_rad.cos();
let y = r * lat_rad.cos() * lon_rad.sin();
let z = r * lat_rad.sin();
let len = (x * x + y * y + z * z).sqrt();
let nx = x / len;
let ny = y / len;
let nz = z / len;
let tx = -lon_rad.sin();
let ty = lon_rad.cos();
let tz = 0.0;
vertices.push(Vertex {
position: [x, y, z],
normal: [nx, ny, nz],
uv: [u as f32, v as f32],
tangent: [tx, ty, tz],
});
}
}
for j in 0..subdivisions {
for i in 0..subdivisions {
let a = j * cols + i;
let b = a + 1;
let c = a + cols;
let d = c + 1;
indices.push(a);
indices.push(c);
indices.push(b);
indices.push(b);
indices.push(c);
indices.push(d);
}
}
Self { vertices, indices }
}
pub fn vertex_count(&self) -> usize {
self.vertices.len()
}
pub fn triangle_count(&self) -> usize {
self.indices.len() / 3
}
}
pub fn vertex_count(lod: u8) -> usize {
match lod {
5 => 65536,
4 => 16384,
3 => 4096,
2 => 1024,
_ => 256,
}
}
pub fn base_radius() -> f64 {
MERCURY_RADIUS
}