1use {
2 super::{Quat, Vec3},
3 gltf::animation::Interpolation as GltfInterpolation,
4 serde::{Deserialize, Serialize},
5};
6
7#[derive(Debug, Deserialize, PartialEq, Serialize)]
9pub struct Animation {
10 channels: Vec<Channel>,
11}
12
13impl Animation {
14 pub(super) fn new(channels: Vec<Channel>) -> Self {
15 Self { channels }
16 }
17
18 pub fn channels(&self) -> &[Channel] {
20 &self.channels
21 }
22}
23
24#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
26pub struct Channel {
27 inputs: Vec<u32>,
28 interpolation: Interpolation,
29 outputs: Outputs,
30 target: String,
31}
32
33impl Channel {
34 #[allow(unused)]
35 pub(crate) fn new<T: AsRef<str>, I: IntoIterator<Item = u32>>(
36 target: T,
37 interpolation: GltfInterpolation,
38 inputs: I,
39 outputs: Outputs,
40 ) -> Self {
41 let inputs = inputs.into_iter().collect::<Vec<_>>();
42 let target = target.as_ref().to_owned();
43
44 assert!(!target.is_empty());
45 assert_ne!(inputs.len(), 0);
46
47 Self {
48 inputs,
49 interpolation: match interpolation {
50 GltfInterpolation::CubicSpline => Interpolation::CubicSpline,
51 GltfInterpolation::Linear => Interpolation::Linear,
52 GltfInterpolation::Step => Interpolation::Step,
53 },
54 outputs,
55 target,
56 }
57 }
58
59 pub fn inputs(&self) -> &[u32] {
60 &self.inputs
61 }
62
63 pub fn interpolation(&self) -> Interpolation {
64 self.interpolation
65 }
66
67 pub fn outputs(&self) -> &Outputs {
68 &self.outputs
69 }
70
71 pub fn target(&self) -> &str {
73 &self.target
74 }
75}
76
77#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
80pub enum Interpolation {
81 Linear = 1,
88
89 Step,
95
96 CubicSpline,
104}
105
106#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
107pub enum Outputs {
108 Rotations(Vec<Quat>),
109 Scales(Vec<Vec3>),
110 Translations(Vec<Vec3>),
111}
112
113impl Outputs {
114 pub fn is_empty(&self) -> bool {
116 match self {
117 Self::Rotations(rotations) => rotations.is_empty(),
118 Self::Scales(scales) => scales.is_empty(),
119 Self::Translations(translations) => translations.is_empty(),
120 }
121 }
122
123 pub fn len(&self) -> usize {
125 match self {
126 Self::Rotations(rotations) => rotations.len(),
127 Self::Scales(scales) => scales.len(),
128 Self::Translations(translations) => translations.len(),
129 }
130 }
131}