1use crate::validation::{Checked, Error, Validate};
2use crate::{accessor, extensions, scene, Extras, Index, Path, Root};
3use gltf_derive::Validate;
4use serde::{de, ser};
5use serde_derive::{Deserialize, Serialize};
6use std::fmt;
7
8pub const VALID_INTERPOLATIONS: &[&str] = &["LINEAR", "STEP", "CUBICSPLINE"];
10
11pub const VALID_PROPERTIES: &[&str] = &["translation", "rotation", "scale", "weights"];
13
14#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize)]
16pub enum Interpolation {
17 Linear = 1,
24
25 Step,
31
32 CubicSpline,
40}
41
42#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize)]
44pub enum Property {
45 Translation = 1,
47 Rotation,
49 Scale,
51 MorphTargetWeights,
53}
54
55#[derive(Clone, Debug, Deserialize, Serialize)]
57pub struct Animation {
58 #[serde(default, skip_serializing_if = "Option::is_none")]
60 pub extensions: Option<extensions::animation::Animation>,
61
62 #[serde(default)]
64 #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
65 #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
66 pub extras: Extras,
67
68 #[serde(skip_serializing_if = "Vec::is_empty")]
73 pub channels: Vec<Channel>,
74
75 #[cfg(feature = "names")]
77 #[cfg_attr(feature = "names", serde(skip_serializing_if = "Option::is_none"))]
78 pub name: Option<String>,
79
80 #[serde(skip_serializing_if = "Vec::is_empty")]
83 pub samplers: Vec<Sampler>,
84}
85
86#[derive(Clone, Debug, Deserialize, Serialize)]
88pub struct Channel {
89 pub sampler: Index<Sampler>,
92
93 pub target: Target,
95
96 #[serde(default, skip_serializing_if = "Option::is_none")]
98 pub extensions: Option<extensions::animation::Channel>,
99
100 #[serde(default)]
102 #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
103 #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
104 pub extras: Extras,
105}
106
107fn node_default() -> Index<scene::Node> {
108 Index::new(u32::MAX)
109}
110
111fn node_is_empty(node: &Index<scene::Node>) -> bool {
112 node.value() == u32::MAX as usize
113}
114
115fn node_validate<P, R>(node: &Index<scene::Node>, root: &Root, path: P, report: &mut R)
116where
117 P: Fn() -> Path,
118 R: FnMut(&dyn Fn() -> Path, Error),
119{
120 if cfg!(feature = "allow_empty_animation_target_node") {
121 if !node_is_empty(node) {
122 node.validate(root, path, report);
123 }
124 } else if node_is_empty(node) {
125 report(&path, Error::Missing);
126 } else {
127 node.validate(root, &path, report);
128 }
129}
130
131#[derive(Clone, Debug, Deserialize, Serialize)]
133pub struct Target {
134 #[serde(default, skip_serializing_if = "Option::is_none")]
136 pub extensions: Option<extensions::animation::Target>,
137
138 #[serde(default)]
140 #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
141 #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
142 pub extras: Extras,
143
144 #[serde(default = "node_default", skip_serializing_if = "node_is_empty")]
146 pub node: Index<scene::Node>,
147
148 pub path: Checked<Property>,
151}
152
153impl Validate for Target {
154 fn validate<P, R>(&self, root: &Root, path: P, report: &mut R)
155 where
156 P: Fn() -> Path,
157 R: FnMut(&dyn Fn() -> Path, Error),
158 {
159 self.extensions
160 .validate(root, || path().field("extensions"), report);
161 node_validate(&self.node, root, || path().field("node"), report);
162 self.path.validate(root, || path().field("path"), report);
163 }
164}
165
166#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
168pub struct Sampler {
169 #[serde(default, skip_serializing_if = "Option::is_none")]
171 pub extensions: Option<extensions::animation::Sampler>,
172
173 #[serde(default)]
175 #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
176 #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
177 pub extras: Extras,
178
179 pub input: Index<accessor::Accessor>,
181
182 #[serde(default)]
184 pub interpolation: Checked<Interpolation>,
185
186 pub output: Index<accessor::Accessor>,
188}
189
190impl Validate for Animation {
191 fn validate<P, R>(&self, root: &Root, path: P, report: &mut R)
192 where
193 P: Fn() -> Path,
194 R: FnMut(&dyn Fn() -> Path, Error),
195 {
196 self.samplers
197 .validate(root, || path().field("samplers"), report);
198 for (index, channel) in self.channels.iter().enumerate() {
199 if channel.sampler.value() >= self.samplers.len() {
200 let path = || path().field("channels").index(index).field("sampler");
201 report(&path, Error::IndexOutOfBounds);
202 }
203 }
204 }
205}
206
207impl Default for Interpolation {
208 fn default() -> Self {
209 Interpolation::Linear
210 }
211}
212
213impl<'de> de::Deserialize<'de> for Checked<Interpolation> {
214 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
215 where
216 D: de::Deserializer<'de>,
217 {
218 struct Visitor;
219 impl de::Visitor<'_> for Visitor {
220 type Value = Checked<Interpolation>;
221
222 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
223 write!(f, "any of: {:?}", VALID_INTERPOLATIONS)
224 }
225
226 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
227 where
228 E: de::Error,
229 {
230 use self::Interpolation::*;
231 use crate::validation::Checked::*;
232 Ok(match value {
233 "LINEAR" => Valid(Linear),
234 "STEP" => Valid(Step),
235 "CUBICSPLINE" => Valid(CubicSpline),
236 _ => Invalid,
237 })
238 }
239 }
240 deserializer.deserialize_str(Visitor)
241 }
242}
243
244impl ser::Serialize for Interpolation {
245 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
246 where
247 S: ser::Serializer,
248 {
249 serializer.serialize_str(match *self {
250 Interpolation::Linear => "LINEAR",
251 Interpolation::Step => "STEP",
252 Interpolation::CubicSpline => "CUBICSPLINE",
253 })
254 }
255}
256
257impl<'de> de::Deserialize<'de> for Checked<Property> {
258 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
259 where
260 D: de::Deserializer<'de>,
261 {
262 struct Visitor;
263 impl de::Visitor<'_> for Visitor {
264 type Value = Checked<Property>;
265
266 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
267 write!(f, "any of: {:?}", VALID_PROPERTIES)
268 }
269
270 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
271 where
272 E: de::Error,
273 {
274 use self::Property::*;
275 use crate::validation::Checked::*;
276 Ok(match value {
277 "translation" => Valid(Translation),
278 "rotation" => Valid(Rotation),
279 "scale" => Valid(Scale),
280 "weights" => Valid(MorphTargetWeights),
281 _ => Invalid,
282 })
283 }
284 }
285 deserializer.deserialize_str(Visitor)
286 }
287}
288
289impl ser::Serialize for Property {
290 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
291 where
292 S: ser::Serializer,
293 {
294 serializer.serialize_str(match *self {
295 Property::Translation => "translation",
296 Property::Rotation => "rotation",
297 Property::Scale => "scale",
298 Property::MorphTargetWeights => "weights",
299 })
300 }
301}