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 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 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 #[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}