o
    ॵi                     @   sh   d dl Z d dlZd dlm  mZ dd ZdefddZdefdd	Z	d
d Z
dejdejfddZdS )    Nc                 C   s   t | d\}}}}d| |  d }t d||| ||    ||| ||   ||| ||   ||| ||   d||| ||    ||| ||   ||| ||   ||| ||   d||| ||    f	d}|| jdd d S )z
    Convert rotations given as quaternions to rotation matrices.

    Args:
        quaternions: quaternions with real part first,
            as tensor of shape (..., 4).

    Returns:
        Rotation matrices as tensor of shape (..., 3, 3).
    g       @   N   r   )torchunbindsumstackreshapeshape)quaternionsrijktwo_so r   i/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/utils/cv/motion_utils/rotation_conversions.pyquaternion_to_matrix
   s    r   axisc              	   C   s   t |}t |}t |}t |}| dkr$|||||| |||f	}| dkr4||||||| ||f	}| dkrD|| |||||||f	}t |d|jd S )aM  
    Return the rotation matrices for one of the rotations about an axis
    of which Euler angles describe, for each value of the angle given.

    Args:
        axis: Axis label "X" or "Y or "Z".
        angle: any shape tensor of Euler angles in radians

    Returns:
        Rotation matrices as tensor of shape (..., 3, 3).
    XYZr   r   )r   cossin	ones_like
zeros_liker	   r
   r   )r   angler   r   onezeroR_flatr   r   r   _axis_angle_rotation)   s   



r"   
conventionc                 C   s   |   dks| jd dkrtdt|dkrtd|d |d |d fv r/td| d	|D ]}|d
vr?td| dq1tt|t| d}t	tj
|S )aW  
    Convert rotations given as Euler angles in radians to rotation matrices.

    Args:
        euler_angles: Euler angles in radians as tensor of shape (..., 3).
        convention: Convention string of three uppercase letters from
            {"X", "Y", and "Z"}.

    Returns:
        Rotation matrices as tensor of shape (..., 3, 3).
    r   r   r   zInvalid input euler angles.zConvention must have 3 letters.r      zInvalid convention .)r   r   r   zInvalid letter z in convention string.)dimr   
ValueErrorlenmapr"   r   r   	functoolsreducematmul)euler_anglesr#   lettermatricesr   r   r   euler_angles_to_matrixE   s   
r0   c                 C   s   t t| S )a  
    Convert rotations given as axis/angle to rotation matrices.

    Args:
        axis_angle: Rotations given as a vector in axis angle form,
            as a tensor of shape (..., 3), where the magnitude is
            the angle turned anticlockwise in radians around the
            vector's direction.

    Returns:
        Rotation matrices as tensor of shape (..., 3, 3).
    )r   axis_angle_to_quaternion)
axis_angler   r   r   axis_angle_to_matrix_   s   r3   d6returnc                 C   s|   | dddf | dddf }}t j|dd}||| jddd|  }t j|dd}tj||dd}tj|||fddS )	a  
    Converts 6D rotation representation by Zhou et al. [1] to rotation matrix
    using Gram--Schmidt orthogonalisation per Section B of [1].
    Args:
        d6: 6D rotation representation, of size (*, 6)

    Returns:
        batch of rotation matrices of size (*, 3, 3)

    [1] Zhou, Y., Barnes, C., Lu, J., Yang, J., & Li, H.
    On the Continuity of Rotation Representations in Neural Networks.
    IEEE Conference on Computer Vision and Pattern Recognition, 2019.
    Retrieved from http://arxiv.org/abs/1812.07035
    .Nr   r   )r&   T)keepdim)F	normalizer   r   crossr	   )r4   a1a2b1b2b3r   r   r   rotation_6d_to_matrixo   s   "r@   )r*   r   torch.nn.functionalnn
functionalr8   r   strr"   r0   r3   Tensorr@   r   r   r   r   <module>   s   