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
107#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
109pub struct Target {
110 #[serde(default, skip_serializing_if = "Option::is_none")]
112 pub extensions: Option<extensions::animation::Target>,
113
114 #[serde(default)]
116 #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
117 #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
118 pub extras: Extras,
119
120 pub node: Index<scene::Node>,
122
123 pub path: Checked<Property>,
126}
127
128#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
130pub struct Sampler {
131 #[serde(default, skip_serializing_if = "Option::is_none")]
133 pub extensions: Option<extensions::animation::Sampler>,
134
135 #[serde(default)]
137 #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
138 #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
139 pub extras: Extras,
140
141 pub input: Index<accessor::Accessor>,
143
144 #[serde(default)]
146 pub interpolation: Checked<Interpolation>,
147
148 pub output: Index<accessor::Accessor>,
150}
151
152impl Validate for Animation {
153 fn validate<P, R>(&self, root: &Root, path: P, report: &mut R)
154 where
155 P: Fn() -> Path,
156 R: FnMut(&dyn Fn() -> Path, Error),
157 {
158 self.samplers
159 .validate(root, || path().field("samplers"), report);
160 for (index, channel) in self.channels.iter().enumerate() {
161 if channel.sampler.value() >= self.samplers.len() {
162 let path = || path().field("channels").index(index).field("sampler");
163 report(&path, Error::IndexOutOfBounds);
164 }
165 }
166 }
167}
168
169impl Default for Interpolation {
170 fn default() -> Self {
171 Interpolation::Linear
172 }
173}
174
175impl<'de> de::Deserialize<'de> for Checked<Interpolation> {
176 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
177 where
178 D: de::Deserializer<'de>,
179 {
180 struct Visitor;
181 impl<'de> de::Visitor<'de> for Visitor {
182 type Value = Checked<Interpolation>;
183
184 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
185 write!(f, "any of: {:?}", VALID_INTERPOLATIONS)
186 }
187
188 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
189 where
190 E: de::Error,
191 {
192 use self::Interpolation::*;
193 use crate::validation::Checked::*;
194 Ok(match value {
195 "LINEAR" => Valid(Linear),
196 "STEP" => Valid(Step),
197 "CUBICSPLINE" => Valid(CubicSpline),
198 _ => Invalid,
199 })
200 }
201 }
202 deserializer.deserialize_str(Visitor)
203 }
204}
205
206impl ser::Serialize for Interpolation {
207 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
208 where
209 S: ser::Serializer,
210 {
211 serializer.serialize_str(match *self {
212 Interpolation::Linear => "LINEAR",
213 Interpolation::Step => "STEP",
214 Interpolation::CubicSpline => "CUBICSPLINE",
215 })
216 }
217}
218
219impl<'de> de::Deserialize<'de> for Checked<Property> {
220 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
221 where
222 D: de::Deserializer<'de>,
223 {
224 struct Visitor;
225 impl<'de> de::Visitor<'de> for Visitor {
226 type Value = Checked<Property>;
227
228 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
229 write!(f, "any of: {:?}", VALID_PROPERTIES)
230 }
231
232 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
233 where
234 E: de::Error,
235 {
236 use self::Property::*;
237 use crate::validation::Checked::*;
238 Ok(match value {
239 "translation" => Valid(Translation),
240 "rotation" => Valid(Rotation),
241 "scale" => Valid(Scale),
242 "weights" => Valid(MorphTargetWeights),
243 _ => Invalid,
244 })
245 }
246 }
247 deserializer.deserialize_str(Visitor)
248 }
249}
250
251impl ser::Serialize for Property {
252 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
253 where
254 S: ser::Serializer,
255 {
256 serializer.serialize_str(match *self {
257 Property::Translation => "translation",
258 Property::Rotation => "rotation",
259 Property::Scale => "scale",
260 Property::MorphTargetWeights => "weights",
261 })
262 }
263}