gltf_v1/
document.rs

1use crate::accessor::Accessors;
2use crate::buffer::Buffers;
3use crate::buffer::Views;
4use crate::camera::Cameras;
5use crate::error::Error;
6use crate::error::Result;
7use crate::image::Images;
8use crate::light::Lights;
9use crate::material::Materials;
10use crate::material::Techniques;
11use crate::mesh::Meshes;
12use crate::node::Nodes;
13use crate::scene::Scene;
14use crate::scene::Scenes;
15use crate::skin::Skins;
16use crate::texture::Samplers;
17use crate::texture::Textures;
18
19#[derive(Clone, Debug)]
20pub struct Document(gltf_v1_json::Root);
21
22impl Document {
23    pub fn from_json(mut json: json::Root) -> Result<Self> {
24        json.add_default_material();
25        let document = Self::from_json_without_validation(json);
26        document.validate()?;
27        Ok(document)
28    }
29
30    pub fn from_json_without_validation(json: json::Root) -> Self {
31        Document(json)
32    }
33
34    pub fn into_json(self) -> json::Root {
35        self.0
36    }
37
38    pub fn as_json(&self) -> &json::Root {
39        &self.0
40    }
41
42    /// Perform validation checks on loaded glTF.
43    pub(crate) fn validate(&self) -> Result<()> {
44        use json::validation::Validate;
45        let mut errors = Vec::new();
46        self.0
47            .validate(&self.0, json::Path::new, &mut |path, error| {
48                errors.push((path(), error))
49            });
50        if errors.is_empty() {
51            Ok(())
52        } else {
53            Err(Error::Validation(errors))
54        }
55    }
56
57    pub fn default_scene(&self) -> Option<Scene<'_>> {
58        self.0
59            .scene
60            .as_ref()
61            .and_then(|index| self.scenes().find(|x| x.index() == index.value()))
62    }
63
64    pub fn accessors(&self) -> Accessors {
65        Accessors {
66            iter: self.0.accessors.iter(),
67            document: self,
68        }
69    }
70    pub fn buffers(&self) -> Buffers {
71        Buffers {
72            iter: self.0.buffers.iter(),
73            document: self,
74        }
75    }
76    pub fn views(&self) -> Views {
77        Views {
78            iter: self.0.buffer_views.iter(),
79            document: self,
80        }
81    }
82    pub fn images(&self) -> Images {
83        Images {
84            iter: self.0.images.iter(),
85            document: self,
86        }
87    }
88    pub fn textures(&self) -> Textures {
89        Textures {
90            iter: self.0.textures.iter(),
91            document: self,
92        }
93    }
94    pub fn samplers(&self) -> Samplers {
95        Samplers {
96            iter: self.0.samplers.iter(),
97            document: self,
98        }
99    }
100    pub fn materials(&self) -> Materials {
101        Materials {
102            iter: self.0.materials.iter(),
103            document: self,
104        }
105    }
106    pub fn techniques(&self) -> Techniques {
107        Techniques {
108            iter: self.0.techniques.iter(),
109            document: self,
110        }
111    }
112    pub fn meshes(&self) -> Meshes {
113        Meshes {
114            iter: self.0.meshes.iter(),
115            document: self,
116        }
117    }
118    pub fn cameras(&self) -> Cameras {
119        Cameras {
120            iter: self.0.cameras.iter(),
121            document: self,
122        }
123    }
124    pub fn nodes(&self) -> Nodes {
125        Nodes {
126            iter: self.0.nodes.iter(),
127            document: self,
128        }
129    }
130    pub fn skins(&self) -> Skins {
131        Skins {
132            iter: self.0.skins.iter(),
133            document: self,
134        }
135    }
136    pub fn scenes(&self) -> Scenes {
137        Scenes {
138            iter: self.0.scenes.iter(),
139            document: self,
140        }
141    }
142    pub fn lights(&self) -> Option<Lights> {
143        //Model only has lights if KHR_materials common is enabled, as it is an extension
144        #[cfg(feature = "KHR_materials_common")]
145        {
146            self.0
147                .extensions
148                .as_ref()
149                .and_then(|x| x.ktr_materials_common.as_ref())
150                .map(|x| Lights {
151                    iter: x.lights.iter(),
152                    document: self,
153                })
154        }
155        #[cfg(not(feature = "KHR_materials_common"))]
156        {
157            None
158        }
159    }
160}