use alloc::borrow::Cow;
use alloc::vec::Vec;
use ownable::IntoOwned;
use serde::Deserialize;
use crate::accessor::Accessor;
use crate::node::Node;
use crate::{Extensions, Extras, Idx};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum InterpolationEnum {
Linear,
Step,
CubicSpline,
}
#[derive(Clone, PartialEq, Eq, Deserialize, IntoOwned)]
#[serde(transparent)]
pub struct Interpolation<'a>(#[serde(borrow)] pub Cow<'a, str>);
impl Default for Interpolation<'_> {
fn default() -> Self {
Self::LINEAR
}
}
impl core::fmt::Debug for Interpolation<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if let Some(e) = self.to_enum() {
e.fmt(f)
} else {
self.0.fmt(f)
}
}
}
impl Interpolation<'_> {
pub const LINEAR: Self = Self(Cow::Borrowed("LINEAR"));
pub const STEP: Self = Self(Cow::Borrowed("STEP"));
pub const CUBICSPLINE: Self = Self(Cow::Borrowed("CUBICSPLINE"));
pub fn to_enum(&self) -> Option<InterpolationEnum> {
if *self == Self::LINEAR {
return Some(InterpolationEnum::Linear);
} else if *self == Self::STEP {
return Some(InterpolationEnum::Step);
} else if *self == Self::CUBICSPLINE {
return Some(InterpolationEnum::CubicSpline);
}
None
}
}
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct AnimationSampler<'a> {
pub input: Idx<Accessor<'static>>,
pub output: Idx<Accessor<'static>>,
#[serde(default, borrow)]
pub interpolation: Interpolation<'a>,
#[serde(borrow)]
pub extensions: Option<Extensions<'a>>,
#[serde(borrow)]
pub extras: Option<Extras<'a>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PropertyEnum {
Translation,
Rotation,
Scale,
Weights,
}
#[derive(Clone, PartialEq, Eq, Deserialize, IntoOwned)]
#[serde(transparent)]
pub struct Property<'a>(#[serde(borrow)] pub Cow<'a, str>);
impl core::fmt::Debug for Property<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if let Some(e) = self.to_enum() {
e.fmt(f)
} else {
self.0.fmt(f)
}
}
}
impl Property<'_> {
pub const TRANSLATION: Self = Self(Cow::Borrowed("translation"));
pub const ROTATION: Self = Self(Cow::Borrowed("rotation"));
pub const SCALE: Self = Self(Cow::Borrowed("scale"));
pub const WEIGHTS: Self = Self(Cow::Borrowed("weights"));
pub fn to_enum(&self) -> Option<PropertyEnum> {
if *self == Self::TRANSLATION {
return Some(PropertyEnum::Translation);
} else if *self == Self::ROTATION {
return Some(PropertyEnum::Rotation);
} else if *self == Self::SCALE {
return Some(PropertyEnum::Scale);
} else if *self == Self::WEIGHTS {
return Some(PropertyEnum::Weights);
}
None
}
}
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct ChannelTarget<'a> {
pub node: Option<Idx<Node<'static>>>,
#[serde(borrow)]
pub path: Property<'a>,
#[serde(borrow)]
pub extensions: Option<Extensions<'a>>,
#[serde(borrow)]
pub extras: Option<Extras<'a>>,
}
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct Channel<'a> {
pub sampler: Idx<AnimationSampler<'static>>,
#[serde(borrow)]
pub target: ChannelTarget<'a>,
#[serde(borrow)]
pub extensions: Option<Extensions<'a>>,
#[serde(borrow)]
pub extras: Option<Extras<'a>>,
}
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct Animation<'a> {
#[serde(borrow)]
pub name: Option<Cow<'a, str>>,
#[serde(borrow)]
pub samplers: Vec<AnimationSampler<'a>>,
#[serde(borrow)]
pub channels: Vec<Channel<'a>>,
#[serde(borrow)]
pub extensions: Option<Extensions<'a>>,
#[serde(borrow)]
pub extras: Option<Extras<'a>>,
}