1use bytemuck::{Pod, Zeroable};
2use std::{ops::Range, vec::Drain};
3
4#[derive(Debug, Copy, Clone, Pod, Zeroable)]
5#[repr(C)]
6pub struct Triangle {
7 pub a: u32,
8 pub b: u32,
9 pub c: u32,
10}
11
12impl Default for Triangle {
13 fn default() -> Self {
14 Self { a: 0, b: 1, c: 2 }
15 }
16}
17
18impl Triangle {
19 pub fn offset(mut self, offset: usize) -> Self {
20 self.a += offset as u32;
21 self.b += offset as u32;
22 self.c += offset as u32;
23 self
24 }
25}
26
27#[derive(Debug, Clone, Copy)]
28pub struct VertexStreamToken {
29 vertices: usize,
30 triangles: usize,
31 batches: usize,
32}
33
34pub struct VertexStream<V: Pod, B> {
35 vertices: Vec<V>,
36 triangles: Vec<Triangle>,
37 batches: Vec<(B, Range<usize>)>,
38 resize_count: usize,
39}
40
41impl<V: Pod, B> Default for VertexStream<V, B> {
42 fn default() -> Self {
43 Self {
44 vertices: Vec::with_capacity(1024),
45 triangles: Vec::with_capacity(1024),
46 batches: Vec::with_capacity(1024),
47 resize_count: 1024,
48 }
49 }
50}
51
52impl<V: Pod, B> VertexStream<V, B> {
53 pub fn new(resize_count: usize) -> Self {
54 Self {
55 vertices: Vec::with_capacity(resize_count),
56 triangles: Vec::with_capacity(resize_count),
57 batches: Vec::with_capacity(resize_count),
58 resize_count,
59 }
60 }
61
62 pub fn fork(&self) -> Self {
63 Self::new(self.resize_count)
64 }
65
66 pub fn token(&self) -> VertexStreamToken {
67 VertexStreamToken {
68 vertices: self.vertices.len(),
69 triangles: self.triangles.len(),
70 batches: self.batches.len(),
71 }
72 }
73
74 pub unsafe fn extract(&mut self, token: VertexStreamToken) -> Self {
77 let VertexStreamToken {
78 vertices,
79 triangles,
80 batches,
81 } = token;
82 let mut result = self.fork();
83 unsafe {
84 result.extend_vertices(self.vertices.drain(vertices..));
85 result.extend_triangles(
86 false,
87 self.triangles.drain(triangles..).map(|mut triangle| {
88 triangle.a -= vertices as u32;
89 triangle.b -= vertices as u32;
90 triangle.c -= vertices as u32;
91 triangle
92 }),
93 );
94 result.extend_batches(self.batches.drain(batches..).map(|(batch, mut range)| {
95 range.start -= triangles;
96 range.end -= triangles;
97 (batch, range)
98 }));
99 }
100 result
101 }
102
103 pub fn transformed(
104 &mut self,
105 mut f: impl FnMut(&mut Self),
106 mut t: impl FnMut(&mut V),
107 ) -> &mut Self {
108 let start = self.vertices.len();
109 f(self);
110 let end = self.vertices.len();
111 for vertex in &mut self.vertices[start..end] {
112 t(vertex);
113 }
114 self
115 }
116
117 pub fn triangle(&mut self, vertices: [V; 3]) -> &mut Self {
118 self.ensure_capacity();
119 let offset = self.vertices.len();
120 self.vertices.extend(vertices);
121 self.triangles.push(Triangle::default().offset(offset));
122 self
123 }
124
125 pub fn triangle_fan(&mut self, vertices: impl IntoIterator<Item = V>) -> &mut Self {
126 self.ensure_capacity();
127 let start = self.vertices.len() as u32;
128 self.vertices.extend(vertices);
129 let end = self.vertices.len() as u32;
130 let count = (end - start).saturating_sub(2);
131 let mut offset = start + 1;
132 for _ in 0..count {
133 self.triangles.push(Triangle {
134 a: start,
135 b: offset,
136 c: offset + 1,
137 });
138 offset += 1;
139 }
140 self
141 }
142
143 pub fn triangle_strip(&mut self, vertices: impl IntoIterator<Item = V>) -> &mut Self {
144 self.ensure_capacity();
145 let start = self.vertices.len() as u32;
146 self.vertices.extend(vertices);
147 let end = self.vertices.len() as u32;
148 let count = (end - start).saturating_sub(2);
149 let mut offset = start;
150 let mut flip = false;
151 for _ in 0..count {
152 self.triangles.push(if flip {
153 Triangle {
154 a: offset + 1,
155 b: offset,
156 c: offset + 2,
157 }
158 } else {
159 Triangle {
160 a: offset,
161 b: offset + 1,
162 c: offset + 2,
163 }
164 });
165 offset += 1;
166 flip = !flip;
167 }
168 self
169 }
170
171 pub fn quad(&mut self, vertices: [V; 4]) -> &mut Self {
172 self.ensure_capacity();
173 let offset = self.vertices.len();
174 self.vertices.extend(vertices);
175 self.triangles
176 .push(Triangle { a: 0, b: 1, c: 2 }.offset(offset));
177 self.triangles
178 .push(Triangle { a: 2, b: 3, c: 0 }.offset(offset));
179 self
180 }
181
182 pub fn extend(
183 &mut self,
184 vertices: impl IntoIterator<Item = V>,
185 triangles: impl IntoIterator<Item = Triangle>,
186 ) -> &mut Self {
187 self.ensure_capacity();
188 let offset = self.vertices.len();
189 self.vertices.extend(vertices);
190 self.triangles.extend(
191 triangles
192 .into_iter()
193 .map(|triangle| triangle.offset(offset)),
194 );
195 self
196 }
197
198 pub unsafe fn extend_vertices(&mut self, iter: impl IntoIterator<Item = V>) -> &Self {
201 self.vertices.extend(iter);
202 self
203 }
204
205 pub unsafe fn extend_triangles(
208 &mut self,
209 relative: bool,
210 iter: impl IntoIterator<Item = Triangle>,
211 ) -> &Self {
212 if relative {
213 let offset = self.vertices.len();
214 self.triangles
215 .extend(iter.into_iter().map(|triangle| triangle.offset(offset)));
216 } else {
217 self.triangles.extend(iter);
218 }
219 self
220 }
221
222 pub unsafe fn extend_batches(
225 &mut self,
226 iter: impl IntoIterator<Item = (B, Range<usize>)>,
227 ) -> &Self {
228 self.batches.extend(iter);
229 self
230 }
231
232 pub fn append(&mut self, other: &mut Self) {
233 let offset = self.triangles.len();
234 self.extend(other.vertices.drain(..), other.triangles.drain(..));
235 self.batches.extend(
236 other
237 .batches
238 .drain(..)
239 .map(|(data, range)| (data, (range.start + offset)..(range.end + offset))),
240 );
241 }
242
243 pub fn append_cloned(&mut self, other: &Self)
244 where
245 B: Clone,
246 {
247 let offset = self.triangles.len();
248 self.extend(
249 other.vertices.iter().copied(),
250 other.triangles.iter().copied(),
251 );
252 self.batches.extend(
253 other
254 .batches
255 .iter()
256 .map(|(data, range)| (data.clone(), (range.start + offset)..(range.end + offset))),
257 );
258 }
259
260 pub fn clear(&mut self) {
261 self.vertices.clear();
262 self.triangles.clear();
263 self.batches.clear();
264 }
265
266 pub fn batch(&mut self, data: B) {
267 if self.batches.len() == self.batches.capacity() {
268 self.batches.reserve_exact(self.resize_count);
269 }
270 self.batch_end();
271 let start = self.triangles.len();
272 self.batches.push((data, start..start))
273 }
274
275 pub fn batch_optimized(&mut self, data: B)
276 where
277 B: PartialEq,
278 {
279 if let Some(last) = self.batches.last_mut() {
280 if last.0 == data {
281 last.1.end = self.triangles.len();
282 return;
283 }
284 }
285 self.batch(data);
286 }
287
288 pub fn batch_end(&mut self) {
289 if let Some(last) = self.batches.last_mut() {
290 last.1.end = self.triangles.len();
291 }
292 }
293
294 pub fn render<R: VertexStreamRenderer<V, B>>(
295 &mut self,
296 renderer: &mut R,
297 ) -> Result<(), R::Error> {
298 self.batch_end();
299 renderer.render(self)
300 }
301
302 pub fn vertices(&self) -> &[V] {
303 &self.vertices
304 }
305
306 pub fn triangles(&self) -> &[Triangle] {
307 &self.triangles
308 }
309
310 pub fn batches(&self) -> &[(B, Range<usize>)] {
311 &self.batches
312 }
313
314 #[allow(clippy::type_complexity)]
315 pub fn drain(&mut self) -> (Drain<V>, Drain<Triangle>, Drain<(B, Range<usize>)>) {
316 self.batch_end();
317 (
318 self.vertices.drain(..),
319 self.triangles.drain(..),
320 self.batches.drain(..),
321 )
322 }
323
324 fn ensure_capacity(&mut self) {
325 if self.vertices.len() == self.vertices.capacity() {
326 self.vertices.reserve_exact(self.resize_count);
327 }
328 if self.triangles.len() == self.triangles.capacity() {
329 self.triangles.reserve_exact(self.resize_count);
330 }
331 }
332}
333
334pub trait VertexStreamRenderer<V: Pod, B> {
335 type Error;
336
337 fn render(&mut self, stream: &mut VertexStream<V, B>) -> Result<(), Self::Error>;
338}
339
340impl<V: Pod, B> VertexStreamRenderer<V, B> for () {
341 type Error = ();
342
343 fn render(&mut self, _: &mut VertexStream<V, B>) -> Result<(), Self::Error> {
344 Ok(())
345 }
346}