use crate::{Transform, Vector};
pub struct AbstractMesh {
pub vertices: Vec<AbstractVertex>,
pub triangles: Vec<AbstractTriangle>,
}
impl AbstractMesh {
pub fn new() -> AbstractMesh {
AbstractMesh {
vertices: Vec::new(),
triangles: Vec::new(),
}
}
pub fn clear(&mut self) {
self.vertices.clear();
self.triangles.clear();
}
pub fn add_triangles(&mut self, vertices: &[Vector], triangles: &[[u32; 3]]) -> u32 {
let offset = self.vertices.len() as u32;
self.vertices
.extend(vertices.iter().cloned().map(AbstractVertex::new));
self.triangles.extend(
triangles
.iter()
.map(|indices| AbstractTriangle::new(offset, *indices)),
);
offset as u32
}
pub fn add_positioned_vertices(
&mut self,
vertices: impl Iterator<Item = Vector>,
trans: Transform,
) -> u32 {
let offset = self.vertices.len();
self.vertices
.extend(vertices.map(|v| AbstractVertex::new(trans * v)));
offset as u32
}
pub fn scale(&mut self, r: f32) {
for p in self.vertices.iter_mut() {
p.pos *= r;
}
}
pub fn normalize(&mut self) {
let mut min_x = 0.0;
let mut min_y = 0.0;
let mut max_x = 0.0;
let mut max_y = 0.0;
for v in &self.vertices {
min_x = v.pos.x.min(min_x);
min_y = v.pos.y.min(min_y);
max_x = v.pos.x.max(max_x);
max_y = v.pos.y.max(max_y);
}
debug_assert_ne!(min_x, max_x, "Cannot normalize mesh with 0 area");
debug_assert_ne!(min_y, max_y, "Cannot normalize mesh with 0 area");
let offset = Vector::new(-min_x, -min_y);
let scale = Vector::new(2.0 / (max_x - min_x), 2.0 / (max_y - min_y));
let const_offset = Vector::new(-1.0, -1.0);
for v in &mut self.vertices {
v.pos += offset;
v.pos = v.pos.times(scale);
v.pos += const_offset;
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct AbstractVertex {
pub pos: Vector,
}
impl AbstractVertex {
pub fn new(pos: impl Into<Vector>) -> AbstractVertex {
AbstractVertex { pos: pos.into() }
}
}
#[derive(Clone)]
pub struct AbstractTriangle {
pub indices: [u32; 3],
}
impl AbstractTriangle {
pub fn new(offset: u32, indices: [u32; 3]) -> AbstractTriangle {
AbstractTriangle {
indices: [
indices[0] + offset,
indices[1] + offset,
indices[2] + offset,
],
}
}
}