1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use {
    crate::math::Quat,
    gltf::animation::Interpolation,
    serde::{Deserialize, Serialize},
};

/// Holds an `Animation` in a `.pak` file. For data transport only.
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Animation {
    /// The channels (joints/bones) of movement used in this `Animation`.
    pub channels: Vec<Channel>,
}

/// Describes the animation of one joint.
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Channel {
    inputs: Vec<f32>,
    interpolation: Interpolation,
    rotations: Vec<Quat>,
    target: String,
}

impl Channel {
    pub(crate) fn new<T: AsRef<str>, I: IntoIterator<Item = f32>, R: IntoIterator<Item = Quat>>(
        target: T,
        interpolation: Interpolation,
        inputs: I,
        rotations: R,
    ) -> Self {
        let inputs = inputs.into_iter().collect::<Vec<_>>();
        let rotations = rotations.into_iter().collect::<Vec<_>>();
        let target = target.as_ref().to_owned();

        assert!(!target.is_empty());
        assert_ne!(inputs.len(), 0);

        match interpolation {
            Interpolation::Linear | Interpolation::Step => {
                assert_eq!(inputs.len(), rotations.len());
            }
            Interpolation::CubicSpline => {
                assert_eq!(inputs.len() * 3, rotations.len());
            }
        }

        Self {
            inputs,
            interpolation,
            rotations,
            target,
        }
    }

    /// The target joint/bone.
    pub fn target(&self) -> &str {
        &self.target
    }
}