[go: up one dir, main page]

gltf/skin/
mod.rs

1#[cfg(feature = "extensions")]
2use serde_json::{Map, Value};
3
4use crate::{Accessor, Document, Node};
5
6#[cfg(feature = "utils")]
7use crate::Buffer;
8
9/// Iterators.
10pub mod iter;
11
12/// Utility functions.
13#[cfg(feature = "utils")]
14#[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
15pub mod util;
16
17#[cfg(feature = "utils")]
18#[doc(inline)]
19pub use self::util::Reader;
20
21/// Joints and matrices defining a skin.
22#[derive(Clone, Debug)]
23pub struct Skin<'a> {
24    /// The parent `Document` struct.
25    document: &'a Document,
26
27    /// The corresponding JSON index.
28    index: usize,
29
30    /// The corresponding JSON struct.
31    json: &'a json::skin::Skin,
32}
33
34impl<'a> Skin<'a> {
35    /// Constructs a `Skin`.
36    pub(crate) fn new(document: &'a Document, index: usize, json: &'a json::skin::Skin) -> Self {
37        Self {
38            document,
39            index,
40            json,
41        }
42    }
43
44    /// Returns the internal JSON index.
45    pub fn index(&self) -> usize {
46        self.index
47    }
48
49    /// Returns extension data unknown to this crate version.
50    #[cfg(feature = "extensions")]
51    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
52    pub fn extensions(&self) -> Option<&Map<String, Value>> {
53        let ext = self.json.extensions.as_ref()?;
54        Some(&ext.others)
55    }
56
57    /// Queries extension data unknown to this crate version.
58    #[cfg(feature = "extensions")]
59    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
60    pub fn extension_value(&self, ext_name: &str) -> Option<&Value> {
61        let ext = self.json.extensions.as_ref()?;
62        ext.others.get(ext_name)
63    }
64
65    /// Optional application specific data.
66    pub fn extras(&self) -> &'a json::Extras {
67        &self.json.extras
68    }
69
70    /// Returns the accessor containing the 4x4 inverse-bind matrices.
71    ///
72    /// When `None`, each matrix is assumed to be the 4x4 identity matrix which
73    /// implies that the inverse-bind matrices were pre-applied.
74    pub fn inverse_bind_matrices(&self) -> Option<Accessor<'a>> {
75        self.json
76            .inverse_bind_matrices
77            .as_ref()
78            .map(|index| self.document.accessors().nth(index.value()).unwrap())
79    }
80
81    /// Constructs a skin reader.
82    #[cfg(feature = "utils")]
83    #[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
84    pub fn reader<'s, F>(&'a self, get_buffer_data: F) -> Reader<'a, 's, F>
85    where
86        F: Clone + Fn(Buffer<'a>) -> Option<&'s [u8]>,
87    {
88        Reader {
89            skin: self.clone(),
90            get_buffer_data,
91        }
92    }
93
94    /// Returns an `Iterator` that visits the skeleton nodes used as joints in
95    /// this skin.
96    pub fn joints(&self) -> iter::Joints<'a> {
97        iter::Joints {
98            document: self.document,
99            iter: self.json.joints.iter(),
100        }
101    }
102
103    /// Optional user-defined name for this object.
104    #[cfg(feature = "names")]
105    #[cfg_attr(docsrs, doc(cfg(feature = "names")))]
106    pub fn name(&self) -> Option<&'a str> {
107        self.json.name.as_deref()
108    }
109
110    /// Returns the node used as the skeleton root. When `None`, joints
111    /// transforms resolve to scene root.
112    pub fn skeleton(&self) -> Option<Node<'a>> {
113        self.json
114            .skeleton
115            .as_ref()
116            .map(|index| self.document.nodes().nth(index.value()).unwrap())
117    }
118}