File size: 1,243 Bytes
2680bd5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import numpy as np
from scipy.spatial.transform import Rotation as R

from ..constant import JOINT_NAME_INDEX_MAP

def axis_angle2matrix(r_in_axis_angle:np.ndarray):
    '''
    r_in_axis_angle: (..., 3)
    return: (..., 3, 3)
    '''
    r = R.from_rotvec(r_in_axis_angle.reshape(-1, 3))
    return r.as_matrix().reshape(r_in_axis_angle.shape[:-1] + (3, 3))

def get_local_coordinate_axis(skeleton_motion:np.ndarray, global_orient:np.ndarray):
    wrist_index = JOINT_NAME_INDEX_MAP['wrist']
    origin = skeleton_motion[:, wrist_index] # (F, 3)
    axis = axis_angle2matrix(global_orient) # (F, 3, 3)
    return axis, origin # (F, 3, 3), (F, 3)

def convert_coordinate(skeleton_motion:np.ndarray, new_axis:np.ndarray | None=None, new_origin:np.ndarray | None=None):
    '''
    skeleton_motion: (F, J, 3)
    new_axis: (F, 3, 3)
    new_origin: (F, 3)
    '''
    if new_origin is not None:
        skeleton_motion = skeleton_motion - new_origin[:, np.newaxis, :] # (F, J, 3)
    if new_axis is not None:
        skeleton_motion = np.matmul(
            np.linalg.inv(new_axis)[:, np.newaxis, :, :], # (F, 1, 3, 3)
            skeleton_motion[:, :, :, np.newaxis] # (F, J, 3, 1)
        ).squeeze(-1) # (F, J, 3)

    return skeleton_motion