1use super::*;
4
5pub trait InputKind {
7 type Array: ArrayKind;
9 type Reader: SourceRead<Self>;
11
12 fn new_reader(&self, acc: &Accessor) -> Option<Self::Reader>;
14}
15
16pub trait SourceRead<K: InputKind + ?Sized>: Sized {
21 type Output: Clone;
24
25 fn load(&self, data: &[<K::Array as ArrayKind>::Elem]) -> Self::Output;
31}
32
33#[derive(Copy, Clone, Debug)]
35pub struct Map<R, F> {
36 reader: R,
37 f: F,
38}
39
40impl<K: InputKind, R: SourceRead<K>, O: Clone, F: Fn(R::Output) -> O> SourceRead<K> for Map<R, F> {
41 type Output = O;
42
43 fn load(&self, data: &[<K::Array as ArrayKind>::Elem]) -> Self::Output {
44 (self.f)(self.reader.load(data))
45 }
46}
47
48impl Accessor {
49 pub fn param_offset(&self, name: &str, ty: &str) -> Option<usize> {
51 let pos = self
52 .param
53 .iter()
54 .position(|p| p.name.as_deref() == Some(name) && p.ty == ty)?;
55 Some(self.offset + pos)
56 }
57}
58
59#[derive(Clone, Debug)]
64pub struct SourceReader<'a, K: InputKind, R = <K as InputKind>::Reader> {
65 kind: K,
66 array: &'a [<K::Array as ArrayKind>::Elem],
67 stride: usize,
68 len: usize,
69 reader: R,
70}
71
72impl Source {
73 pub fn reader<K: InputKind>(&self, kind: K) -> Option<SourceReader<'_, K>> {
78 let arr = self.array.as_ref()?;
79 if matches!((arr.id(), &self.accessor.source), (Some(id), Url::Fragment(s)) if s == id) {
80 let array = K::Array::from_array_element(arr)?;
81 debug_assert!(self.accessor.count * self.accessor.stride == array.len());
82 Some(SourceReader {
83 reader: kind.new_reader(&self.accessor)?,
84 kind,
85 array,
86 stride: self.accessor.stride,
87 len: self.accessor.count,
88 })
89 } else {
90 None }
92 }
93}
94
95impl<'a, K: InputKind, R: SourceRead<K>> SourceReader<'a, K, R> {
96 pub fn map_reader<S: SourceRead<K>>(self, f: impl FnOnce(R) -> S) -> SourceReader<'a, K, S> {
98 SourceReader {
99 kind: self.kind,
100 array: self.array,
101 stride: self.stride,
102 len: self.len,
103 reader: f(self.reader),
104 }
105 }
106 pub fn map<O: Clone, F: Fn(R::Output) -> O>(self, f: F) -> SourceReader<'a, K, Map<R, F>> {
108 self.map_reader(|reader| Map { reader, f })
109 }
110
111 pub fn get(&self, i: usize) -> R::Output {
113 let elems = &self.array[i * self.stride..][..self.stride];
114 self.reader.load(elems)
115 }
116
117 pub fn advance_by(&mut self, n: usize) -> Result<(), usize> {
119 if n <= self.len {
120 self.array = &self.array[n * self.stride..];
121 Ok(())
122 } else {
123 Err(self.len)
124 }
125 }
126
127 pub fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
130 if n <= self.len {
131 self.array = &self.array[..self.array.len() - n * self.stride];
132 Ok(())
133 } else {
134 Err(self.len)
135 }
136 }
137}
138
139impl<'a, K: InputKind, R: SourceRead<K>> ExactSizeIterator for SourceReader<'a, K, R> {
140 fn len(&self) -> usize {
141 self.len
142 }
143}
144
145impl<'a, K: InputKind, R: SourceRead<K>> DoubleEndedIterator for SourceReader<'a, K, R> {
146 fn next_back(&mut self) -> Option<Self::Item> {
147 self.len = self.len.checked_sub(1)?;
148 let (left, right) = self.array.split_at(self.len);
149 self.array = left;
150 Some(self.reader.load(right))
151 }
152
153 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
154 self.advance_back_by(n).ok()?;
155 self.next_back()
156 }
157}
158
159impl<'a, K: InputKind, R: SourceRead<K>> Iterator for SourceReader<'a, K, R> {
160 type Item = R::Output;
161
162 fn next(&mut self) -> Option<Self::Item> {
163 self.len = self.len.checked_sub(1)?;
164 let (left, right) = self.array.split_at(self.stride);
165 self.array = right;
166 Some(self.reader.load(left))
167 }
168
169 fn size_hint(&self) -> (usize, Option<usize>) {
170 (self.len, Some(self.len))
171 }
172
173 fn count(self) -> usize {
174 self.len
175 }
176
177 fn last(mut self) -> Option<Self::Item> {
178 self.next_back()
179 }
180
181 fn nth(&mut self, n: usize) -> Option<Self::Item> {
182 self.advance_by(n).ok()?;
183 self.next()
184 }
185}
186
187#[derive(Copy, Clone, Debug, Default)]
190pub struct XYZ;
191
192impl InputKind for XYZ {
193 type Array = FloatArray;
194 type Reader = XYZReader;
195 fn new_reader(&self, acc: &Accessor) -> Option<Self::Reader> {
196 Some(XYZReader {
197 x: acc.param_offset("X", "float")?,
198 y: acc.param_offset("Y", "float")?,
199 z: acc.param_offset("Z", "float")?,
200 })
201 }
202}
203
204#[derive(Copy, Clone, Debug)]
207pub struct XYZReader {
208 x: usize,
209 y: usize,
210 z: usize,
211}
212
213impl SourceRead<XYZ> for XYZReader {
214 type Output = [f32; 3];
215 fn load(&self, data: &[f32]) -> Self::Output {
216 [data[self.x], data[self.y], data[self.z]]
217 }
218}
219
220#[derive(Copy, Clone, Debug, Default)]
224pub struct ST;
225
226impl InputKind for ST {
227 type Array = FloatArray;
228 type Reader = STReader;
229 fn new_reader(&self, acc: &Accessor) -> Option<Self::Reader> {
230 Some(STReader {
231 s: acc.param_offset("S", "float")?,
232 t: acc.param_offset("T", "float")?,
233 })
234 }
235}
236
237#[derive(Copy, Clone, Debug)]
241pub struct STReader {
242 s: usize,
243 t: usize,
244}
245
246impl SourceRead<ST> for STReader {
247 type Output = [f32; 2];
248 fn load(&self, data: &[f32]) -> Self::Output {
249 [data[self.s], data[self.t]]
250 }
251}