three_d_asset/
animation.rs1use crate::{prelude::*, Interpolation};
2
3#[derive(Debug, Clone, Default)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub struct KeyFrameAnimation {
7 pub name: Option<String>,
11 pub key_frames: Vec<(Mat4, std::sync::Arc<KeyFrames>)>,
13}
14
15impl KeyFrameAnimation {
16 pub fn transformation(&self, time: f32) -> Mat4 {
18 let mut transformation = Mat4::identity();
19 for (t, animation) in self.key_frames.iter() {
20 transformation = transformation * t * animation.transformation(time);
21 }
22 transformation
23 }
24}
25
26#[derive(Debug, Clone, Default)]
30#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31pub struct KeyFrames {
32 pub loop_time: Option<f32>,
34 pub interpolation: Interpolation,
36 pub times: Vec<f32>,
38 pub rotations: Option<Vec<Quat>>,
40 pub translations: Option<Vec<Vec3>>,
42 pub scales: Option<Vec<Vec3>>,
44 pub weights: Option<Vec<Vec<f32>>>,
46}
47
48impl KeyFrames {
49 pub fn rotation(&self, time: f32) -> Option<Quat> {
51 self.rotations
52 .as_ref()
53 .map(|values| self.interpolate_rotation(time, values))
54 }
55 pub fn translation(&self, time: f32) -> Option<Vec3> {
57 self.translations
58 .as_ref()
59 .map(|values| self.interpolate(time, values))
60 }
61 pub fn scale(&self, time: f32) -> Option<Vec3> {
63 self.scales
64 .as_ref()
65 .map(|values| self.interpolate(time, values))
66 }
67
68 pub fn transformation(&self, time: f32) -> Mat4 {
70 let mut transformation = Mat4::identity();
71 if let Some(value) = self.scale(time) {
72 transformation =
73 Mat4::from_nonuniform_scale(value.x, value.y, value.z) * transformation;
74 }
75 if let Some(value) = self.rotation(time) {
76 transformation = transformation * Mat4::from(value);
77 }
78 if let Some(value) = self.translation(time) {
79 transformation = Mat4::from_translation(value) * transformation;
80 }
81 transformation
82 }
83
84 pub fn weights(&self, time: f32) -> Option<Vec<f32>> {
86 self.weights
87 .as_ref()
88 .map(|values| self.interpolate_array(time, values))
89 }
90
91 fn interpolate_rotation(&self, time: f32, values: &[Quat]) -> Quat {
92 let time = self.loop_time.map(|t| time % t).unwrap_or(time);
93 if time < self.times[0] {
94 values[0]
95 } else {
96 for i in 0..self.times.len() - 1 {
97 if self.times[i] <= time && time < self.times[i + 1] {
98 let t = (time - self.times[i]) / (self.times[i + 1] - self.times[i]);
99 return values[i].slerp(values[i + 1], t);
100 }
101 }
102 *values.last().unwrap()
103 }
104 }
105
106 fn interpolate_array(&self, time: f32, values: &[Vec<f32>]) -> Vec<f32> {
107 let time = self.loop_time.map(|t| time % t).unwrap_or(time);
108 if time < self.times[0] {
109 values[0].clone()
110 } else {
111 for i in 0..self.times.len() - 1 {
112 if self.times[i] <= time && time < self.times[i + 1] {
113 let t = (time - self.times[i]) / (self.times[i + 1] - self.times[i]);
114 let mut result = Vec::new();
115 for j in 0..values[i].len() {
116 result.push(values[i][j] * (1.0 - t) + values[i + 1][j] * t);
117 }
118 return result;
119 }
120 }
121 values.last().unwrap().clone()
122 }
123 }
124
125 fn interpolate<T: Copy + std::ops::Mul<f32, Output = T> + std::ops::Add<T, Output = T>>(
126 &self,
127 time: f32,
128 values: &[T],
129 ) -> T {
130 let time = self.loop_time.map(|t| time % t).unwrap_or(time);
131 if time < self.times[0] {
132 values[0]
133 } else {
134 for i in 0..self.times.len() - 1 {
135 if self.times[i] <= time && time < self.times[i + 1] {
136 let t = (time - self.times[i]) / (self.times[i + 1] - self.times[i]);
137 return values[i] * (1.0 - t) + values[i + 1] * t;
138 }
139 }
140 *values.last().unwrap()
141 }
142 }
143}