
    i                    |    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ZddZddZddZ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                Z    t          t          j        | |z
  |z  dz   dd                    S )uD   Smooth step from 0 → 1 around `threshold` with `width` transition.      ?              ?)r   npclip)r   r   r   s      S/dataset/kemix-engine/package/face/animasync-face-v3/scripts/compiler/parametric.py
_soft_gater      s,    !i-5036SAABBB    gammac                r    | dk    r0t          t          j        t          d|           |                    ndS )z4Raise to power only if positive, return 0 otherwise.r   r   )r   r   powermax)r   r   s     r   	_pow_safer#       s1    23a%%5#c1++u--...S@r   vad
np.ndarrayc           	     X
   t          | d                   }t          | d                   }t          | d                   }t          d|          }t          d|           }t          d|          }t          d|           }t          d|          }t          d|           }	t          j        dt          j                  }
dt          |t                    z  t          |d          z  dt          |t                    z  |d	k    rd
ndz  z   }||
d<   ||
d<   dt          |t                    z  dt          |t                    z  d
d|z  z
  z  z   dt          |	t                    z  z   }t          d
|          |
d<   dt          |t                    z  dt          |	t                    z  z   }||
d<   ||
d<   dt          |d          z  t          |d          z  |dk    r|dk     rd
ndz  |
d<   dt          |t                    z  t          |d	          z  }||
d<   ||
d<   dt          |d
          z  }||
d<   ||
d<   d	t          |	t                    z  t          | d          z  }||
d<   ||
d<   dt          |t                    z  t          |d          z  }d	t          |t                    z  }dt          |d
          z  t          |          d	k     rd
ndz  }t          |||          }||
d<   ||
d<   d t          |d!          z  }d	t          |	t                    z  t          |d          z  }t          d
||z             }||
d"<   ||
d#<   d$d%t          |d
          z  |d	k    rd
ndz  z   |
d&<   dt          |t                    z  }||
d'<   ||
d(<   d)t          |t                    z  }||
d*<   ||
d+<   t          d
dt          |t                    z  d	t          |t                    z  |dk    rd
ndz  z             }||
d,<   ||
d-<   dt          |t                    z  d.t          |t                    z  z   }||
d/<   ||
d0<   d1t          |t                    z  }||
d2<   ||
d3<   dt          |t                    z  |d4k     rd
ndz  }dt          |t                    z  }d.t          |t                    z  |d)k    rd
ndz  }t          d
t          ||          |z             } | |
d5<   | |
d6<   t          j        |
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_sneers!                                    r   parametric_layerrj   %   sv    	c!fAc!fAc!fA	S!B	S1"B	S!B	S1"B	S!B	S1"B
(2RZ
(
(
(C
 	yZ(((:a+=+==
2z**
*Q#XXcc3
G	H  CFCF 	yZ(((
2y))
)S38^
<	=
2z**
*	+ 
 m$$CF 9R333dYr9=U=U6UUMCFCF Ib#&&&2s););;CAHH3CF 	y4555
1c8J8JJ  CFCF yS)))ICFCF 9R333j!S6I6IIMCGCG 2y!9!99Jq#<N<NN)B	":"::iC0003q66C<<CCSQ(*>@PQQJCGCG iC0009R333iC6H6HHM3(=89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#XXcc3
G	H K
 CGCG 2y111D9R;S;S4SSKCGCG 2'>???KCGCG )B
333a$hhssCPLIb*555N)B
333a$hhssCPLS#lN;;lJKKJCGCG 73S!!((444r   bsc                p   t          |d                   }t          |d                   }t          |d                   }|                                 }|t          k    r<t          dd|t          z  z
            }|dxx         |z  cc<   |dxx         |z  cc<   nH|t           k    r<t          dd| t          z  z
            }|dxx         |z  cc<   |d	xx         |z  cc<   |t          k    r/t          d|t          z
  d
z            }|dxx         d|z
  z  cc<   n|t          k     r
d|d<   d|d<   |t          k     r#t          d|dz   dt          z   z            }	||	z  }|t          k    rd|t          z
  t          z  z   }
||
z  }t          j        |dd                              t          j                  S )uD   Apply §5.4 conflict resolution rules to a 52-dim blendshape vector.r   r   r'   r   r   r;   r<   rA   rB   r*   )r   copyr
   r"   r   rG   r   r   r   r   r   r   rI   rF   )rk   r$   rJ   rK   rL   rS   frown_scalesmile_scaleblendscaleamps              r   apply_conflict_resolutionrs      s   c!fAc!fAc!fA
''))C 	'''#sQ)D%DDEEB;B;	
**	*	*#sqb,G%GGHHB;B; 	'''C!::cABBA3;	
(	(	(AA 	"""C!c'c,C&CDEEu 	(((Q66:SSSs
73S!!((444r   c                L    |                                  }t          D ]}d||<   |S )z;Zero out LIPSYNC_ONLY channels (compiler doesn't own them).r   )rm   r   )rk   rS   idxs      r   apply_channel_maskrv      s.    
''))C  CJr   )r   )r   r   r   r   r   r   r   r   )r   r   r   r   r   r   )r$   r%   r   r%   )rk   r%   r$   r%   r   r%   )rk   r%   r   r%   )__doc__
__future__r   numpyr   	constantsr   r   r   r   r	   r
   r   r   r   r   r   r   r#   rj   rs   rv    r   r   <module>r|      s3    # " " " " "                             C C C C C
A A A A
F5 F5 F5 F5R$5 $5 $5 $5N     r   