smpl_core/conversions/
pose_chunked.rs1use crate::common::{
2 metadata::SmplMetadata,
3 pose::Pose,
4 pose_parts::PosePart,
5 types::{SmplType, UpAxis},
6};
7use ndarray as nd;
8use ndarray::prelude::*;
9use std::ops::Range;
10#[derive(Debug)]
12pub struct PoseChunked {
13 pub global_trans: nd::Array2<f32>,
14 pub global_orient: Option<nd::Array2<f32>>,
15 pub body_pose: Option<nd::Array2<f32>>,
16 pub left_hand_pose: Option<nd::Array2<f32>>,
17 pub right_hand_pose: Option<nd::Array2<f32>>,
18 pub jaw_pose: Option<nd::Array2<f32>>,
19 pub left_eye_pose: Option<nd::Array2<f32>>,
20 pub right_eye_pose: Option<nd::Array2<f32>>,
21 pub up_axis: UpAxis,
22 pub smpl_type: SmplType,
23}
24impl Default for PoseChunked {
25 fn default() -> Self {
26 let global_trans = ndarray::Array2::<f32>::zeros((1, 3));
27 Self {
28 global_trans,
29 global_orient: None,
30 body_pose: None,
31 left_hand_pose: None,
32 right_hand_pose: None,
33 jaw_pose: None,
34 left_eye_pose: None,
35 right_eye_pose: None,
36 up_axis: UpAxis::Y,
37 smpl_type: SmplType::SmplX,
38 }
39 }
40}
41impl PoseChunked {
42 #[allow(clippy::missing_panics_doc)]
43 pub fn new(pose: &Pose, metadata: &SmplMetadata) -> Self {
44 if pose.smpl_type == SmplType::SmplPP {
45 return Self {
46 global_trans: pose.global_trans.to_shape((1, 3)).unwrap().to_owned(),
47 global_orient: None,
48 body_pose: Some(pose.joint_poses.clone()),
49 left_hand_pose: None,
50 right_hand_pose: None,
51 jaw_pose: None,
52 left_eye_pose: None,
53 right_eye_pose: None,
54 up_axis: pose.up_axis,
55 smpl_type: pose.smpl_type,
56 };
57 }
58 let p2r = &metadata.parts2jointranges;
59 let joint_poses = &pose.joint_poses;
60 let max_range = 0..joint_poses.dim().0;
61 let clamp_closure = |lhs: &Range<usize>, rhs: &Range<usize>| -> Range<usize> {
62 if lhs.end > rhs.end {
63 0..0
64 } else {
65 lhs.clone()
66 }
67 };
68 let global_orient_clamped = clamp_closure(&p2r[PosePart::RootRotation], &max_range);
69 let mut global_orient = Some(joint_poses.slice(s![global_orient_clamped, ..]).to_owned());
70 let body_clamped = clamp_closure(&p2r[PosePart::Body], &max_range);
71 let mut body_pose = Some(joint_poses.slice(s![body_clamped, ..]).to_owned());
72 let left_hand_clamped = clamp_closure(&p2r[PosePart::LeftHand], &max_range);
73 let mut left_hand_pose = Some(joint_poses.slice(s![left_hand_clamped, ..]).to_owned());
74 let right_hand_clamped = clamp_closure(&p2r[PosePart::RightHand], &max_range);
75 let mut right_hand_pose = Some(joint_poses.slice(s![right_hand_clamped, ..]).to_owned());
76 let jaw_clamped = clamp_closure(&p2r[PosePart::Jaw], &max_range);
77 let mut jaw_pose = Some(joint_poses.slice(s![jaw_clamped, ..]).to_owned());
78 let left_eye_clamped = clamp_closure(&p2r[PosePart::LeftEye], &max_range);
79 let mut left_eye_pose = Some(joint_poses.slice(s![left_eye_clamped, ..]).to_owned());
80 let right_eye_clamped = clamp_closure(&p2r[PosePart::RightEye], &max_range);
81 let mut right_eye_pose = Some(joint_poses.slice(s![right_eye_clamped, ..]).to_owned());
82 if global_orient.as_ref().unwrap().dim().0 == 0 {
83 global_orient = None;
84 }
85 if body_pose.as_ref().unwrap().dim().0 == 0 {
86 body_pose = None;
87 }
88 if left_hand_pose.as_ref().unwrap().dim().0 == 0 {
89 left_hand_pose = None;
90 }
91 if right_hand_pose.as_ref().unwrap().dim().0 == 0 {
92 right_hand_pose = None;
93 }
94 if jaw_pose.as_ref().unwrap().dim().0 == 0 {
95 jaw_pose = None;
96 }
97 if left_eye_pose.as_ref().unwrap().dim().0 == 0 {
98 left_eye_pose = None;
99 }
100 if right_eye_pose.as_ref().unwrap().dim().0 == 0 {
101 right_eye_pose = None;
102 }
103 Self {
104 global_trans: pose.global_trans.to_shape((1, 3)).unwrap().to_owned(),
105 global_orient,
106 body_pose,
107 left_hand_pose,
108 right_hand_pose,
109 jaw_pose,
110 left_eye_pose,
111 right_eye_pose,
112 up_axis: pose.up_axis,
113 smpl_type: pose.smpl_type,
114 }
115 }
116 #[allow(clippy::missing_panics_doc)]
117 pub fn to_pose(&self, metadata: &SmplMetadata, smpl_type: SmplType) -> Pose {
118 if smpl_type == SmplType::SmplPP {
119 let zeros = nd::Array2::<f32>::zeros((46, 1));
120 let mut pose = Pose::new_empty(self.up_axis, smpl_type);
121 pose.joint_poses.assign(self.body_pose.as_ref().unwrap_or(&zeros));
122 pose.global_trans.assign(&self.global_trans.to_shape(3).unwrap().to_owned());
123 return pose;
124 }
125 let mut pose = Pose::new_empty(self.up_axis, smpl_type);
126 let zeros = nd::Array2::<f32>::zeros((1, 3));
127 pose.global_trans = self.global_trans.to_shape(3).unwrap().to_owned();
128 pose.joint_poses
129 .slice_mut(s![metadata.parts2jointranges[PosePart::RootRotation].clone(), ..])
130 .assign(self.global_orient.as_ref().unwrap_or(&zeros));
131 pose.joint_poses
132 .slice_mut(s![metadata.parts2jointranges[PosePart::Body].clone(), ..])
133 .assign(self.body_pose.as_ref().unwrap_or(&zeros));
134 pose.joint_poses
135 .slice_mut(s![metadata.parts2jointranges[PosePart::LeftHand].clone(), ..])
136 .assign(self.left_hand_pose.as_ref().unwrap_or(&zeros));
137 pose.joint_poses
138 .slice_mut(s![metadata.parts2jointranges[PosePart::RightHand].clone(), ..])
139 .assign(self.right_hand_pose.as_ref().unwrap_or(&zeros));
140 pose.joint_poses
141 .slice_mut(s![metadata.parts2jointranges[PosePart::Jaw].clone(), ..])
142 .assign(self.jaw_pose.as_ref().unwrap_or(&zeros));
143 pose.joint_poses
144 .slice_mut(s![metadata.parts2jointranges[PosePart::LeftEye].clone(), ..])
145 .assign(self.left_eye_pose.as_ref().unwrap_or(&zeros));
146 pose.joint_poses
147 .slice_mut(s![metadata.parts2jointranges[PosePart::RightEye].clone(), ..])
148 .assign(self.right_eye_pose.as_ref().unwrap_or(&zeros));
149 pose
150 }
151}