99 lines
1.9 KiB
Rust
99 lines
1.9 KiB
Rust
use glam::Vec3;
|
|
|
|
use super::Vertex;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Mesh<T: Copy = Vertex> {
|
|
pub faces: Vec<[T; 3]>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct MeshIndexed<T: Copy = Vertex> {
|
|
pub vertices: Vec<T>,
|
|
pub faces: Vec<[u16; 3]>,
|
|
}
|
|
|
|
pub type CpuMesh = Mesh<Vertex>;
|
|
pub type CpuMeshIndexed = MeshIndexed<Vertex>;
|
|
|
|
impl<T: Copy> Mesh<T> {
|
|
pub fn new() -> Self {
|
|
Self { faces: Vec::new() }
|
|
}
|
|
|
|
pub fn concat(meshes: impl IntoIterator<Item = Self>) -> Self {
|
|
Self {
|
|
faces: meshes
|
|
.into_iter()
|
|
.map(|mesh| mesh.faces)
|
|
.flatten()
|
|
.collect(),
|
|
}
|
|
}
|
|
|
|
pub fn into_indexed(self) -> MeshIndexed<T> {
|
|
if self.faces.len() >= (1 << 16) / 3 {
|
|
panic!("too many faces");
|
|
}
|
|
let n_faces = self.faces.len() as u16;
|
|
MeshIndexed {
|
|
vertices: self.faces.into_iter().flatten().collect(),
|
|
faces: (0..n_faces)
|
|
.map(|face| [3 * face, 3 * face + 1, 3 * face + 2])
|
|
.collect(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Mesh<Vec3> {
|
|
pub fn to_standard_mesh(&self) -> CpuMesh {
|
|
CpuMesh {
|
|
faces: self
|
|
.faces
|
|
.iter()
|
|
.map(|face| {
|
|
let [a, b, c] = face;
|
|
let normal = (b - a).cross(c - a).normalize();
|
|
face.map(|position| Vertex { position, normal })
|
|
})
|
|
.collect(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: Copy> MeshIndexed<T> {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
vertices: Vec::new(),
|
|
faces: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn concat(meshes: impl IntoIterator<Item = Self>) -> Self {
|
|
let mut ret = Self::new();
|
|
for mesh in meshes {
|
|
let base = ret.vertices.len() as u16;
|
|
ret.vertices.extend(mesh.vertices);
|
|
if ret.vertices.len() > 1 << 16 {
|
|
panic!("too many vertices");
|
|
}
|
|
ret.faces.extend(
|
|
mesh.faces
|
|
.into_iter()
|
|
.map(|face| face.map(|index| base + index)),
|
|
);
|
|
}
|
|
ret
|
|
}
|
|
|
|
pub fn to_mesh(&self) -> Mesh<T> {
|
|
Mesh {
|
|
faces: self
|
|
.faces
|
|
.iter()
|
|
.map(|face| face.map(|index| self.vertices[index as usize]))
|
|
.collect(),
|
|
}
|
|
}
|
|
}
|