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