gltf/mesh/util/
mod.rs

1/// Casting iterator adapters for colors.
2pub mod colors;
3
4/// Casting iterator adapters for vertex indices.
5pub mod indices;
6
7/// Casting iterator adapters for joint indices.
8pub mod joints;
9
10/// Casting iterator adapters for texture co-ordinates.
11pub mod tex_coords;
12
13/// Casting iterator adapters for node weights.
14pub mod weights;
15
16use crate::mesh;
17
18use crate::accessor::Iter;
19use crate::Buffer;
20
21/// XYZ vertex positions of type `[f32; 3]`.
22pub type ReadPositions<'a> = Iter<'a, [f32; 3]>;
23
24/// XYZ vertex normals of type `[f32; 3]`.
25pub type ReadNormals<'a> = Iter<'a, [f32; 3]>;
26
27/// XYZW vertex tangents of type `[f32; 4]` where the `w` component is a
28/// sign value (-1 or +1) indicating the handedness of the tangent basis.
29pub type ReadTangents<'a> = Iter<'a, [f32; 4]>;
30
31/// XYZ vertex position displacements of type `[f32; 3]`.
32pub type ReadPositionDisplacements<'a> = Iter<'a, [f32; 3]>;
33
34/// XYZ vertex normal displacements of type `[f32; 3]`.
35pub type ReadNormalDisplacements<'a> = Iter<'a, [f32; 3]>;
36
37/// XYZ vertex tangent displacements.
38pub type ReadTangentDisplacements<'a> = Iter<'a, [f32; 3]>;
39
40/// Vertex colors.
41#[derive(Clone, Debug)]
42pub enum ReadColors<'a> {
43    /// RGB vertex color of type `[u8; 3]>`.
44    RgbU8(Iter<'a, [u8; 3]>),
45    /// RGB vertex color of type `[u16; 3]>`.
46    RgbU16(Iter<'a, [u16; 3]>),
47    /// RGB vertex color of type `[f32; 3]`.
48    RgbF32(Iter<'a, [f32; 3]>),
49    /// RGBA vertex color of type `[u8; 4]>`.
50    RgbaU8(Iter<'a, [u8; 4]>),
51    /// RGBA vertex color of type `[u16; 4]>`.
52    RgbaU16(Iter<'a, [u16; 4]>),
53    /// RGBA vertex color of type `[f32; 4]`.
54    RgbaF32(Iter<'a, [f32; 4]>),
55}
56
57/// Index data.
58#[derive(Clone, Debug)]
59pub enum ReadIndices<'a> {
60    /// Index data of type U8
61    U8(Iter<'a, u8>),
62    /// Index data of type U16
63    U16(Iter<'a, u16>),
64    /// Index data of type U32
65    U32(Iter<'a, u32>),
66}
67
68/// Vertex joints.
69#[derive(Clone, Debug)]
70pub enum ReadJoints<'a> {
71    /// Joints of type `[u8; 4]`.
72    /// Refer to the documentation on morph targets and skins for more
73    /// information.
74    U8(Iter<'a, [u8; 4]>),
75    /// Joints of type `[u16; 4]`.
76    /// Refer to the documentation on morph targets and skins for more
77    /// information.
78    U16(Iter<'a, [u16; 4]>),
79}
80
81/// UV texture co-ordinates.
82#[derive(Clone, Debug)]
83pub enum ReadTexCoords<'a> {
84    /// UV texture co-ordinates of type `[u8; 2]>`.
85    U8(Iter<'a, [u8; 2]>),
86    /// UV texture co-ordinates of type `[u16; 2]>`.
87    U16(Iter<'a, [u16; 2]>),
88    /// UV texture co-ordinates of type `[f32; 2]`.
89    F32(Iter<'a, [f32; 2]>),
90}
91
92/// Weights.
93#[derive(Clone, Debug)]
94pub enum ReadWeights<'a> {
95    /// Weights of type `[u8; 4]`.
96    U8(Iter<'a, [u8; 4]>),
97    /// Weights of type `[u16; 4]`.
98    U16(Iter<'a, [u16; 4]>),
99    /// Weights of type `[f32; 4]`.
100    F32(Iter<'a, [f32; 4]>),
101}
102
103/// Morph targets.
104#[derive(Clone, Debug)]
105pub struct ReadMorphTargets<'a, 's, F>
106where
107    F: Clone + Fn(Buffer<'a>) -> Option<&'s [u8]>,
108{
109    pub(crate) index: usize,
110    pub(crate) reader: mesh::Reader<'a, 's, F>,
111}
112
113impl<'a, 's, F> ExactSizeIterator for ReadMorphTargets<'a, 's, F> where
114    F: Clone + Fn(Buffer<'a>) -> Option<&'s [u8]>
115{
116}
117
118impl<'a, 's, F> Iterator for ReadMorphTargets<'a, 's, F>
119where
120    F: Clone + Fn(Buffer<'a>) -> Option<&'s [u8]>,
121{
122    type Item = (
123        Option<ReadPositionDisplacements<'s>>,
124        Option<ReadNormalDisplacements<'s>>,
125        Option<ReadTangentDisplacements<'s>>,
126    );
127    fn next(&mut self) -> Option<Self::Item> {
128        self.index += 1;
129        self.reader
130            .primitive
131            .morph_targets()
132            .nth(self.index - 1)
133            .map(|morph_target| {
134                let positions = morph_target
135                    .positions()
136                    .and_then(|accessor| Iter::new(accessor, self.reader.get_buffer_data.clone()));
137                let normals = morph_target
138                    .normals()
139                    .and_then(|accessor| Iter::new(accessor, self.reader.get_buffer_data.clone()));
140                let tangents = morph_target
141                    .tangents()
142                    .and_then(|accessor| Iter::new(accessor, self.reader.get_buffer_data.clone()));
143                (positions, normals, tangents)
144            })
145    }
146
147    fn size_hint(&self) -> (usize, Option<usize>) {
148        self.reader.primitive.morph_targets().size_hint()
149    }
150}
151
152impl<'a> ReadColors<'a> {
153    /// Reinterpret colors as RGB u8, discarding alpha, if present.  Lossy if
154    /// the underlying iterator yields u16, f32 or any RGBA.
155    pub fn into_rgb_u8(self) -> self::colors::CastingIter<'a, self::colors::RgbU8> {
156        self::colors::CastingIter::new(self)
157    }
158
159    /// Reinterpret colors as RGB u16, discarding alpha, if present.  Lossy if
160    /// the underlying iterator yields f32 or any RGBA.
161    pub fn into_rgb_u16(self) -> self::colors::CastingIter<'a, self::colors::RgbU16> {
162        self::colors::CastingIter::new(self)
163    }
164
165    /// Reinterpret colors as RGB f32, discarding alpha, if present.  Lossy if
166    /// the underlying iterator yields u16 or any RGBA.
167    pub fn into_rgb_f32(self) -> self::colors::CastingIter<'a, self::colors::RgbF32> {
168        self::colors::CastingIter::new(self)
169    }
170
171    /// Reinterpret colors as RGBA u8, with default alpha 255.  Lossy if the
172    /// underlying iterator yields u16 or f32.
173    pub fn into_rgba_u8(self) -> self::colors::CastingIter<'a, self::colors::RgbaU8> {
174        self::colors::CastingIter::new(self)
175    }
176
177    /// Reinterpret colors as RGBA u16, with default alpha 65535.  Lossy if the
178    /// underlying iterator yields f32.
179    pub fn into_rgba_u16(self) -> self::colors::CastingIter<'a, self::colors::RgbaU16> {
180        self::colors::CastingIter::new(self)
181    }
182
183    /// Reinterpret colors as RGBA f32, with default alpha 1.0.  Lossy if the
184    /// underlying iterator yields u16.
185    pub fn into_rgba_f32(self) -> self::colors::CastingIter<'a, self::colors::RgbaF32> {
186        self::colors::CastingIter::new(self)
187    }
188}
189
190impl<'a> ReadIndices<'a> {
191    /// Reinterpret indices as u32, which can fit any possible index.
192    pub fn into_u32(self) -> self::indices::CastingIter<'a, self::indices::U32> {
193        self::indices::CastingIter::new(self)
194    }
195}
196
197impl<'a> ReadJoints<'a> {
198    /// Reinterpret joints as u16, which can fit any possible joint.
199    pub fn into_u16(self) -> self::joints::CastingIter<'a, self::joints::U16> {
200        self::joints::CastingIter::new(self)
201    }
202}
203
204impl<'a> ReadTexCoords<'a> {
205    /// Reinterpret texture coordinates as u8.  Lossy if the underlying iterator
206    /// yields u16 or f32.
207    pub fn into_u8(self) -> self::tex_coords::CastingIter<'a, self::tex_coords::U8> {
208        self::tex_coords::CastingIter::new(self)
209    }
210
211    /// Reinterpret texture coordinates as u16.  Lossy if the underlying
212    /// iterator yields f32.
213    pub fn into_u16(self) -> self::tex_coords::CastingIter<'a, self::tex_coords::U16> {
214        self::tex_coords::CastingIter::new(self)
215    }
216
217    /// Reinterpret texture coordinates as f32.  Lossy if the underlying
218    /// iterator yields u16.
219    pub fn into_f32(self) -> self::tex_coords::CastingIter<'a, self::tex_coords::F32> {
220        self::tex_coords::CastingIter::new(self)
221    }
222}
223
224impl<'a> ReadWeights<'a> {
225    /// Reinterpret weights as u8.  Lossy if the underlying iterator yields u16
226    /// or f32.
227    pub fn into_u8(self) -> self::weights::CastingIter<'a, self::weights::U8> {
228        self::weights::CastingIter::new(self)
229    }
230
231    /// Reinterpret weights as u16.  Lossy if the underlying iterator yields
232    /// f32.
233    pub fn into_u16(self) -> self::weights::CastingIter<'a, self::weights::U16> {
234        self::weights::CastingIter::new(self)
235    }
236
237    /// Reinterpret weights as f32.  Lossy if the underlying iterator yields
238    /// u16.
239    pub fn into_f32(self) -> self::weights::CastingIter<'a, self::weights::F32> {
240        self::weights::CastingIter::new(self)
241    }
242}