Skip to main content

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