[go: up one dir, main page]

gltf/animation/
mod.rs

1use crate::{accessor, scene, Document};
2
3#[cfg(feature = "utils")]
4use crate::Buffer;
5
6pub use json::animation::{Interpolation, Property};
7#[cfg(feature = "extensions")]
8use serde_json::{Map, Value};
9
10/// Iterators.
11pub mod iter;
12
13/// Utility functions.
14#[cfg(feature = "utils")]
15#[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
16pub mod util;
17
18#[cfg(feature = "utils")]
19#[doc(inline)]
20pub use self::util::Reader;
21
22/// A keyframe animation.
23#[derive(Clone, Debug)]
24pub struct Animation<'a> {
25    /// The parent `Document` struct.
26    document: &'a Document,
27
28    /// The corresponding JSON index.
29    index: usize,
30
31    /// The corresponding JSON struct.
32    json: &'a json::animation::Animation,
33}
34
35/// Targets an animation's sampler at a node's property.
36#[derive(Clone, Debug)]
37pub struct Channel<'a> {
38    /// The parent `Animation` struct.
39    anim: Animation<'a>,
40
41    /// The corresponding JSON index.
42    index: usize,
43
44    /// The corresponding JSON struct.
45    json: &'a json::animation::Channel,
46}
47
48/// Defines a keyframe graph (but not its target).
49#[derive(Clone, Debug)]
50pub struct Sampler<'a> {
51    /// The parent `Animation` struct.
52    anim: Animation<'a>,
53
54    /// The corresponding JSON index.
55    index: usize,
56
57    /// The corresponding JSON struct.
58    json: &'a json::animation::Sampler,
59}
60
61/// The node and TRS property that an animation channel targets.
62#[derive(Clone, Debug)]
63pub struct Target<'a> {
64    /// The parent `Animation` struct.
65    anim: Animation<'a>,
66
67    /// The corresponding JSON struct.
68    json: &'a json::animation::Target,
69}
70
71impl<'a> Animation<'a> {
72    /// Constructs an `Animation`.
73    pub(crate) fn new(
74        document: &'a Document,
75        index: usize,
76        json: &'a json::animation::Animation,
77    ) -> Self {
78        Self {
79            document,
80            index,
81            json,
82        }
83    }
84
85    /// Returns the internal JSON index.
86    pub fn index(&self) -> usize {
87        self.index
88    }
89
90    /// Optional application specific data.
91    pub fn extras(&self) -> &'a json::Extras {
92        &self.json.extras
93    }
94
95    /// Returns an `Iterator` over the animation channels.
96    ///
97    /// Each channel targets an animation's sampler at a node's property.
98    pub fn channels(&self) -> iter::Channels<'a> {
99        iter::Channels {
100            anim: self.clone(),
101            iter: self.json.channels.iter().enumerate(),
102        }
103    }
104
105    /// Optional user-defined name for this object.
106    #[cfg(feature = "names")]
107    pub fn name(&self) -> Option<&'a str> {
108        self.json.name.as_deref()
109    }
110
111    /// Returns an `Iterator` over the animation samplers.
112    ///
113    /// Each sampler combines input and output accessors with an
114    /// interpolation algorithm to define a keyframe graph (but not its target).
115    pub fn samplers(&self) -> iter::Samplers<'a> {
116        iter::Samplers {
117            anim: self.clone(),
118            iter: self.json.samplers.iter().enumerate(),
119        }
120    }
121
122    /// Returns extension data unknown to this crate version.
123    #[cfg(feature = "extensions")]
124    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
125    pub fn extensions(&self) -> Option<&Map<String, Value>> {
126        let ext = self.json.extensions.as_ref()?;
127        Some(&ext.others)
128    }
129
130    /// Queries extension data unknown to this crate version.
131    #[cfg(feature = "extensions")]
132    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
133    pub fn extension_value(&self, ext_name: &str) -> Option<&Value> {
134        let ext = self.json.extensions.as_ref()?;
135        ext.others.get(ext_name)
136    }
137}
138
139impl<'a> Channel<'a> {
140    /// Constructs a `Channel`.
141    pub(crate) fn new(
142        anim: Animation<'a>,
143        json: &'a json::animation::Channel,
144        index: usize,
145    ) -> Self {
146        Self { anim, json, index }
147    }
148
149    /// Returns the parent `Animation` struct.
150    pub fn animation(&self) -> Animation<'a> {
151        self.anim.clone()
152    }
153
154    /// Returns the sampler in this animation used to compute the value for the
155    /// target.
156    pub fn sampler(&self) -> Sampler<'a> {
157        self.anim.samplers().nth(self.json.sampler.value()).unwrap()
158    }
159
160    /// Returns the node and property to target.
161    pub fn target(&self) -> Target<'a> {
162        Target::new(self.anim.clone(), &self.json.target)
163    }
164
165    /// Constructs an animation channel reader.
166    #[cfg(feature = "utils")]
167    #[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
168    pub fn reader<'s, F>(&self, get_buffer_data: F) -> Reader<'a, 's, F>
169    where
170        F: Clone + Fn(Buffer<'a>) -> Option<&'s [u8]>,
171    {
172        Reader {
173            channel: self.clone(),
174            get_buffer_data,
175        }
176    }
177
178    /// Optional application specific data.
179    pub fn extras(&self) -> &'a json::Extras {
180        &self.json.extras
181    }
182
183    /// Returns the internal JSON index.
184    pub fn index(&self) -> usize {
185        self.index
186    }
187}
188
189impl<'a> Target<'a> {
190    /// Constructs a `Target`.
191    pub(crate) fn new(anim: Animation<'a>, json: &'a json::animation::Target) -> Self {
192        Self { anim, json }
193    }
194
195    /// Returns the parent `Animation` struct.
196    pub fn animation(&self) -> Animation<'a> {
197        self.anim.clone()
198    }
199
200    /// Optional application specific data.
201    pub fn extras(&self) -> &'a json::Extras {
202        &self.json.extras
203    }
204
205    /// Returns the target node.
206    pub fn node(&self) -> scene::Node<'a> {
207        self.anim
208            .document
209            .nodes()
210            .nth(self.json.node.value())
211            .unwrap()
212    }
213
214    /// Returns the node's property to modify or the 'weights' of the morph
215    /// targets it instantiates.
216    pub fn property(&self) -> Property {
217        self.json.path.unwrap()
218    }
219}
220
221impl<'a> Sampler<'a> {
222    /// Constructs a `Sampler`.
223    pub(crate) fn new(
224        anim: Animation<'a>,
225        json: &'a json::animation::Sampler,
226        index: usize,
227    ) -> Self {
228        Self { anim, json, index }
229    }
230
231    /// Returns the parent `Animation` struct.
232    pub fn animation(&self) -> Animation<'a> {
233        self.anim.clone()
234    }
235
236    /// Optional application specific data.
237    pub fn extras(&self) -> &'a json::Extras {
238        &self.json.extras
239    }
240
241    /// Returns the internal JSON index.
242    pub fn index(&self) -> usize {
243        self.index
244    }
245
246    /// Returns the accessor containing the keyframe input values (e.g. time).
247    pub fn input(&self) -> accessor::Accessor<'a> {
248        self.anim
249            .document
250            .accessors()
251            .nth(self.json.input.value())
252            .unwrap()
253    }
254
255    /// Returns the keyframe interpolation algorithm.
256    pub fn interpolation(&self) -> Interpolation {
257        self.json.interpolation.unwrap()
258    }
259
260    /// Returns the accessor containing the keyframe output values.
261    pub fn output(&self) -> accessor::Accessor<'a> {
262        self.anim
263            .document
264            .accessors()
265            .nth(self.json.output.value())
266            .unwrap()
267    }
268}