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