def transfer_rotation(smplx_model, body_pose, part_rot, part_idx, transfer_type="g2l", result_format="rotmat"): assert transfer_type in ["g2l", "l2g"] assert result_format in ['rotmat', 'aa'] assert type(body_pose) == type(part_rot) return_np = False if isinstance(body_pose, np.ndarray): body_pose = torch.from_numpy(body_pose) return_np = True if isinstance(part_rot, np.ndarray): part_rot = torch.from_numpy(part_rot) return_np = True if body_pose.dim() == 2: # aa assert body_pose.size(0) == 1 and body_pose.size(1) in [66, 72] body_pose_rotmat = gu.angle_axis_to_rotation_matrix( body_pose.view(22, 3)).clone() else: # rotmat assert body_pose.dim() == 4 assert body_pose.size(0) == 1 and body_pose.size(1) in [22, 24] assert body_pose.size(2) == 3 and body_pose.size(3) == 3 body_pose_rotmat = body_pose[0].clone() if part_rot.dim() == 2: # aa assert part_rot.size(0) == 1 and part_rot.size(1) == 3 part_rotmat = gu.angle_axis_to_rotation_matrix(part_rot)[ 0, :3, :3].clone() else: # rotmat assert part_rot.dim() == 3 assert part_rot.size(0) == 1 and part_rot.size( 1) == 3 and part_rot.size(2) == 3 part_rotmat = part_rot[0, :3, :3].clone() kinematic_map = get_kinematic_map(smplx_model, part_idx) part_rot_trans = __transfer_rot(body_pose_rotmat, part_rotmat, kinematic_map, transfer_type) if result_format == 'rotmat': return_value = part_rot_trans else: part_rot_aa = gu.rotation_matrix_to_angle_axis(part_rot_trans) return_value = part_rot_aa if return_np: return_value = return_value.numpy() return return_value
def __transfer_hand_rot(body_pose_mat, hand_rot, kinematic_map, transfer_type): # get global rotmat parent_id = 0 rotmat= body_pose_mat[0] # global orientation of body while parent_id in kinematic_map: child_id = kinematic_map[parent_id] local_rotmat = body_pose_mat[child_id] rotmat = torch.matmul(rotmat, local_rotmat) parent_id = child_id if hand_rot.dim() == 2: # hand rot in angle-axis format assert hand_rot.size(0) == 1 and hand_rot.size(1) == 3 else: # hand rot in rotation matrix format assert hand_rot.dim() == 3 assert hand_rot.size(0) == 1 and hand_rot.size(1) == 3 and hand_rot.size(2) == 3 if hand_rot.dim() == 2: # hand rot in angle-axis format hand_rotmat = gu.angle_axis_to_rotation_matrix(hand_rot)[0,:3,:3] else: # hand rot in rotation matrix format hand_rotmat = hand_rot[0,:3,:3] if transfer_type == 'g2l': hand_rot_new = torch.matmul(rotmat.T, hand_rotmat) else: assert transfer_type == 'l2g' hand_rot_new = torch.matmul(rotmat, hand_rotmat) return hand_rot_new
def get_local_hand_rot(body_pose, hand_rot_global, kinematic_map): hand_rotmat_global = gu.angle_axis_to_rotation_matrix( hand_rot_global.view(1, 3)) body_pose = body_pose.reshape(-1, 3) # the shape is (1,4,4), torch matmul support 3 dimension rotmat = gu.angle_axis_to_rotation_matrix(body_pose[0].view(1, 3)) parent_id = 0 while parent_id in kinematic_map: child_id = kinematic_map[parent_id] local_rotmat = gu.angle_axis_to_rotation_matrix( body_pose[child_id].view(1, 3)) rotmat = torch.matmul(rotmat, local_rotmat) parent_id = child_id hand_rotmat_local = torch.matmul(rotmat.inverse(), hand_rotmat_global) # print("hand_rotmat_local", hand_rotmat_local.size()) hand_rot_local = gu.rotation_matrix_to_angle_axis( hand_rotmat_local[:, :3, :]) return hand_rot_local
def get_global_hand_rot_mat(body_pose_mat, hand_rot_local, kinematic_map): hand_rotmat_local = gu.angle_axis_to_rotation_matrix( hand_rot_local.view(1, 3))[0, :3, :3] rotmat = body_pose_mat[0] #global orientation of body parent_id = 0 while parent_id in kinematic_map: child_id = kinematic_map[parent_id] local_rotmat = body_pose_mat[child_id] rotmat = torch.matmul(rotmat, local_rotmat) parent_id = child_id hand_rot_local_mat = torch.matmul(rotmat.T, hand_rotmat_local) return hand_rot_local_mat