@vincentt-xr/sdk 2.0.0-alpha.8 → 2.0.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (517) hide show
  1. package/GROUNDING.md +4643 -170
  2. package/README.md +1 -0
  3. package/dist/CanonicalHeadFrame-BHcWyaiK.js +1506 -0
  4. package/dist/CanonicalHeadFrame-D-_T1OMU.cjs +1 -0
  5. package/dist/DebuggerUI-7ngnJsBe.js +275 -0
  6. package/dist/DebuggerUI-CoglgKdO.cjs +1 -0
  7. package/dist/FaceRetouch-CLoTfrcs.js +1071 -0
  8. package/dist/FaceRetouch-J1lC1WbS.cjs +134 -0
  9. package/dist/FaceSurface-CHAMEeG1.cjs +1 -0
  10. package/dist/FaceSurface-DmP9AEeC.js +27 -0
  11. package/dist/SegmentationOverlay-D_FWkcyP.cjs +35 -0
  12. package/dist/SegmentationOverlay-vn5x_knv.js +6237 -0
  13. package/dist/SkeletonUtils-C2r90MtN.js +21 -0
  14. package/dist/SkeletonUtils-CddIup1F.cjs +1 -0
  15. package/dist/TextLabel-XE0rQSDn.cjs +2 -0
  16. package/dist/TextLabel-c9BCucOI.js +961 -0
  17. package/dist/assets/gltfLoader.d.ts +16 -0
  18. package/dist/assets/loaders.d.ts +16 -1
  19. package/dist/body-pose/index.d.ts +521 -0
  20. package/dist/body-trigger/__fixtures__/syntheticBody.d.ts +83 -0
  21. package/dist/body-trigger/frame.d.ts +88 -0
  22. package/dist/body-trigger/index.d.ts +6 -0
  23. package/dist/body-trigger/moves.d.ts +235 -0
  24. package/dist/body-trigger/trigger.d.ts +75 -0
  25. package/dist/calibration/calibration.d.ts +11 -6
  26. package/dist/canonicalFace-BHwyCx1c.js +9 -0
  27. package/dist/canonicalFace-C83I225R.cjs +1 -0
  28. package/dist/components/BodyInstruction/BodyPoseHint.d.ts +63 -0
  29. package/dist/components/BodyInstruction/index.d.ts +69 -0
  30. package/dist/components/BodyInstruction/useBodyPose.d.ts +23 -0
  31. package/dist/components/BodyTracker/index.d.ts +10 -2
  32. package/dist/components/BodyTrigger/index.d.ts +49 -0
  33. package/dist/components/Debugger/DebuggerProvider.d.ts +14 -1
  34. package/dist/components/Debugger/DebuggerUI.d.ts +3 -1
  35. package/dist/components/FaceAtlas/FaceAtlasLayer.d.ts +114 -0
  36. package/dist/components/FaceAtlas/MadeUpCamera.d.ts +80 -0
  37. package/dist/components/FaceAtlas/constants.d.ts +8 -0
  38. package/dist/components/FaceAtlas/index.d.ts +7 -0
  39. package/dist/components/FaceAtlas/useFaceAtlasSurface.d.ts +84 -0
  40. package/dist/components/FaceAtlas/useFaceSkin.d.ts +84 -0
  41. package/dist/components/FaceCharacter/ExternalFaceMesh.d.ts +109 -0
  42. package/dist/components/FaceCharacter/FaceExpressionController.d.ts +53 -0
  43. package/dist/components/FaceCharacter/FaceMorph.d.ts +71 -0
  44. package/dist/components/FaceCharacter/FacePiercing.d.ts +65 -0
  45. package/dist/components/FaceCharacter/FaceReprojection.d.ts +85 -0
  46. package/dist/components/FaceCharacter/FaceRig.d.ts +38 -0
  47. package/dist/components/FaceCharacter/FaceSurface.d.ts +49 -0
  48. package/dist/components/FaceCharacter/FaceSurfaceOccluder.d.ts +39 -0
  49. package/dist/components/FaceCharacter/PinToFaceMesh.d.ts +68 -0
  50. package/dist/components/FaceCharacter/index.d.ts +18 -0
  51. package/dist/components/FaceCharacter/useFaceReprojector.d.ts +10 -0
  52. package/dist/components/FaceInset/FaceInset.d.ts +68 -0
  53. package/dist/components/FaceInset/frame.d.ts +94 -0
  54. package/dist/components/FaceInset/index.d.ts +6 -0
  55. package/dist/components/FaceInset/material.d.ts +40 -0
  56. package/dist/components/FaceInset/useFaceInsetTexture.d.ts +37 -0
  57. package/dist/components/FaceInstruction/FaceExpressionHint.d.ts +43 -0
  58. package/dist/components/FaceInstruction/index.d.ts +56 -0
  59. package/dist/components/FaceInstruction/useFaceExpression.d.ts +20 -0
  60. package/dist/components/FaceLiquify/FaceLiquify.d.ts +49 -0
  61. package/dist/components/FaceLiquify/debug.d.ts +37 -0
  62. package/dist/components/FaceLiquify/frame.d.ts +55 -0
  63. package/dist/components/FaceLiquify/index.d.ts +10 -0
  64. package/dist/components/FaceLiquify/material.d.ts +39 -0
  65. package/dist/components/FaceLiquify/pass.d.ts +49 -0
  66. package/dist/components/FaceLiquify/presence.d.ts +25 -0
  67. package/dist/components/FaceLiquify/presets.d.ts +82 -0
  68. package/dist/components/FaceLiquify/selfTest.d.ts +66 -0
  69. package/dist/components/FaceLiquify/target.d.ts +85 -0
  70. package/dist/components/FaceLiquify/warp.d.ts +72 -0
  71. package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +5 -3
  72. package/dist/components/FaceMesh/canonical/geometryGroups.d.ts +21 -0
  73. package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +9 -0
  74. package/dist/components/FaceMesh/index.d.ts +1 -1
  75. package/dist/components/FaceRetouch/Background.d.ts +3 -1
  76. package/dist/components/FaceRetouch/FaceRetouch.d.ts +5 -0
  77. package/dist/components/FaceRetouch/renderState.d.ts +19 -0
  78. package/dist/components/FaceSwap/FaceMirror.d.ts +46 -0
  79. package/dist/components/FaceSwap/FaceSwap.d.ts +58 -0
  80. package/dist/components/FaceSwap/FaceTextureLayer.d.ts +72 -0
  81. package/dist/components/FaceSwap/faceSwapPlan.d.ts +91 -0
  82. package/dist/components/FaceSwap/index.d.ts +13 -0
  83. package/dist/components/FaceSwap/settings.d.ts +300 -0
  84. package/dist/components/FaceSwap/useFaceTexture.d.ts +35 -0
  85. package/dist/components/FaceSwap/useLiveFace.d.ts +38 -0
  86. package/dist/components/FaceSwap/useLiveFaceTexture.d.ts +31 -0
  87. package/dist/components/FaceWarp3D/FaceWarp3D.d.ts +50 -0
  88. package/dist/components/FaceWarp3D/index.d.ts +2 -3
  89. package/dist/components/Faceless/Faceless.d.ts +51 -0
  90. package/dist/components/Faceless/index.d.ts +2 -0
  91. package/dist/components/HairLock/HairLock.d.ts +39 -0
  92. package/dist/components/HairLock/index.d.ts +2 -0
  93. package/dist/components/HairLock/lockGeometry.d.ts +15 -0
  94. package/dist/components/HandCutout/index.d.ts +35 -0
  95. package/dist/components/HandInstruction/HandGestureHint.d.ts +70 -0
  96. package/dist/components/HandInstruction/index.d.ts +74 -0
  97. package/dist/components/HandInstruction/useHandGesture.d.ts +22 -0
  98. package/dist/components/HandRig/ForearmOccluder.d.ts +29 -0
  99. package/dist/components/HandRig/HandAttachment.d.ts +34 -0
  100. package/dist/components/HandRig/HandOccluder.d.ts +55 -0
  101. package/dist/components/HandRig/HandTattoo.d.ts +61 -0
  102. package/dist/components/HandRig/WristAttachment.d.ts +34 -0
  103. package/dist/components/HandRig/index.d.ts +101 -0
  104. package/dist/components/HandRig/useArmMask.d.ts +29 -0
  105. package/dist/components/HandRig/wristSolve.d.ts +69 -0
  106. package/dist/components/HandTouch/HandTouch.d.ts +62 -0
  107. package/dist/components/HandTouch/Touchable.d.ts +36 -0
  108. package/dist/components/HandTouch/index.d.ts +2 -0
  109. package/dist/components/HeadBinding/index.d.ts +14 -0
  110. package/dist/components/HeadOccluder/CanonicalHeadFrame.d.ts +22 -0
  111. package/dist/components/HeadOccluder/Earrings.d.ts +55 -0
  112. package/dist/components/HeadOccluder/HeadAttachment.d.ts +38 -0
  113. package/dist/components/HeadOccluder/NeckOccluder.d.ts +64 -0
  114. package/dist/components/HeadOccluder/earringPlacement.d.ts +31 -0
  115. package/dist/components/HeadOccluder/headAttachmentPoints.d.ts +69 -0
  116. package/dist/components/HeadOccluder/index.d.ts +57 -3
  117. package/dist/components/HeadOccluder/useCanonicalHeadFit.d.ts +36 -0
  118. package/dist/components/HeadOccluder/useLandmarkPoseFit.d.ts +80 -0
  119. package/dist/components/Instruction/HintStage.d.ts +29 -0
  120. package/dist/components/Instruction/InstructionCue.d.ts +126 -0
  121. package/dist/components/Instruction/gestureHold.d.ts +20 -0
  122. package/dist/components/Instruction/ghost.d.ts +129 -0
  123. package/dist/components/Instruction/hintBlend.d.ts +19 -0
  124. package/dist/components/Instruction/hintLook.d.ts +81 -0
  125. package/dist/components/Instruction/hintLoop.d.ts +36 -0
  126. package/dist/components/Instruction/index.d.ts +41 -0
  127. package/dist/components/Instruction/useGhostModel.d.ts +33 -0
  128. package/dist/components/Instruction/useInstructionHold.d.ts +72 -0
  129. package/dist/components/LipEffect/LipEffect.d.ts +22 -2
  130. package/dist/components/LipEffect/LipEffectMaterial.d.ts +62 -10
  131. package/dist/components/LipEffect/LipEffects.d.ts +5 -2
  132. package/dist/components/LipEffect/defaults.d.ts +21 -2
  133. package/dist/components/LipEffect/index.d.ts +1 -1
  134. package/dist/components/LipEffect/lipShading.d.ts +73 -0
  135. package/dist/components/LipEffect/settings.d.ts +117 -13
  136. package/dist/components/LipEffect/shader.d.ts +39 -0
  137. package/dist/components/LipEffect/types.d.ts +82 -10
  138. package/dist/components/LipEffect/useLipDesignTextures.d.ts +6 -0
  139. package/dist/components/LipEffect/uvGuide.d.ts +31 -16
  140. package/dist/components/Makeup/Blush.d.ts +18 -0
  141. package/dist/components/Makeup/Brows.d.ts +20 -0
  142. package/dist/components/Makeup/Contour.d.ts +17 -0
  143. package/dist/components/Makeup/Eyeliner.d.ts +20 -0
  144. package/dist/components/Makeup/Eyeshadow.d.ts +20 -0
  145. package/dist/components/Makeup/Highlighter.d.ts +18 -0
  146. package/dist/components/Makeup/MakeupDesign.d.ts +37 -0
  147. package/dist/components/Makeup/MakeupRegion.d.ts +132 -0
  148. package/dist/components/Makeup/constants.d.ts +44 -0
  149. package/dist/components/Makeup/design.d.ts +106 -0
  150. package/dist/components/Makeup/designSamples.d.ts +42 -0
  151. package/dist/components/Makeup/eyes.d.ts +114 -0
  152. package/dist/components/Makeup/fields.d.ts +10 -0
  153. package/dist/components/Makeup/geometry.d.ts +106 -0
  154. package/dist/components/Makeup/index.d.ts +26 -0
  155. package/dist/components/Makeup/looks.d.ts +28 -0
  156. package/dist/components/Makeup/material.d.ts +239 -0
  157. package/dist/components/Makeup/settings.d.ts +54 -0
  158. package/dist/components/Makeup/shades.d.ts +143 -0
  159. package/dist/components/Makeup/shapes.d.ts +27 -0
  160. package/dist/components/Makeup/skinTone.d.ts +135 -0
  161. package/dist/components/Makeup/types.d.ts +110 -0
  162. package/dist/components/Makeup/useMakeupSkinTone.d.ts +40 -0
  163. package/dist/components/Necklace/Necklace.d.ts +44 -0
  164. package/dist/components/Necklace/index.d.ts +1 -0
  165. package/dist/components/ParticleEmitter/ParticleEmitter.d.ts +69 -0
  166. package/dist/components/ParticleEmitter/index.d.ts +1 -0
  167. package/dist/components/ShoulderOccluder/index.d.ts +43 -0
  168. package/dist/components/ShoulderOccluder/useCanonicalTorsoFit.d.ts +24 -0
  169. package/dist/components/SpringSwing/SpringSwing.d.ts +22 -0
  170. package/dist/components/SpringSwing/index.d.ts +1 -0
  171. package/dist/components/XRScene/renderOutputTarget.d.ts +12 -0
  172. package/dist/components/index.d.ts +8 -0
  173. package/dist/config/index.d.ts +0 -1
  174. package/dist/context-DTxSQvp4.js +13 -0
  175. package/dist/context-hA0Rb2Xa.cjs +1 -0
  176. package/dist/contexts-BH7PdKFS.cjs +1 -0
  177. package/dist/contexts-jak8-tND.js +667 -0
  178. package/dist/coordinates/index.d.ts +2 -0
  179. package/dist/coordinates/side.d.ts +40 -0
  180. package/dist/debug-ui/default-setting.cjs +2 -2
  181. package/dist/debug-ui/face-swap-settings/index.d.ts +22 -0
  182. package/dist/debug-ui/hierarchy-panel/index.d.ts +3 -2
  183. package/dist/debug-ui/index.d.ts +4 -3
  184. package/dist/debug-ui/media-source/index.d.ts +1 -1
  185. package/dist/debug-ui/media-source/session.d.ts +30 -2
  186. package/dist/debug-ui/media-source.cjs +1 -1
  187. package/dist/debug-ui/media-source.js +1 -1
  188. package/dist/debug-ui/object-inspector-panel/index.d.ts +3 -2
  189. package/dist/debug-ui/product-hotspots/index.d.ts +3 -2
  190. package/dist/debug-ui/scene-editor/hierarchy-panel.d.ts +3 -1
  191. package/dist/debug-ui/scene-editor/inspector-panel.d.ts +3 -1
  192. package/dist/debug-ui/screen-image-settings/index.d.ts +3 -1
  193. package/dist/debug-ui/screen-text-settings/ScreenTextSettingsPanel.d.ts +1 -1
  194. package/dist/debug-ui/screen-text-settings/types.d.ts +2 -0
  195. package/dist/debug-ui/settings-panel/index.d.ts +6 -1
  196. package/dist/debug-ui/shared/debugWindow.d.ts +51 -0
  197. package/dist/debug-ui/xr-diagnostics/index.d.ts +3 -2
  198. package/dist/debug-ui.cjs +3 -3
  199. package/dist/debug-ui.js +2250 -2472
  200. package/dist/entries/all.d.ts +3 -1
  201. package/dist/entries/core.d.ts +3 -2
  202. package/dist/entries/face-effects.d.ts +114 -8
  203. package/dist/entries/instructions.d.ts +48 -0
  204. package/dist/entries/internal.d.ts +2 -1
  205. package/dist/entries/low-level.d.ts +28 -1
  206. package/dist/entries/particles.d.ts +11 -0
  207. package/dist/entries/tracking.d.ts +37 -2
  208. package/dist/face-atlas/attributes.d.ts +30 -0
  209. package/dist/face-atlas/eyes.d.ts +272 -0
  210. package/dist/face-atlas/faceAtlas.generated.d.ts +46 -0
  211. package/dist/face-atlas/glsl/atlasVertex.d.ts +46 -0
  212. package/dist/face-atlas/glsl/common.d.ts +55 -0
  213. package/dist/face-atlas/glsl/design.d.ts +49 -0
  214. package/dist/face-atlas/glsl/eyes.d.ts +73 -0
  215. package/dist/face-atlas/glsl/finish.d.ts +24 -0
  216. package/dist/face-atlas/glsl/format.d.ts +4 -0
  217. package/dist/face-atlas/glsl/index.d.ts +59 -0
  218. package/dist/face-atlas/glsl/shading.d.ts +15 -0
  219. package/dist/face-atlas/glsl/shapes.d.ts +66 -0
  220. package/dist/face-atlas/glsl/sparkle.d.ts +19 -0
  221. package/dist/face-atlas/glsl/uniforms.d.ts +106 -0
  222. package/dist/face-atlas/guide.d.ts +51 -0
  223. package/dist/face-atlas/index.d.ts +25 -0
  224. package/dist/face-atlas/lead.d.ts +117 -0
  225. package/dist/face-atlas/madeUpCamera.d.ts +125 -0
  226. package/dist/face-atlas/masks.d.ts +53 -0
  227. package/dist/face-atlas/obj.d.ts +69 -0
  228. package/dist/face-atlas/polylines.d.ts +63 -0
  229. package/dist/face-atlas/probe/FaceSkinProbe.d.ts +208 -0
  230. package/dist/face-atlas/probe/__fixtures__/emulate.d.ts +9 -0
  231. package/dist/face-atlas/probe/__fixtures__/face.d.ts +24 -0
  232. package/dist/face-atlas/probe/constants.d.ts +137 -0
  233. package/dist/face-atlas/probe/glsl.d.ts +43 -0
  234. package/dist/face-atlas/probe/lightFit.d.ts +108 -0
  235. package/dist/face-atlas/probe/schedule.d.ts +44 -0
  236. package/dist/face-atlas/probe/selfTest.d.ts +87 -0
  237. package/dist/face-atlas/probe/stats.d.ts +143 -0
  238. package/dist/face-atlas/probe/targets.d.ts +70 -0
  239. package/dist/face-atlas/probe/unwrap.d.ts +76 -0
  240. package/dist/face-atlas/quality.d.ts +28 -0
  241. package/dist/face-atlas/regions.d.ts +31 -0
  242. package/dist/face-atlas/registry.d.ts +252 -0
  243. package/dist/face-atlas/renderState.d.ts +86 -0
  244. package/dist/face-atlas/selfOcclusion.d.ts +62 -0
  245. package/dist/face-atlas/shading.d.ts +406 -0
  246. package/dist/face-atlas/shapes.d.ts +86 -0
  247. package/dist/face-atlas/sides.d.ts +41 -0
  248. package/dist/face-atlas/skinMask.d.ts +35 -0
  249. package/dist/face-atlas/surface.d.ts +155 -0
  250. package/dist/face-atlas/topology.d.ts +44 -0
  251. package/dist/face-character/__fixtures__/faceImageDetections.d.ts +25 -0
  252. package/dist/face-character/__fixtures__/faceNode.d.ts +22 -0
  253. package/dist/face-character/bindFaceModel.d.ts +106 -0
  254. package/dist/face-character/canonicalFace.d.ts +17 -0
  255. package/dist/face-character/canonicalFaceGeometry.d.ts +11 -0
  256. package/dist/face-character/canonicalFacePositions.d.ts +7 -0
  257. package/dist/face-character/driveFaceModel.d.ts +57 -0
  258. package/dist/face-character/expressionOutputs.d.ts +45 -0
  259. package/dist/face-character/faceExpressions.d.ts +104 -0
  260. package/dist/face-character/faceImageLandmarker.d.ts +93 -0
  261. package/dist/face-character/faceMeshBinding.d.ts +62 -0
  262. package/dist/face-character/faceMorph.d.ts +77 -0
  263. package/dist/face-character/faceMorphs.d.ts +46 -0
  264. package/dist/face-character/facePhoto.d.ts +138 -0
  265. package/dist/face-character/facePiercings.d.ts +116 -0
  266. package/dist/face-character/facePin.d.ts +131 -0
  267. package/dist/face-character/faceReprojection.d.ts +273 -0
  268. package/dist/face-character/faceReprojector.d.ts +171 -0
  269. package/dist/face-character/faceRig.d.ts +176 -0
  270. package/dist/face-character/faceSwapPresence.d.ts +85 -0
  271. package/dist/face-character/faceTexture.d.ts +169 -0
  272. package/dist/face-character/faceTextureBaker.d.ts +86 -0
  273. package/dist/face-character/faceTextureGuide.d.ts +106 -0
  274. package/dist/face-character/faceTextureStats.d.ts +298 -0
  275. package/dist/face-character/faceTransfer.d.ts +396 -0
  276. package/dist/face-character/faceTransferGeometry.d.ts +109 -0
  277. package/dist/face-character/faceTransferSelfTest.d.ts +94 -0
  278. package/dist/face-character/faceWarp3D.d.ts +101 -0
  279. package/dist/face-character/faceless.d.ts +79 -0
  280. package/dist/face-character/featureWarp.d.ts +28 -0
  281. package/dist/face-character/liveFaceRegistry.d.ts +370 -0
  282. package/dist/face-character/liveValue.d.ts +12 -0
  283. package/dist/face-character/memo.d.ts +15 -0
  284. package/dist/face-effects.cjs +2252 -83
  285. package/dist/face-effects.js +14234 -1231
  286. package/dist/face-expression/index.d.ts +182 -0
  287. package/dist/face-info/landmarks.d.ts +17 -3
  288. package/dist/face-info/types.d.ts +20 -3
  289. package/dist/gestures/definitions.d.ts +15 -2
  290. package/dist/gestures/index.d.ts +1 -1
  291. package/dist/gestures/measures.d.ts +21 -8
  292. package/dist/getFaceInfo-B1otSDMX.cjs +1 -0
  293. package/dist/getFaceInfo-Cu4xDWiL.js +62 -0
  294. package/dist/hand/armFit.d.ts +46 -0
  295. package/dist/hand/armMask.d.ts +178 -0
  296. package/dist/hand/handCutout.d.ts +23 -0
  297. package/dist/hand/handCutoutRegistry.d.ts +7 -0
  298. package/dist/hand/handGestures.d.ts +524 -0
  299. package/dist/hand/handPose.d.ts +98 -0
  300. package/dist/hand/handRigSolver.d.ts +159 -0
  301. package/dist/hand/handTattoo.d.ts +81 -0
  302. package/dist/hand/handTouch.d.ts +240 -0
  303. package/dist/hand/wrist.d.ts +44 -0
  304. package/dist/hand/wristFilter.d.ts +44 -0
  305. package/dist/hooks/selectors.d.ts +8 -0
  306. package/dist/hooks/useFaceModelAcquisition.d.ts +38 -0
  307. package/dist/hooks/useTrackerContext.d.ts +6 -0
  308. package/dist/index-B1_TzJaI.js +1104 -0
  309. package/dist/index-BavF06C6.js +190 -0
  310. package/dist/index-BfFmpddl.cjs +21 -0
  311. package/dist/index-BuBzneeW.cjs +46 -0
  312. package/dist/index-CGsQWodV.cjs +1 -0
  313. package/dist/index-CIe7eCMH.js +3200 -0
  314. package/dist/index-CfSF8LXa.cjs +1 -0
  315. package/dist/index-D5GTzOzD.cjs +1 -0
  316. package/dist/index-DBhQzvVa.js +314 -0
  317. package/dist/index-DE17y0ZI.cjs +1 -0
  318. package/dist/index-JII7huPk.js +442 -0
  319. package/dist/index-tpCr9CLj.cjs +1 -0
  320. package/dist/{renderPasses-NnKZVfBy.js → index-w1S7fI2B.js} +219 -247
  321. package/dist/index-zGaqrz_K.js +188 -0
  322. package/dist/instructions.cjs +30 -0
  323. package/dist/instructions.js +1507 -0
  324. package/dist/{internal-vsfNQycj.js → internal-B90P-clC.js} +138 -118
  325. package/dist/internal-Cjinca64.cjs +1 -0
  326. package/dist/internal.cjs +1 -1
  327. package/dist/internal.js +15 -10
  328. package/dist/iris/compute.d.ts +7 -5
  329. package/dist/iris/types.d.ts +6 -4
  330. package/dist/{landmarkMask-CbTFzBYG.js → landmarkMask-BFDyBnKM.js} +6 -6
  331. package/dist/landmarks-BlUqf5MZ.cjs +1 -0
  332. package/dist/landmarks-bftdwq6Z.js +76 -0
  333. package/dist/loaders-BGAUACsd.js +363 -0
  334. package/dist/loaders-BJ1_QCHt.cjs +1 -0
  335. package/dist/low-level.cjs +1 -1
  336. package/dist/low-level.js +666 -602
  337. package/dist/main.cjs +1 -1
  338. package/dist/main.js +866 -1182
  339. package/dist/models/Body/index.d.ts +2 -0
  340. package/dist/models/Face/constants.d.ts +8 -0
  341. package/dist/models/Face/index.d.ts +3 -11
  342. package/dist/models/Face/rotation.d.ts +18 -3
  343. package/dist/models/Hand/HandTracking.d.ts +17 -1
  344. package/dist/models/Segmentation/index.d.ts +2 -0
  345. package/dist/models/nodeSource.d.ts +9 -0
  346. package/dist/particles/emission.d.ts +24 -0
  347. package/dist/particles/eyes.d.ts +24 -0
  348. package/dist/particles/glsl.d.ts +14 -0
  349. package/dist/particles/index.d.ts +10 -0
  350. package/dist/particles/motion.d.ts +42 -0
  351. package/dist/particles/presets.d.ts +12 -0
  352. package/dist/particles/ring.d.ts +58 -0
  353. package/dist/particles/selfTest.d.ts +53 -0
  354. package/dist/particles/settings.d.ts +127 -0
  355. package/dist/particles/shapes.d.ts +29 -0
  356. package/dist/particles/spawner.d.ts +60 -0
  357. package/dist/particles/system.d.ts +64 -0
  358. package/dist/particles.cjs +122 -0
  359. package/dist/particles.js +774 -0
  360. package/dist/product.cjs +1 -1
  361. package/dist/product.js +29 -29
  362. package/dist/{providers-C0Dlhh9Z.js → providers-C8rE26Uf.js} +127 -126
  363. package/dist/providers-DHsrhDI2.cjs +62 -0
  364. package/dist/render/renderPasses.d.ts +8 -0
  365. package/dist/render/sceneBeforeRender.d.ts +12 -0
  366. package/dist/{renderGroups-CN1cGFUo.js → renderGroups-B38pUaX2.js} +1 -1
  367. package/dist/{renderGroups-O4KmaMl9.cjs → renderGroups-Cb_4Ar1Q.cjs} +1 -1
  368. package/dist/renderPasses-B6l8IpJv.js +1290 -0
  369. package/dist/renderPasses-dqmkft4P.cjs +158 -0
  370. package/dist/renderState-CJNmj5jz.js +39 -0
  371. package/dist/renderState-apSfg4eR.cjs +1 -0
  372. package/dist/scene-object.cjs +1 -1
  373. package/dist/scene-object.js +2 -2
  374. package/dist/segmentation-Cb3ouK6Z.js +1758 -0
  375. package/dist/segmentation-D9pYO6aR.cjs +1 -0
  376. package/dist/segmentation2d/types.d.ts +6 -0
  377. package/dist/select-Ck5LGz-J.cjs +1 -0
  378. package/dist/select-pYRo_win.js +233 -0
  379. package/dist/selectors-C4X71aoD.cjs +1 -0
  380. package/dist/selectors-DmNaKIwE.js +196 -0
  381. package/dist/session-BrH8G7iJ.cjs +31 -0
  382. package/dist/session-DgA_z6O1.js +418 -0
  383. package/dist/{settings-aQk845NJ.js → settings-BJ7FMBsO.js} +53 -15
  384. package/dist/settings-C63FMBlF.cjs +1 -0
  385. package/dist/similarityFit-BFqHND2e.cjs +1 -0
  386. package/dist/similarityFit-Bbz-R8AY.js +91 -0
  387. package/dist/spring/index.d.ts +2 -0
  388. package/dist/spring/spring.d.ts +69 -0
  389. package/dist/spring/swing.d.ts +54 -0
  390. package/dist/tracking.cjs +10 -1
  391. package/dist/tracking.js +1002 -855
  392. package/dist/trigger-D0Pm9noT.cjs +49 -0
  393. package/dist/trigger-IQeys0oS.js +2128 -0
  394. package/dist/types/face.d.ts +20 -1
  395. package/dist/types/hand-tracking.d.ts +9 -0
  396. package/dist/types/nodes.d.ts +20 -1
  397. package/dist/types/segmentation.d.ts +5 -0
  398. package/dist/updateThrottle-BseecYag.js +4 -0
  399. package/dist/updateThrottle-Of5Y4SVa.cjs +1 -0
  400. package/dist/useFaceInfo-BHDNCvsJ.cjs +1 -0
  401. package/dist/useFaceInfo-J4x7LsqL.js +76 -0
  402. package/dist/useFaceResultReader-BvEo5REG.js +61 -0
  403. package/dist/useFaceResultReader-DuaL1KJG.cjs +1 -0
  404. package/dist/useInstructionHold-DOu-RpCM.js +53 -0
  405. package/dist/useInstructionHold-DwJY1Alr.cjs +1 -0
  406. package/dist/useLandmarkPoseFit-Bg-h9BPb.cjs +1 -0
  407. package/dist/useLandmarkPoseFit-Bmb3h6Mw.js +87 -0
  408. package/dist/{useXRCapabilities-B1R2ghy-.cjs → useXRCapabilities-Cr3RzuAW.cjs} +1 -1
  409. package/dist/{useXRCapabilities-C68v__wB.js → useXRCapabilities-Cxmlmpbd.js} +1 -1
  410. package/dist/utils/canonicalRigidLandmarks.d.ts +8 -0
  411. package/dist/utils/headOccluderFit.d.ts +42 -0
  412. package/dist/utils/integrity.d.ts +17 -0
  413. package/dist/utils/resolveNumFaces.d.ts +13 -0
  414. package/dist/utils/shoulderOccluderFit.d.ts +38 -0
  415. package/dist/utils/similarityFit.d.ts +23 -0
  416. package/dist/uv-BMFt19bg.cjs +1 -0
  417. package/dist/{index-CsUdQ-pn.js → uv-DJU_XfmN.js} +15 -249
  418. package/docs/SDK_DOCUMENTATION.md +1 -2
  419. package/docs/api/adaptive-quality.mdx +1 -1
  420. package/docs/api/body-instructions.mdx +285 -0
  421. package/docs/api/body-triggers.mdx +234 -0
  422. package/docs/api/camera-permission.mdx +1 -1
  423. package/docs/api/coordinate-spaces.mdx +7 -4
  424. package/docs/api/cross-camera.mdx +3 -2
  425. package/docs/api/debug-ui-scene-editor.mdx +23 -2
  426. package/docs/api/external-face-mesh.mdx +231 -0
  427. package/docs/api/face-actions.mdx +20 -16
  428. package/docs/api/face-attribute-expression.mdx +1 -1
  429. package/docs/api/face-binding-anchors.mdx +4 -2
  430. package/docs/api/face-character.mdx +157 -0
  431. package/docs/api/face-effects.mdx +3 -0
  432. package/docs/api/face-expression-controller.mdx +153 -0
  433. package/docs/api/face-info.mdx +17 -11
  434. package/docs/api/face-inset.mdx +204 -0
  435. package/docs/api/face-instructions.mdx +183 -0
  436. package/docs/api/face-liquify.mdx +196 -0
  437. package/docs/api/face-mesh.mdx +4 -7
  438. package/docs/api/face-morph.mdx +117 -0
  439. package/docs/api/face-painting.mdx +7 -0
  440. package/docs/api/face-reprojection.mdx +154 -0
  441. package/docs/api/face-retouching.mdx +18 -10
  442. package/docs/api/face-swap.mdx +350 -0
  443. package/docs/api/face-warp-3d.mdx +166 -0
  444. package/docs/api/faceless.mdx +143 -0
  445. package/docs/api/gestures.mdx +68 -32
  446. package/docs/api/hair.mdx +97 -0
  447. package/docs/api/hand-instructions.mdx +222 -0
  448. package/docs/api/hand-rig.mdx +535 -0
  449. package/docs/api/hand-touch.mdx +162 -0
  450. package/docs/api/head-occluder.mdx +563 -0
  451. package/docs/api/holistic-tracker.mdx +6 -1
  452. package/docs/api/instructions.mdx +323 -0
  453. package/docs/api/iris-tracking.mdx +24 -19
  454. package/docs/api/made-up-camera.mdx +131 -0
  455. package/docs/api/makeup-skin-tone.mdx +135 -0
  456. package/docs/api/makeup.mdx +353 -0
  457. package/docs/api/multi-subject.mdx +4 -1
  458. package/docs/api/particles.mdx +155 -0
  459. package/docs/api/person-cutout.mdx +1 -1
  460. package/docs/api/pin-to-face-mesh.mdx +274 -0
  461. package/docs/api/product-ar.mdx +5 -2
  462. package/docs/api/segmentation-overlay.mdx +1 -1
  463. package/docs/docs.json +29 -1
  464. package/docs/examples/lip-shaders.mdx +82 -33
  465. package/docs/guides/face-atlas-template.svg +1 -0
  466. package/docs/guides/face-atlas-textures.mdx +186 -0
  467. package/docs/guides/face-texture-template.svg +1 -0
  468. package/docs/guides/harness-debug-ui.mdx +4 -4
  469. package/docs/guides/lip-effect-textures.mdx +178 -102
  470. package/docs/guides/lip-uv-template.png +0 -0
  471. package/docs/guides/lip-uv-template.svg +1 -1
  472. package/docs/guides/makeup-design-textures.mdx +109 -0
  473. package/docs/introduction.mdx +1 -2
  474. package/package.json +11 -1
  475. package/dist/DebuggerUI-C-ldiozL.js +0 -269
  476. package/dist/DebuggerUI-CWX5EtQv.cjs +0 -1
  477. package/dist/FaceMeshRenderer-BEEXZwS6.cjs +0 -158
  478. package/dist/FaceMeshRenderer-UuH5sTXG.js +0 -1322
  479. package/dist/FaceRetouch-C7h7x9kd.js +0 -683
  480. package/dist/FaceRetouch-DqftT26Y.cjs +0 -134
  481. package/dist/GLTFLoader-C5q63sKO.js +0 -1633
  482. package/dist/GLTFLoader-Cb_CRwmG.cjs +0 -1
  483. package/dist/SegmentationOverlay-DQuW3dsc.js +0 -133
  484. package/dist/SegmentationOverlay-aWVod8Kl.cjs +0 -1
  485. package/dist/components/FaceWarp3D/FaceWarp3DHead.d.ts +0 -15
  486. package/dist/components/FaceWarp3D/defaults.d.ts +0 -37
  487. package/dist/components/FaceWarp3D/warp.d.ts +0 -13
  488. package/dist/contexts-CO0sd4JQ.cjs +0 -1
  489. package/dist/contexts-FzlnnMYD.js +0 -669
  490. package/dist/debug-ui/face-warp-3d/index.d.ts +0 -6
  491. package/dist/getFaceInfo-BkZfaQs-.js +0 -118
  492. package/dist/getFaceInfo-ahPxQFGu.cjs +0 -1
  493. package/dist/index--RgGzZ6X.cjs +0 -47
  494. package/dist/index-CHVbH0hz.js +0 -214
  495. package/dist/index-CeVkgsag.cjs +0 -1
  496. package/dist/index-CnGox6Xr.js +0 -3054
  497. package/dist/index-DKBAh6hV.cjs +0 -1
  498. package/dist/index-DsZwTfG0.cjs +0 -1
  499. package/dist/index-Dw6tj2Mi.js +0 -144
  500. package/dist/index-OCPjOaeP.cjs +0 -1
  501. package/dist/index-s9pF4zkG.js +0 -2053
  502. package/dist/internal-BYza1h8_.cjs +0 -1
  503. package/dist/measures-9dQPdw96.js +0 -154
  504. package/dist/measures-KfJzpvod.cjs +0 -1
  505. package/dist/providers-YNwkmNeK.cjs +0 -62
  506. package/dist/renderPasses-Cg-zqmEz.cjs +0 -21
  507. package/dist/screenTransform-BenfCtZt.js +0 -44
  508. package/dist/screenTransform-BiXdpVf0.cjs +0 -1
  509. package/dist/segmentation-9PhSvc-R.cjs +0 -1
  510. package/dist/segmentation-CeOTKemr.js +0 -5
  511. package/dist/selectors-C5G1PMYL.js +0 -195
  512. package/dist/selectors-Du_PsVnW.cjs +0 -1
  513. package/dist/session-BBr0yN8h.cjs +0 -31
  514. package/dist/session-Cy0m7l7-.js +0 -363
  515. package/dist/settings-DRR7-snV.cjs +0 -1
  516. package/dist/useFaceInfo-Blf7FCu3.js +0 -303
  517. package/dist/useFaceInfo-C5mO8NQY.cjs +0 -1
