enigma_3d/
animation.rs

1use std::vec::Vec;
2use nalgebra::{Matrix4, Quaternion, UnitQuaternion, Vector3};
3use serde::{Deserialize, Serialize};
4use crate::logging::EnigmaError;
5use crate::smart_format;
6
7pub(crate) const MAX_BONES: usize = 128;
8
9#[derive(Clone)]
10pub struct Bone {
11    pub name: String,
12    pub id: usize,
13    pub parent_id: Option<usize>,
14    pub inverse_bind_pose: Matrix4<f32>
15}
16
17#[derive(Serialize, Deserialize, Clone)]
18pub struct BoneSerializer {
19    pub name: String,
20    pub id: usize,
21    pub parent_id: Option<usize>,
22    pub inverse_bind_pose: [[f32;4];4]
23}
24
25impl Bone {
26    pub fn to_serializer(&self) -> BoneSerializer {
27        BoneSerializer {
28            name: self.name.clone(),
29            id: self.id,
30            parent_id: self.parent_id,
31            inverse_bind_pose: self.inverse_bind_pose.into()
32        }
33    }
34
35    pub fn from_serializer(serializer: BoneSerializer) -> Self{
36        Self {
37            name: serializer.name,
38            id: serializer.id,
39            parent_id: serializer.parent_id,
40            inverse_bind_pose: Matrix4::from(serializer.inverse_bind_pose)
41        }
42    }
43}
44
45#[derive(Clone)]
46pub struct Skeleton {
47    pub bones: Vec<Bone>,
48}
49#[derive(Serialize, Deserialize, Clone)]
50pub struct SkeletonSerializer {
51    pub bones: Vec<BoneSerializer>,
52}
53
54impl Skeleton {
55    pub fn to_serializer(&self) -> SkeletonSerializer {
56        SkeletonSerializer {
57            bones: self.bones.iter().map(|x| x.to_serializer()).collect()
58        }
59    }
60
61    pub fn from_serializer(serializer: SkeletonSerializer) -> Self {
62        let mut bones = Vec::new();
63        for s in serializer.bones {
64            let bone = Bone::from_serializer(s);
65            bones.push(bone);
66        }
67        Self {
68            bones
69        }
70    }
71    pub fn validate(&self) -> Result<(), EnigmaError> {
72        for bone in self.bones.iter() {
73            if let Some(parent_id) = bone.parent_id {
74                if parent_id >= self.bones.len() {
75                    return Err(EnigmaError::new(Some(smart_format!("Invalid parent ID {} for bone {} with id {}. There are only {} bones in the skeleton.", parent_id, bone.name, bone.id, self.bones.len()).as_str()), true))
76                }
77            }
78        }
79        Ok(())
80    }
81
82    pub fn try_fix(&mut self) -> Result<(), EnigmaError> {
83        let len = self.bones.len();
84        for bone in self.bones.iter_mut() {
85            if let Some(parent_id) = bone.parent_id {
86                if parent_id >= len {
87                    bone.parent_id = None;
88                }
89            }
90        }
91        Ok(())
92    }
93}
94
95#[derive(Serialize, Deserialize, Clone)]
96pub enum AnimationTransform {
97    Translation([f32; 3]),
98    Rotation([f32;4]),
99    Scale([f32;3]),
100}
101
102#[derive(Clone)]
103pub struct AnimationKeyframe{
104    pub time: f32,
105    pub transform: AnimationTransform,
106}
107
108impl AnimationKeyframe {
109
110    pub fn to_serializer(&self) -> AnimationKeyframeSerializer {
111        AnimationKeyframeSerializer {
112            time: self.time.clone(),
113            transform: self.transform.clone()
114        }
115    }
116
117    pub fn from_serializer(serializer: AnimationKeyframeSerializer) -> Self {
118        Self {
119            time: serializer.time,
120            transform: serializer.transform
121        }
122    }
123
124    pub fn get_matrix(&self) -> Matrix4<f32> {
125        match &self.transform {
126            AnimationTransform::Translation(translation) => {
127                Matrix4::new_translation(&Vector3::new(translation[0], translation[1], translation[2]))
128            },
129            AnimationTransform::Rotation(quaternion) => {
130                let quat = UnitQuaternion::new_normalize(
131                    Quaternion::new(quaternion[3], quaternion[0], quaternion[1], quaternion[2])
132                );
133                quat.to_homogeneous()
134            },
135            AnimationTransform::Scale(scale) => {
136                Matrix4::new_nonuniform_scaling(&Vector3::new(scale[0], scale[1], scale[2]))
137            }
138        }
139    }
140}
141
142#[derive(Serialize, Deserialize, Clone)]
143pub struct AnimationKeyframeSerializer {
144    pub time: f32,
145    pub transform: AnimationTransform,
146}
147
148#[derive(Clone)]
149pub struct AnimationChannel {
150    pub bone_id: usize,
151    pub keyframes: Vec<AnimationKeyframe>,
152}
153#[derive(Serialize, Deserialize, Clone)]
154pub struct AnimationState {
155    pub name: String,
156    pub time: f32,
157    pub speed: f32,
158    pub looping: bool,
159}
160
161impl AnimationChannel {
162    pub fn to_serializer(&self) -> AnimationChannelSerializer {
163        AnimationChannelSerializer {
164            bone_id: self.bone_id.clone(),
165            keyframes: self.keyframes.iter().map(|x| x.to_serializer()).collect()
166        }
167    }
168
169    pub fn from_serializer(serializer: AnimationChannelSerializer) -> Self {
170        let mut keyframes = Vec::new();
171        for s in serializer.keyframes {
172            let keyframe = AnimationKeyframe::from_serializer(s);
173            keyframes.push(keyframe);
174        }
175        Self {
176            bone_id: serializer.bone_id,
177            keyframes
178        }
179    }
180}
181
182#[derive(Serialize, Deserialize, Clone)]
183pub struct AnimationChannelSerializer {
184    pub bone_id: usize,
185    pub keyframes: Vec<AnimationKeyframeSerializer>,
186}
187
188#[derive(Clone)]
189pub struct Animation {
190    pub name: String,
191    pub duration: f32,
192    pub channels: Vec<AnimationChannel>,
193}
194
195impl Animation {
196    pub fn to_serializer(&self) -> AnimationSerializer {
197        AnimationSerializer {
198            name: self.name.clone(),
199            duration: self.duration.clone(),
200            channels: self.channels.iter().map(|x| x.to_serializer()).collect()
201        }
202    }
203
204    pub fn from_serializer(serializer: AnimationSerializer) -> Self {
205        let mut channels = Vec::new();
206        for s in serializer.channels {
207            let channel = AnimationChannel::from_serializer(s);
208            channels.push(channel);
209        }
210        Self {
211            name: serializer.name,
212            duration: serializer.duration,
213            channels
214        }
215    }
216}
217
218#[derive(Serialize, Deserialize, Clone)]
219pub struct AnimationSerializer {
220    pub name: String,
221    pub duration: f32,
222    pub channels: Vec<AnimationChannelSerializer>,
223}