gltf_v1/
mesh.rs

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    /// The parent `Document` struct.
15    pub(crate) document: &'a Document,
16
17    /// The parent `Primitive` struct.
18    #[allow(dead_code)]
19    pub(crate) prim: Primitive<'a>,
20
21    /// The internal attribute iterator.
22    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    /// The parent `Mesh` struct.
29    mesh: Mesh<'a>,
30
31    /// The corresponding JSON index.
32    index: usize,
33
34    /// The corresponding JSON struct.
35    json: &'a json::mesh::Primitive,
36}
37
38impl<'a> Primitive<'a> {
39    /// Constructs a `Primitive`.
40    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/// A set of primitives to be rendered.
84#[derive(Clone, Debug)]
85pub struct Mesh<'a> {
86    /// The parent `Document` struct.
87    document: &'a Document,
88
89    /// The corresponding JSON index.
90    index: &'a String,
91
92    /// The corresponding JSON struct.
93    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    /// The parent `Mesh` struct.
162    pub(crate) mesh: Mesh<'a>,
163
164    /// The internal JSON primitive iterator.
165    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}