1#![deny(missing_docs)]
2#![allow(unknown_lints)]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4
5#[cfg(test)]
83#[macro_use]
84extern crate approx;
85#[cfg(feature = "import")]
86extern crate image as image_crate;
87
88pub extern crate gltf_json as json;
90
91pub mod accessor;
93
94pub mod animation;
96
97pub mod binary;
99
100pub mod buffer;
102
103pub mod camera;
105
106pub mod image;
108
109#[cfg(feature = "import")]
111#[cfg_attr(docsrs, doc(cfg(feature = "import")))]
112mod import;
113
114pub mod iter;
116
117#[cfg(feature = "KHR_lights_punctual")]
119#[cfg_attr(docsrs, doc(cfg(feature = "KHR_lights_punctual")))]
120pub mod khr_lights_punctual;
121
122#[cfg(feature = "KHR_materials_variants")]
124#[cfg_attr(docsrs, doc(cfg(feature = "KHR_materials_variants")))]
125pub mod khr_materials_variants;
126
127pub mod material;
129
130mod math;
132
133pub mod mesh;
135
136pub mod scene;
138
139pub mod skin;
141
142pub mod texture;
144
145#[cfg(feature = "extensions")]
146use json::Value;
147#[cfg(feature = "extensions")]
148use serde_json::Map;
149
150#[doc(inline)]
151pub use self::accessor::Accessor;
152#[doc(inline)]
153pub use self::animation::Animation;
154#[doc(inline)]
155pub use self::binary::Glb;
156#[doc(inline)]
157pub use self::buffer::Buffer;
158#[doc(inline)]
159pub use self::camera::Camera;
160#[doc(inline)]
161pub use self::image::Image;
162#[cfg(feature = "import")]
163#[doc(inline)]
164pub use self::import::import;
165#[cfg(feature = "import")]
166#[doc(inline)]
167pub use self::import::import_buffers;
168#[cfg(feature = "import")]
169#[doc(inline)]
170pub use self::import::import_images;
171#[cfg(feature = "import")]
172#[doc(inline)]
173pub use self::import::import_slice;
174#[doc(inline)]
175pub use self::material::Material;
176#[doc(inline)]
177pub use self::mesh::{Attribute, Mesh, Primitive, Semantic};
178#[doc(inline)]
179pub use self::scene::{Node, Scene};
180#[doc(inline)]
181pub use self::skin::Skin;
182#[doc(inline)]
183pub use self::texture::Texture;
184
185use std::path::Path;
186use std::{fs, io, ops, result};
187
188pub(crate) trait Normalize<T> {
189 fn normalize(self) -> T;
190}
191
192pub type Result<T> = result::Result<T, Error>;
194
195#[derive(Debug)]
197pub enum Error {
198 #[cfg(feature = "import")]
200 #[cfg_attr(docsrs, doc(cfg(feature = "import")))]
201 Base64(base64::DecodeError),
202
203 Binary(binary::Error),
205
206 #[cfg(feature = "import")]
208 #[cfg_attr(docsrs, doc(cfg(feature = "import")))]
209 BufferLength {
210 buffer: usize,
212
213 expected: usize,
215
216 actual: usize,
218 },
219
220 Deserialize(json::Error),
222
223 Io(std::io::Error),
225
226 #[cfg(feature = "import")]
228 #[cfg_attr(docsrs, doc(cfg(feature = "import")))]
229 Image(image_crate::ImageError),
230
231 #[cfg(feature = "import")]
233 #[cfg_attr(docsrs, doc(cfg(feature = "import")))]
234 MissingBlob,
235
236 #[cfg(feature = "import")]
238 #[cfg_attr(docsrs, doc(cfg(feature = "import")))]
239 ExternalReferenceInSliceImport,
240
241 #[cfg(feature = "import")]
243 #[cfg_attr(docsrs, doc(cfg(feature = "import")))]
244 UnsupportedImageEncoding,
245
246 #[cfg(feature = "import")]
248 #[cfg_attr(docsrs, doc(cfg(feature = "import")))]
249 UnsupportedImageFormat(image_crate::DynamicImage),
250
251 #[cfg(feature = "import")]
253 #[cfg_attr(docsrs, doc(cfg(feature = "import")))]
254 UnsupportedScheme,
255
256 Validation(Vec<(json::Path, json::validation::Error)>),
258}
259
260#[derive(Clone, Debug)]
262pub struct Gltf {
263 pub document: Document,
265
266 pub blob: Option<Vec<u8>>,
268}
269
270#[derive(Clone, Debug)]
272pub struct Document(json::Root);
273
274impl Gltf {
275 pub fn open<P>(path: P) -> Result<Self>
277 where
278 P: AsRef<Path>,
279 {
280 let file = fs::File::open(path)?;
281 let reader = io::BufReader::new(file);
282 let gltf = Self::from_reader(reader)?;
283 Ok(gltf)
284 }
285
286 pub fn from_reader_without_validation<R>(mut reader: R) -> Result<Self>
288 where
289 R: io::Read + io::Seek,
290 {
291 let mut magic = [0u8; 4];
292 reader.read_exact(&mut magic)?;
293 reader.seek(io::SeekFrom::Current(-4))?;
294 let (json, blob): (json::Root, Option<Vec<u8>>);
295 if magic.starts_with(b"glTF") {
296 let mut glb = binary::Glb::from_reader(reader)?;
297 json = json::deserialize::from_slice(&glb.json)?;
299 blob = glb.bin.take().map(|x| x.into_owned());
300 } else {
301 json = json::deserialize::from_reader(reader)?;
302 blob = None;
303 };
304 let document = Document::from_json_without_validation(json);
305 Ok(Gltf { document, blob })
306 }
307
308 pub fn from_reader<R>(reader: R) -> Result<Self>
310 where
311 R: io::Read + io::Seek,
312 {
313 let gltf = Self::from_reader_without_validation(reader)?;
314 gltf.document.validate()?;
315 Ok(gltf)
316 }
317
318 pub fn from_slice_without_validation(slice: &[u8]) -> Result<Self> {
321 let (json, blob): (json::Root, Option<Vec<u8>>);
322 if slice.starts_with(b"glTF") {
323 let mut glb = binary::Glb::from_slice(slice)?;
324 json = json::deserialize::from_slice(&glb.json)?;
325 blob = glb.bin.take().map(|x| x.into_owned());
326 } else {
327 json = json::deserialize::from_slice(slice)?;
328 blob = None;
329 };
330 let document = Document::from_json_without_validation(json);
331 Ok(Gltf { document, blob })
332 }
333
334 pub fn from_slice(slice: &[u8]) -> Result<Self> {
336 let gltf = Self::from_slice_without_validation(slice)?;
337 gltf.document.validate()?;
338 Ok(gltf)
339 }
340}
341
342impl ops::Deref for Gltf {
343 type Target = Document;
344 fn deref(&self) -> &Self::Target {
345 &self.document
346 }
347}
348
349impl ops::DerefMut for Gltf {
350 fn deref_mut(&mut self) -> &mut Self::Target {
351 &mut self.document
352 }
353}
354
355impl Document {
356 pub fn from_json(json: json::Root) -> Result<Self> {
358 let document = Self::from_json_without_validation(json);
359 document.validate()?;
360 Ok(document)
361 }
362
363 pub fn from_json_without_validation(json: json::Root) -> Self {
366 Document(json)
367 }
368
369 pub fn into_json(self) -> json::Root {
371 self.0
372 }
373
374 pub fn as_json(&self) -> &json::Root {
376 &self.0
377 }
378
379 pub(crate) fn validate(&self) -> Result<()> {
381 use json::validation::Validate;
382 let mut errors = Vec::new();
383 self.0
384 .validate(&self.0, json::Path::new, &mut |path, error| {
385 errors.push((path(), error))
386 });
387 if errors.is_empty() {
388 Ok(())
389 } else {
390 Err(Error::Validation(errors))
391 }
392 }
393
394 pub fn accessors(&self) -> iter::Accessors<'_> {
396 iter::Accessors {
397 iter: self.0.accessors.iter().enumerate(),
398 document: self,
399 }
400 }
401
402 pub fn animations(&self) -> iter::Animations<'_> {
404 iter::Animations {
405 iter: self.0.animations.iter().enumerate(),
406 document: self,
407 }
408 }
409
410 pub fn buffers(&self) -> iter::Buffers<'_> {
412 iter::Buffers {
413 iter: self.0.buffers.iter().enumerate(),
414 document: self,
415 }
416 }
417
418 pub fn cameras(&self) -> iter::Cameras<'_> {
420 iter::Cameras {
421 iter: self.0.cameras.iter().enumerate(),
422 document: self,
423 }
424 }
425
426 pub fn default_scene(&self) -> Option<Scene<'_>> {
428 self.0
429 .scene
430 .as_ref()
431 .map(|index| self.scenes().nth(index.value()).unwrap())
432 }
433
434 pub fn extensions_used(&self) -> iter::ExtensionsUsed<'_> {
436 iter::ExtensionsUsed(self.0.extensions_used.iter())
437 }
438
439 pub fn extensions_required(&self) -> iter::ExtensionsRequired<'_> {
441 iter::ExtensionsRequired(self.0.extensions_required.iter())
442 }
443
444 pub fn images(&self) -> iter::Images<'_> {
446 iter::Images {
447 iter: self.0.images.iter().enumerate(),
448 document: self,
449 }
450 }
451
452 #[cfg(feature = "extensions")]
454 #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
455 pub fn extensions(&self) -> Option<&Map<String, Value>> {
456 let root = self.0.extensions.as_ref()?;
457 Some(&root.others)
458 }
459
460 #[cfg(feature = "extensions")]
462 #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
463 pub fn extension_value(&self, ext_name: &str) -> Option<&Value> {
464 let root = self.0.extensions.as_ref()?;
465 root.others.get(ext_name)
466 }
467
468 #[cfg(feature = "KHR_lights_punctual")]
471 #[cfg_attr(docsrs, doc(cfg(feature = "KHR_lights_punctual")))]
472 pub fn lights(&self) -> Option<iter::Lights> {
473 let iter = self
474 .0
475 .extensions
476 .as_ref()?
477 .khr_lights_punctual
478 .as_ref()?
479 .lights
480 .iter()
481 .enumerate();
482
483 Some(iter::Lights {
484 iter,
485 document: self,
486 })
487 }
488
489 #[cfg(feature = "KHR_materials_variants")]
492 #[cfg_attr(docsrs, doc(cfg(feature = "KHR_materials_variants")))]
493 pub fn variants(&self) -> Option<iter::Variants> {
494 let iter = self
495 .0
496 .extensions
497 .as_ref()?
498 .khr_materials_variants
499 .as_ref()?
500 .variants
501 .iter()
502 .enumerate();
503
504 Some(iter::Variants {
505 iter,
506 document: self,
507 })
508 }
509
510 pub fn materials(&self) -> iter::Materials<'_> {
512 iter::Materials {
513 iter: self.0.materials.iter().enumerate(),
514 document: self,
515 }
516 }
517
518 pub fn meshes(&self) -> iter::Meshes<'_> {
520 iter::Meshes {
521 iter: self.0.meshes.iter().enumerate(),
522 document: self,
523 }
524 }
525
526 pub fn nodes(&self) -> iter::Nodes<'_> {
528 iter::Nodes {
529 iter: self.0.nodes.iter().enumerate(),
530 document: self,
531 }
532 }
533
534 pub fn samplers(&self) -> iter::Samplers<'_> {
536 iter::Samplers {
537 iter: self.0.samplers.iter().enumerate(),
538 document: self,
539 }
540 }
541
542 pub fn scenes(&self) -> iter::Scenes<'_> {
544 iter::Scenes {
545 iter: self.0.scenes.iter().enumerate(),
546 document: self,
547 }
548 }
549
550 pub fn skins(&self) -> iter::Skins<'_> {
552 iter::Skins {
553 iter: self.0.skins.iter().enumerate(),
554 document: self,
555 }
556 }
557
558 pub fn textures(&self) -> iter::Textures<'_> {
560 iter::Textures {
561 iter: self.0.textures.iter().enumerate(),
562 document: self,
563 }
564 }
565
566 pub fn views(&self) -> iter::Views<'_> {
569 iter::Views {
570 iter: self.0.buffer_views.iter().enumerate(),
571 document: self,
572 }
573 }
574}
575
576impl std::fmt::Display for Error {
577 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
578 match self {
579 #[cfg(feature = "import")]
580 Error::Base64(ref e) => e.fmt(f),
581 Error::Binary(ref e) => e.fmt(f),
582 #[cfg(feature = "import")]
583 Error::BufferLength {
584 buffer,
585 expected,
586 actual,
587 } => {
588 write!(
589 f,
590 "buffer {}: expected {} bytes but received {} bytes",
591 buffer, expected, actual
592 )
593 }
594 Error::Deserialize(ref e) => e.fmt(f),
595 Error::Io(ref e) => e.fmt(f),
596 #[cfg(feature = "import")]
597 Error::Image(ref e) => e.fmt(f),
598 #[cfg(feature = "import")]
599 Error::MissingBlob => write!(f, "missing binary portion of binary glTF"),
600 #[cfg(feature = "import")]
601 Error::ExternalReferenceInSliceImport => {
602 write!(f, "external reference in slice only import")
603 }
604 #[cfg(feature = "import")]
605 Error::UnsupportedImageEncoding => write!(f, "unsupported image encoding"),
606 #[cfg(feature = "import")]
607 Error::UnsupportedImageFormat(image) => {
608 write!(f, "unsupported image format: {:?}", image.color())
609 }
610 #[cfg(feature = "import")]
611 Error::UnsupportedScheme => write!(f, "unsupported URI scheme"),
612 Error::Validation(ref xs) => {
613 write!(f, "invalid glTF:")?;
614 for (ref path, ref error) in xs {
615 write!(f, " {}: {};", path, error)?;
616 }
617 Ok(())
618 }
619 }
620 }
621}
622
623impl std::error::Error for Error {}
624
625impl From<binary::Error> for Error {
626 fn from(err: binary::Error) -> Self {
627 Error::Binary(err)
628 }
629}
630
631impl From<std::io::Error> for Error {
632 fn from(err: std::io::Error) -> Self {
633 Error::Io(err)
634 }
635}
636
637#[cfg(feature = "import")]
638impl From<image_crate::ImageError> for Error {
639 fn from(err: image_crate::ImageError) -> Self {
640 Error::Image(err)
641 }
642}
643
644impl From<json::Error> for Error {
645 fn from(err: json::Error) -> Self {
646 Error::Deserialize(err)
647 }
648}
649
650impl From<Vec<(json::Path, json::validation::Error)>> for Error {
651 fn from(errs: Vec<(json::Path, json::validation::Error)>) -> Self {
652 Error::Validation(errs)
653 }
654}
655
656impl Normalize<i8> for i8 {
657 fn normalize(self) -> i8 {
658 self
659 }
660}
661
662impl Normalize<u8> for i8 {
663 fn normalize(self) -> u8 {
664 self.max(0) as u8 * 2
665 }
666}
667
668impl Normalize<i16> for i8 {
669 fn normalize(self) -> i16 {
670 self as i16 * 0x100
671 }
672}
673
674impl Normalize<u16> for i8 {
675 fn normalize(self) -> u16 {
676 self.max(0) as u16 * 0x200
677 }
678}
679
680impl Normalize<f32> for i8 {
681 fn normalize(self) -> f32 {
682 (self as f32 * 127.0_f32.recip()).max(-1.0)
683 }
684}
685
686impl Normalize<i8> for u8 {
687 fn normalize(self) -> i8 {
688 (self / 2) as i8
689 }
690}
691
692impl Normalize<u8> for u8 {
693 fn normalize(self) -> u8 {
694 self
695 }
696}
697
698impl Normalize<i16> for u8 {
699 fn normalize(self) -> i16 {
700 self as i16 * 0x80
701 }
702}
703
704impl Normalize<u16> for u8 {
705 fn normalize(self) -> u16 {
706 self as u16 * 0x100
707 }
708}
709
710impl Normalize<f32> for u8 {
711 fn normalize(self) -> f32 {
712 self as f32 * 255.0_f32.recip()
713 }
714}
715
716impl Normalize<i8> for i16 {
717 fn normalize(self) -> i8 {
718 (self / 0x100) as i8
719 }
720}
721
722impl Normalize<u8> for i16 {
723 fn normalize(self) -> u8 {
724 (self.max(0) / 0x80) as u8
725 }
726}
727
728impl Normalize<i16> for i16 {
729 fn normalize(self) -> i16 {
730 self
731 }
732}
733
734impl Normalize<u16> for i16 {
735 fn normalize(self) -> u16 {
736 self.max(0) as u16 * 2
737 }
738}
739
740impl Normalize<f32> for i16 {
741 fn normalize(self) -> f32 {
742 (self as f32 * 32767.0_f32.recip()).max(-1.0)
743 }
744}
745
746impl Normalize<i8> for u16 {
747 fn normalize(self) -> i8 {
748 (self / 0x200) as i8
749 }
750}
751
752impl Normalize<u8> for u16 {
753 fn normalize(self) -> u8 {
754 (self / 0x100) as u8
755 }
756}
757
758impl Normalize<i16> for u16 {
759 fn normalize(self) -> i16 {
760 (self / 2) as i16
761 }
762}
763
764impl Normalize<u16> for u16 {
765 fn normalize(self) -> u16 {
766 self
767 }
768}
769
770impl Normalize<f32> for u16 {
771 fn normalize(self) -> f32 {
772 self as f32 * 65535.0_f32.recip()
773 }
774}
775
776impl Normalize<i8> for f32 {
777 fn normalize(self) -> i8 {
778 (self * 127.0) as i8
779 }
780}
781
782impl Normalize<u8> for f32 {
783 fn normalize(self) -> u8 {
784 (self.max(0.0) * 255.0) as u8
785 }
786}
787
788impl Normalize<i16> for f32 {
789 fn normalize(self) -> i16 {
790 (self * 32767.0) as i16
791 }
792}
793
794impl Normalize<u16> for f32 {
795 fn normalize(self) -> u16 {
796 (self.max(0.0) * 65535.0) as u16
797 }
798}
799
800impl Normalize<f32> for f32 {
801 fn normalize(self) -> f32 {
802 self
803 }
804}
805
806impl<U, T> Normalize<[T; 2]> for [U; 2]
807where
808 U: Normalize<T> + Copy,
809{
810 fn normalize(self) -> [T; 2] {
811 [self[0].normalize(), self[1].normalize()]
812 }
813}
814
815impl<U, T> Normalize<[T; 3]> for [U; 3]
816where
817 U: Normalize<T> + Copy,
818{
819 fn normalize(self) -> [T; 3] {
820 [
821 self[0].normalize(),
822 self[1].normalize(),
823 self[2].normalize(),
824 ]
825 }
826}
827
828impl<U, T> Normalize<[T; 4]> for [U; 4]
829where
830 U: Normalize<T> + Copy,
831{
832 fn normalize(self) -> [T; 4] {
833 [
834 self[0].normalize(),
835 self[1].normalize(),
836 self[2].normalize(),
837 self[3].normalize(),
838 ]
839 }
840}