
    8j                        S r SSKJr  SSKrSSKJrJrJrJ	r	J
r
JrJrJrJrJrJr  SSS jjrSS jrSS jrSS	 jrSS
 jrg)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_COEFFc                T    [        [        R                  " X-
  U-  S-   SS5      5      $ )uD   Smooth step from 0 → 1 around `threshold` with `width` transition.      ?              ?)floatnpclip)x	thresholdwidths      _/home/ubuntu/service/kemix-engine/package/face/animasync-face-v3/scripts/compiler/parametric.py
_soft_gater      s&    !-5036SABB    c                f    U S:  a*  [        [        R                  " [        SU 5      U5      5      $ S$ )z4Raise to power only if positive, return 0 otherwise.r   r   )r   r   powermax)r   gammas     r   	_pow_safer!       s)    23a%5#c1+u-.@S@r   c           	        [        U S   5      n[        U S   5      n[        U S   5      n[        SU5      n[        SU* 5      n[        SU5      n[        SU* 5      n[        SU5      n[        SU* 5      n	[        R                  " S[        R                  S9n
S[        U[        5      -  [        US5      -  S[        U[        5      -  US	:  a  S
OS-  -   nXS'   XS'   S[        U[        5      -  S[        U[        5      -  S
SU-  -
  -  -   S[        U	[        5      -  -   n[        S
U5      U
S'   S[        U[        5      -  S[        U	[        5      -  -   nXS'   XS'   S[        US5      -  [        US5      -  US:  a  US:  a  S
OS-  U
S'   S[        U[        5      -  [        US	5      -  nXS'   XS'   S[        US
5      -  nXS'   XS'   S	[        U	[        5      -  [        U* S5      -  nUU
S'   UU
S'   S[        U[        5      -  [        US5      -  nS	[        U[        5      -  nS[        US
5      -  [        U5      S	:  a  S
OS-  n[        UUU5      nUU
S'   UU
S'   S [        US!5      -  nS	[        U	[        5      -  [        US5      -  n[        S
UU-   5      nUU
S"'   UU
S#'   S$S%[        US
5      -  US	:  a  S
OS-  -   U
S&'   S[        U[        5      -  nUU
S''   UU
S('   S)[        U[        5      -  nUU
S*'   UU
S+'   [        S
S[        U[        5      -  S	[        U[        5      -  US:  a  S
OS-  -   5      nUU
S,'   UU
S-'   S[        U[        5      -  S.[        U[        5      -  -   nUU
S/'   UU
S0'   S1[        U[        5      -  nUU
S2'   UU
S3'   S[        U[        5      -  US4:  a  S
OS-  nS[        U[        5      -  nS.[        U[        5      -  US):  a  S
OS-  n[        S
[        UU5      U-   5      n U U
S5'   U U
S6'   [        R                  " U
SS
5      R                  [        R                  5      $ )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?      皙?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)!vad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_sneers!                                    r   parametric_layerrh   %   s    	c!fAc!fAc!fA	S!B	S1"B	S!B	S1"B	S!B	S1"B
((2RZZ
(C
 	yZ((:a+==
2z*
*Q#Xc3
G	H  FF 	yZ((
2y)
)S38^
<	=
2z*
*	+ 
 m$CF 9R33dYr9=U6UUMFF Ib#&&2s);;CAH3CF 	y455
1c8JJ  FF yS))IFF 9R33j!S6IIMCGCG 2y!99Jq#<NN)B	"::iC003q6C<CSQ(*>@PQJCGCG iC009R33iC6HHM3(=89HCGCG TIb#..S#cJJCG )B(?@@LCGCG 2'>??KCGCG yZ((
2z*
*Q#Xc3
G	HK
 CGCG 2y11D9R;S4SSKCGCG 2'>??KCGCG )B
33a$hsCPLIb*55N)B
33a$hsCPLS#lN;lJKJCGCG 773S!((44r   c                   [        US   5      n[        US   5      n[        US   5      nU R                  5       nU[        :  a1  [        SSU[        -  -
  5      nUS==   U-  ss'   US==   U-  ss'   O<U[        * ::  a1  [        SSU* [        -  -
  5      nUS==   U-  ss'   US	==   U-  ss'   U[        :  a'  [        SU[        -
  S
-  5      nUS==   SU-
  -  ss'   OU[        :  a
  SUS'   SUS'   U[        :  a  [        SUS-   S[        -   -  5      n	XY-  nU[        :  a  SU[        -
  [        -  -   n
XZ-  n[        R                  " USS5      R                  [        R                  5      $ )uD   Apply §5.4 conflict resolution rules to a 52-dim blendshape vector.r   r   r#   r   r   r8   r9   r>   r?   r&   )r   copyr
   r   r   rD   r   r   r   r   r   r   rF   rC   )bsrG   rH   rI   rJ   rQ   frown_scalesmile_scaleblendscaleamps              r   apply_conflict_resolutionrq      sy   c!fAc!fAc!fA
'')C 	''#sQ)D%DDEB;B;	
**	*#sqb,G%GGHB;B; 	''C!::cABA3;	
(	(AA 	""C!c'c,C&CDE 	((Q66:SSS
773S!((44r   c                H    U R                  5       n[         H  nSX'   M	     U$ )z;Zero out LIPSYNC_ONLY channels (compiler doesn't own them).r   )rj   r   )rk   rQ   idxs      r   apply_channel_maskrt      s#    
'')C Jr   )r)   )r   r   r   r   r   r   returnr   )r   r   r    r   ru   r   )rG   
np.ndarrayru   rv   )rk   rv   rG   rv   ru   rv   )rk   rv   ru   rv   )__doc__
__future__r   numpyr   	constantsr   r   r   r   r	   r
   r   r   r   r   r   r   r!   rh   rq   rt    r   r   <module>r|      sD    #    C
A
F5R$5Nr   