resonite_core/animation/
mod.rs

1//! # Animation data (AnimJ & AnimX)
2
3pub mod types;
4use types::*;
5
6use std::{fmt::Debug, io::{BufWriter, Read, Write}};
7use serde::{de::{Error, IgnoredAny, Visitor}, Deserialize, Deserializer};
8
9/// The overarching type for animations
10/// 
11/// This type implements ``serde::Deserialize`` and is meant to be deserealized from an AnimJ (JSON) structure\
12/// There are also functions for writing and reading AnimX streams (Binary)
13#[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    /// Function for writing data as an AnimX stream\
23    /// Compression is not yet supported.
24    /// 
25    /// ```
26    /// use resonite_core::animation::Animation;
27    /// 
28    /// let anim: Animation = serde_json::from_str(/* AnimJ */)?;
29    /// let mut buf = Vec::new();
30    /// anim.write_animx(&mut buf);
31    /// ```
32    /// 
33    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);    // "AnimX" magic header
42        01u32.write(write);                 // Version 01 (wiki says this is supposed to be a byte, but it's an Int / i32)
43        self.tracks.len().write(write);     // Length (wiki says this is supposed to be a 7bit integer, but this is actually a varint)
44        self.global_duration.write(write);  // Length of animation in seconds
45        self.name.write(write);             // Name of animation
46        write(&[0x00,]);                    // Encoding flag (just none for now)
47        for track in &self.tracks {
48            track.write(write);             // Tracks
49        }
50    }
51
52    /// Function for reading data from an AnimX stream\
53    /// Compression is not yet supported.
54    /// 
55    /// ```
56    /// use resonite_core::animation::Animation;
57    /// 
58    /// let reader = BufReader::new(/* AnimX */);
59    /// let anim = Animation::from_animx(reader)?;
60    /// ```
61    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                                // This technically makes Curve keyframes on String values possible...
340                                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    /// I think the types for ``left_tangent`` & ``right_tangent`` are incorrect but I'm not sure what they should be...\
525    /// Maybe they're supposed to be ``(f32, T)`` pairs?
526
527    #[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}