resonite_core/animation/
mod.rs

1//! # Animation data (AnimJ & AnimX)
2
3pub mod types;
4use types::*;
5
6use std::{fmt::Debug, io::{BufWriter, 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/// 
13/// There is also a function for writing an AnimX stream (Binary)
14/// 
15/// Deserealizing AnimX is currently **not** supported
16#[allow(private_interfaces)]
17#[derive(Debug, Default)]
18pub struct Animation {
19    pub name: Option<String>,
20    pub global_duration: Option<f32>,
21    pub tracks: Vec<Box<dyn TrackTrait>>,
22}
23
24impl Animation {
25    /// Function for writing data as an AnimX stream
26    /// 
27    /// Compression is not yet supported.
28    /// 
29    /// ```
30    /// use resonite_core::animation::Animation;
31    /// 
32    /// let anim: Animation = serde_json::from_str(/* AnimJ */)?;
33    /// let mut buf = Vec::new();
34    /// anim.write_animx(&mut buf);
35    /// ```
36    /// 
37    pub fn write_animx(&self, buf: impl Write) {
38        let mut writer = BufWriter::new(buf);
39        let mut write = |bytes: &[u8]| { writer.write(bytes).unwrap(); };
40
41        self.write_contents(&mut write);
42    }
43
44    fn write_contents(&self, write: &mut dyn FnMut(&[u8])) {
45        "AnimX".to_owned().write(write);    // "AnimX" magic header
46        01u32.write(write);                 // Version 01 (wiki says this is supposed to be a byte, but it's an Int / i32)
47        self.tracks.len().write(write);     // Length (wiki says this is supposed to be a 7bit integer, but this is actually a varint)
48        self.global_duration.write(write);  // Length of animation in seconds
49        self.name.write(write);             // Name of animation
50        write(&[0x00,]);                    // Encoding flag (just none for now)
51        for track in &self.tracks {
52            track.write(write);             // Tracks
53        }
54    }
55}
56
57impl<'de> Deserialize<'de> for Animation {
58    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
59        where D: Deserializer<'de>
60    {
61        struct AnimVisitor;
62
63        impl<'de> Visitor<'de> for AnimVisitor {
64            type Value = Animation;
65        
66            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
67                formatter.write_str("a map with a tracks list")
68            }
69            
70            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
71            where
72                A: serde::de::MapAccess<'de>,
73            {
74                let mut output = Animation::default();
75                while let Some(key) = map.next_key::<String>()? {
76                    match key.as_str() {
77                        "name" => {
78                            let name: String = map.next_value()?;
79                            output.name = Some(name);
80                        },
81                        "globalDuration" => {
82                            let f: f32 = map.next_value()?;
83                            output.global_duration = Some(f);
84                        },
85                        "tracks" => {
86                            let v: serde_json::Value = map.next_value()?;
87                            let tracks = v.as_array().ok_or(Error::custom("incorrect field type for \"tracks\", expected 'Value::Array'"))?;
88                            let tracks = tracks.iter().map(|v| {
89                                let v = v.clone();
90                                let info: TrackInfo = serde_json::from_value(v.clone())?;
91
92                                // This technically makes Curve keyframes on String values possible...
93                                let track = metamatch::metamatch!(match info.track_type {
94                                    #[expand(for (T,X) in [
95                                        (Raw, RawData),
96                                        (Discrete, DiscreteData),
97                                        (Curve, CurveData),
98                                    ])]
99                                    TrackType::T => {
100                                        metamatch::metamatch!(match info.value_type {
101                                            #[expand(for V in [
102                                                Byte, Ushort, Ulong, Sbyte, Short,
103                                                Bool, Bool2, Bool3, Bool4,
104                                                Int, Int2, Int3, Int4,
105                                                Uint, Uint2, Uint3, Uint4,
106                                                Long, Long2, Long3, Long4,
107                                                Float, Float2, Float3, Float4,
108                                                FloatQ, Float2x2, Float3x3, Float4x4,
109                                                Double, Double2, Double3, Double4,
110                                                DoubleQ, Double2x2, Double3x3, Double4x4,
111                                                Color, Color32, OptString,
112                                            ])]
113                                            ValueType::V => serde_json::from_value::<Box<Track<X<V>>>>(v)? as Box<dyn TrackTrait>,
114                                        })
115                                    },
116                                    TrackType::Bezier => todo!(),
117                                });
118                                Ok(track)
119                            }).map(|r| r.map_err(|e: serde_json::Error| Error::custom(e)));
120                            for track in tracks {
121                                output.tracks.push(track?);
122                            }
123                        },
124                        _ => {
125                            let _: IgnoredAny = map.next_value()?;
126                        },
127                    }
128                }
129
130                Ok(output)
131            }
132        }
133
134        deserializer.deserialize_any(AnimVisitor)
135    }
136}
137
138#[derive(Debug, Deserialize)]
139struct TrackInfo where {
140    #[serde(rename = "trackType")]
141    pub track_type: TrackType,
142    #[serde(rename = "valueType")]
143    pub value_type: ValueType,
144}
145
146#[allow(private_bounds)]
147#[derive(Debug, Deserialize)]
148pub struct Track<T> where T: KeyframeTrait {
149    #[serde(rename = "trackType")]
150    pub track_type: TrackType,
151    #[serde(rename = "valueType")]
152    pub value_type: ValueType,
153    pub data: T,
154}
155
156impl<T> WriteBytes for Track<T> where T: KeyframeTrait {
157    fn write(&self, write: &mut dyn FnMut(&[u8])) {
158        write(&[self.track_type as u8, self.value_type as u8]);
159        self.data.write(write);
160    }
161}
162
163impl<T> TrackTrait for Track<T> where T: KeyframeTrait {}
164
165#[allow(private_bounds)]
166#[derive(Debug, Deserialize)]
167pub struct RawData<T> where T: WriteBytes + Debug {
168    pub node: Option<String>,
169    pub property: Option<String>,
170    pub interval: Option<f32>,
171    pub keyframes: Vec<T>,
172}
173
174impl<T> WriteBytes for RawData<T> where T: WriteBytes + Debug {
175    fn write(&self, write: &mut dyn FnMut(&[u8])) {
176        self.node.write(write);
177        self.property.write(write);
178        self.keyframes.len().write(write);
179        self.interval.write(write);
180        for keyframe in &self.keyframes {
181            keyframe.write(write);
182        }
183    }
184}
185
186impl<T> KeyframeTrait for RawData<T> where T: WriteBytes + Debug {}
187
188#[allow(private_bounds)]
189#[derive(Debug, Deserialize)]
190pub struct DiscreteData<T> where T: WriteBytes + Debug {
191    pub node: Option<String>,
192    pub property: Option<String>,
193    pub keyframes: Vec<DiscreteKeyframe<T>>,
194}
195
196impl<T> WriteBytes for DiscreteData<T> where T: WriteBytes + Debug {
197    fn write(&self, write: &mut dyn FnMut(&[u8])) {
198        self.node.write(write);
199        self.property.write(write);
200        self.keyframes.len().write(write);
201        for keyframe in &self.keyframes {
202            keyframe.write(write);
203        }
204    }
205}
206
207impl<T> KeyframeTrait for DiscreteData<T> where T: WriteBytes + Debug {}
208
209#[allow(private_bounds)]
210#[derive(Debug, Deserialize)]
211pub struct DiscreteKeyframe<T> where T: WriteBytes + Debug {
212    pub time: f32,
213    pub value: T,
214}
215
216impl<T> WriteBytes for DiscreteKeyframe<T> where T: WriteBytes + Debug {
217    fn write(&self, write: &mut dyn FnMut(&[u8])) {
218        self.time.write(write);
219        self.value.write(write);
220    }
221}
222
223#[allow(private_bounds)]
224#[derive(Debug, Deserialize)]
225pub struct CurveData<T> where T: WriteBytes + Debug {
226    pub node: Option<String>,
227    pub property: Option<String>,
228    pub keyframes: Vec<CurveKeyframe<T>>,
229}
230
231impl<T> WriteBytes for CurveData<T> where T: WriteBytes + Debug {
232    fn write(&self, write: &mut dyn FnMut(&[u8])) {
233        let interpolation = self.keyframes.first().map(|k| k.interpolation).unwrap_or(Interpolation::Hold);
234        let mut info = 0x1;
235        for keyframe in &self.keyframes {
236            if keyframe.interpolation != interpolation {
237                info |= 0x1;
238            }
239            info |= keyframe.interpolation as u8 & 0x2;
240        }
241
242        self.node.write(write);
243        self.property.write(write);
244        self.keyframes.len().write(write);
245        write(&[info]);
246
247        if info & 0x1 == 0x1 {
248            for keyframe in &self.keyframes {
249                (keyframe.interpolation as u8).write(write);
250            }
251        } else {
252            (interpolation as u8).write(write);
253        }
254
255        for keyframe in &self.keyframes {
256            keyframe.write(write);
257        }
258
259        if info & 0x2 == 0x2 {
260            for keyframe in &self.keyframes {
261                keyframe.left_tangent.as_ref().expect("interpolation mode was tangent or bezier, but leftTangent wasn't present").write(write);
262                keyframe.right_tangent.as_ref().expect("interpolation mode was tangent or bezier, but rightTangent wasn't present").write(write);
263            }
264        }
265    }
266}
267
268impl<T> KeyframeTrait for CurveData<T> where T: WriteBytes + Debug {}
269
270#[allow(private_bounds)]
271#[derive(Debug, Deserialize)]
272pub struct CurveKeyframe<T> where T: WriteBytes + Debug {
273    pub time: f32,
274    pub value: T,
275    pub interpolation: Interpolation,
276
277    /// I think the types for ``left_tangent`` & ``right_tangent`` are incorrect but I'm not sure what they should be...\
278    /// Maybe they're supposed to be ``(f32, T)`` pairs?
279
280    #[serde(rename = "leftTangent")]
281    pub left_tangent: Option<T>,
282    #[serde(rename = "rightTangent")]
283    pub right_tangent: Option<T>,
284}
285
286impl<T> WriteBytes for CurveKeyframe<T> where T: WriteBytes + Debug {
287    fn write(&self, write: &mut dyn FnMut(&[u8])) {
288        self.time.write(write);
289        self.value.write(write);
290    }
291}
292
293#[derive(Debug, PartialEq, Eq, Deserialize, Clone, Copy)]
294pub enum Interpolation {
295    Hold,
296    Linear,
297    Tangent,
298    CubicBezier,
299}