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