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 {
127 fn extend<T: IntoIterator<Item = u32>>(&mut self, iter: T) {
128 let mut iter = iter.into_iter();
129 match self {
130 Indices::U32(indices) => indices.extend(iter),
131 Indices::U16(indices) => {
132 indices.reserve(iter.size_hint().0);
133 while let Some(index) = iter.next() {
134 match u16::try_from(index) {
135 Ok(index) => indices.push(index),
136 Err(_) => {
137 let new_vec = indices
138 .iter()
139 .map(|&index| u32::from(index))
140 .chain(iter::once(index))
141 .chain(iter)
142 .collect::<Vec<u32>>();
143 *self = Indices::U32(new_vec);
144 break;
145 }
146 }
147 }
148 }
149 }
150 }
151}
152
153enum IndicesIter<'a> {
155 U16(core::slice::Iter<'a, u16>),
156 U32(core::slice::Iter<'a, u32>),
157}
158
159impl Iterator for IndicesIter<'_> {
160 type Item = usize;
161
162 fn next(&mut self) -> Option<Self::Item> {
163 match self {
164 IndicesIter::U16(iter) => iter.next().map(|val| *val as usize),
165 IndicesIter::U32(iter) => iter.next().map(|val| *val as usize),
166 }
167 }
168
169 fn size_hint(&self) -> (usize, Option<usize>) {
170 match self {
171 IndicesIter::U16(iter) => iter.size_hint(),
172 IndicesIter::U32(iter) => iter.size_hint(),
173 }
174 }
175}
176
177impl<'a> ExactSizeIterator for IndicesIter<'a> {}
178
179impl<'a> FusedIterator for IndicesIter<'a> {}
180
181impl From<&Indices> for IndexFormat {
182 fn from(indices: &Indices) -> Self {
183 match indices {
184 Indices::U16(_) => IndexFormat::Uint16,
185 Indices::U32(_) => IndexFormat::Uint32,
186 }
187 }
188}
189
190#[cfg(test)]
191mod tests {
192 use crate::Indices;
193 use wgpu_types::IndexFormat;
194
195 #[test]
196 fn test_indices_push() {
197 let mut indices = Indices::U16(Vec::new());
198 indices.push(10);
199 assert_eq!(IndexFormat::Uint16, IndexFormat::from(&indices));
200 assert_eq!(vec![10], indices.iter().collect::<Vec<_>>());
201
202 indices.push(0x10000);
204 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
205 assert_eq!(vec![10, 0x10000], indices.iter().collect::<Vec<_>>());
206
207 indices.push(20);
208 indices.push(0x20000);
209 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
210 assert_eq!(
211 vec![10, 0x10000, 20, 0x20000],
212 indices.iter().collect::<Vec<_>>()
213 );
214 }
215
216 #[test]
217 fn test_indices_extend() {
218 let mut indices = Indices::U16(Vec::new());
219 indices.extend([10, 11]);
220 assert_eq!(IndexFormat::Uint16, IndexFormat::from(&indices));
221 assert_eq!(vec![10, 11], indices.iter().collect::<Vec<_>>());
222
223 indices.extend([12, 0x10013, 0x10014]);
225 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
226 assert_eq!(
227 vec![10, 11, 12, 0x10013, 0x10014],
228 indices.iter().collect::<Vec<_>>()
229 );
230
231 indices.extend([15, 0x10016]);
232 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
233 assert_eq!(
234 vec![10, 11, 12, 0x10013, 0x10014, 15, 0x10016],
235 indices.iter().collect::<Vec<_>>()
236 );
237 }
238}