veloren_voxygen/render/
mesh.rs

1use super::Vertex;
2use core::{iter::FromIterator, ops::Range};
3
4/// A `Vec`-based mesh structure used to store mesh data on the CPU.
5pub struct Mesh<V: Vertex> {
6    verts: Vec<V>,
7}
8
9impl<V: Vertex> Clone for Mesh<V> {
10    fn clone(&self) -> Self {
11        Self {
12            verts: self.verts.clone(),
13        }
14    }
15}
16
17impl<V: Vertex> Mesh<V> {
18    #[expect(clippy::new_without_default)]
19    /// Create a new `Mesh`.
20    pub fn new() -> Self { Self { verts: Vec::new() } }
21
22    /// Clear vertices, allows reusing allocated memory of the underlying Vec.
23    pub fn clear(&mut self) { self.verts.clear(); }
24
25    /// Get a slice referencing the vertices of this mesh.
26    pub fn vertices(&self) -> &[V] { &self.verts }
27
28    /// Get a mutable slice referencing the vertices of this mesh.
29    pub fn vertices_mut(&mut self) -> &mut [V] { &mut self.verts }
30
31    /// Get a mutable vec referencing the vertices of this mesh.
32    pub fn vertices_mut_vec(&mut self) -> &mut Vec<V> { &mut self.verts }
33
34    /// Push a new vertex onto the end of this mesh.
35    pub fn push(&mut self, vert: V) { self.verts.push(vert); }
36
37    /// Push a new polygon onto the end of this mesh.
38    pub fn push_tri(&mut self, tri: Tri<V>) {
39        self.verts.push(tri.a);
40        self.verts.push(tri.b);
41        self.verts.push(tri.c);
42    }
43
44    /// Push a new quad onto the end of this mesh.
45    pub fn push_quad(&mut self, quad: Quad<V>) {
46        // A quad is composed of two triangles. The code below converts the former to
47        // the latter.
48        if V::QUADS_INDEX.is_some() {
49            // 0, 1, 2, 2, 1, 3
50            // b, c, a, a, c, d
51            self.verts.push(quad.b);
52            self.verts.push(quad.c);
53            self.verts.push(quad.a);
54            self.verts.push(quad.d);
55        } else {
56            // Tri 1
57            self.verts.push(quad.a);
58            self.verts.push(quad.b);
59            self.verts.push(quad.c);
60
61            // Tri 2
62            self.verts.push(quad.c);
63            self.verts.push(quad.d);
64            self.verts.push(quad.a);
65        }
66    }
67
68    /// Overwrite a quad
69    pub fn replace_quad(&mut self, index: usize, quad: Quad<V>) {
70        if V::QUADS_INDEX.is_some() {
71            debug_assert!(index % 4 == 0);
72            assert!(index + 3 < self.verts.len());
73            self.verts[index] = quad.b;
74            self.verts[index + 1] = quad.c;
75            self.verts[index + 2] = quad.a;
76            self.verts[index + 3] = quad.d;
77        } else {
78            debug_assert!(index % 3 == 0);
79            assert!(index + 5 < self.verts.len());
80            // Tri 1
81            self.verts[index] = quad.a;
82            self.verts[index + 1] = quad.b;
83            self.verts[index + 2] = quad.c;
84
85            // Tri 2
86            self.verts[index + 3] = quad.c;
87            self.verts[index + 4] = quad.d;
88            self.verts[index + 5] = quad.a;
89        }
90    }
91
92    /// Push the vertices of another mesh onto the end of this mesh.
93    pub fn push_mesh(&mut self, other: &Mesh<V>) { self.verts.extend_from_slice(other.vertices()); }
94
95    /// Map and push the vertices of another mesh onto the end of this mesh.
96    pub fn push_mesh_map<F: FnMut(V) -> V>(&mut self, other: &Mesh<V>, mut f: F) {
97        // Reserve enough space in our Vec. This isn't necessary, but it tends to reduce
98        // the number of required (re)allocations.
99        self.verts.reserve(other.vertices().len());
100
101        for vert in other.vertices() {
102            self.verts.push(f(*vert));
103        }
104    }
105
106    pub fn iter(&self) -> std::slice::Iter<V> { self.verts.iter() }
107
108    /// NOTE: Panics if vertex_range is out of bounds of vertices.
109    pub fn iter_mut(&mut self, vertex_range: Range<usize>) -> std::slice::IterMut<V> {
110        self.verts[vertex_range].iter_mut()
111    }
112
113    pub fn len(&self) -> usize { self.verts.len() }
114
115    pub fn is_empty(&self) -> bool { self.len() == 0 }
116}
117
118impl<V: Vertex> IntoIterator for Mesh<V> {
119    type IntoIter = std::vec::IntoIter<V>;
120    type Item = V;
121
122    fn into_iter(self) -> Self::IntoIter { self.verts.into_iter() }
123}
124
125impl<V: Vertex> FromIterator<Tri<V>> for Mesh<V> {
126    fn from_iter<I: IntoIterator<Item = Tri<V>>>(tris: I) -> Self {
127        let mut this = Self::new();
128        let tris = tris.into_iter();
129        let (lower, upper) = tris.size_hint();
130        this.verts.reserve(3 * upper.unwrap_or(lower));
131        tris.fold(this, |mut this, tri| {
132            this.push_tri(tri);
133            this
134        })
135    }
136}
137
138impl<V: Vertex> FromIterator<Quad<V>> for Mesh<V> {
139    fn from_iter<I: IntoIterator<Item = Quad<V>>>(quads: I) -> Self {
140        let mut this = Self::new();
141        let quads = quads.into_iter();
142        let (lower, upper) = quads.size_hint();
143        this.verts
144            .reserve(if V::QUADS_INDEX.is_some() { 4 } else { 6 } * upper.unwrap_or(lower));
145        quads.fold(this, |mut this, quad| {
146            this.push_quad(quad);
147            this
148        })
149    }
150}
151
152/// Represents a triangle stored on the CPU.
153pub struct Tri<V: Vertex> {
154    pub a: V,
155    pub b: V,
156    pub c: V,
157}
158
159impl<V: Vertex> Tri<V> {
160    pub fn new(a: V, b: V, c: V) -> Self { Self { a, b, c } }
161}
162
163/// Represents a quad stored on the CPU.
164pub struct Quad<V: Vertex> {
165    pub a: V,
166    pub b: V,
167    pub c: V,
168    pub d: V,
169}
170
171impl<V: Vertex> Quad<V> {
172    pub fn new(a: V, b: V, c: V, d: V) -> Self { Self { a, b, c, d } }
173
174    #[must_use]
175    pub fn rotated_by(self, n: usize) -> Self {
176        let verts = [self.a, self.b, self.c, self.d];
177
178        Self {
179            a: verts[n % 4],
180            b: verts[(1 + n) % 4],
181            c: verts[(2 + n) % 4],
182            d: verts[(3 + n) % 4],
183        }
184    }
185}