use {
super::{Quat, Vec3},
gltf::animation::Interpolation as GltfInterpolation,
serde::{Deserialize, Serialize},
};
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Animation {
channels: Vec<Channel>,
}
impl Animation {
pub(super) fn new(channels: Vec<Channel>) -> Self {
Self { channels }
}
pub fn channels(&self) -> &[Channel] {
&self.channels
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct Channel {
inputs: Vec<u32>,
interpolation: Interpolation,
outputs: Outputs,
target: String,
}
impl Channel {
#[allow(unused)]
pub(crate) fn new<T: AsRef<str>, I: IntoIterator<Item = u32>>(
target: T,
interpolation: GltfInterpolation,
inputs: I,
outputs: Outputs,
) -> Self {
let inputs = inputs.into_iter().collect::<Vec<_>>();
let target = target.as_ref().to_owned();
assert!(!target.is_empty());
assert_ne!(inputs.len(), 0);
Self {
inputs,
interpolation: match interpolation {
GltfInterpolation::CubicSpline => Interpolation::CubicSpline,
GltfInterpolation::Linear => Interpolation::Linear,
GltfInterpolation::Step => Interpolation::Step,
},
outputs,
target,
}
}
pub fn inputs(&self) -> &[u32] {
&self.inputs
}
pub fn interpolation(&self) -> Interpolation {
self.interpolation
}
pub fn outputs(&self) -> &Outputs {
&self.outputs
}
pub fn target(&self) -> &str {
&self.target
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub enum Interpolation {
Linear = 1,
Step,
CubicSpline,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub enum Outputs {
Rotations(Vec<Quat>),
Scales(Vec<Vec3>),
Translations(Vec<Vec3>),
}
impl Outputs {
pub fn is_empty(&self) -> bool {
match self {
Self::Rotations(rotations) => rotations.is_empty(),
Self::Scales(scales) => scales.is_empty(),
Self::Translations(translations) => translations.is_empty(),
}
}
pub fn len(&self) -> usize {
match self {
Self::Rotations(rotations) => rotations.len(),
Self::Scales(scales) => scales.len(),
Self::Translations(translations) => translations.len(),
}
}
}