1use crate::components::GlossInterop;
2use crate::scene::SceneAnimation;
3use gloss_renderer::network::{FromSerializable, ToSerializable};
4use gloss_utils::bshare::ToNdArray;
5use num_traits::FromPrimitive;
6use serde::{Deserialize, Serialize};
7use smpl_core::common::{
8 animation::{AnimWrap, Animation, AnimationConfig, AnimationRunner},
9 betas::Betas,
10 smpl_params::SmplParams,
11 transform_sequence::TransformSequence,
12 types::{AngleType, FaceType, Gender, SmplType, UpAxis},
13};
14use std::time::Duration;
15#[derive(Clone, Debug, Serialize, Deserialize)]
17pub struct SerializableSmplParams {
18 pub smpl_type: u8,
19 pub gender: u8,
20 pub enable_pose_corrective: bool,
21}
22impl ToSerializable<SerializableSmplParams> for SmplParams {
23 fn to_serializable(&self) -> SerializableSmplParams {
24 SerializableSmplParams {
25 smpl_type: self.smpl_type as u8,
26 gender: self.gender as u8,
27 enable_pose_corrective: self.enable_pose_corrective,
28 }
29 }
30}
31impl FromSerializable<SerializableSmplParams> for SmplParams {
32 fn from_serializable(s: &SerializableSmplParams) -> SmplParams {
33 SmplParams {
34 smpl_type: SmplType::from_u8(s.smpl_type).unwrap(),
35 gender: Gender::from_u8(s.gender).unwrap(),
36 enable_pose_corrective: s.enable_pose_corrective,
37 }
38 }
39}
40#[derive(Clone, Debug, Serialize, Deserialize)]
42pub struct SerializableBetas {
43 pub betas_data: Vec<f32>,
44}
45impl ToSerializable<SerializableBetas> for Betas {
46 fn to_serializable(&self) -> SerializableBetas {
47 let betas_ndarray = self.betas.to_ndarray();
48 SerializableBetas {
49 betas_data: betas_ndarray.to_vec(),
50 }
51 }
52}
53impl FromSerializable<SerializableBetas> for Betas {
54 fn from_serializable(s: &SerializableBetas) -> Betas {
55 Betas::new_from_ndarray(ndarray::Array1::from(s.betas_data.clone()))
56 }
57}
58#[derive(Clone, Debug, Serialize, Deserialize)]
60pub struct SerializableAnimation {
61 pub per_frame_joint_poses_shape: (usize, usize, usize),
62 pub per_frame_joint_poses_data: Vec<f32>,
63 pub per_frame_root_trans_shape: (usize, usize),
64 pub per_frame_root_trans_data: Vec<f32>,
65 pub per_frame_expression_coeffs_shape: Option<(usize, usize)>,
66 pub per_frame_expression_coeffs_data: Option<Vec<f32>>,
67 pub start_offset: usize,
68 pub anim_current_time_nanos: u64,
69 pub anim_reversed: bool,
70 pub nr_repetitions: u32,
71 pub paused: bool,
72 pub temporary_pause: bool,
73 pub fps: f32,
74 pub wrap_behaviour: u8,
75 pub angle_type: u8,
76 pub up_axis: u8,
77 pub smpl_type: u8,
78 pub face_type: u8,
79}
80#[allow(clippy::cast_possible_truncation)]
81impl ToSerializable<SerializableAnimation> for Animation {
82 fn to_serializable(&self) -> SerializableAnimation {
83 let expr_shape_data = if let Some(ref expr) = self.per_frame_expression_coeffs {
84 (Some(expr.dim()), Some(expr.as_slice().unwrap().to_vec()))
85 } else {
86 (None, None)
87 };
88 SerializableAnimation {
89 per_frame_joint_poses_shape: self.per_frame_joint_poses.dim(),
90 per_frame_joint_poses_data: self.per_frame_joint_poses.as_slice().unwrap().to_vec(),
91 per_frame_root_trans_shape: self.per_frame_root_trans.dim(),
92 per_frame_root_trans_data: self.per_frame_root_trans.as_slice().unwrap().to_vec(),
93 per_frame_expression_coeffs_shape: expr_shape_data.0,
94 per_frame_expression_coeffs_data: expr_shape_data.1,
95 start_offset: self.start_offset,
96 anim_current_time_nanos: self.runner.anim_current_time.as_nanos() as u64,
97 anim_reversed: self.runner.anim_reversed,
98 nr_repetitions: self.runner.nr_repetitions,
99 paused: self.runner.paused,
100 temporary_pause: self.runner.temporary_pause,
101 fps: self.config.fps,
102 wrap_behaviour: match self.config.wrap_behaviour {
103 AnimWrap::Clamp => 0,
104 AnimWrap::Loop => 1,
105 AnimWrap::Reverse => 2,
106 },
107 angle_type: match self.config.angle_type {
108 AngleType::AxisAngle => 0,
109 AngleType::Euler => 1,
110 },
111 up_axis: match self.config.up_axis {
112 UpAxis::Y => 0,
113 UpAxis::Z => 1,
114 },
115 smpl_type: self.config.smpl_type as u8,
116 face_type: self.config.face_type as u8,
117 }
118 }
119}
120impl FromSerializable<SerializableAnimation> for Animation {
121 fn from_serializable(s: &SerializableAnimation) -> Animation {
122 use ndarray::Array2;
123 let per_frame_joint_poses = ndarray::Array3::from_shape_vec(s.per_frame_joint_poses_shape, s.per_frame_joint_poses_data.clone()).unwrap();
124 let per_frame_root_trans = Array2::from_shape_vec(s.per_frame_root_trans_shape, s.per_frame_root_trans_data.clone()).unwrap();
125 let per_frame_expression_coeffs =
126 if let (Some(shape), Some(data)) = (&s.per_frame_expression_coeffs_shape, &s.per_frame_expression_coeffs_data) {
127 Some(Array2::from_shape_vec(*shape, data.clone()).unwrap())
128 } else {
129 None
130 };
131 #[allow(clippy::match_same_arms)]
132 let wrap_behaviour = match s.wrap_behaviour {
133 0 => AnimWrap::Clamp,
134 1 => AnimWrap::Loop,
135 2 => AnimWrap::Reverse,
136 _ => AnimWrap::Loop,
137 };
138 #[allow(clippy::match_same_arms)]
139 let angle_type = match s.angle_type {
140 0 => AngleType::AxisAngle,
141 1 => AngleType::Euler,
142 _ => AngleType::AxisAngle,
143 };
144 #[allow(clippy::match_same_arms)]
145 let up_axis = match s.up_axis {
146 0 => UpAxis::Y,
147 1 => UpAxis::Z,
148 _ => UpAxis::Y,
149 };
150 Animation {
151 per_frame_joint_poses,
152 per_frame_root_trans,
153 per_frame_expression_coeffs,
154 start_offset: s.start_offset,
155 runner: AnimationRunner {
156 anim_current_time: Duration::from_nanos(s.anim_current_time_nanos),
157 anim_reversed: s.anim_reversed,
158 nr_repetitions: s.nr_repetitions,
159 paused: s.paused,
160 temporary_pause: s.temporary_pause,
161 },
162 config: AnimationConfig {
163 fps: s.fps,
164 wrap_behaviour,
165 angle_type,
166 up_axis,
167 smpl_type: SmplType::from_u8(s.smpl_type).unwrap_or(SmplType::SmplX),
168 face_type: FaceType::from_u8(s.face_type).unwrap_or(FaceType::SmplX),
169 },
170 }
171 }
172}
173#[derive(Clone, Debug, Serialize, Deserialize)]
175pub struct SerializableGlossInterop {
176 pub with_uv: bool,
177}
178impl ToSerializable<SerializableGlossInterop> for GlossInterop {
179 fn to_serializable(&self) -> SerializableGlossInterop {
180 SerializableGlossInterop { with_uv: self.with_uv }
181 }
182}
183impl FromSerializable<SerializableGlossInterop> for GlossInterop {
184 fn from_serializable(s: &SerializableGlossInterop) -> GlossInterop {
185 GlossInterop { with_uv: s.with_uv }
186 }
187}
188#[derive(Clone, Debug, Serialize, Deserialize)]
190pub struct SerializableSceneAnimation {
191 pub num_frames: usize,
192 pub anim_current_time_nanos: u64,
193 pub anim_reversed: bool,
194 pub nr_repetitions: u32,
195 pub paused: bool,
196 pub temporary_pause: bool,
197 pub fps: f32,
198 pub wrap_behaviour: u8,
199 pub angle_type: u8,
200 pub up_axis: u8,
201 pub smpl_type: u8,
202 pub face_type: u8,
203}
204impl ToSerializable<SerializableSceneAnimation> for SceneAnimation {
205 fn to_serializable(&self) -> SerializableSceneAnimation {
206 #[allow(clippy::cast_possible_truncation)]
207 SerializableSceneAnimation {
208 num_frames: self.num_frames,
209 anim_current_time_nanos: self.runner.anim_current_time.as_nanos() as u64,
210 anim_reversed: self.runner.anim_reversed,
211 nr_repetitions: self.runner.nr_repetitions,
212 paused: self.runner.paused,
213 temporary_pause: self.runner.temporary_pause,
214 fps: self.config.fps,
215 wrap_behaviour: match self.config.wrap_behaviour {
216 AnimWrap::Clamp => 0,
217 AnimWrap::Loop => 1,
218 AnimWrap::Reverse => 2,
219 },
220 angle_type: match self.config.angle_type {
221 AngleType::AxisAngle => 0,
222 AngleType::Euler => 1,
223 },
224 up_axis: match self.config.up_axis {
225 UpAxis::Y => 0,
226 UpAxis::Z => 1,
227 },
228 smpl_type: self.config.smpl_type as u8,
229 face_type: self.config.face_type as u8,
230 }
231 }
232}
233impl FromSerializable<SerializableSceneAnimation> for SceneAnimation {
234 fn from_serializable(s: &SerializableSceneAnimation) -> SceneAnimation {
235 #[allow(clippy::match_same_arms)]
236 let wrap_behaviour = match s.wrap_behaviour {
237 0 => AnimWrap::Clamp,
238 1 => AnimWrap::Loop,
239 2 => AnimWrap::Reverse,
240 _ => AnimWrap::Loop,
241 };
242 #[allow(clippy::match_same_arms)]
243 let angle_type = match s.angle_type {
244 0 => AngleType::AxisAngle,
245 1 => AngleType::Euler,
246 _ => AngleType::AxisAngle,
247 };
248 #[allow(clippy::match_same_arms)]
249 let up_axis = match s.up_axis {
250 0 => UpAxis::Y,
251 1 => UpAxis::Z,
252 _ => UpAxis::Y,
253 };
254 SceneAnimation {
255 num_frames: s.num_frames,
256 runner: AnimationRunner {
257 anim_current_time: std::time::Duration::from_nanos(s.anim_current_time_nanos),
258 anim_reversed: s.anim_reversed,
259 nr_repetitions: s.nr_repetitions,
260 paused: s.paused,
261 temporary_pause: s.temporary_pause,
262 },
263 config: AnimationConfig {
264 fps: s.fps,
265 wrap_behaviour,
266 angle_type,
267 up_axis,
268 smpl_type: SmplType::from_u8(s.smpl_type).unwrap_or(SmplType::SmplX),
269 face_type: FaceType::from_u8(s.face_type).unwrap_or(FaceType::SmplX),
270 },
271 }
272 }
273}
274#[derive(Clone, Debug, Serialize, Deserialize)]
276pub struct SerializableTransformSequence {
277 pub translations_shape: (usize, usize),
278 pub translations_data: Vec<f32>,
279 pub rotations_shape: (usize, usize),
280 pub rotations_data: Vec<f32>,
281 pub scales_shape: usize,
282 pub scales_data: Vec<f32>,
283}
284impl ToSerializable<SerializableTransformSequence> for TransformSequence {
285 fn to_serializable(&self) -> SerializableTransformSequence {
286 SerializableTransformSequence {
287 translations_shape: self.translations.dim(),
288 translations_data: self.translations.as_slice().unwrap().to_vec(),
289 rotations_shape: self.rotations.dim(),
290 rotations_data: self.rotations.as_slice().unwrap().to_vec(),
291 scales_shape: self.scales.len(),
292 scales_data: self.scales.as_slice().unwrap().to_vec(),
293 }
294 }
295}
296impl FromSerializable<SerializableTransformSequence> for TransformSequence {
297 fn from_serializable(s: &SerializableTransformSequence) -> TransformSequence {
298 TransformSequence {
299 translations: ndarray::Array2::from_shape_vec(s.translations_shape, s.translations_data.clone()).unwrap(),
300 rotations: ndarray::Array2::from_shape_vec(s.rotations_shape, s.rotations_data.clone()).unwrap(),
301 scales: ndarray::Array1::from(s.scales_data.clone()),
302 }
303 }
304}
305gloss_renderer::impl_network_sendable_and_receivable!(
306 SerializableSmplParams,
307 SerializableBetas,
308 SerializableAnimation,
309 SerializableGlossInterop,
310 SerializableSceneAnimation,
311 SerializableTransformSequence,
312);