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