1pub mod types;
4use types::*;
5
6use std::{fmt::Debug, io::{BufWriter, Read, Write}};
7use serde::{de::{Error, IgnoredAny, Visitor}, Deserialize, Deserializer};
8
9#[allow(private_interfaces)]
14#[derive(Debug, Default)]
15pub struct Animation {
16 pub name: Option<String>,
17 pub global_duration: Option<f32>,
18 pub tracks: Vec<Box<dyn TrackTrait>>,
19}
20
21impl Animation {
22 pub fn write_animx(&self, buf: impl Write) {
34 let mut writer = BufWriter::new(buf);
35 let mut write = |bytes: &[u8]| { writer.write(bytes).unwrap(); };
36
37 self.write_contents(&mut write);
38 }
39
40 fn write_contents(&self, write: &mut dyn FnMut(&[u8])) {
41 "AnimX".to_owned().write(write); 01u32.write(write); self.tracks.len().write(write); self.global_duration.write(write); self.name.write(write); write(&[0x00,]); for track in &self.tracks {
48 track.write(write); }
50 }
51
52 pub fn from_animx(data: impl Read) -> Result<Animation, AnimXError> {
62 let mut output = Animation::default();
63 let mut reader = AnimXReader(data);
64
65 if reader.read_string()? != "AnimX" { Err(AnimXError::IncorrectHeader)? }
66 if reader.read_i32()? != 1 { Err(AnimXError::UnsupportedVersion)? }
67
68 let tracks = reader.read_varint()?;
69 output.global_duration = Some(reader.read_f32()?);
70 output.name = Some(reader.read_string()?);
71
72 if reader.read_u8()? != 0 { Err(AnimXError::UnsupportedEncoding)? }
73
74 for _ in 0..tracks {
75 let track_type: TrackType = reader.read_u8()?.try_into().map_err(|_| AnimXError::IncorrectTrackType)?;
76 let value_type: ValueType = reader.read_u8()?.try_into().map_err(|_| AnimXError::IncorrectValueType)?;
77
78 let node = Some(reader.read_string()?);
79 let property = Some(reader.read_string()?);
80 let frames = reader.read_varint()?;
81
82 match track_type {
83 TrackType::Raw => {
84 let interval = Some(reader.read_f32()?);
85 metamatch::metamatch!(match value_type {
86 #[expand(for T in [
87 Byte, Ushort, Ulong, Sbyte, Short,
88 Bool, Bool2, Bool3, Bool4,
89 Int, Int2, Int3, Int4,
90 Uint, Uint2, Uint3, Uint4,
91 Long, Long2, Long3, Long4,
92 Float, Float2, Float3, Float4,
93 FloatQ, Float2x2, Float3x3, Float4x4,
94 Double, Double2, Double3, Double4,
95 DoubleQ, Double2x2, Double3x3, Double4x4,
96 Color, Color32, OptString,
97 ])]
98 ValueType::T => {
99 let mut keyframes = Vec::new();
100 for _ in 0..frames {
101 keyframes.push(T::read(&mut reader)?);
102 }
103 output.tracks.push(
104 Box::new(
105 Track{
106 track_type,
107 value_type,
108 data: RawData {
109 node,
110 property,
111 interval,
112 keyframes,
113 },
114 }
115 )
116 );
117 },
118 })
119 },
120 TrackType::Discrete => {
121 metamatch::metamatch!(match value_type {
122 #[expand(for T in [
123 Byte, Ushort, Ulong, Sbyte, Short,
124 Bool, Bool2, Bool3, Bool4,
125 Int, Int2, Int3, Int4,
126 Uint, Uint2, Uint3, Uint4,
127 Long, Long2, Long3, Long4,
128 Float, Float2, Float3, Float4,
129 FloatQ, Float2x2, Float3x3, Float4x4,
130 Double, Double2, Double3, Double4,
131 DoubleQ, Double2x2, Double3x3, Double4x4,
132 Color, Color32, OptString,
133 ])]
134 ValueType::T => {
135 let mut keyframes = Vec::new();
136 for _ in 0..frames {
137 let time = reader.read_f32()?;
138 let value = T::read(&mut reader)?;
139 keyframes.push(DiscreteKeyframe{time, value});
140 }
141 output.tracks.push(
142 Box::new(
143 Track{
144 track_type,
145 value_type,
146 data: DiscreteData {
147 node,
148 property,
149 keyframes,
150 },
151 }
152 )
153 );
154 },
155 })
156 },
157 TrackType::Curve => {
158 let info = Bool2::read(&mut reader)?;
159 let mut interpolations = Vec::new();
160 for _ in if info.x {0..frames} else {0..1} {
161 interpolations.push(Interpolation::try_from(reader.read_u8()?).map_err(|_| AnimXError::IncorrectInterpolationType)?);
162 }
163
164 metamatch::metamatch!(match value_type {
165 #[expand(for T in [
166 Byte, Ushort, Ulong, Sbyte, Short,
167 Bool, Bool2, Bool3, Bool4,
168 Int, Int2, Int3, Int4,
169 Uint, Uint2, Uint3, Uint4,
170 Long, Long2, Long3, Long4,
171 Float, Float2, Float3, Float4,
172 FloatQ, Float2x2, Float3x3, Float4x4,
173 Double, Double2, Double3, Double4,
174 DoubleQ, Double2x2, Double3x3, Double4x4,
175 Color, Color32, OptString,
176 ])]
177 ValueType::T => {
178 let mut keyframes = Vec::new();
179 for i in 0..frames {
180 let time = reader.read_f32()?;
181 let value = T::read(&mut reader)?;
182 let interpolation = interpolations[if info.x {i} else {0}];
183 keyframes.push(CurveKeyframe{time, value, interpolation, left_tangent: None, right_tangent: None});
184 }
185 if info.y {
186 for i in 0..frames {
187 let keyframe = &mut keyframes[i];
188 keyframe.left_tangent = Some(T::read(&mut reader)?);
189 keyframe.right_tangent = Some(T::read(&mut reader)?);
190 }
191 }
192 output.tracks.push(
193 Box::new(
194 Track{
195 track_type,
196 value_type,
197 data: CurveData {
198 node,
199 property,
200 keyframes,
201 },
202 }
203 )
204 );
205 },
206 })
207 },
208 _ => unreachable!(),
209 }
210 }
211
212 Ok(output)
213 }
214}
215
216#[derive(Debug)]
217pub enum AnimXError {
218 IncorrectHeader,
219 UnsupportedVersion,
220 UnsupportedEncoding,
221 IncorrectTrackType,
222 IncorrectValueType,
223 IncorrectInterpolationType,
224 IoError(std::io::Error),
225 FromUtf8Error(std::string::FromUtf8Error),
226}
227
228impl From<std::io::Error> for AnimXError {
229 fn from(e: std::io::Error) -> Self {
230 Self::IoError(e)
231 }
232}
233
234impl From<std::string::FromUtf8Error> for AnimXError {
235 fn from(e: std::string::FromUtf8Error) -> Self {
236 Self::FromUtf8Error(e)
237 }
238}
239
240pub(crate) struct AnimXReader<R>(R) where R: Read;
241
242impl<R: Read> AnimXReader<R> {
243 fn read_into(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
244 self.0.read_exact(buf)
245 }
246
247 fn read_bytes(&mut self, len: usize) -> std::io::Result<Vec<u8>> {
248 let mut buf = vec![0u8; len];
249 self.0.read_exact(&mut buf)?;
250 Ok(buf)
251 }
252
253 fn read_bool(&mut self) -> std::io::Result<bool> {
254 let mut buf = [0u8;1];
255 self.0.read_exact(&mut buf)?;
256 Ok(buf[0] == 1)
257 }
258
259 fn read_u8(&mut self) -> std::io::Result<u8> {
260 let mut buf = [0u8;1];
261 self.0.read_exact(&mut buf)?;
262 Ok(buf[0])
263 }
264
265 fn read_i32(&mut self) -> std::io::Result<i32> {
266 let mut buf = [0u8;4];
267 self.0.read_exact(&mut buf)?;
268 Ok(i32::from_le_bytes(buf))
269 }
270
271 fn read_f32(&mut self) -> std::io::Result<f32> {
272 let mut buf = [0u8;4];
273 self.0.read_exact(&mut buf)?;
274 Ok(f32::from_le_bytes(buf))
275 }
276
277 fn read_varint(&mut self) -> std::io::Result<usize> {
278 let mut data = 0;
279 let mut shift = 0;
280 let mut buf = [0u8;1];
281 while { self.0.read_exact(&mut buf)?; buf[0] & 128 == 128 } {
282 data += (buf[0] as usize & 127) << shift;
283 shift += 7;
284 }
285 data += (buf[0] as usize & 127) << shift;
286
287 Ok(data)
288 }
289
290 fn read_string(&mut self) -> Result<String, AnimXError> {
291 let len = self.read_varint()?;
292 Ok(String::from_utf8(self.read_bytes(len)?)?)
293 }
294
295 fn read_nullable_string(&mut self) -> Result<Option<String>, AnimXError> {
296 if self.read_bool()? {
297 self.read_string().map(|s| Some(s))
298 } else {
299 Ok(None)
300 }
301 }
302}
303
304impl<'de> Deserialize<'de> for Animation {
305 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
306 where D: Deserializer<'de>
307 {
308 struct AnimVisitor;
309
310 impl<'de> Visitor<'de> for AnimVisitor {
311 type Value = Animation;
312
313 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
314 formatter.write_str("a map with a tracks list")
315 }
316
317 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
318 where
319 A: serde::de::MapAccess<'de>,
320 {
321 let mut output = Animation::default();
322 while let Some(key) = map.next_key::<String>()? {
323 match key.as_str() {
324 "name" => {
325 let name: String = map.next_value()?;
326 output.name = Some(name);
327 },
328 "globalDuration" => {
329 let f: f32 = map.next_value()?;
330 output.global_duration = Some(f);
331 },
332 "tracks" => {
333 let v: serde_json::Value = map.next_value()?;
334 let tracks = v.as_array().ok_or(Error::custom("incorrect field type for \"tracks\", expected 'Value::Array'"))?;
335 let tracks = tracks.iter().map(|v| {
336 let v = v.clone();
337 let info: TrackInfo = serde_json::from_value(v.clone())?;
338
339 let track = metamatch::metamatch!(match info.track_type {
341 #[expand(for (T,X) in [
342 (Raw, RawData),
343 (Discrete, DiscreteData),
344 (Curve, CurveData),
345 ])]
346 TrackType::T => {
347 metamatch::metamatch!(match info.value_type {
348 #[expand(for V in [
349 Byte, Ushort, Ulong, Sbyte, Short,
350 Bool, Bool2, Bool3, Bool4,
351 Int, Int2, Int3, Int4,
352 Uint, Uint2, Uint3, Uint4,
353 Long, Long2, Long3, Long4,
354 Float, Float2, Float3, Float4,
355 FloatQ, Float2x2, Float3x3, Float4x4,
356 Double, Double2, Double3, Double4,
357 DoubleQ, Double2x2, Double3x3, Double4x4,
358 Color, Color32, OptString,
359 ])]
360 ValueType::V => serde_json::from_value::<Box<Track<X<V>>>>(v)? as Box<dyn TrackTrait>,
361 })
362 },
363 TrackType::Bezier => todo!(),
364 });
365 Ok(track)
366 }).map(|r| r.map_err(|e: serde_json::Error| Error::custom(e)));
367 for track in tracks {
368 output.tracks.push(track?);
369 }
370 },
371 _ => {
372 let _: IgnoredAny = map.next_value()?;
373 },
374 }
375 }
376
377 Ok(output)
378 }
379 }
380
381 deserializer.deserialize_any(AnimVisitor)
382 }
383}
384
385#[derive(Debug, Deserialize)]
386struct TrackInfo where {
387 #[serde(rename = "trackType")]
388 pub track_type: TrackType,
389 #[serde(rename = "valueType")]
390 pub value_type: ValueType,
391}
392
393#[allow(private_bounds)]
394#[derive(Debug, Deserialize)]
395pub struct Track<T> where T: KeyframeTrait {
396 #[serde(rename = "trackType")]
397 pub track_type: TrackType,
398 #[serde(rename = "valueType")]
399 pub value_type: ValueType,
400 pub data: T,
401}
402
403impl<T> WriteBytes for Track<T> where T: KeyframeTrait {
404 fn write(&self, write: &mut dyn FnMut(&[u8])) {
405 write(&[self.track_type as u8, self.value_type as u8]);
406 self.data.write(write);
407 }
408}
409
410impl<T> TrackTrait for Track<T> where T: KeyframeTrait {}
411
412#[allow(private_bounds)]
413#[derive(Debug, Deserialize)]
414pub struct RawData<T> where T: WriteBytes + Debug {
415 pub node: Option<String>,
416 pub property: Option<String>,
417 pub interval: Option<f32>,
418 pub keyframes: Vec<T>,
419}
420
421impl<T> WriteBytes for RawData<T> where T: WriteBytes + Debug {
422 fn write(&self, write: &mut dyn FnMut(&[u8])) {
423 self.node.write(write);
424 self.property.write(write);
425 self.keyframes.len().write(write);
426 self.interval.write(write);
427 for keyframe in &self.keyframes {
428 keyframe.write(write);
429 }
430 }
431}
432
433impl<T> KeyframeTrait for RawData<T> where T: WriteBytes + Debug {}
434
435#[allow(private_bounds)]
436#[derive(Debug, Deserialize)]
437pub struct DiscreteData<T> where T: WriteBytes + Debug {
438 pub node: Option<String>,
439 pub property: Option<String>,
440 pub keyframes: Vec<DiscreteKeyframe<T>>,
441}
442
443impl<T> WriteBytes for DiscreteData<T> where T: WriteBytes + Debug {
444 fn write(&self, write: &mut dyn FnMut(&[u8])) {
445 self.node.write(write);
446 self.property.write(write);
447 self.keyframes.len().write(write);
448 for keyframe in &self.keyframes {
449 keyframe.write(write);
450 }
451 }
452}
453
454impl<T> KeyframeTrait for DiscreteData<T> where T: WriteBytes + Debug {}
455
456#[allow(private_bounds)]
457#[derive(Debug, Deserialize)]
458pub struct DiscreteKeyframe<T> where T: WriteBytes + Debug {
459 pub time: f32,
460 pub value: T,
461}
462
463impl<T> WriteBytes for DiscreteKeyframe<T> where T: WriteBytes + Debug {
464 fn write(&self, write: &mut dyn FnMut(&[u8])) {
465 self.time.write(write);
466 self.value.write(write);
467 }
468}
469
470#[allow(private_bounds)]
471#[derive(Debug, Deserialize)]
472pub struct CurveData<T> where T: WriteBytes + Debug {
473 pub node: Option<String>,
474 pub property: Option<String>,
475 pub keyframes: Vec<CurveKeyframe<T>>,
476}
477
478impl<T> WriteBytes for CurveData<T> where T: WriteBytes + Debug {
479 fn write(&self, write: &mut dyn FnMut(&[u8])) {
480 let interpolation = self.keyframes.first().map(|k| k.interpolation).unwrap_or(Interpolation::Hold);
481 let mut info = 0x1;
482 for keyframe in &self.keyframes {
483 if keyframe.interpolation != interpolation {
484 info |= 0x1;
485 }
486 info |= keyframe.interpolation as u8 & 0x2;
487 }
488
489 self.node.write(write);
490 self.property.write(write);
491 self.keyframes.len().write(write);
492 write(&[info]);
493
494 if info & 0x1 == 0x1 {
495 for keyframe in &self.keyframes {
496 (keyframe.interpolation as u8).write(write);
497 }
498 } else {
499 (interpolation as u8).write(write);
500 }
501
502 for keyframe in &self.keyframes {
503 keyframe.write(write);
504 }
505
506 if info & 0x2 == 0x2 {
507 for keyframe in &self.keyframes {
508 keyframe.left_tangent.as_ref().expect("interpolation mode was tangent or bezier, but leftTangent wasn't present").write(write);
509 keyframe.right_tangent.as_ref().expect("interpolation mode was tangent or bezier, but rightTangent wasn't present").write(write);
510 }
511 }
512 }
513}
514
515impl<T> KeyframeTrait for CurveData<T> where T: WriteBytes + Debug {}
516
517#[allow(private_bounds)]
518#[derive(Debug, Deserialize)]
519pub struct CurveKeyframe<T> where T: WriteBytes + Debug {
520 pub time: f32,
521 pub value: T,
522 pub interpolation: Interpolation,
523
524 #[serde(rename = "leftTangent")]
528 pub left_tangent: Option<T>,
529 #[serde(rename = "rightTangent")]
530 pub right_tangent: Option<T>,
531}
532
533impl<T> WriteBytes for CurveKeyframe<T> where T: WriteBytes + Debug {
534 fn write(&self, write: &mut dyn FnMut(&[u8])) {
535 self.time.write(write);
536 self.value.write(write);
537 }
538}
539
540#[derive(Debug, PartialEq, Eq, Deserialize, Clone, Copy)]
541pub enum Interpolation {
542 Hold,
543 Linear,
544 Tangent,
545 CubicBezier,
546}
547
548impl TryFrom<u8> for Interpolation {
549 type Error = ();
550
551 fn try_from(value: u8) -> Result<Self, Self::Error> {
552 match value {
553 0 => Ok(Self::Hold),
554 1 => Ok(Self::Linear),
555 2 => Ok(Self::Tangent),
556 3 => Ok(Self::CubicBezier),
557 _ => Err(()),
558 }
559 }
560}