@@ -0,0 +1,234 @@
1
+ ---
2
+ title: "Body Triggers"
3
+ description: "Fire on full-body poses (T-pose, hands up, squat) and moves over time (jump, squat reps, wave, clap, punch, arm flap, kick, step, march) with begin / end events."
4
+ sidebarTitle: "Body Triggers"
5
+ icon: "person-running"
6
+ ---
7
+
8
+ `BodyTrigger` fires when the person holds a body pose or performs a body move. It reads the body
9
+ model's 33 pose landmarks (it acquires the model itself; no `BodyTracker` needed) and runs the same
10
+ lifecycle as [`useGesture`](/api/gestures): begin / end events, hold, cooldown, loss grace and a
11
+ count.
12
+
13
+ Import from `@vincentt-xr/sdk/tracking`.
14
+
15
+ ```tsx
16
+ import { BodyTrigger, useBodyTrigger } from "@vincentt-xr/sdk/tracking";
17
+
18
+ // Declarative: mount inside the scene, act on the events.
19
+ <BodyTrigger pose="tPose" onBegin={() => takeOff()} onEnd={() => land()} />;
20
+ <BodyTrigger move="jump" onBegin={() => hop()} />;
21
+ <BodyTrigger move="punch" side="right" onBegin={(state) => hit(state.side)} />;
22
+
23
+ // Hook: React state that changes only when the trigger's state changes.
24
+ const squats = useBodyTrigger({ move: "squat" });
25
+ // squats.count = reps so far; squats.active = at the bottom of a rep.
26
+ ```
27
+
28
+ Pass exactly one of `pose` or `move`. Left / right are the person's own sides on every camera.
29
+
30
+ ## Poses
31
+
32
+ `pose` takes BodyInstruction's vocabulary (`BODY_POSES` from `@vincentt-xr/sdk/instructions`) and
33
+ its classifier (`analyzeBodyShape` + `matchBodyPose`), so a pose that completes a
34
+ [`BodyInstruction`](/api/body-instructions) also fires a `BodyTrigger`.
35
+
36
+ | You want | `pose` | Needs |
37
+ | -------------------------------- | ---------------------------------------------------------- | ---------- |
38
+ | T-pose | `"tPose"` | upper body |
39
+ | Hands up | `"handsUp"` (alias of `"hooray"`) | upper body |
40
+ | Hands on hips | `"handsOnHips"` | upper body |
41
+ | Arms crossed | `"armsCrossed"` | upper body |
42
+ | Squat position | `"squat"` | whole body |
43
+ | Raise one arm | `"raiseLeft"` / `"raiseRight"` | upper body |
44
+ | Hands on head, thumbs up, salute | `"handsOnHead"`, `"thumbUp"`, `"bothThumbsUp"`, `"salute"` | upper body |
45
+ | Lean, one leg, star | `"leanLeft"` / `"leanRight"`, `"oneLeg"`, `"star"` | whole body |
46
+
47
+ `pose` also takes a rule, a match function or a `defineBodyPose` definition:
48
+
49
+ ```tsx
50
+ <BodyTrigger pose={{ arms: { left: "raised", right: "out" } }} onBegin={point} />
51
+ <BodyTrigger pose={(shape) => shape.arms.left.up > 1.2} onBegin={reach} />
52
+ ```
53
+
54
+ A pose begins once it has been held (the match is smoothed over about 80 ms, then `holdMs`, 150 by
55
+ default) and ends when it is released. A one-frame flicker of the classifier neither ends nor
56
+ restarts it. Pose defaults: `BODY_POSE_TRIGGER_DEFAULTS` (enter 0.6, exit 0.25, hold 150 ms, loss
57
+ grace 250 ms).
58
+
59
+ Poses read the same on portrait, landscape and square feeds. Tracker x and y each span the frame,
60
+ so on a 9:16 portrait feed a horizontal distance reads 1.78 times too long next to a vertical one;
61
+ the trigger multiplies x by the frame's aspect ratio (`useXRFeedAspect()`) before classifying.
62
+ `handsUp` and `hooray` are the same pose: each answers the other.
63
+
64
+ ## Moves
65
+
66
+ `move` takes a `BODY_MOVES` name (`BODY_MOVE_NAMES`) or your own `defineBodyMove` definition.
67
+
68
+ | `move` | Begins | Ends | Needs | `side` | Cooldown |
69
+ | ---------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------ | ---------- | ------ | -------- |
70
+ | `"jump"` | shoulders, hips and both feet rise together above the standing level (take-off) | on landing | whole body | – | 150 ms |
71
+ | `"squat"` | from standing, both thighs drop toward level (bottom of a rep) | back up standing | whole body | – | 200 ms |
72
+ | `"wave"` | a raised forearm swings side to side (three turning points within 1.5 s) | when the swinging stops | the arm | yes | 600 ms |
73
+ | `"clap"` | the hands meet fast (apart to touching within 0.25 s) | when they part | both arms | – | 100 ms |
74
+ | `"punch"` | an arm snaps from bent to straight (within 0.2 s) at shoulder height, to the camera or the side | when it bends back | the arm | yes | 150 ms |
75
+ | `"armFlap"` | both arms, out like wings, beat down together | when the arms rise again | both arms | – | 100 ms |
76
+ | `"kick"` | one foot swings up fast with the knee lifted and the lower leg raised | when the foot is down | whole body | yes | 300 ms |
77
+ | `"stepLeft"` / `"stepRight"` | hips and both feet move to the person's own left / right by half a shoulder width within 0.7 s | when the body settles | whole body | – | 300 ms |
78
+ | `"march"` | each alternating knee (or foot) lift; the first lift only starts the count | when that foot is down | whole body | – | 0 |
79
+
80
+ Every move counts: `state.count` goes up on each begin (jumps, reps, claps, punches, flaps, kicks,
81
+ steps, march steps). `onEnd` with `endReason: "released"` means the move completed. `state.side` is the
82
+ limb behind the begin (`wave`, `punch`, `kick`, `march`) or the step direction.
83
+
84
+ `side` (`"left"`, `"right"`, default `"either"`) picks the limb a `wave`, `punch` or `kick` watches.
85
+
86
+ ### Telling moves apart
87
+
88
+ The moves are built not to answer each other: a squat is not a jump (the feet stay down), a march
89
+ step is not a kick (the foot hangs under the knee), a heel kick is not a kick (the knee stays down),
90
+ lowering the arms from the front is not a flap, dropping or raising a bent arm is not a punch, a slow
91
+ reach is not a punch, hands brought together slowly are not a clap, walking toward the camera is not
92
+ a step, and a single knee raise is not marching.
93
+
94
+ Moves read body motion in the frame, so a camera that moves fast reads as motion too: a jerked
95
+ handheld phone can look like a jump or a step. Slow drift never does. For leg moves, prop the phone up.
96
+
97
+ ## Whole body in view
98
+
99
+ Leg moves need shoulders, hips, knees and ankles in view. A joint counts when MediaPipe's visibility
100
+ is at least 0.2 and it sits no more than 0.12 past the frame edge (`BODY_MOVE_VIEW_LIMITS`; the
101
+ frame spans −1..1). Both bars are deliberate: MediaPipe often reports 0.2 to 0.5 for ankles that are
102
+ in frame, and an ankle can sit just past the edge when the feet are partly cropped. Legs cut off by a
103
+ front camera held close sit far past the edge with visibility near 0, so leg moves never fire.
104
+ Tune per trigger with `view`:
105
+
106
+ ```tsx
107
+ <BodyTrigger move="jump" view={{ visible: 0.3, edge: 0.05 }} onBegin={hop} />
108
+ ```
109
+
110
+ The leg poses (`squat`, `leanLeft`, `leanRight`, `oneLeg`, `star`) use BodyInstruction's own check
111
+ (visibility at least `BODY_SHAPE_LIMITS.visible`, 0.5). The trigger reports what it needs:
112
+
113
+ - `state.view`: `"full"` (needs the whole body) or `"upper"`.
114
+ - `state.inView`: whether what it needs is in view now.
115
+
116
+ ```tsx
117
+ const jump = useBodyTrigger({ move: "jump", onBegin: hop });
118
+ // Show "Step back so your whole body is in view" while this is true.
119
+ const needsStepBack = jump.view === "full" && !jump.inView;
120
+ ```
121
+
122
+ Leaving view while a move is active is tracking loss: after `lostGraceMs` it ends with
123
+ `endReason: "lost"`, and the move's memory starts fresh when the body is back.
124
+
125
+ ## Thresholds
126
+
127
+ Arm moves measure in shoulder widths (like BodyInstruction's classifier). Leg moves measure vertical
128
+ against vertical (torso length, the standing shin), so distance from the camera and the frame's aspect
129
+ ratio cancel. Defaults are in `BODY_MOVE_LIMITS`; each move lists the keys it reads in
130
+ `BODY_MOVES[name].limitKeys`. Override per trigger:
131
+
132
+ ```tsx
133
+ <BodyTrigger move="jump" limits={{ jumpRise: 0.2 }} onBegin={hop} />
134
+ <BodyTrigger move="squat" limits={{ squatDown: 0.75 }} onBegin={rep} /> {/* shallower squats count */}
135
+ ```
136
+
137
+ | Key | Default | Meaning |
138
+ | ----------------------------------------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------- |
139
+ | `jumpRise` / `jumpLand` | 0.12 / 0.06 | take-off rise and landing tolerance, torso lengths |
140
+ | `jumpMaxAirMs` / `jumpLevelMs` | 900 / 300 | longest air time; how fast the standing level follows slow drift |
141
+ | `squatDown` / `squatUp` | 0.6 / 0.85 | thigh height ÷ shin height at the bottom / back up (standing ≈ 1) |
142
+ | `waveForearmUp`, `waveAmplitude`, `waveReversals`, `waveWindowMs` | 0.25, 0.3, 3, 1500 | forearm raised; swing between turning points; turning points within the window |
143
+ | `clapApart`, `clapTogether`, `clapWithinMs`, `clapRelease` | 0.6, 0.3, 250, 0.45 | hands apart, then together within the time; parted again |
144
+ | `punchBent`, `punchStraight`, `punchWithinMs`, `punchBand` | 0.75, 0.93, 200, 0.9 | arm straightness (shoulder → wrist ÷ arm length, in 3D) from bent to straight; wrist near shoulder height |
145
+ | `flapStroke`, `flapWithinMs`, `flapTop`, `flapOut` | 0.7, 500, −0.4, 0.3 | both wrists drop this far, from a top near shoulder level, out to the sides |
146
+ | `kickLift`, `kickKnee`, `kickShin`, `kickWithinMs` | 0.35, 0.15, 0.6, 600 | foot and knee above the standing ones; the foot not hanging under the knee |
147
+ | `stepShift`, `stepWithinMs` | 0.5, 700 | sideways travel of hips and feet, shoulder widths |
148
+ | `marchLift`, `marchDrop`, `marchWithinMs` | 0.2, 0.08, 1200 | knee or foot above the other one; alternation window |
149
+
150
+ For poses, `limits` also takes BodyInstruction's classifier thresholds (`BODY_SHAPE_LIMITS` keys).
151
+ The lifecycle options are the gesture engine's (`enterThreshold`, `exitThreshold`, `holdMs`,
152
+ `cooldownMs`, `minConfidence`, `lostGraceMs`), per trigger.
153
+
154
+ ## Options
155
+
156
+ `useBodyTrigger({ pose | move, … })` and `<BodyTrigger … />` take:
157
+
158
+ - `pose` or `move` (exactly one).
159
+ - `side`: `"either"` (default), `"left"`, `"right"`.
160
+ - `limits`: `Partial<BodyMoveLimits & BodyShapeLimits>`.
161
+ - `view`: `Partial<BodyMoveViewLimits>` (`{ visible, edge }`, the leg moves' view gate).
162
+ - The lifecycle options above.
163
+ - `bodyIndex` (default 0), `active` (default `true`; `false` pauses and releases the body model),
164
+ `targetFps`.
165
+ - `onBegin`, `onEnd`, `onChange`: called from the frame loop with that frame's `BodyTriggerState`.
166
+
167
+ `BodyTriggerState` is `GestureState` (`active`, `value`, `confidence`, `tracked`, `phase`,
168
+ `justBegan`, `justEnded`, `endReason`, `startedAtMs`, `durationMs`, `count`) plus `kind`
169
+ (`"pose"` | `"move"`), `view`, `inView` and `side`.
170
+
171
+ ## Custom moves
172
+
173
+ ```ts
174
+ import { defineBodyMove } from "@vincentt-xr/sdk/tracking";
175
+
176
+ // Both wrists above the head, then down below the hips within a second: a "touch the floor".
177
+ const touchFloor = defineBodyMove({
178
+ name: "touchFloor",
179
+ label: "Touch the floor",
180
+ description: "Hands from overhead to below the knees within 1 s.",
181
+ view: "full",
182
+ createMemory: () => ({ upAt: -Infinity }),
183
+ measure: (frame, memory, nowMs) => {
184
+ const { joints: j } = frame;
185
+ if (j.leftWrist.y > j.nose.y && j.rightWrist.y > j.nose.y) memory.upAt = nowMs;
186
+ const down = j.leftWrist.y < j.leftKnee.y && j.rightWrist.y < j.rightKnee.y;
187
+ return { value: down && nowMs - memory.upAt < 1000 ? 1 : 0 };
188
+ },
189
+ });
190
+
191
+ <BodyTrigger move={touchFloor} onBegin={celebrate} />;
192
+ ```
193
+
194
+ `measure(frame, memory, nowMs, { side, limits })` runs once per new tracker sample of a body in
195
+ view and returns `{ value, side? }` (`value` ≥ 0.5 while the move is happening, for the default
196
+ thresholds). `frame` (`BodyMoveFrame`) carries BodyInstruction's `shape`, the person's own `joints`
197
+ (`joints.leftWrist` is their left wrist) in square units (x multiplied by the frame's aspect, so x and
198
+ y compare), `visibility` and `seen` per joint (the view gate above), `shoulderWidth`, `torso`
199
+ (vertical shoulder-to-hip length), `leftward` (the tracker-x direction of the person's left),
200
+ `upperInView`, `fullInView` and `aspect`. Memory is recreated whenever the body is lost or leaves
201
+ view. Define moves at module scope: a definition is keyed by its `name`.
202
+
203
+ The pure layer is on `@vincentt-xr/sdk/low-level` for tests and custom runners:
204
+ `createBodyMoveFrame(landmarks, { mirrored, visibility, aspect, view })`, `createBodyTrigger(target, options)`,
205
+ `stepBodyTrigger(machine, frame | null, nowMs, fresh?)`, `snapshotBodyTriggerState`,
206
+ `bodyTriggerStatesEqual`, `setBodyTriggerOptions`, `resolveBodyTriggerOptions`,
207
+ `resolveBodyMoveLimits`, `BODY_POSE_TRIGGER_DEFAULTS`, `sideJoint` and `TimedSeries` (windowed
208
+ min / max over a fixed ring, for custom moves).
209
+
210
+ ## Performance
211
+
212
+ All body triggers read one shared body model; each tracker sample is analysed once and shared by
213
+ every trigger reading it. Moves keep a short fixed-size history and measure only new tracker samples,
214
+ not every rendered frame.
215
+
216
+ ## Manual validation
217
+
218
+ Run `/gestures` (webcam by default; the fallback clip shows a full body). The body triggers section
219
+ lists every pose and move with a light and, for moves, a count.
220
+
221
+ | Case | Steps | Expect |
222
+ | ---------------- | ----------------------------------------------------------- | -------------------------------------------------------------- |
223
+ | Poses | hold a T-pose, hands up, hands on hips, arms crossed, squat | That row lights while held, off when released |
224
+ | Jump | stand back (whole body in view), jump three times | `jump` ×3; no `squat`, `march` or `step` |
225
+ | Squat reps | three squats | `squat` ×3, counted at the bottom |
226
+ | Wave | wave with your left hand, `side` = right | No count; set `side` = left, it counts with side `left` |
227
+ | Clap | clap four times | `clap` ×4; slowly pressing the palms together: no count |
228
+ | Punch | jab at the camera with each hand | `punch` counts with the right side |
229
+ | Arm flap | flap both arms like wings | `armFlap` counts each downstroke |
230
+ | Kick, march | kick once; then march in place | `kick` ×1; `march` counts steps, `kick` stays still |
231
+ | Steps | step to your left, then to your right | `stepLeft` then `stepRight`, on the webcam and rear camera |
232
+ | Legs out of view | come close so only the upper body shows | Leg rows turn amber ("needs full body") and never count |
233
+ | Fallback clip | "Person Fullbody" (portrait, standing still) | No pose lit (not `squat`); leg rows in view, counts at 0 |
234
+ | Feed shape | switch the stage between portrait and landscape | The same poses light; the "leg view gate" readout says in view |
@@ -128,7 +128,7 @@ next to `XRErrorReason`, for callers that classify their own
128
128
 
129
129
  ## Manual validation
130
130
 
131
- Run `/camera-permission`:
131
+ Run `/camera`:
132
132
 
133
133
  | Case | Steps | Expect |
134
134
  | ------------ | ----------------------------------------- | ----------------------------------------------------------------- |
@@ -80,10 +80,13 @@ less than the frame (zoom > 1 never does; a contain-shaped source does);
80
80
 
81
81
  - Positions never need a flip: landmarks already live in the (possibly
82
82
  mirrored) feed, and the feed is what you see.
83
- - **Direction signs** do. Holistic hand labels and the iris `offset.x` are
84
- corrected with `isMirroredSourceKind(sourceKind)` so "the person's left"
85
- means the same thing on every source. Use the same helper, never
86
- `sourceKind === "webcam"` inline.
83
+ - **Direction signs and side names** do. Every SDK left / right is the
84
+ person's own side on every source (GROUNDING "Left and right"); MediaPipe's
85
+ own sides (landmark indices, labels, blendshape names) are swapped on the
86
+ mirrored webcam. The SDK corrects them with `isMirroredSourceKind(sourceKind)`
87
+ / `useXRMirrored()`; for your own reads use `personSide(side, mirrored)`,
88
+ `feedSidedName(name, mirrored)` and `personLeftSign(mirrored)` from
89
+ `@vincentt-xr/sdk`, never `sourceKind === "webcam"` inline.
87
90
  - `mirrorFeedX` flips a feed point's x (for a direction vector, or to compare
88
91
  a selfie feed with a straight recording).
89
92
 
@@ -50,7 +50,8 @@ unprojected to the scene lands where the preview shows it on every camera.
50
50
  Consumers never flip positions; `useXRMirrored()` (low-level, the same
51
51
  answer as `isMirroredSourceKind(sourceKind)`) is for _direction_ semantics
52
52
  only, such as which hand is the person's left. Every tracker and the
53
- coordinate toolkit already key off the kind.
53
+ coordinate toolkit already key off the kind, so every SDK left / right is the
54
+ person's own side on every camera (GROUNDING "Left and right").
54
55
 
55
56
  ## Orientation
56
57
 
@@ -76,7 +77,7 @@ on the face through a rotation and a camera switch. Use
76
77
 
77
78
  ## Manual validation
78
79
 
79
- Run `/camera-switching` on a phone:
80
+ Run `/camera` on a phone:
80
81
 
81
82
  | Case | Steps | Expect |
82
83
  | ------------------- | ----------------------------------- | ---------------------------------------------------------------------- |
@@ -32,11 +32,10 @@ from final preview/runtime surfaces.
32
32
 
33
33
  ## In-repo examples
34
34
 
35
- - `/viewport-editor`: general 3D scene-object editor.
36
35
  - `/unified-architecture`: unified face-tracking scene using
37
36
  `XRSceneEditorProvider`, `XRSceneViewport`, hierarchy, inspector, toolbar, and
38
37
  media switching.
39
- - `/testing-hook`: multi-face face mesh setup backed by the same reusable
38
+ - `/face-mesh?faces=two`: multi-face face mesh setup backed by the same reusable
40
39
  editor primitives.
41
40
  - `/debugger`: debugger overlay mounted beside a minimal tracked scene.
42
41
 
@@ -129,6 +128,28 @@ It renders sections for components present on the selected object:
129
128
 
130
129
  All edits route through `onComponentChange` or `onObjectChange`.
131
130
 
131
+ ## Docked windows
132
+
133
+ The hierarchy and inspector float by default: draggable glass cards over the
134
+ page. To put them in your own layout — a side panel or a settings drawer — pass
135
+ `docked`. A docked window renders in place: no portal, no fixed position, no
136
+ dragging. It takes the container's width, grows with its content, and drops the
137
+ glass card so it blends into the host.
138
+
139
+ ```tsx
140
+ <XRSceneEditorProvider defaultStore={store}>
141
+ <aside className="my-side-panel">
142
+ <SceneHierarchyPanel docked />
143
+ <SceneInspectorPanel docked />
144
+ </aside>
145
+ <XRSceneViewport />
146
+ </XRSceneEditorProvider>
147
+ ```
148
+
149
+ The provider must wrap the layout that hosts the docked panels. `docked` also
150
+ works on `HierarchyPanel`, `ObjectInspectorPanel`, `ScreenImageSettingsPanel`,
151
+ `ScreenTextSettingsPanel`, `ProductHotspotPanel` and `XRDiagnosticsPanel`.
152
+
132
153
  ## `ViewportToolbar`
133
154
 
134
155
  Small optional toolbar for transient viewport controls.
@@ -0,0 +1,231 @@
1
+ ---
2
+ title: "External Face Mesh"
3
+ description: "Wear your own head or face model on the tracked face: it follows the head pose and the face's expression, with any topology and UV layout."
4
+ sidebarTitle: "External Face Mesh"
5
+ icon: "masks-theater"
6
+ ---
7
+
8
+ `ExternalFaceMesh` puts your own face model on the tracked face. It follows the head pose and the
9
+ face's expression in two ways at once:
10
+
11
+ - **Landmarks:** the tracked landmarks bend the mesh, so the jaw opens and the lips and cheeks move.
12
+ - **Morphs:** the model's own ARKit-named morph targets play the face's blendshapes. That gives an
13
+ authored blink and raised brows, and the eyeballs turn with the gaze.
14
+
15
+ It is the foundation of the face-character pipeline
16
+ ([#194](https://github.com/vincentt-xr/sdk/issues/194)). Expression controllers, pinned accessories
17
+ and face reprojection build on the same `FaceRig`.
18
+
19
+ Import from `@vincentt-xr/sdk/face-effects`.
20
+
21
+ ## Quick start
22
+
23
+ ```tsx
24
+ import { useLoader } from "@react-three/fiber";
25
+ import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
26
+ import { FaceTracker } from "@vincentt-xr/sdk/tracking";
27
+ import { ExternalFaceMesh } from "@vincentt-xr/sdk/face-effects";
28
+
29
+ const Character = () => {
30
+ const head = useLoader(GLTFLoader, headUrl); // authored in canonical centimetres
31
+ return (
32
+ <FaceTracker>
33
+ <ExternalFaceMesh model={head.scene} />
34
+ </FaceTracker>
35
+ );
36
+ };
37
+ ```
38
+
39
+ It reads the parent `FaceTracker`'s face (or a `HeadBinding`'s) and never acquires the face model
40
+ itself. The model is cloned with its geometry, so one loaded model can back several faces.
41
+
42
+ ## Authoring the model
43
+
44
+ Author the model in the **canonical head frame**, the same frame as `CanonicalHeadFrame` and the v3
45
+ head occluder `.blend` in `assets-src/head-occluder/`:
46
+
47
+ - **Units and axes:** centimetres, +Y up, +Z out of the face toward the camera.
48
+ - **Origin:** landmark 4, just above the nose tip, sits at `(0, -0.46, 7.59)`.
49
+
50
+ The easiest way is to open the occluder `.blend` and fit your head over it. Its first 468 vertices
51
+ are the tracked face landmarks, so the eyes, nose and mouth line up when your model sits on them.
52
+
53
+ Any topology and any UV layout works. The face area should lie close to the canonical face surface:
54
+ the closer it is, the more of the face follows the expression. The rest (skull, ears, neck,
55
+ accessories) can go anywhere and stays rigid.
56
+
57
+ ## How it follows the face
58
+
59
+ **What drives it** is set by `drive`:
60
+
61
+ | `drive` | What moves it |
62
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------- |
63
+ | `"auto"` (default) | `"morphs"` for a full ARKit set (mouth morphs too), `"hybrid"` with only eye or brow morphs, else `"landmarks"`. |
64
+ | `"hybrid"` | Landmarks for the jaw, lips and cheeks; the model's morphs for the eyes and brows. |
65
+ | `"morphs"` | Only the model's morph targets, driven by the blendshapes; otherwise just the head pose. |
66
+ | `"landmarks"` | Only the landmarks bend the mesh. |
67
+ | `"none"` | The head pose only. |
68
+
69
+ For a model with a full ARKit set, such as Face Cap's, the authored morphs look best, so `"auto"`
70
+ picks `"morphs"`. Binding then plays no part, because nothing is bent.
71
+
72
+ Why hybrid for eye and brow morphs: MediaPipe only tracks the edge of each eyelid, 16 points around each eye. Bending a
73
+ sculpted lid with those points drags its edge down without rolling the lid over the eyeball. That
74
+ leaves slits at the corners and creases the lid. An authored `eyeBlink` morph closes it cleanly, so
75
+ hybrid masks the eye and brow landmarks (`FACE_REGION_MASKS`) and lets the morphs move those parts.
76
+
77
+ **Morph names** map to MediaPipe's 51 blendshape channels (`FACE_MORPH_NAMES`, ARKit names). The
78
+ match accepts:
79
+
80
+ - ARKit names, e.g. `eyeBlinkLeft`;
81
+ - Face Cap and Blender styles, e.g. `eyeBlink_L`, `eyeBlink.L`, `eyeBlink_left`;
82
+ - any case;
83
+ - exporter prefixes such as `blendShape1.`.
84
+
85
+ `Left` is the model's own left (landmark 263's side, MediaPipe's left), as in ARKit. It is driven
86
+ mesh to mesh, so the model's eye in front of the person's blinking eye blinks on every feed (on the
87
+ mirrored webcam that is MediaPipe's right channel for the person's real left eye; GROUNDING "Left
88
+ and right"). MediaPipe has no `tongueOut`.
89
+ Morphs that no channel drives are left alone, so your own animation keeps them. The model's rest pose
90
+ must have every morph at 0.
91
+
92
+ **Binding** happens once, at load. Each vertex is bound to a point on the canonical face surface,
93
+ which is MediaPipe's 853 face triangles. The mouth and eye openings are holes, so a lip never binds
94
+ across the mouth. `binding` picks how:
95
+
96
+ | `binding` | Binds by |
97
+ | ------------------ | ------------------------------------------------------------------------------------ |
98
+ | `"auto"` (default) | UV when the mesh's UVs are a canonical layout (most UV hits agree with 3D), else 3D. |
99
+ | `"uv"` | UV only, for a mesh whose face UVs follow `CANONICAL_FACE_UVS` (either v direction). |
100
+ | `"surface"` | The closest point in 3D. Any topology and layout. |
101
+
102
+ **Influence** depends on how far a vertex sits from the face surface. Within `falloff[0]` (0.8 cm)
103
+ it follows fully; it fades to rigid at `falloff[1]` (2.5 cm). The back of the head, the ears and the
104
+ neck therefore stay rigid.
105
+
106
+ **Parts:** each mesh of the model follows in one of three ways (`parts`, by object name):
107
+
108
+ - `"surface"`: every vertex follows its own point. Use it for skin.
109
+ - `"follow"`: the whole mesh moves as one with the point under its centre, keeping its shape. Use
110
+ it for eyeballs, teeth or a nose ring. A follow part named like an eye (`eye…`) also turns with
111
+ the gaze (`eyeLookIn/Out/Up/Down`, up to `gazeDegrees` = `[25, 20]`).
112
+ - `"rigid"`: head pose only. Use it for a helmet or hair.
113
+
114
+ By default, a mesh whose median vertex sits more than 0.3 cm behind the face (eyeballs, teeth) is
115
+ `"follow"`, and everything else is `"surface"`.
116
+
117
+ **Neutral.** Only the expression moves the model, not the person's own face shape or resting
118
+ expression. With `neutral: "auto"` (default), the rig averages the landmarks and the blendshape
119
+ scores over the first `neutralMs` (600 ms) after the face is found, and subtracts that rest face. The
120
+ blendshapes are rescaled, so a resting 0.1 reads 0 and a full blink still reads 1. It recaptures every time the face is found again, and when
121
+ `neutralKey` changes: bind it to a "Recalibrate" button and ask the person to relax and look at the
122
+ camera. With `neutral: "none"` the model also takes on the person's face shape (wider eyes, a longer
123
+ jaw).
124
+
125
+ ## `ExternalFaceMesh`
126
+
127
+ | Prop | Default | What it does |
128
+ | --------------------- | ------------- | ------------------------------------------------------------------------------------------- |
129
+ | `model` | — | The face model (e.g. a GLTF scene) in the canonical head frame. |
130
+ | `drive` | `"auto"` | What moves it: `"auto"`, `"hybrid"`, `"morphs"`, `"landmarks"` or `"none"`. |
131
+ | `binding` | `"auto"` | `"auto"`, `"uv"` or `"surface"`. |
132
+ | `falloff` | `[0.8, 2.5]` | Full influence up to the first distance (cm), rigid beyond the second. |
133
+ | `parts` | auto | Per mesh name: `"surface"`, `"follow"` or `"rigid"`. |
134
+ | `expression` | `1` | 0 = rigid, 1 = the tracked face, > 1 exaggerates. |
135
+ | `morphGain` | — | A gain per channel on its morph, e.g. `{ eyeBlinkLeft: 1.2 }`. |
136
+ | `gazeDegrees` | `[25, 20]` | How far a full look turns an eyeball: sideways, up/down (degrees). |
137
+ | `onBind` | — | Called once per model with every mesh's binding (readouts, debug views). |
138
+ | `faceIndex` | the tracker's | Which tracked face (when not inside a `FaceRig`; likewise the rows below). |
139
+ | `smoothing` | `0.5` | Head pose EMA while still (`1` = none). Fast turns follow at once, so a shake never trails. |
140
+ | `expressionSmoothing` | `0.6` | Expression EMA, `1` = none. MediaPipe's depth is noisy; a little keeps the mesh calm. |
141
+ | `holdMs` | `250` | Keep the last pose and expression through shorter dropouts. |
142
+ | `neutral` | `"auto"` | `"auto"` subtracts the captured rest face; `"none"` keeps the person's face shape. |
143
+ | `neutralMs` | `600` | How long the neutral capture averages. |
144
+ | `neutralKey` | — | A new value captures the neutral again. |
145
+ | `leadMs` | `0` | Landmark lead between inferences (One Euro + velocity, at most this long). 0 = raw. |
146
+ | `onTrackingChange` | — | Called once on found (`true`) and once on lost (`false`). |
147
+ | `children` | — | More content in the canonical head frame. |
148
+
149
+ ## `FaceRig`
150
+
151
+ `FaceRig` is the engine underneath, and every face-character component shares one. It is a group in
152
+ the canonical head frame, like `CanonicalHeadFrame`, that also publishes the face's expression. Put
153
+ several components inside one `FaceRig` to share it:
154
+
155
+ ```tsx
156
+ <FaceTracker>
157
+ <FaceRig neutralKey={recalibrations}>
158
+ <ExternalFaceMesh model={head.scene} />
159
+ <ExternalFaceMesh model={beard.scene} />
160
+ </FaceRig>
161
+ </FaceTracker>
162
+ ```
163
+
164
+ `useFaceRig()` returns a ref to the live `FaceRigState`. Read it inside `useFrame`:
165
+
166
+ - `tracking`: `"tracked"`, `"held"` or `"lost"`.
167
+ - `pose`: `{ position, quaternion, scale }`, canonical cm → world.
168
+ - `local`: the 468 landmarks in the head frame (cm).
169
+ - `residual`: the expression, as each landmark's offset from the rest face (cm, 468 × 3).
170
+ - `morphs`: the 51 blendshape channels (0..1, neutral removed).
171
+ - `neutral`, `morphNeutral` and `neutralState`.
172
+
173
+ The rig holds its last state through dropouts shorter than `holdMs`, hides when the face is lost,
174
+ and snaps on reacquire.
175
+
176
+ The pure pieces are exported for custom renderers:
177
+
178
+ - `stepFaceRig(state, worldLandmarks, nowMs, options, scores)`, `createFaceRigState()` and
179
+ `recalibrateFaceRig(state)`.
180
+ - `bindFaceMesh(positionsCm, uvs, { mode, falloff, uvTolerance })` and
181
+ `deformFaceMesh(binding, rest, residual, out, amount, toLocal)`.
182
+ - `bindFaceModel(root, options)`, `planFaceDrive(meshes, mode)` and
183
+ `driveFaceModel(meshes, plan, rig, options)`.
184
+ - `faceMorphChannel(name)`, `faceMorphRegion`, `FACE_GAZE_CHANNELS` and `FACE_REGION_MASKS`.
185
+ - The canonical data: `CANONICAL_FACE_POSITIONS`, `CANONICAL_FACE_TRIANGLES` and
186
+ `CANONICAL_FACE_UVS`.
187
+
188
+ ## Example
189
+
190
+ `/external-face-mesh` wears the three.js "facecap" head when it is present. The file goes in the
191
+ git-ignored `example/src/assets/models/local/facecap-canonical.glb`; it has no redistribution
192
+ licence, so it is never committed. That copy is prepared as follows:
193
+
194
+ - aligned to the canonical frame;
195
+ - ears raised to the anatomical height (brow to nose base);
196
+ - every morph zeroed at rest (the original kept a frame of its animation).
197
+
198
+ It carries all 52 ARKit morphs, of which 51 are tracked. Without it, the page uses the canonical
199
+ head.
200
+
201
+ The page has controls for:
202
+
203
+ - drive, binding, expression and falloff;
204
+ - a binding heat map (red follows, blue rigid);
205
+ - keeping the face shape;
206
+ - recalibrating the neutral;
207
+ - the head occluder and two faces.
208
+
209
+ ## Manual visual test plan
210
+
211
+ Open `/external-face-mesh` on the webcam.
212
+
213
+ 1. **Placement**: the model sits on your head, with its eyes, nose and mouth on yours, and stays
214
+ there as you turn and tilt.
215
+ 2. **Neutral**: look at the camera relaxed when it appears. At rest it keeps its own shape: eyes
216
+ not stretched, jaw not lengthened. Tick "keep the person's face shape" and it conforms to yours;
217
+ untick it.
218
+ 3. **Expression**: open your mouth (the jaw drops and the lips part, never stretching across), smile
219
+ (the mouth corners and cheeks move), raise your brows. With drive "none", nothing moves but the
220
+ pose.
221
+ 4. **Blink and gaze** (facecap, drive "auto" = morphs): blink one eye, then both. The lid rolls down over the
222
+ eye and closes, with no slit at the corners and no crease. Look left, right, up and down: the
223
+ eyeballs turn with you. Open your mouth and smile: facecap's own jawOpen and smile shapes play.
224
+ Switch drive to "landmarks" to see the difference.
225
+ 5. **Parts**: the eyes and teeth move as whole pieces, never squashed. The back of the head and the
226
+ ears stay rigid; the heat map shows red on the face fading to blue.
227
+ 6. **Recalibrate**: start with your mouth open, then relax and press Recalibrate. The rest pose is
228
+ corrected.
229
+ 7. **Dropouts**: a brief cover of the camera holds the head. Longer, and it hides, then snaps back
230
+ on reacquire.
231
+ 8. **Two faces**: on the two-people image, each face wears its own copy.
@@ -37,21 +37,23 @@ const isPouting = hasFaceAction(face, "mouthPout");
37
37
 
38
38
  ## Actions
39
39
 
40
- | Name | Meaning |
41
- | ------------------------------- | ---------------------------- |
42
- | `browRaise` | Either brow is raised |
43
- | `eyeBlink` | Both eyes blink |
44
- | `eyeBlinkEither` | Either eye blinks |
45
- | `eyeBlinkLeft`, `eyeBlinkRight` | Viewer-left/right eye blinks |
46
- | `mouthOpen` | Jaw opens |
47
- | `mouthPout` | Lips pucker |
48
- | `headUp`, `headDown` | Pitch from neutral |
49
- | `headTurnLeft`, `headTurnRight` | Yaw from neutral |
50
- | `headTiltLeft`, `headTiltRight` | Roll from neutral |
40
+ | Name | Meaning |
41
+ | ------------------------------- | ---------------------------------------------------------------- |
42
+ | `browRaise` | Either brow is raised |
43
+ | `eyeBlink` | Both eyes blink |
44
+ | `eyeBlinkEither` | Either eye blinks |
45
+ | `eyeBlinkLeft`, `eyeBlinkRight` | The person's own left / right eye blinks |
46
+ | `mouthOpen` | Jaw opens |
47
+ | `mouthPout` | Lips pucker |
48
+ | `headUp`, `headDown` | Pitch from neutral |
49
+ | `headTurnLeft`, `headTurnRight` | Yaw from neutral, toward the person's own left / right |
50
+ | `headTiltLeft`, `headTiltRight` | Roll from neutral, toward the person's own left / right shoulder |
51
51
 
52
52
  Blendshape values are in `[0, 1]`. Head values are non-negative radians. Up and
53
- left follow the SDK convention and are positive before they are converted to an
54
- action magnitude.
53
+ the person's own left follow the SDK convention and are positive before they
54
+ are converted to an action magnitude. Left and right are the person's own side
55
+ on every feed: the mirrored webcam, the rear camera, images and video
56
+ (GROUNDING "Left and right").
55
57
 
56
58
  ## Neutral head pose
57
59
 
@@ -89,15 +91,17 @@ left, right, both, and either-eye movement cases. Use `mouthOpen`, `mouthPout`,
89
91
  and `browRaise` for the matching physical movements. These actions report
90
92
  observable pose/blendshape movement; they do not infer emotion.
91
93
 
92
- Left/right blink names use the mirrored viewer-facing convention used by effect
93
- editors. Raw `FaceInfo.blendshapes` retain MediaPipe's anatomical-side names.
94
+ Left/right blink names are the person's own eyes on every feed. Raw
95
+ `FaceInfo.blendshapes` keep MediaPipe's names (`eyeBlinkLeft` = MediaPipe's left
96
+ eye: the person's own left on an unmirrored feed, their right on the mirrored
97
+ webcam); the actions read the right one for `face.mirrored`.
94
98
  The lifecycle guarantees one `stay` frame between `begin` and `end`, including
95
99
  for a blink that drops below its release threshold on the next input frame.
96
100
 
97
101
  For image-based happy, sad, angry, fear, disgust, surprise, neutral, and unknown
98
102
  classification, use the separate `useFaceAttributeExpression` hook. The SDK
99
103
  does not fabricate these labels from movement thresholds. The verified
100
- `/facial-movement-expression` page exposes both independent surfaces.
104
+ `/face-actions` page exposes both independent surfaces.
101
105
 
102
106
  Use `/face-actions` to view every value, calibrate neutral pose, adjust the
103
107
  selected action, and repeat the live verification checklist. All actions and
@@ -82,6 +82,6 @@ Without those headers, ONNX Runtime falls back to single-threaded WASM.
82
82
  Treat classifications as model estimates of visible facial expression—not
83
83
  ground-truth emotion, intent, identity, or mental state.
84
84
 
85
- Use the verified `/facial-movement-expression` page to inspect the live winning
85
+ Use the verified `/face-actions` page to inspect the live winning
86
86
  class and all seven probabilities. Its real-camera model flow, including every
87
87
  expression class, was verified on 26 July 2026.
@@ -7,7 +7,9 @@ icon: "locate-fixed"
7
7
 
8
8
  Use `TrackingAnchor` to attach content to semantic face locations. Build editor
9
9
  dropdowns from `FACE_TARGETS`; do not copy landmark indices or invent target
10
- strings. Left and right use the tracked person's perspective.
10
+ strings. Left and right are the tracked person's own side on every feed (GROUNDING "Left and
11
+ right"): `face.leftEarlobe` is their real left ear lobe on the mirrored webcam (the screen's left)
12
+ and on a video (the screen's right).
11
13
 
12
14
  ## Presets
13
15
 
@@ -33,7 +35,7 @@ does not provide anatomical earlobe points.
33
35
  ## Custom points
34
36
 
35
37
  For `face.custom`, pass `customAnchorPoint`. X and Y are clamped to `[-1, 1]`;
36
- the origin is face center, X runs from the person's left to right, Y runs from
38
+ the origin is face center, X runs from the person's own left to right on every feed, Y runs from
37
39
  chin to forehead, and positive Z points toward the camera.
38
40
 
39
41
  ```tsx