o
    i                     @  s   d Z ddlmZ ddlZddlmZmZmZm	Z	m
Z
mZmZmZmZmZmZ ddddZdddZdddZdddZdddZdS ) u  Parametric layer: emotion + VAD → 52 blendshapes via closed-form functions.

Implementation of docs/research/vad-to-arkit-blendshape-mapping.md §4 & §5.

VAD convention: [-1, 1] scale (native anchor convention).
  V⁺ = max(0, V), V⁻ = max(0, -V), same for A, D.
    )annotationsN   )LIPSYNC_ONLYGAMMA_MOUTH_SMILE_FROWN	GAMMA_EYE
GAMMA_BROW
GAMMA_NOSEVALENCE_EXCLUSION_THRESHOLDDOMINANCE_BROW_CONFLICT_HIGHDOMINANCE_BROW_CONFLICT_LOWAROUSAL_VISIBILITY_GATEAROUSAL_EXTREME_AMP_THRESHOLDAROUSAL_EXTREME_AMP_COEFF皙?xfloat	thresholdwidthreturnc                 C  s   t t| | | d ddS )uD   Smooth step from 0 → 1 around `threshold` with `width` transition.      ?              ?)r   npclip)r   r   r    r   S/dataset/kemix-engine/package/face/animasync-face-v3/scripts/compiler/parametric.py
_soft_gate   s   r   gammac                 C  s"   | dkrt ttd| |S dS )z4Raise to power only if positive, return 0 otherwise.r   r   )r   r   powermax)r   r   r   r   r   	_pow_safe    s   "r    vad
np.ndarrayc           !      C  s  t | d }t | d }t | d }td|}td| }td|}td| }td|}td| }	tjdtjd}
dt|t t|d dt|t |d	krRd
nd  }||
d< ||
d< dt|t dt|t d
d|    dt|	t  }t	d
||
d< dt|t dt|	t  }||
d< ||
d< dt|d t|d |dkr|dk rd
nd |
d< dt|t
 t|d	 }||
d< ||
d< dt|d
 }||
d< ||
d< d	t|	t t| d }||
d< ||
d< dt|t t|d }d	t|t }dt|d
 t|d	k r
d
nd }t|||}||
d< ||
d< d t|d! }d	t|	t t|d }t	d
|| }||
d"< ||
d#< d$d%t|d
 |d	krKd
nd  |
d&< dt|t
 }||
d'< ||
d(< d)t|t
 }||
d*< ||
d+< t	d
dt|t d	t|t |dkrd
nd  }||
d,< ||
d-< dt|t d.t|t  }||
d/< ||
d0< d1t|t
 }||
d2< ||
d3< dt|t |d4k rd
nd }dt|t }d.t|t |d)krd
nd }t	d
t||| } | |
d5< | |
d6< t|
dd
tjS )7zCompute 52 blendshape values from VAD via parametric rules.

    vad: np.ndarray shape (3,) in [-1, 1]
    Returns: np.ndarray shape (52,) in [0, 1]
    r   r      r   4   )dtypeg?皙?g333333?r   g?r   g333333?g?gffffff?      r   g       @gٿ   g?      g      ?   	   
            gffffff?g      ?      g{Gz?gQ?         g      ?      #   $   g333333?)   *   g333333?+   ,   g333333ӿ1   2   )r   r   r   zerosfloat32r    r   r   r   minr   absr   r   astype)!r!   VADVpVnApAnDpDnout	brow_downbrow_inner_upbrow_outer_upcheek_squint	eye_blinkeye_look_downeye_squint_duchenneeye_squint_dominanceeye_squint_relax
eye_squinteye_wide_arousaleye_wide_feareye_widemouth_dimplemouth_frownmouth_pressmouth_shrugmouth_smilenose_disgustnose_dominancenose_arousal
nose_sneerr   r   r   parametric_layer%   s   


$(  rf   bsc                 C  sJ  t |d }t |d }t |d }|  }|tkr4tdd|t  }|d  |9  < |d  |9  < n|t krStdd| t  }|d  |9  < |d	  |9  < |tkrktd|t d
 }|d  d| 9  < n|tk rwd|d< d|d< |tk rtd|d dt  }	||	9 }|tkrd|t t	  }
||
9 }t
|ddt
jS )uD   Apply §5.4 conflict resolution rules to a 52-dim blendshape vector.r   r   r#   r   r   r7   r8   r=   r>   r&   )r   copyr	   r   r
   rC   r   r   r   r   r   r   rE   rB   )rg   r!   rF   rG   rH   rO   frown_scalesmile_scaleblendscaleampr   r   r   apply_conflict_resolution   s2   
rn   c                 C  s   |   }tD ]}d||< q|S )z;Zero out LIPSYNC_ONLY channels (compiler doesn't own them).r   )rh   r   )rg   rO   idxr   r   r   apply_channel_mask   s   
rp   )r   )r   r   r   r   r   r   r   r   )r   r   r   r   r   r   )r!   r"   r   r"   )rg   r"   r!   r"   r   r"   )rg   r"   r   r"   )__doc__
__future__r   numpyr   	constantsr   r   r   r   r   r	   r
   r   r   r   r   r   r    rf   rn   rp   r   r   r   r   <module>   s    4

 

'