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                            OptString,
167                        ])]
168                        ValueType::T => {
169                            let mut keyframes = Vec::new();
170                            for i in 0..frames {
171                                let time = reader.read_f32()?;
172                                let value = T::read(&mut reader)?;
173                                let interpolation = interpolations[if info.x {i} else {0}];
174                                keyframes.push(CurveKeyframe{time, value, interpolation, left_tangent: None, right_tangent: None});
175                            }
176                            if info.y {
177                                for i in 0..frames {
178                                    let keyframe = &mut keyframes[i];
179                                    keyframe.left_tangent = Some(T::read(&mut reader)?);
180                                    keyframe.right_tangent = Some(T::read(&mut reader)?);
181                                }
182                            }
183                            output.tracks.push(
184                                Box::new(
185                                    Track{
186                                        track_type,
187                                        value_type,
188                                        data: CurveData {
189                                            node,
190                                            property,
191                                            keyframes,
192                                        },
193                                    }
194                                )
195                            );
196                        },
197                        _ => todo!(),
198                    })
199                },
200                _ => unreachable!(),
201            }
202        }
203
204        Ok(output)
205    }
206}
207
208#[derive(Debug)]
209pub enum AnimXError {
210    IncorrectHeader,
211    UnsupportedVersion,
212    UnsupportedEncoding,
213    IncorrectTrackType,
214    IncorrectValueType,
215    IncorrectInterpolationType,
216    IoError(std::io::Error),
217    FromUtf8Error(std::string::FromUtf8Error),
218}
219
220impl From<std::io::Error> for AnimXError {
221    fn from(e: std::io::Error) -> Self {
222        Self::IoError(e)
223    }
224}
225
226impl From<std::string::FromUtf8Error> for AnimXError {
227    fn from(e: std::string::FromUtf8Error) -> Self {
228        Self::FromUtf8Error(e)
229    }
230}
231
232pub(crate) struct AnimXReader<R>(R) where R: Read;
233
234impl<R: Read> AnimXReader<R> {
235    fn read_into(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
236        self.0.read_exact(buf)
237    }
238
239    fn read_bytes(&mut self, len: usize) -> std::io::Result<Vec<u8>> {
240        let mut buf = vec![0u8; len];
241        self.0.read_exact(&mut buf)?;
242        Ok(buf)
243    }
244
245    fn read_bool(&mut self) -> std::io::Result<bool> {
246        let mut buf = [0u8;1];
247        self.0.read_exact(&mut buf)?;
248        Ok(buf[0] == 1)
249    }
250
251    fn read_u8(&mut self) -> std::io::Result<u8> {
252        let mut buf = [0u8;1];
253        self.0.read_exact(&mut buf)?;
254        Ok(buf[0])
255    }
256
257    fn read_i32(&mut self) -> std::io::Result<i32> {
258        let mut buf = [0u8;4];
259        self.0.read_exact(&mut buf)?;
260        Ok(i32::from_le_bytes(buf))
261    }
262
263    fn read_f32(&mut self) -> std::io::Result<f32> {
264        let mut buf = [0u8;4];
265        self.0.read_exact(&mut buf)?;
266        Ok(f32::from_le_bytes(buf))
267    }
268
269    fn read_varint(&mut self) -> std::io::Result<usize> {
270        let mut data = 0;
271        let mut shift = 0;
272        let mut buf = [0u8;1];
273        while { self.0.read_exact(&mut buf)?; buf[0] & 128 == 128 } {
274            data += (buf[0] as usize & 127) << shift;
275            shift += 7;
276        }
277        data += (buf[0] as usize & 127) << shift;
278
279        Ok(data)
280    }
281
282    fn read_string(&mut self) -> Result<String, AnimXError> {
283        let len = self.read_varint()?;
284        Ok(String::from_utf8(self.read_bytes(len)?)?)
285    }
286
287    fn read_nullable_string(&mut self) -> Result<Option<String>, AnimXError> {
288        if self.read_bool()? {
289            self.read_string().map(|s| Some(s))
290        } else {
291            Ok(None)
292        }
293    }
294}
295
296impl<'de> Deserialize<'de> for Animation {
297    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
298        where D: Deserializer<'de>
299    {
300        struct AnimVisitor;
301
302        impl<'de> Visitor<'de> for AnimVisitor {
303            type Value = Animation;
304        
305            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
306                formatter.write_str("a map with a tracks list")
307            }
308            
309            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
310            where
311                A: serde::de::MapAccess<'de>,
312            {
313                let mut output = Animation::default();
314                while let Some(key) = map.next_key::<String>()? {
315                    match key.as_str() {
316                        "name" => {
317                            let name: String = map.next_value()?;
318                            output.name = Some(name);
319                        },
320                        "globalDuration" => {
321                            let f: f32 = map.next_value()?;
322                            output.global_duration = Some(f);
323                        },
324                        "tracks" => {
325                            let v: serde_json::Value = map.next_value()?;
326                            let tracks = v.as_array().ok_or(Error::custom("incorrect field type for \"tracks\", expected 'Value::Array'"))?;
327                            let tracks = tracks.iter().map(|v| {
328                                let v = v.clone();
329                                let info: TrackInfo = serde_json::from_value(v.clone())?;
330
331                                // This technically makes Curve keyframes on String values possible...
332                                let track = metamatch::metamatch!(match info.track_type {
333                                    #[expand(for (T,X) in [
334                                        (Raw, RawData),
335                                        (Discrete, DiscreteData),
336                                        (Curve, CurveData),
337                                    ])]
338                                    TrackType::T => {
339                                        metamatch::metamatch!(match info.value_type {
340                                            #[expand(for V in [
341                                                Byte, Ushort, Ulong, Sbyte, Short,
342                                                Bool, Bool2, Bool3, Bool4,
343                                                Int, Int2, Int3, Int4,
344                                                Uint, Uint2, Uint3, Uint4,
345                                                Long, Long2, Long3, Long4,
346                                                Float, Float2, Float3, Float4,
347                                                FloatQ, Float2x2, Float3x3, Float4x4,
348                                                Double, Double2, Double3, Double4,
349                                                DoubleQ, Double2x2, Double3x3, Double4x4,
350                                                Color, Color32, OptString,
351                                            ])]
352                                            ValueType::V => serde_json::from_value::<Box<Track<X<V>>>>(v)? as Box<dyn TrackTrait>,
353                                        })
354                                    },
355                                    TrackType::Bezier => todo!(),
356                                });
357                                Ok(track)
358                            }).map(|r| r.map_err(|e: serde_json::Error| Error::custom(e)));
359                            for track in tracks {
360                                output.tracks.push(track?);
361                            }
362                        },
363                        _ => {
364                            let _: IgnoredAny = map.next_value()?;
365                        },
366                    }
367                }
368
369                Ok(output)
370            }
371        }
372
373        deserializer.deserialize_any(AnimVisitor)
374    }
375}
376
377#[derive(Debug, Deserialize)]
378struct TrackInfo where {
379    #[serde(rename = "trackType")]
380    pub track_type: TrackType,
381    #[serde(rename = "valueType")]
382    pub value_type: ValueType,
383}
384
385#[allow(private_bounds)]
386#[derive(Debug, Deserialize)]
387pub struct Track<T> where T: KeyframeTrait {
388    #[serde(rename = "trackType")]
389    pub track_type: TrackType,
390    #[serde(rename = "valueType")]
391    pub value_type: ValueType,
392    pub data: T,
393}
394
395impl<T> WriteBytes for Track<T> where T: KeyframeTrait {
396    fn write(&self, write: &mut dyn FnMut(&[u8])) {
397        write(&[self.track_type as u8, self.value_type as u8]);
398        self.data.write(write);
399    }
400}
401
402impl<T> TrackTrait for Track<T> where T: KeyframeTrait {}
403
404#[allow(private_bounds)]
405#[derive(Debug, Deserialize)]
406pub struct RawData<T> where T: WriteBytes + Debug {
407    pub node: Option<String>,
408    pub property: Option<String>,
409    pub interval: Option<f32>,
410    pub keyframes: Vec<T>,
411}
412
413impl<T> WriteBytes for RawData<T> where T: WriteBytes + Debug {
414    fn write(&self, write: &mut dyn FnMut(&[u8])) {
415        self.node.write(write);
416        self.property.write(write);
417        self.keyframes.len().write(write);
418        self.interval.write(write);
419        for keyframe in &self.keyframes {
420            keyframe.write(write);
421        }
422    }
423}
424
425impl<T> KeyframeTrait for RawData<T> where T: WriteBytes + Debug {}
426
427#[allow(private_bounds)]
428#[derive(Debug, Deserialize)]
429pub struct DiscreteData<T> where T: WriteBytes + Debug {
430    pub node: Option<String>,
431    pub property: Option<String>,
432    pub keyframes: Vec<DiscreteKeyframe<T>>,
433}
434
435impl<T> WriteBytes for DiscreteData<T> where T: WriteBytes + Debug {
436    fn write(&self, write: &mut dyn FnMut(&[u8])) {
437        self.node.write(write);
438        self.property.write(write);
439        self.keyframes.len().write(write);
440        for keyframe in &self.keyframes {
441            keyframe.write(write);
442        }
443    }
444}
445
446impl<T> KeyframeTrait for DiscreteData<T> where T: WriteBytes + Debug {}
447
448#[allow(private_bounds)]
449#[derive(Debug, Deserialize)]
450pub struct DiscreteKeyframe<T> where T: WriteBytes + Debug {
451    pub time: f32,
452    pub value: T,
453}
454
455impl<T> WriteBytes for DiscreteKeyframe<T> where T: WriteBytes + Debug {
456    fn write(&self, write: &mut dyn FnMut(&[u8])) {
457        self.time.write(write);
458        self.value.write(write);
459    }
460}
461
462#[allow(private_bounds)]
463#[derive(Debug, Deserialize)]
464pub struct CurveData<T> where T: WriteBytes + Debug {
465    pub node: Option<String>,
466    pub property: Option<String>,
467    pub keyframes: Vec<CurveKeyframe<T>>,
468}
469
470impl<T> WriteBytes for CurveData<T> where T: WriteBytes + Debug {
471    fn write(&self, write: &mut dyn FnMut(&[u8])) {
472        let interpolation = self.keyframes.first().map(|k| k.interpolation).unwrap_or(Interpolation::Hold);
473        let mut info = 0x1;
474        for keyframe in &self.keyframes {
475            if keyframe.interpolation != interpolation {
476                info |= 0x1;
477            }
478            info |= keyframe.interpolation as u8 & 0x2;
479        }
480
481        self.node.write(write);
482        self.property.write(write);
483        self.keyframes.len().write(write);
484        write(&[info]);
485
486        if info & 0x1 == 0x1 {
487            for keyframe in &self.keyframes {
488                (keyframe.interpolation as u8).write(write);
489            }
490        } else {
491            (interpolation as u8).write(write);
492        }
493
494        for keyframe in &self.keyframes {
495            keyframe.write(write);
496        }
497
498        if info & 0x2 == 0x2 {
499            for keyframe in &self.keyframes {
500                keyframe.left_tangent.as_ref().expect("interpolation mode was tangent or bezier, but leftTangent wasn't present").write(write);
501                keyframe.right_tangent.as_ref().expect("interpolation mode was tangent or bezier, but rightTangent wasn't present").write(write);
502            }
503        }
504    }
505}
506
507impl<T> KeyframeTrait for CurveData<T> where T: WriteBytes + Debug {}
508
509#[allow(private_bounds)]
510#[derive(Debug, Deserialize)]
511pub struct CurveKeyframe<T> where T: WriteBytes + Debug {
512    pub time: f32,
513    pub value: T,
514    pub interpolation: Interpolation,
515
516    /// I think the types for ``left_tangent`` & ``right_tangent`` are incorrect but I'm not sure what they should be...\
517    /// Maybe they're supposed to be ``(f32, T)`` pairs?
518
519    #[serde(rename = "leftTangent")]
520    pub left_tangent: Option<T>,
521    #[serde(rename = "rightTangent")]
522    pub right_tangent: Option<T>,
523}
524
525impl<T> WriteBytes for CurveKeyframe<T> where T: WriteBytes + Debug {
526    fn write(&self, write: &mut dyn FnMut(&[u8])) {
527        self.time.write(write);
528        self.value.write(write);
529    }
530}
531
532#[derive(Debug, PartialEq, Eq, Deserialize, Clone, Copy)]
533pub enum Interpolation {
534    Hold,
535    Linear,
536    Tangent,
537    CubicBezier,
538}
539
540impl TryFrom<u8> for Interpolation {
541    type Error = ();
542
543    fn try_from(value: u8) -> Result<Self, Self::Error> {
544        match value {
545            0 => Ok(Self::Hold),
546            1 => Ok(Self::Linear),
547            2 => Ok(Self::Tangent),
548            3 => Ok(Self::CubicBezier),
549            _ => Err(()),
550        }
551    }
552}