use sciforge::hub::prelude::constants::EARTH_RADIUS;
#[derive(Debug, Clone, Copy)]
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 fromregion(
latmin: f64,
latmax: f64,
lonmin: f64,
lonmax: f64,
subdivisions: u32,
elevationfn: &dyn Fn(f64, f64) -> f64,
) -> Self {
let mut vertices = Vec::new();
let mut indices = Vec::new();
let steps = subdivisions + 1;
for j in 0..steps {
for i in 0..steps {
let u = i as f64 / subdivisions as f64;
let v = j as f64 / subdivisions as f64;
let lat = latmin + (latmax - latmin) * v;
let lon = lonmin + (lonmax - lonmin) * u;
let latrad = lat.to_radians();
let lonrad = lon.to_radians();
let r = EARTH_RADIUS + elevationfn(lat, lon);
let x = r * latrad.cos() * lonrad.cos();
let y = r * latrad.cos() * lonrad.sin();
let z = r * latrad.sin();
let nx = latrad.cos() * lonrad.cos();
let ny = latrad.cos() * lonrad.sin();
let nz = latrad.sin();
let tx = -lonrad.sin();
let ty = lonrad.cos();
vertices.push(Vertex {
position: [x, y, z],
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 a = j * steps + i;
let b = a + 1;
let c = a + steps;
let d = c + 1;
indices.extend_from_slice(&[a, c, b, b, c, d]);
}
}
Self { vertices, indices }
}
pub fn vertexcount(&self) -> usize {
self.vertices.len()
}
pub fn trianglecount(&self) -> usize {
self.indices.len() / 3
}
}