1use bevy_reflect::Reflect;
2use core::iter;
3use core::iter::FusedIterator;
4use derive_more::derive::{Display, Error};
5use wgpu::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, Display)]
38pub enum MeshWindingInvertError {
39 #[display("Mesh winding invertation does not work for primitive topology `PointList`")]
41 WrongTopology,
42
43 #[display("Indices weren't in chunks according to topology")]
47 AbruptIndicesEnd,
48}
49
50#[derive(Debug, Error, Display)]
52pub enum MeshTrianglesError {
53 #[display("Source mesh does not have primitive topology TriangleList or TriangleStrip")]
54 WrongTopology,
55
56 #[display("Source mesh lacks position data")]
57 MissingPositions,
58
59 #[display("Source mesh position data is not Float32x3")]
60 PositionsFormat,
61
62 #[display("Source mesh lacks face index data")]
63 MissingIndices,
64
65 #[display("Face index data references vertices that do not exist")]
66 BadIndices,
67}
68
69#[derive(Debug, Clone, Reflect)]
73pub enum Indices {
74 U16(Vec<u16>),
75 U32(Vec<u32>),
76}
77
78impl Indices {
79 pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
81 match self {
82 Indices::U16(vec) => IndicesIter::U16(vec.iter()),
83 Indices::U32(vec) => IndicesIter::U32(vec.iter()),
84 }
85 }
86
87 pub fn len(&self) -> usize {
89 match self {
90 Indices::U16(vec) => vec.len(),
91 Indices::U32(vec) => vec.len(),
92 }
93 }
94
95 pub fn is_empty(&self) -> bool {
97 match self {
98 Indices::U16(vec) => vec.is_empty(),
99 Indices::U32(vec) => vec.is_empty(),
100 }
101 }
102
103 pub fn push(&mut self, index: u32) {
106 match self {
107 Indices::U32(vec) => vec.push(index),
108 Indices::U16(vec) => match u16::try_from(index) {
109 Ok(index) => vec.push(index),
110 Err(_) => {
111 let new_vec = vec
112 .iter()
113 .map(|&index| u32::from(index))
114 .chain(iter::once(index))
115 .collect::<Vec<u32>>();
116 *self = Indices::U32(new_vec);
117 }
118 },
119 }
120 }
121}
122
123enum IndicesIter<'a> {
125 U16(core::slice::Iter<'a, u16>),
126 U32(core::slice::Iter<'a, u32>),
127}
128
129impl Iterator for IndicesIter<'_> {
130 type Item = usize;
131
132 fn next(&mut self) -> Option<Self::Item> {
133 match self {
134 IndicesIter::U16(iter) => iter.next().map(|val| *val as usize),
135 IndicesIter::U32(iter) => iter.next().map(|val| *val as usize),
136 }
137 }
138
139 fn size_hint(&self) -> (usize, Option<usize>) {
140 match self {
141 IndicesIter::U16(iter) => iter.size_hint(),
142 IndicesIter::U32(iter) => iter.size_hint(),
143 }
144 }
145}
146
147impl<'a> ExactSizeIterator for IndicesIter<'a> {}
148impl<'a> FusedIterator for IndicesIter<'a> {}
149
150impl From<&Indices> for IndexFormat {
151 fn from(indices: &Indices) -> Self {
152 match indices {
153 Indices::U16(_) => IndexFormat::Uint16,
154 Indices::U32(_) => IndexFormat::Uint32,
155 }
156 }
157}
158
159#[cfg(test)]
160mod tests {
161 use crate::Indices;
162 use wgpu::IndexFormat;
163
164 #[test]
165 fn test_indices_push() {
166 let mut indices = Indices::U16(Vec::new());
167 indices.push(10);
168 assert_eq!(IndexFormat::Uint16, IndexFormat::from(&indices));
169 assert_eq!(vec![10], indices.iter().collect::<Vec<_>>());
170
171 indices.push(0x10000);
173 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
174 assert_eq!(vec![10, 0x10000], indices.iter().collect::<Vec<_>>());
175
176 indices.push(20);
177 indices.push(0x20000);
178 assert_eq!(IndexFormat::Uint32, IndexFormat::from(&indices));
179 assert_eq!(
180 vec![10, 0x10000, 20, 0x20000],
181 indices.iter().collect::<Vec<_>>()
182 );
183 }
184}