1use alloc::borrow::Cow;
2use alloc::vec::Vec;
3use ownable::IntoOwned;
4use serde::Deserialize;
5
6use crate::accessor::Accessor;
7use crate::node::Node;
8use crate::{Extensions, Extras, Idx};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum InterpolationEnum {
13 Linear,
14 Step,
15 CubicSpline,
16}
17
18#[derive(Clone, PartialEq, Eq, Deserialize, IntoOwned)]
20#[serde(transparent)]
21pub struct Interpolation<'a>(#[serde(borrow)] pub Cow<'a, str>);
22
23impl Default for Interpolation<'_> {
24 fn default() -> Self {
25 Self::LINEAR
26 }
27}
28
29impl core::fmt::Debug for Interpolation<'_> {
30 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
31 if let Some(e) = self.to_enum() {
32 e.fmt(f)
33 } else {
34 self.0.fmt(f)
35 }
36 }
37}
38
39impl Interpolation<'_> {
40 pub const LINEAR: Self = Self(Cow::Borrowed("LINEAR"));
41 pub const STEP: Self = Self(Cow::Borrowed("STEP"));
42 pub const CUBICSPLINE: Self = Self(Cow::Borrowed("CUBICSPLINE"));
43
44 pub fn to_enum(&self) -> Option<InterpolationEnum> {
45 if *self == Self::LINEAR {
46 return Some(InterpolationEnum::Linear);
47 } else if *self == Self::STEP {
48 return Some(InterpolationEnum::Step);
49 } else if *self == Self::CUBICSPLINE {
50 return Some(InterpolationEnum::CubicSpline);
51 }
52
53 None
54 }
55}
56
57#[derive(Debug, Clone, Deserialize, IntoOwned)]
60pub struct AnimationSampler<'a> {
61 pub input: Idx<Accessor<'static>>,
63 pub output: Idx<Accessor<'static>>,
65 #[serde(default, borrow)]
67 pub interpolation: Interpolation<'a>,
68
69 #[serde(borrow)]
70 pub extensions: Option<Extensions<'a>>,
71 #[serde(borrow)]
72 pub extras: Option<Extras<'a>>,
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77pub enum PropertyEnum {
78 Translation,
79 Rotation,
80 Scale,
81 Weights,
82}
83
84#[derive(Clone, PartialEq, Eq, Deserialize, IntoOwned)]
87#[serde(transparent)]
88pub struct Property<'a>(#[serde(borrow)] pub Cow<'a, str>);
89
90impl core::fmt::Debug for Property<'_> {
91 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
92 if let Some(e) = self.to_enum() {
93 e.fmt(f)
94 } else {
95 self.0.fmt(f)
96 }
97 }
98}
99
100impl Property<'_> {
101 pub const TRANSLATION: Self = Self(Cow::Borrowed("translation"));
102 pub const ROTATION: Self = Self(Cow::Borrowed("rotation"));
103 pub const SCALE: Self = Self(Cow::Borrowed("scale"));
104 pub const WEIGHTS: Self = Self(Cow::Borrowed("weights"));
105
106 pub fn to_enum(&self) -> Option<PropertyEnum> {
107 if *self == Self::TRANSLATION {
108 return Some(PropertyEnum::Translation);
109 } else if *self == Self::ROTATION {
110 return Some(PropertyEnum::Rotation);
111 } else if *self == Self::SCALE {
112 return Some(PropertyEnum::Scale);
113 } else if *self == Self::WEIGHTS {
114 return Some(PropertyEnum::Weights);
115 }
116
117 None
118 }
119}
120
121#[derive(Debug, Clone, Deserialize, IntoOwned)]
123pub struct ChannelTarget<'a> {
124 pub node: Option<Idx<Node<'static>>>,
126 #[serde(borrow)]
129 pub path: Property<'a>,
130
131 #[serde(borrow)]
132 pub extensions: Option<Extensions<'a>>,
133 #[serde(borrow)]
134 pub extras: Option<Extras<'a>>,
135}
136
137#[derive(Debug, Clone, Deserialize, IntoOwned)]
139pub struct Channel<'a> {
140 pub sampler: Idx<AnimationSampler<'static>>,
142 #[serde(borrow)]
144 pub target: ChannelTarget<'a>,
145
146 #[serde(borrow)]
147 pub extensions: Option<Extensions<'a>>,
148 #[serde(borrow)]
149 pub extras: Option<Extras<'a>>,
150}
151
152#[derive(Debug, Clone, Deserialize, IntoOwned)]
154pub struct Animation<'a> {
155 #[serde(borrow)]
157 pub name: Option<Cow<'a, str>>,
158
159 #[serde(borrow)]
161 pub samplers: Vec<AnimationSampler<'a>>,
162 #[serde(borrow)]
164 pub channels: Vec<Channel<'a>>,
165
166 #[serde(borrow)]
167 pub extensions: Option<Extensions<'a>>,
168 #[serde(borrow)]
169 pub extras: Option<Extras<'a>>,
170}