1use crate::validation::{Checked, Error, Validate};
2use crate::{accessor, extensions, scene, Index, Path, Root};
3use serde::{de, ser};
4use serde_derive::{Deserialize, Serialize};
5use shine_gltf_macro::Validate;
6use std::fmt;
7
8pub const VALID_INTERPOLATIONS: &[&str] = &["LINEAR", "STEP", "CATMULLROMSPLINE", "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 CatmullRomSpline,
40
41 CubicSpline,
49}
50
51#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize)]
53pub enum Property {
54 Translation = 1,
56
57 Rotation,
59
60 Scale,
62
63 MorphTargetWeights,
65}
66
67#[derive(Clone, Debug, Deserialize, Serialize)]
69pub struct Animation {
70 #[serde(default, skip_serializing_if = "Option::is_none")]
72 pub extensions: Option<extensions::animation::Animation>,
73
74 #[serde(skip_serializing_if = "Vec::is_empty")]
79 pub channels: Vec<Channel>,
80
81 #[serde(skip_serializing_if = "Vec::is_empty")]
84 pub samplers: Vec<Sampler>,
85}
86
87#[derive(Clone, Debug, Deserialize, Serialize)]
89pub struct Channel {
90 pub sampler: Index<Sampler>,
93
94 pub target: Target,
96
97 #[serde(default, skip_serializing_if = "Option::is_none")]
99 pub extensions: Option<extensions::animation::Channel>,
100}
101
102#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
104pub struct Target {
105 #[serde(default, skip_serializing_if = "Option::is_none")]
107 pub extensions: Option<extensions::animation::Target>,
108
109 pub node: Index<scene::Node>,
111
112 pub path: Checked<Property>,
115}
116
117#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
119pub struct Sampler {
120 #[serde(default, skip_serializing_if = "Option::is_none")]
122 pub extensions: Option<extensions::animation::Sampler>,
123
124 pub input: Index<accessor::Accessor>,
126
127 #[serde(default)]
129 pub interpolation: Checked<Interpolation>,
130
131 pub output: Index<accessor::Accessor>,
133}
134
135impl Validate for Animation {
136 fn validate_minimally<P, R>(&self, root: &Root, path: P, report: &mut R)
137 where
138 P: Fn() -> Path,
139 R: FnMut(&dyn Fn() -> Path, Error),
140 {
141 self.samplers.validate_minimally(root, || path().field("samplers"), report);
142 for (index, channel) in self.channels.iter().enumerate() {
143 if channel.sampler.value() as usize >= self.samplers.len() {
144 let path = || path().field("channels").index(index).field("sampler");
145 report(&path, Error::IndexOutOfBounds);
146 }
147 }
148 }
149}
150
151impl Default for Interpolation {
152 fn default() -> Self {
153 Interpolation::Linear
154 }
155}
156
157impl<'de> de::Deserialize<'de> for Checked<Interpolation> {
158 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
159 where
160 D: de::Deserializer<'de>,
161 {
162 struct Visitor;
163 impl<'de> de::Visitor<'de> for Visitor {
164 type Value = Checked<Interpolation>;
165
166 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 write!(f, "any of: {:?}", VALID_INTERPOLATIONS)
168 }
169
170 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
171 where
172 E: de::Error,
173 {
174 use self::Interpolation::*;
175 use crate::validation::Checked::*;
176 Ok(match value {
177 "LINEAR" => Valid(Linear),
178 "STEP" => Valid(Step),
179 "CATMULLROMSPLINE" => Valid(CatmullRomSpline),
180 "CUBICSPLINE" => Valid(CubicSpline),
181 _ => Invalid,
182 })
183 }
184 }
185 deserializer.deserialize_str(Visitor)
186 }
187}
188
189impl ser::Serialize for Interpolation {
190 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
191 where
192 S: ser::Serializer,
193 {
194 serializer.serialize_str(match *self {
195 Interpolation::Linear => "LINEAR",
196 Interpolation::Step => "STEP",
197 Interpolation::CatmullRomSpline => "CATMULLROMSPLINE",
198 Interpolation::CubicSpline => "CUBICSPLINE",
199 })
200 }
201}
202
203impl<'de> de::Deserialize<'de> for Checked<Property> {
204 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205 where
206 D: de::Deserializer<'de>,
207 {
208 struct Visitor;
209 impl<'de> de::Visitor<'de> for Visitor {
210 type Value = Checked<Property>;
211
212 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 write!(f, "any of: {:?}", VALID_PROPERTIES)
214 }
215
216 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
217 where
218 E: de::Error,
219 {
220 use self::Property::*;
221 use crate::validation::Checked::*;
222 Ok(match value {
223 "translation" => Valid(Translation),
224 "rotation" => Valid(Rotation),
225 "scale" => Valid(Scale),
226 "weights" => Valid(MorphTargetWeights),
227 _ => Invalid,
228 })
229 }
230 }
231 deserializer.deserialize_str(Visitor)
232 }
233}
234
235impl ser::Serialize for Property {
236 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
237 where
238 S: ser::Serializer,
239 {
240 serializer.serialize_str(match *self {
241 Property::Translation => "translation",
242 Property::Rotation => "rotation",
243 Property::Scale => "scale",
244 Property::MorphTargetWeights => "weights",
245 })
246 }
247}