1use std::{iter, slice};
2
3use json::{
4 mesh::{PrimitiveMode, Semantic},
5 validation::Checked,
6};
7
8use crate::{Accessor, Document, material::Material};
9
10pub type Attribute<'a> = (Checked<Semantic>, Accessor<'a>);
11
12#[derive(Clone, Debug)]
13pub struct Attributes<'a> {
14 pub(crate) document: &'a Document,
16
17 #[allow(dead_code)]
19 pub(crate) prim: Primitive<'a>,
20
21 pub(crate) iter:
23 indexmap::map::Iter<'a, Checked<Semantic>, gltf_v1_json::StringIndex<json::Accessor>>,
24}
25
26#[derive(Clone, Debug)]
27pub struct Primitive<'a> {
28 mesh: Mesh<'a>,
30
31 index: usize,
33
34 json: &'a json::mesh::Primitive,
36}
37
38impl<'a> Primitive<'a> {
39 pub(crate) fn new(mesh: Mesh<'a>, index: usize, json: &'a json::mesh::Primitive) -> Self {
41 Self { mesh, index, json }
42 }
43 pub fn index(&self) -> usize {
44 self.index
45 }
46 pub fn mode(&self) -> PrimitiveMode {
47 self.json.mode.unwrap()
48 }
49 pub fn get(&self, semantic: &Semantic) -> Option<Accessor<'a>> {
50 self.json
51 .attributes
52 .get(&Checked::Valid(*semantic))
53 .and_then(|x| {
54 self.mesh
55 .document
56 .accessors()
57 .find(|y| y.index() == x.value())
58 })
59 }
60 pub fn indices(&self) -> Option<Accessor<'a>> {
61 self.json.indices.as_ref().and_then(|x| {
62 self.mesh
63 .document
64 .accessors()
65 .find(|y| y.index() == x.value())
66 })
67 }
68 pub fn material(&self) -> Material<'a> {
69 self.mesh
70 .document
71 .materials()
72 .find(|x| x.index() == self.json.material.value())
73 .unwrap()
74 }
75 pub fn attributes(&self) -> Attributes<'a> {
76 Attributes {
77 document: self.mesh.document,
78 prim: self.clone(),
79 iter: self.json.attributes.iter(),
80 }
81 }
82}
83#[derive(Clone, Debug)]
85pub struct Mesh<'a> {
86 document: &'a Document,
88
89 index: &'a String,
91
92 json: &'a json::mesh::Mesh,
94}
95
96impl<'a> Mesh<'a> {
97 pub(crate) fn new(
98 document: &'a Document,
99 index: &'a String,
100 json: &'a json::mesh::Mesh,
101 ) -> Self {
102 Self {
103 document,
104 index,
105 json,
106 }
107 }
108
109 pub fn index(&self) -> &str {
110 self.index
111 }
112
113 pub fn name(&self) -> Option<&'a str> {
114 self.json.name.as_deref()
115 }
116
117 pub fn primitives(&self) -> Primitives<'a> {
118 Primitives {
119 mesh: self.clone(),
120 iter: self.json.primitives.iter().enumerate(),
121 }
122 }
123}
124#[derive(Clone, Debug)]
125pub struct Meshes<'a> {
126 pub(crate) iter: indexmap::map::Iter<'a, String, gltf_v1_json::Mesh>,
127
128 pub(crate) document: &'a Document,
129}
130
131impl ExactSizeIterator for Meshes<'_> {}
132impl<'a> Iterator for Meshes<'a> {
133 type Item = Mesh<'a>;
134
135 fn next(&mut self) -> Option<Self::Item> {
136 self.iter
137 .next()
138 .map(|(index, json)| Mesh::new(self.document, index, json))
139 }
140 fn size_hint(&self) -> (usize, Option<usize>) {
141 self.iter.size_hint()
142 }
143 fn count(self) -> usize {
144 self.iter.count()
145 }
146 fn last(self) -> Option<Self::Item> {
147 let document = self.document;
148 self.iter
149 .last()
150 .map(|(index, json)| Mesh::new(document, index, json))
151 }
152 fn nth(&mut self, n: usize) -> Option<Self::Item> {
153 self.iter
154 .nth(n)
155 .map(|(index, json)| Mesh::new(self.document, index, json))
156 }
157}
158
159#[derive(Clone, Debug)]
160pub struct Primitives<'a> {
161 pub(crate) mesh: Mesh<'a>,
163
164 pub(crate) iter: iter::Enumerate<slice::Iter<'a, json::mesh::Primitive>>,
166}
167impl ExactSizeIterator for Primitives<'_> {}
168impl<'a> Iterator for Primitives<'a> {
169 type Item = Primitive<'a>;
170 fn next(&mut self) -> Option<Self::Item> {
171 self.iter
172 .next()
173 .map(|(index, json)| Primitive::new(self.mesh.clone(), index, json))
174 }
175 fn size_hint(&self) -> (usize, Option<usize>) {
176 self.iter.size_hint()
177 }
178 fn count(self) -> usize {
179 self.iter.count()
180 }
181 fn last(mut self) -> Option<Self::Item> {
182 let mesh = self.mesh;
183 self.iter
184 .next_back()
185 .map(|(index, json)| Primitive::new(mesh, index, json))
186 }
187 fn nth(&mut self, n: usize) -> Option<Self::Item> {
188 self.iter
189 .nth(n)
190 .map(|(index, json)| Primitive::new(self.mesh.clone(), index, json))
191 }
192}
193
194impl ExactSizeIterator for Attributes<'_> {}
195impl<'a> Iterator for Attributes<'a> {
196 type Item = Attribute<'a>;
197 fn next(&mut self) -> Option<Self::Item> {
198 self.iter.next().map(|(key, index)| {
199 let semantic = *key;
200 let accessor = self
201 .document
202 .accessors()
203 .find(|x| x.index() == index.value())
204 .unwrap();
205 (semantic, accessor)
206 })
207 }
208
209 fn size_hint(&self) -> (usize, Option<usize>) {
210 self.iter.size_hint()
211 }
212}