1use bevy_reflect::Reflect;
2use core::iter;
3use core::iter::FusedIterator;
4use thiserror::Error;
5use wgpu_types::IndexFormat;
6
7pub(crate) enum FourIterators<A, B, C, D> {
11 First(A),
12 Second(B),
13 Third(C),
14 Fourth(D),
15}
16
17impl<A, B, C, D, I> Iterator for FourIterators<A, B, C, D>
18where
19 A: Iterator<Item = I>,
20 B: Iterator<Item = I>,
21 C: Iterator<Item = I>,
22 D: Iterator<Item = I>,
23{
24 type Item = I;
25
26 fn next(&mut self) -> Option<Self::Item> {
27 match self {
28 FourIterators::First(iter) => iter.next(),
29 FourIterators::Second(iter) => iter.next(),
30 FourIterators::Third(iter) => iter.next(),
31 FourIterators::Fourth(iter) => iter.next(),
32 }
33 }
34}
35
36#[derive(Debug, Error)]
38pub enum MeshWindingInvertError {
39 #[error("Mesh winding inversion does not work for primitive topology `PointList`")]
41 WrongTopology,
42
43 #[error("Indices weren't in chunks according to topology")]
47 AbruptIndicesEnd,
48}
49
50#[derive(Debug, Error)]
52pub enum MeshTrianglesError {
53 #[error("Source mesh does not have primitive topology TriangleList or TriangleStrip")]
54 WrongTopology,
55
56 #[error("Source mesh lacks position data")]
57 MissingPositions,
58
59 #[error("Source mesh position data is not Float32x3")]
60 PositionsFormat,
61
62 #[error("Source mesh lacks face index data")]
63 MissingIndices,
64
65 #[error("Face index data references vertices that do not exist")]
66 BadIndices,
67}
68
69#[derive(Debug, Clone, Reflect)]
73#[reflect(Clone)]
74pub enum Indices {
75 U16(Vec<u16>),
76 U32(Vec<u32>),
77}
78
79impl Indices {
80 pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
82 match self {
83 Indices::U16(vec) => IndicesIter::U16(vec.iter()),
84 Indices::U32(vec) => IndicesIter::U32(vec.iter()),
85 }
86 }
87
88 pub fn len(&self) -> usize {
90 match self {
91 Indices::U16(vec) => vec.len(),
92 Indices::U32(vec) => vec.len(),
93 }
94 }
95
96 pub fn is_empty(&self) -> bool {
98 match self {
99 Indices::U16(vec) => vec.is_empty(),
100 Indices::U32(vec) => vec.is_empty(),
101 }
102 }
103
104 pub fn push(&mut self, index: u32) {
107 self.extend([index]);
108 }
109}
110
111impl Extend<u32> for Indices {
115 fn extend<T: IntoIterator<Item = u32>>(&mut self, iter: T) {
116 let mut iter = iter.into_iter();
117 match self {
118 Indices::U32(indices) => indices.extend(iter),
119 Indices::U16(indices) => {
120 indices.reserve(iter.size_hint().0);
121 while let Some(index) = iter.next() {
122 match u16::try_from(index) {
123 Ok(index) => indices.push(index),
124 Err(_) => {
125 let new_vec = indices
126 .iter()
127 .map(|&index| u32::from(index))
128 .chain(iter::once(index))
129 .chain(iter)
130 .collect::<Vec<u32>>();
131 *self = Indices::U32(new_vec);
132 break;
133 }
134 }
135 }
136 }
137 }
138 }
139}
140
141enum IndicesIter<'a> {
143 U16(core::slice::Iter<'a, u16>),
144 U32(core::slice::Iter<'a, u32>),
145}
146
147impl Iterator for IndicesIter<'_> {
148 type Item = usize;
149
150 fn next(&mut self) -> Option<Self::Item> {
151 match self {
152 IndicesIter::U16(iter) => iter.next().map(|val| *val as usize),
153 IndicesIter::U32(iter) => iter.next().map(|val| *val as usize),
154 }
155 }
156
157 fn size_hint(&self) -> (usize, Option<usize>) {
158 match self {
159 IndicesIter::U16(iter) => iter.size_hint(),
160 IndicesIter::U32(iter) => iter.size_hint(),
161 }
162 }
163}
164
165impl<'a> ExactSizeIterator for IndicesIter<'a> {}
166impl<'a> FusedIterator for IndicesIter<'a> {}
167
168impl From<&Indices> for IndexFormat {
169 fn from(indices: &Indices) -> Self {
170 match indices {
171 Indices::U16(_) => IndexFormat::Uint16,
172 Indices::U32(_) => IndexFormat::Uint32,
173 }
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use crate::Indices;
180 use wgpu_types::IndexFormat;
181
182 #[test]
183 fn test_indices_push() {
184 let mut indices = Indices::U16(Vec::new());
185 indices.push(10);
186 assert_eq!(IndexFormat::Uint16, IndexFormat::from(&indices));
187 assert_eq!(vec![10], indices.iter().collect::<Vec<_>>());
188
189 indices.push(0x10000);
191 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
192 assert_eq!(vec![10, 0x10000], indices.iter().collect::<Vec<_>>());
193
194 indices.push(20);
195 indices.push(0x20000);
196 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
197 assert_eq!(
198 vec![10, 0x10000, 20, 0x20000],
199 indices.iter().collect::<Vec<_>>()
200 );
201 }
202
203 #[test]
204 fn test_indices_extend() {
205 let mut indices = Indices::U16(Vec::new());
206 indices.extend([10, 11]);
207 assert_eq!(IndexFormat::Uint16, IndexFormat::from(&indices));
208 assert_eq!(vec![10, 11], indices.iter().collect::<Vec<_>>());
209
210 indices.extend([12, 0x10013, 0x10014]);
212 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
213 assert_eq!(
214 vec![10, 11, 12, 0x10013, 0x10014],
215 indices.iter().collect::<Vec<_>>()
216 );
217
218 indices.extend([15, 0x10016]);
219 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
220 assert_eq!(
221 vec![10, 11, 12, 0x10013, 0x10014, 15, 0x10016],
222 indices.iter().collect::<Vec<_>>()
223 );
224 }
225}