use super::Pipeline; use core::{iter::FromIterator, ops::Range}; /// A `Vec`-based mesh structure used to store mesh data on the CPU. pub struct Mesh { verts: Vec, } impl Clone for Mesh

where P::Vertex: Clone, { fn clone(&self) -> Self { Self { verts: self.verts.clone(), } } } impl Mesh

{ /// Create a new `Mesh`. #[allow(clippy::new_without_default)] // TODO: Pending review in #587 pub fn new() -> Self { Self { verts: Vec::new() } } /// Clear vertices, allows reusing allocated memory of the underlying Vec. pub fn clear(&mut self) { self.verts.clear(); } /// Get a slice referencing the vertices of this mesh. pub fn vertices(&self) -> &[P::Vertex] { &self.verts } /// Get a mutable slice referencing the vertices of this mesh. pub fn vertices_mut(&mut self) -> &mut [P::Vertex] { &mut self.verts } /// Push a new vertex onto the end of this mesh. pub fn push(&mut self, vert: P::Vertex) { self.verts.push(vert); } /// Push a new polygon onto the end of this mesh. pub fn push_tri(&mut self, tri: Tri

) { self.verts.push(tri.a); self.verts.push(tri.b); self.verts.push(tri.c); } /// Push a new quad onto the end of this mesh. pub fn push_quad(&mut self, quad: Quad

) { // A quad is composed of two triangles. The code below converts the former to // the latter. // Tri 1 self.verts.push(quad.a.clone()); self.verts.push(quad.b); self.verts.push(quad.c.clone()); // Tri 2 self.verts.push(quad.c); self.verts.push(quad.d); self.verts.push(quad.a); } /// Overwrite a quad pub fn replace_quad(&mut self, index: usize, quad: Quad

) { debug_assert!(index % 3 == 0); assert!(index + 5 < self.verts.len()); // Tri 1 self.verts[index] = quad.a.clone(); self.verts[index + 1] = quad.b; self.verts[index + 2] = quad.c.clone(); // Tri 2 self.verts[index + 3] = quad.c; self.verts[index + 4] = quad.d; self.verts[index + 5] = quad.a; } /// Push the vertices of another mesh onto the end of this mesh. pub fn push_mesh(&mut self, other: &Mesh

) { self.verts.extend_from_slice(other.vertices()); } /// Map and push the vertices of another mesh onto the end of this mesh. pub fn push_mesh_map P::Vertex>(&mut self, other: &Mesh

, mut f: F) { // Reserve enough space in our Vec. This isn't necessary, but it tends to reduce // the number of required (re)allocations. self.verts.reserve(other.vertices().len()); for vert in other.vertices() { self.verts.push(f(vert.clone())); } } pub fn iter(&self) -> std::slice::Iter { self.verts.iter() } /// NOTE: Panics if vertex_range is out of bounds of vertices. pub fn iter_mut(&mut self, vertex_range: Range) -> std::slice::IterMut { self.verts[vertex_range].iter_mut() } } impl IntoIterator for Mesh

{ type IntoIter = std::vec::IntoIter; type Item = P::Vertex; fn into_iter(self) -> Self::IntoIter { self.verts.into_iter() } } impl FromIterator> for Mesh

{ fn from_iter>>(tris: I) -> Self { tris.into_iter().fold(Self::new(), |mut this, tri| { this.push_tri(tri); this }) } } impl FromIterator> for Mesh

{ fn from_iter>>(quads: I) -> Self { quads.into_iter().fold(Self::new(), |mut this, quad| { this.push_quad(quad); this }) } } /// Represents a triangle stored on the CPU. pub struct Tri { a: P::Vertex, b: P::Vertex, c: P::Vertex, } impl Tri

{ pub fn new(a: P::Vertex, b: P::Vertex, c: P::Vertex) -> Self { Self { a, b, c } } } /// Represents a quad stored on the CPU. pub struct Quad { a: P::Vertex, b: P::Vertex, c: P::Vertex, d: P::Vertex, } impl Quad

{ pub fn new(a: P::Vertex, b: P::Vertex, c: P::Vertex, d: P::Vertex) -> Self { Self { a, b, c, d } } pub fn rotated_by(self, n: usize) -> Self where P::Vertex: Clone, { let verts = [self.a, self.b, self.c, self.d]; Self { a: verts[n % 4].clone(), b: verts[(1 + n) % 4].clone(), c: verts[(2 + n) % 4].clone(), d: verts[(3 + n) % 4].clone(), } } }