@vincentt-xr/sdk 2.0.0-alpha.7 → 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 (639) hide show
  1. package/GROUNDING.md +5651 -82
  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/cache.d.ts +99 -0
  18. package/dist/assets/estimate.d.ts +11 -0
  19. package/dist/assets/gltfLoader.d.ts +16 -0
  20. package/dist/assets/index.d.ts +7 -0
  21. package/dist/assets/loaders.d.ts +43 -0
  22. package/dist/assets/react.d.ts +33 -0
  23. package/dist/body-pose/index.d.ts +521 -0
  24. package/dist/body-trigger/__fixtures__/syntheticBody.d.ts +83 -0
  25. package/dist/body-trigger/frame.d.ts +88 -0
  26. package/dist/body-trigger/index.d.ts +6 -0
  27. package/dist/body-trigger/moves.d.ts +235 -0
  28. package/dist/body-trigger/trigger.d.ts +75 -0
  29. package/dist/calibration/calibration.d.ts +75 -0
  30. package/dist/calibration/index.d.ts +6 -0
  31. package/dist/calibration/storage.d.ts +13 -0
  32. package/dist/calibration/types.d.ts +53 -0
  33. package/dist/calibration/useXRCalibration.d.ts +46 -0
  34. package/dist/camera/CameraPermissionGate.d.ts +26 -0
  35. package/dist/camera/devices.d.ts +26 -0
  36. package/dist/camera/index.d.ts +8 -0
  37. package/dist/camera/permission.d.ts +86 -0
  38. package/dist/camera/useCameraPermission.d.ts +35 -0
  39. package/dist/canonicalFace-BHwyCx1c.js +9 -0
  40. package/dist/canonicalFace-C83I225R.cjs +1 -0
  41. package/dist/capabilities/detect.d.ts +45 -0
  42. package/dist/capabilities/index.d.ts +5 -0
  43. package/dist/capabilities/types.d.ts +120 -0
  44. package/dist/capabilities/useXRCapabilities.d.ts +18 -0
  45. package/dist/compat/environment.d.ts +5 -0
  46. package/dist/compat/index.d.ts +4 -0
  47. package/dist/compat/run.d.ts +18 -0
  48. package/dist/compat/scenarios.d.ts +10 -0
  49. package/dist/compat/types.d.ts +101 -0
  50. package/dist/components/BodyInstruction/BodyPoseHint.d.ts +63 -0
  51. package/dist/components/BodyInstruction/index.d.ts +69 -0
  52. package/dist/components/BodyInstruction/useBodyPose.d.ts +23 -0
  53. package/dist/components/BodyTracker/index.d.ts +17 -0
  54. package/dist/components/BodyTrigger/index.d.ts +49 -0
  55. package/dist/components/Debugger/DebuggerProvider.d.ts +14 -1
  56. package/dist/components/Debugger/DebuggerUI.d.ts +3 -1
  57. package/dist/components/FaceAtlas/FaceAtlasLayer.d.ts +114 -0
  58. package/dist/components/FaceAtlas/MadeUpCamera.d.ts +80 -0
  59. package/dist/components/FaceAtlas/constants.d.ts +8 -0
  60. package/dist/components/FaceAtlas/index.d.ts +7 -0
  61. package/dist/components/FaceAtlas/useFaceAtlasSurface.d.ts +84 -0
  62. package/dist/components/FaceAtlas/useFaceSkin.d.ts +84 -0
  63. package/dist/components/FaceCharacter/ExternalFaceMesh.d.ts +109 -0
  64. package/dist/components/FaceCharacter/FaceExpressionController.d.ts +53 -0
  65. package/dist/components/FaceCharacter/FaceMorph.d.ts +71 -0
  66. package/dist/components/FaceCharacter/FacePiercing.d.ts +65 -0
  67. package/dist/components/FaceCharacter/FaceReprojection.d.ts +85 -0
  68. package/dist/components/FaceCharacter/FaceRig.d.ts +38 -0
  69. package/dist/components/FaceCharacter/FaceSurface.d.ts +49 -0
  70. package/dist/components/FaceCharacter/FaceSurfaceOccluder.d.ts +39 -0
  71. package/dist/components/FaceCharacter/PinToFaceMesh.d.ts +68 -0
  72. package/dist/components/FaceCharacter/index.d.ts +18 -0
  73. package/dist/components/FaceCharacter/useFaceReprojector.d.ts +10 -0
  74. package/dist/components/FaceInset/FaceInset.d.ts +68 -0
  75. package/dist/components/FaceInset/frame.d.ts +94 -0
  76. package/dist/components/FaceInset/index.d.ts +6 -0
  77. package/dist/components/FaceInset/material.d.ts +40 -0
  78. package/dist/components/FaceInset/useFaceInsetTexture.d.ts +37 -0
  79. package/dist/components/FaceInstruction/FaceExpressionHint.d.ts +43 -0
  80. package/dist/components/FaceInstruction/index.d.ts +56 -0
  81. package/dist/components/FaceInstruction/useFaceExpression.d.ts +20 -0
  82. package/dist/components/FaceLiquify/FaceLiquify.d.ts +49 -0
  83. package/dist/components/FaceLiquify/debug.d.ts +37 -0
  84. package/dist/components/FaceLiquify/frame.d.ts +55 -0
  85. package/dist/components/FaceLiquify/index.d.ts +10 -0
  86. package/dist/components/FaceLiquify/material.d.ts +39 -0
  87. package/dist/components/FaceLiquify/pass.d.ts +49 -0
  88. package/dist/components/FaceLiquify/presence.d.ts +25 -0
  89. package/dist/components/FaceLiquify/presets.d.ts +82 -0
  90. package/dist/components/FaceLiquify/selfTest.d.ts +66 -0
  91. package/dist/components/FaceLiquify/target.d.ts +85 -0
  92. package/dist/components/FaceLiquify/warp.d.ts +72 -0
  93. package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +37 -5
  94. package/dist/components/FaceMesh/canonical/geometryGroups.d.ts +21 -0
  95. package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +21 -0
  96. package/dist/components/FaceMesh/canonical/shaders.d.ts +1 -1
  97. package/dist/components/FaceMesh/index.d.ts +2 -2
  98. package/dist/components/FaceRetouch/Background.d.ts +3 -1
  99. package/dist/components/FaceRetouch/FaceRetouch.d.ts +5 -0
  100. package/dist/components/FaceRetouch/renderState.d.ts +19 -0
  101. package/dist/components/FaceSwap/FaceMirror.d.ts +46 -0
  102. package/dist/components/FaceSwap/FaceSwap.d.ts +58 -0
  103. package/dist/components/FaceSwap/FaceTextureLayer.d.ts +72 -0
  104. package/dist/components/FaceSwap/faceSwapPlan.d.ts +91 -0
  105. package/dist/components/FaceSwap/index.d.ts +13 -0
  106. package/dist/components/FaceSwap/settings.d.ts +300 -0
  107. package/dist/components/FaceSwap/useFaceTexture.d.ts +35 -0
  108. package/dist/components/FaceSwap/useLiveFace.d.ts +38 -0
  109. package/dist/components/FaceSwap/useLiveFaceTexture.d.ts +31 -0
  110. package/dist/components/FaceWarp3D/FaceWarp3D.d.ts +50 -0
  111. package/dist/components/FaceWarp3D/index.d.ts +2 -3
  112. package/dist/components/Faceless/Faceless.d.ts +51 -0
  113. package/dist/components/Faceless/index.d.ts +2 -0
  114. package/dist/components/GestureListener/index.d.ts +11 -0
  115. package/dist/components/HairLock/HairLock.d.ts +39 -0
  116. package/dist/components/HairLock/index.d.ts +2 -0
  117. package/dist/components/HairLock/lockGeometry.d.ts +15 -0
  118. package/dist/components/HandCutout/index.d.ts +35 -0
  119. package/dist/components/HandInstruction/HandGestureHint.d.ts +70 -0
  120. package/dist/components/HandInstruction/index.d.ts +74 -0
  121. package/dist/components/HandInstruction/useHandGesture.d.ts +22 -0
  122. package/dist/components/HandRig/ForearmOccluder.d.ts +29 -0
  123. package/dist/components/HandRig/HandAttachment.d.ts +34 -0
  124. package/dist/components/HandRig/HandOccluder.d.ts +55 -0
  125. package/dist/components/HandRig/HandTattoo.d.ts +61 -0
  126. package/dist/components/HandRig/WristAttachment.d.ts +34 -0
  127. package/dist/components/HandRig/index.d.ts +101 -0
  128. package/dist/components/HandRig/useArmMask.d.ts +29 -0
  129. package/dist/components/HandRig/wristSolve.d.ts +69 -0
  130. package/dist/components/HandTouch/HandTouch.d.ts +62 -0
  131. package/dist/components/HandTouch/Touchable.d.ts +36 -0
  132. package/dist/components/HandTouch/index.d.ts +2 -0
  133. package/dist/components/HandTracker/index.d.ts +10 -0
  134. package/dist/components/HeadBinding/index.d.ts +14 -0
  135. package/dist/components/HeadOccluder/CanonicalHeadFrame.d.ts +22 -0
  136. package/dist/components/HeadOccluder/Earrings.d.ts +55 -0
  137. package/dist/components/HeadOccluder/HeadAttachment.d.ts +38 -0
  138. package/dist/components/HeadOccluder/NeckOccluder.d.ts +64 -0
  139. package/dist/components/HeadOccluder/earringPlacement.d.ts +31 -0
  140. package/dist/components/HeadOccluder/headAttachmentPoints.d.ts +69 -0
  141. package/dist/components/HeadOccluder/index.d.ts +57 -3
  142. package/dist/components/HeadOccluder/useCanonicalHeadFit.d.ts +36 -0
  143. package/dist/components/HeadOccluder/useLandmarkPoseFit.d.ts +80 -0
  144. package/dist/components/HolisticTracker/index.d.ts +69 -0
  145. package/dist/components/HolisticTracker/settings.d.ts +58 -0
  146. package/dist/components/HolisticTracker/signals.d.ts +49 -0
  147. package/dist/components/Instruction/HintStage.d.ts +29 -0
  148. package/dist/components/Instruction/InstructionCue.d.ts +126 -0
  149. package/dist/components/Instruction/gestureHold.d.ts +20 -0
  150. package/dist/components/Instruction/ghost.d.ts +129 -0
  151. package/dist/components/Instruction/hintBlend.d.ts +19 -0
  152. package/dist/components/Instruction/hintLook.d.ts +81 -0
  153. package/dist/components/Instruction/hintLoop.d.ts +36 -0
  154. package/dist/components/Instruction/index.d.ts +41 -0
  155. package/dist/components/Instruction/useGhostModel.d.ts +33 -0
  156. package/dist/components/Instruction/useInstructionHold.d.ts +72 -0
  157. package/dist/components/IrisEffect/IrisMaterial.d.ts +73 -0
  158. package/dist/components/IrisEffect/index.d.ts +51 -0
  159. package/dist/components/IrisEffect/settings.d.ts +117 -0
  160. package/dist/components/LipEffect/LipEffect.d.ts +27 -1
  161. package/dist/components/LipEffect/LipEffectMaterial.d.ts +95 -7
  162. package/dist/components/LipEffect/LipEffects.d.ts +12 -0
  163. package/dist/components/LipEffect/defaults.d.ts +46 -4
  164. package/dist/components/LipEffect/index.d.ts +11 -3
  165. package/dist/components/LipEffect/lipShading.d.ts +73 -0
  166. package/dist/components/LipEffect/settings.d.ts +375 -0
  167. package/dist/components/LipEffect/shader.d.ts +39 -0
  168. package/dist/components/LipEffect/types.d.ts +128 -9
  169. package/dist/components/LipEffect/useLipDesignTextures.d.ts +17 -0
  170. package/dist/components/LipEffect/uvGuide.d.ts +74 -0
  171. package/dist/components/Makeup/Blush.d.ts +18 -0
  172. package/dist/components/Makeup/Brows.d.ts +20 -0
  173. package/dist/components/Makeup/Contour.d.ts +17 -0
  174. package/dist/components/Makeup/Eyeliner.d.ts +20 -0
  175. package/dist/components/Makeup/Eyeshadow.d.ts +20 -0
  176. package/dist/components/Makeup/Highlighter.d.ts +18 -0
  177. package/dist/components/Makeup/MakeupDesign.d.ts +37 -0
  178. package/dist/components/Makeup/MakeupRegion.d.ts +132 -0
  179. package/dist/components/Makeup/constants.d.ts +44 -0
  180. package/dist/components/Makeup/design.d.ts +106 -0
  181. package/dist/components/Makeup/designSamples.d.ts +42 -0
  182. package/dist/components/Makeup/eyes.d.ts +114 -0
  183. package/dist/components/Makeup/fields.d.ts +10 -0
  184. package/dist/components/Makeup/geometry.d.ts +106 -0
  185. package/dist/components/Makeup/index.d.ts +26 -0
  186. package/dist/components/Makeup/looks.d.ts +28 -0
  187. package/dist/components/Makeup/material.d.ts +239 -0
  188. package/dist/components/Makeup/settings.d.ts +54 -0
  189. package/dist/components/Makeup/shades.d.ts +143 -0
  190. package/dist/components/Makeup/shapes.d.ts +27 -0
  191. package/dist/components/Makeup/skinTone.d.ts +135 -0
  192. package/dist/components/Makeup/types.d.ts +110 -0
  193. package/dist/components/Makeup/useMakeupSkinTone.d.ts +40 -0
  194. package/dist/components/Necklace/Necklace.d.ts +44 -0
  195. package/dist/components/Necklace/index.d.ts +1 -0
  196. package/dist/components/ParticleEmitter/ParticleEmitter.d.ts +69 -0
  197. package/dist/components/ParticleEmitter/index.d.ts +1 -0
  198. package/dist/components/PersonCutout/index.d.ts +50 -0
  199. package/dist/components/PersonCutout/personCutout.d.ts +16 -0
  200. package/dist/components/ScreenImage/components/ScreenImageBody.d.ts +1 -1
  201. package/dist/components/ScreenImage/index.d.ts +3 -1
  202. package/dist/components/ScreenImage/materials/ScreenImageBlendMaterial.d.ts +1 -1
  203. package/dist/components/ScreenImage/materials/ScreenImageMaskMaterial.d.ts +11 -0
  204. package/dist/components/ScreenImage/source.d.ts +6 -0
  205. package/dist/components/ScreenImage/types.d.ts +18 -0
  206. package/dist/components/SegmentationOverlay/SegmentationOverlay.d.ts +37 -0
  207. package/dist/components/SegmentationOverlay/SegmentationOverlayMaterial.d.ts +31 -0
  208. package/dist/components/SegmentationOverlay/index.d.ts +9 -0
  209. package/dist/components/SegmentationOverlay/maskTexture.d.ts +23 -0
  210. package/dist/components/SegmentationOverlay/providers.d.ts +72 -0
  211. package/dist/components/SegmentationOverlay/settings.d.ts +65 -0
  212. package/dist/components/ShoulderOccluder/index.d.ts +43 -0
  213. package/dist/components/ShoulderOccluder/useCanonicalTorsoFit.d.ts +24 -0
  214. package/dist/components/SpringSwing/SpringSwing.d.ts +22 -0
  215. package/dist/components/SpringSwing/index.d.ts +1 -0
  216. package/dist/components/XRProvider/index.d.ts +16 -2
  217. package/dist/components/XRScene/renderOutputTarget.d.ts +12 -0
  218. package/dist/components/XRViewport/hooks/useViewportExternalFaces.d.ts +1 -1
  219. package/dist/components/XRViewport/hooks/useViewportMediaSource.d.ts +1 -1
  220. package/dist/components/XRViewport/hooks/useViewportPipeline.d.ts +1 -1
  221. package/dist/components/index.d.ts +11 -0
  222. package/dist/config/index.d.ts +0 -1
  223. package/dist/constants/index.d.ts +4 -1
  224. package/dist/context-DTxSQvp4.js +13 -0
  225. package/dist/context-hA0Rb2Xa.cjs +1 -0
  226. package/dist/contexts-BH7PdKFS.cjs +1 -0
  227. package/dist/contexts-jak8-tND.js +667 -0
  228. package/dist/coordinates/feed.d.ts +52 -0
  229. package/dist/coordinates/index.d.ts +7 -0
  230. package/dist/coordinates/side.d.ts +40 -0
  231. package/dist/coordinates/spaces.d.ts +49 -0
  232. package/dist/coordinates/viewport.d.ts +22 -0
  233. package/dist/coordinates/world.d.ts +15 -0
  234. package/dist/debug-ui/default-setting.cjs +2 -2
  235. package/dist/debug-ui/face-swap-settings/index.d.ts +22 -0
  236. package/dist/debug-ui/gesture-settings/index.d.ts +14 -0
  237. package/dist/debug-ui/hierarchy-panel/index.d.ts +3 -2
  238. package/dist/debug-ui/holistic-tracker-settings/index.d.ts +16 -0
  239. package/dist/debug-ui/index.d.ts +18 -3
  240. package/dist/debug-ui/iris-effect-settings/index.d.ts +12 -0
  241. package/dist/debug-ui/lip-effect-settings/index.d.ts +15 -0
  242. package/dist/debug-ui/media-source/index.d.ts +1 -1
  243. package/dist/debug-ui/media-source/session.d.ts +30 -2
  244. package/dist/debug-ui/media-source.cjs +1 -1
  245. package/dist/debug-ui/media-source.js +1 -1
  246. package/dist/debug-ui/object-inspector-panel/index.d.ts +3 -2
  247. package/dist/debug-ui/product-hotspots/index.d.ts +25 -0
  248. package/dist/debug-ui/scene-editor/hierarchy-panel.d.ts +3 -1
  249. package/dist/debug-ui/scene-editor/inspector-panel.d.ts +3 -1
  250. package/dist/debug-ui/screen-image-settings/index.d.ts +3 -1
  251. package/dist/debug-ui/screen-text-settings/ScreenTextSettingsPanel.d.ts +1 -1
  252. package/dist/debug-ui/screen-text-settings/types.d.ts +2 -0
  253. package/dist/debug-ui/segmentation-overlay-settings/index.d.ts +12 -0
  254. package/dist/debug-ui/settings-panel/index.d.ts +6 -1
  255. package/dist/debug-ui/shared/debugWindow.d.ts +51 -0
  256. package/dist/debug-ui/xr-diagnostics/index.d.ts +26 -0
  257. package/dist/debug-ui.cjs +3 -3
  258. package/dist/debug-ui.js +2695 -2547
  259. package/dist/detector-K8aej4MB.js +59 -0
  260. package/dist/detector-ijypGtse.cjs +1 -0
  261. package/dist/entries/all.d.ts +3 -1
  262. package/dist/entries/core.d.ts +20 -2
  263. package/dist/entries/face-effects.d.ts +123 -9
  264. package/dist/entries/instructions.d.ts +48 -0
  265. package/dist/entries/internal.d.ts +2 -1
  266. package/dist/entries/low-level.d.ts +49 -3
  267. package/dist/entries/particles.d.ts +11 -0
  268. package/dist/entries/product.d.ts +11 -0
  269. package/dist/entries/tracking.d.ts +60 -2
  270. package/dist/face-atlas/attributes.d.ts +30 -0
  271. package/dist/face-atlas/eyes.d.ts +272 -0
  272. package/dist/face-atlas/faceAtlas.generated.d.ts +46 -0
  273. package/dist/face-atlas/glsl/atlasVertex.d.ts +46 -0
  274. package/dist/face-atlas/glsl/common.d.ts +55 -0
  275. package/dist/face-atlas/glsl/design.d.ts +49 -0
  276. package/dist/face-atlas/glsl/eyes.d.ts +73 -0
  277. package/dist/face-atlas/glsl/finish.d.ts +24 -0
  278. package/dist/face-atlas/glsl/format.d.ts +4 -0
  279. package/dist/face-atlas/glsl/index.d.ts +59 -0
  280. package/dist/face-atlas/glsl/shading.d.ts +15 -0
  281. package/dist/face-atlas/glsl/shapes.d.ts +66 -0
  282. package/dist/face-atlas/glsl/sparkle.d.ts +19 -0
  283. package/dist/face-atlas/glsl/uniforms.d.ts +106 -0
  284. package/dist/face-atlas/guide.d.ts +51 -0
  285. package/dist/face-atlas/index.d.ts +25 -0
  286. package/dist/face-atlas/lead.d.ts +117 -0
  287. package/dist/face-atlas/madeUpCamera.d.ts +125 -0
  288. package/dist/face-atlas/masks.d.ts +53 -0
  289. package/dist/face-atlas/obj.d.ts +69 -0
  290. package/dist/face-atlas/polylines.d.ts +63 -0
  291. package/dist/face-atlas/probe/FaceSkinProbe.d.ts +208 -0
  292. package/dist/face-atlas/probe/__fixtures__/emulate.d.ts +9 -0
  293. package/dist/face-atlas/probe/__fixtures__/face.d.ts +24 -0
  294. package/dist/face-atlas/probe/constants.d.ts +137 -0
  295. package/dist/face-atlas/probe/glsl.d.ts +43 -0
  296. package/dist/face-atlas/probe/lightFit.d.ts +108 -0
  297. package/dist/face-atlas/probe/schedule.d.ts +44 -0
  298. package/dist/face-atlas/probe/selfTest.d.ts +87 -0
  299. package/dist/face-atlas/probe/stats.d.ts +143 -0
  300. package/dist/face-atlas/probe/targets.d.ts +70 -0
  301. package/dist/face-atlas/probe/unwrap.d.ts +76 -0
  302. package/dist/face-atlas/quality.d.ts +28 -0
  303. package/dist/face-atlas/regions.d.ts +31 -0
  304. package/dist/face-atlas/registry.d.ts +252 -0
  305. package/dist/face-atlas/renderState.d.ts +86 -0
  306. package/dist/face-atlas/selfOcclusion.d.ts +62 -0
  307. package/dist/face-atlas/shading.d.ts +406 -0
  308. package/dist/face-atlas/shapes.d.ts +86 -0
  309. package/dist/face-atlas/sides.d.ts +41 -0
  310. package/dist/face-atlas/skinMask.d.ts +35 -0
  311. package/dist/face-atlas/surface.d.ts +155 -0
  312. package/dist/face-atlas/topology.d.ts +44 -0
  313. package/dist/face-character/__fixtures__/faceImageDetections.d.ts +25 -0
  314. package/dist/face-character/__fixtures__/faceNode.d.ts +22 -0
  315. package/dist/face-character/bindFaceModel.d.ts +106 -0
  316. package/dist/face-character/canonicalFace.d.ts +17 -0
  317. package/dist/face-character/canonicalFaceGeometry.d.ts +11 -0
  318. package/dist/face-character/canonicalFacePositions.d.ts +7 -0
  319. package/dist/face-character/driveFaceModel.d.ts +57 -0
  320. package/dist/face-character/expressionOutputs.d.ts +45 -0
  321. package/dist/face-character/faceExpressions.d.ts +104 -0
  322. package/dist/face-character/faceImageLandmarker.d.ts +93 -0
  323. package/dist/face-character/faceMeshBinding.d.ts +62 -0
  324. package/dist/face-character/faceMorph.d.ts +77 -0
  325. package/dist/face-character/faceMorphs.d.ts +46 -0
  326. package/dist/face-character/facePhoto.d.ts +138 -0
  327. package/dist/face-character/facePiercings.d.ts +116 -0
  328. package/dist/face-character/facePin.d.ts +131 -0
  329. package/dist/face-character/faceReprojection.d.ts +273 -0
  330. package/dist/face-character/faceReprojector.d.ts +171 -0
  331. package/dist/face-character/faceRig.d.ts +176 -0
  332. package/dist/face-character/faceSwapPresence.d.ts +85 -0
  333. package/dist/face-character/faceTexture.d.ts +169 -0
  334. package/dist/face-character/faceTextureBaker.d.ts +86 -0
  335. package/dist/face-character/faceTextureGuide.d.ts +106 -0
  336. package/dist/face-character/faceTextureStats.d.ts +298 -0
  337. package/dist/face-character/faceTransfer.d.ts +396 -0
  338. package/dist/face-character/faceTransferGeometry.d.ts +109 -0
  339. package/dist/face-character/faceTransferSelfTest.d.ts +94 -0
  340. package/dist/face-character/faceWarp3D.d.ts +101 -0
  341. package/dist/face-character/faceless.d.ts +79 -0
  342. package/dist/face-character/featureWarp.d.ts +28 -0
  343. package/dist/face-character/liveFaceRegistry.d.ts +370 -0
  344. package/dist/face-character/liveValue.d.ts +12 -0
  345. package/dist/face-character/memo.d.ts +15 -0
  346. package/dist/face-effects.cjs +2324 -1
  347. package/dist/face-effects.js +14208 -2268
  348. package/dist/face-expression/index.d.ts +182 -0
  349. package/dist/face-info/landmarks.d.ts +17 -3
  350. package/dist/face-info/types.d.ts +20 -3
  351. package/dist/gestures/definitions.d.ts +98 -0
  352. package/dist/gestures/detector.d.ts +87 -0
  353. package/dist/gestures/index.d.ts +8 -0
  354. package/dist/gestures/measures.d.ts +114 -0
  355. package/dist/gestures/settings.d.ts +49 -0
  356. package/dist/getFaceInfo-B1otSDMX.cjs +1 -0
  357. package/dist/getFaceInfo-Cu4xDWiL.js +62 -0
  358. package/dist/hand/armFit.d.ts +46 -0
  359. package/dist/hand/armMask.d.ts +178 -0
  360. package/dist/hand/handCutout.d.ts +23 -0
  361. package/dist/hand/handCutoutRegistry.d.ts +7 -0
  362. package/dist/hand/handGestures.d.ts +524 -0
  363. package/dist/hand/handPose.d.ts +98 -0
  364. package/dist/hand/handRigSolver.d.ts +159 -0
  365. package/dist/hand/handTattoo.d.ts +81 -0
  366. package/dist/hand/handTouch.d.ts +240 -0
  367. package/dist/hand/wrist.d.ts +44 -0
  368. package/dist/hand/wristFilter.d.ts +44 -0
  369. package/dist/hooks/selectors.d.ts +76 -1
  370. package/dist/hooks/useCalibrationFaceTracker.d.ts +1 -1
  371. package/dist/hooks/useFaceInfo.d.ts +13 -1
  372. package/dist/hooks/useFaceInfos.d.ts +1 -1
  373. package/dist/hooks/useFaceModelAcquisition.d.ts +38 -0
  374. package/dist/hooks/useGesture.d.ts +32 -0
  375. package/dist/hooks/useIrisTracking.d.ts +45 -0
  376. package/dist/hooks/useTrackerContext.d.ts +6 -0
  377. package/dist/hooks/useXRDiagnostics.d.ts +81 -0
  378. package/dist/hooks/useXRModel.d.ts +7 -0
  379. package/dist/hooks/useXRSession/facade.d.ts +42 -2
  380. package/dist/hooks/useXRSession/index.d.ts +2 -2
  381. package/dist/hooks/useXRSession/reason.d.ts +3 -1
  382. package/dist/hooks/useXRSession/registry.d.ts +14 -0
  383. package/dist/hooks/useXRSession/store.d.ts +52 -3
  384. package/dist/index-B1_TzJaI.js +1104 -0
  385. package/dist/index-BavF06C6.js +190 -0
  386. package/dist/index-BfFmpddl.cjs +21 -0
  387. package/dist/index-BuBzneeW.cjs +46 -0
  388. package/dist/index-CGsQWodV.cjs +1 -0
  389. package/dist/index-CIe7eCMH.js +3200 -0
  390. package/dist/index-CfSF8LXa.cjs +1 -0
  391. package/dist/index-D5GTzOzD.cjs +1 -0
  392. package/dist/index-DBhQzvVa.js +314 -0
  393. package/dist/index-DE17y0ZI.cjs +1 -0
  394. package/dist/index-JII7huPk.js +442 -0
  395. package/dist/index-tpCr9CLj.cjs +1 -0
  396. package/dist/index-w1S7fI2B.js +1432 -0
  397. package/dist/index-zGaqrz_K.js +188 -0
  398. package/dist/instructions.cjs +30 -0
  399. package/dist/instructions.js +1507 -0
  400. package/dist/{internal-Dmk1cTXq.js → internal-B90P-clC.js} +138 -119
  401. package/dist/internal-Cjinca64.cjs +1 -0
  402. package/dist/internal.cjs +1 -1
  403. package/dist/internal.js +15 -10
  404. package/dist/iris/compute.d.ts +27 -0
  405. package/dist/iris/index.d.ts +4 -0
  406. package/dist/iris/lead.d.ts +19 -0
  407. package/dist/iris/types.d.ts +89 -0
  408. package/dist/landmarkMask-BFDyBnKM.js +224 -0
  409. package/dist/landmarkMask-u7es2k4X.cjs +1 -0
  410. package/dist/landmarks-BlUqf5MZ.cjs +1 -0
  411. package/dist/landmarks-bftdwq6Z.js +76 -0
  412. package/dist/loaders-BGAUACsd.js +363 -0
  413. package/dist/loaders-BJ1_QCHt.cjs +1 -0
  414. package/dist/low-level.cjs +1 -1
  415. package/dist/low-level.js +1190 -675
  416. package/dist/main.cjs +1 -1
  417. package/dist/main.js +1190 -452
  418. package/dist/models/Base/index.d.ts +49 -0
  419. package/dist/models/Body/index.d.ts +3 -1
  420. package/dist/models/Face/constants.d.ts +8 -0
  421. package/dist/models/Face/index.d.ts +4 -12
  422. package/dist/models/Face/rotation.d.ts +18 -3
  423. package/dist/models/Hand/GestureTracking.d.ts +1 -1
  424. package/dist/models/Hand/HandTracking.d.ts +17 -1
  425. package/dist/models/Holistic/index.d.ts +49 -0
  426. package/dist/models/Holistic/result.d.ts +68 -0
  427. package/dist/models/Segmentation/index.d.ts +2 -0
  428. package/dist/models/SemanticSegmentation/index.d.ts +31 -0
  429. package/dist/models/SemanticSegmentation/presets.d.ts +28 -0
  430. package/dist/models/index.d.ts +2 -0
  431. package/dist/models/nodeSource.d.ts +9 -0
  432. package/dist/particles/emission.d.ts +24 -0
  433. package/dist/particles/eyes.d.ts +24 -0
  434. package/dist/particles/glsl.d.ts +14 -0
  435. package/dist/particles/index.d.ts +10 -0
  436. package/dist/particles/motion.d.ts +42 -0
  437. package/dist/particles/presets.d.ts +12 -0
  438. package/dist/particles/ring.d.ts +58 -0
  439. package/dist/particles/selfTest.d.ts +53 -0
  440. package/dist/particles/settings.d.ts +127 -0
  441. package/dist/particles/shapes.d.ts +29 -0
  442. package/dist/particles/spawner.d.ts +60 -0
  443. package/dist/particles/system.d.ts +64 -0
  444. package/dist/particles.cjs +122 -0
  445. package/dist/particles.js +774 -0
  446. package/dist/product/ProductDimensions.d.ts +16 -0
  447. package/dist/product/ProductHotspot.d.ts +16 -0
  448. package/dist/product/ProductViewer.d.ts +9 -0
  449. package/dist/product/details.d.ts +53 -0
  450. package/dist/product/index.d.ts +14 -0
  451. package/dist/product/loadModelViewer.d.ts +4 -0
  452. package/dist/product/types.d.ts +71 -0
  453. package/dist/product/useProductAr.d.ts +37 -0
  454. package/dist/product/useProductDetails.d.ts +60 -0
  455. package/dist/product.cjs +1 -0
  456. package/dist/product.js +414 -0
  457. package/dist/providers-C8rE26Uf.js +366 -0
  458. package/dist/providers-DHsrhDI2.cjs +62 -0
  459. package/dist/quality/XRQualityController.d.ts +25 -0
  460. package/dist/quality/controller.d.ts +33 -0
  461. package/dist/quality/index.d.ts +6 -0
  462. package/dist/quality/types.d.ts +100 -0
  463. package/dist/quality/useXRQuality.d.ts +28 -0
  464. package/dist/render/renderPasses.d.ts +8 -0
  465. package/dist/render/sceneBeforeRender.d.ts +12 -0
  466. package/dist/{renderGroups-KZk6eRiY.js → renderGroups-B38pUaX2.js} +1 -1
  467. package/dist/{renderGroups-80H3DpTl.cjs → renderGroups-Cb_4Ar1Q.cjs} +1 -1
  468. package/dist/renderPasses-B6l8IpJv.js +1290 -0
  469. package/dist/renderPasses-dqmkft4P.cjs +158 -0
  470. package/dist/renderState-CJNmj5jz.js +39 -0
  471. package/dist/renderState-apSfg4eR.cjs +1 -0
  472. package/dist/scene-object.cjs +1 -1
  473. package/dist/scene-object.js +2 -2
  474. package/dist/segmentation-Cb3ouK6Z.js +1758 -0
  475. package/dist/segmentation-D9pYO6aR.cjs +1 -0
  476. package/dist/segmentation2d/faceMemory.d.ts +28 -0
  477. package/dist/segmentation2d/faceRegions.d.ts +24 -0
  478. package/dist/segmentation2d/index.d.ts +9 -0
  479. package/dist/segmentation2d/maskUv.d.ts +23 -0
  480. package/dist/segmentation2d/rasterize.d.ts +14 -0
  481. package/dist/segmentation2d/types.d.ts +52 -0
  482. package/dist/select-Ck5LGz-J.cjs +1 -0
  483. package/dist/select-pYRo_win.js +233 -0
  484. package/dist/selectors-C4X71aoD.cjs +1 -0
  485. package/dist/selectors-DmNaKIwE.js +196 -0
  486. package/dist/session-BrH8G7iJ.cjs +31 -0
  487. package/dist/session-DgA_z6O1.js +418 -0
  488. package/dist/settings-BJ7FMBsO.js +111 -0
  489. package/dist/settings-C63FMBlF.cjs +1 -0
  490. package/dist/similarityFit-BFqHND2e.cjs +1 -0
  491. package/dist/similarityFit-Bbz-R8AY.js +91 -0
  492. package/dist/spring/index.d.ts +2 -0
  493. package/dist/spring/spring.d.ts +69 -0
  494. package/dist/spring/swing.d.ts +54 -0
  495. package/dist/subjects/index.d.ts +2 -0
  496. package/dist/subjects/select.d.ts +62 -0
  497. package/dist/subjects/types.d.ts +55 -0
  498. package/dist/tracking-config/apply.d.ts +57 -0
  499. package/dist/tracking-config/index.d.ts +7 -0
  500. package/dist/tracking-config/resolve.d.ts +25 -0
  501. package/dist/tracking-config/storage.d.ts +8 -0
  502. package/dist/tracking-config/types.d.ts +106 -0
  503. package/dist/tracking-config/useXRTrackingConfig.d.ts +38 -0
  504. package/dist/tracking.cjs +10 -1
  505. package/dist/tracking.js +1326 -506
  506. package/dist/trigger-D0Pm9noT.cjs +49 -0
  507. package/dist/trigger-IQeys0oS.js +2128 -0
  508. package/dist/types/compositor.d.ts +21 -0
  509. package/dist/types/face.d.ts +20 -1
  510. package/dist/types/hand-tracking.d.ts +9 -0
  511. package/dist/types/holistic.d.ts +121 -0
  512. package/dist/types/index.d.ts +1 -0
  513. package/dist/types/model.d.ts +22 -2
  514. package/dist/types/nodes.d.ts +47 -3
  515. package/dist/types/segmentation.d.ts +24 -0
  516. package/dist/types/session.d.ts +41 -3
  517. package/dist/updateThrottle-BseecYag.js +4 -0
  518. package/dist/updateThrottle-Of5Y4SVa.cjs +1 -0
  519. package/dist/useFaceInfo-BHDNCvsJ.cjs +1 -0
  520. package/dist/useFaceInfo-J4x7LsqL.js +76 -0
  521. package/dist/useFaceResultReader-BvEo5REG.js +61 -0
  522. package/dist/useFaceResultReader-DuaL1KJG.cjs +1 -0
  523. package/dist/useInstructionHold-DOu-RpCM.js +53 -0
  524. package/dist/useInstructionHold-DwJY1Alr.cjs +1 -0
  525. package/dist/useLandmarkPoseFit-Bg-h9BPb.cjs +1 -0
  526. package/dist/useLandmarkPoseFit-Bmb3h6Mw.js +87 -0
  527. package/dist/useXRCapabilities-Cr3RzuAW.cjs +1 -0
  528. package/dist/useXRCapabilities-Cxmlmpbd.js +30 -0
  529. package/dist/utils/canonicalRigidLandmarks.d.ts +8 -0
  530. package/dist/utils/fns.d.ts +6 -3
  531. package/dist/utils/headOccluderFit.d.ts +42 -0
  532. package/dist/utils/integrity.d.ts +21 -1
  533. package/dist/utils/resolveNumFaces.d.ts +13 -0
  534. package/dist/utils/shoulderOccluderFit.d.ts +38 -0
  535. package/dist/utils/similarityFit.d.ts +23 -0
  536. package/dist/utils/updateThrottle.d.ts +2 -0
  537. package/dist/utils/useStableUniforms.d.ts +18 -0
  538. package/dist/uv-BMFt19bg.cjs +1 -0
  539. package/dist/{index-ByoNj0QP.js → uv-DJU_XfmN.js} +15 -247
  540. package/docs/SDK_DOCUMENTATION.md +1 -2
  541. package/docs/api/adaptive-quality.mdx +104 -0
  542. package/docs/api/asset-lifecycle.mdx +78 -0
  543. package/docs/api/body-instructions.mdx +285 -0
  544. package/docs/api/body-triggers.mdx +234 -0
  545. package/docs/api/camera-permission.mdx +142 -0
  546. package/docs/api/coordinate-spaces.mdx +168 -0
  547. package/docs/api/cross-camera.mdx +89 -0
  548. package/docs/api/debug-ui-scene-editor.mdx +23 -2
  549. package/docs/api/diagnostics-calibration.mdx +97 -0
  550. package/docs/api/external-face-mesh.mdx +231 -0
  551. package/docs/api/face-actions.mdx +20 -16
  552. package/docs/api/face-attribute-expression.mdx +1 -1
  553. package/docs/api/face-binding-anchors.mdx +4 -2
  554. package/docs/api/face-character.mdx +157 -0
  555. package/docs/api/face-effects.mdx +9 -0
  556. package/docs/api/face-expression-controller.mdx +153 -0
  557. package/docs/api/face-info.mdx +17 -11
  558. package/docs/api/face-inset.mdx +204 -0
  559. package/docs/api/face-instructions.mdx +183 -0
  560. package/docs/api/face-liquify.mdx +196 -0
  561. package/docs/api/face-mesh.mdx +8 -9
  562. package/docs/api/face-morph.mdx +117 -0
  563. package/docs/api/face-painting.mdx +7 -0
  564. package/docs/api/face-reprojection.mdx +154 -0
  565. package/docs/api/face-retouching.mdx +18 -10
  566. package/docs/api/face-swap.mdx +350 -0
  567. package/docs/api/face-warp-3d.mdx +166 -0
  568. package/docs/api/faceless.mdx +143 -0
  569. package/docs/api/gestures.mdx +209 -0
  570. package/docs/api/hair.mdx +97 -0
  571. package/docs/api/hand-instructions.mdx +222 -0
  572. package/docs/api/hand-rig.mdx +535 -0
  573. package/docs/api/hand-touch.mdx +162 -0
  574. package/docs/api/head-occluder.mdx +563 -0
  575. package/docs/api/holistic-tracker.mdx +164 -0
  576. package/docs/api/instructions.mdx +323 -0
  577. package/docs/api/iris-tracking.mdx +247 -0
  578. package/docs/api/made-up-camera.mdx +131 -0
  579. package/docs/api/makeup-skin-tone.mdx +135 -0
  580. package/docs/api/makeup.mdx +353 -0
  581. package/docs/api/multi-subject.mdx +98 -0
  582. package/docs/api/particles.mdx +155 -0
  583. package/docs/api/person-cutout.mdx +136 -0
  584. package/docs/api/pin-to-face-mesh.mdx +274 -0
  585. package/docs/api/product-ar.mdx +114 -0
  586. package/docs/api/product-details.mdx +78 -0
  587. package/docs/api/screen-space-coordinates.mdx +4 -1
  588. package/docs/api/segmentation-overlay.mdx +301 -0
  589. package/docs/api/session-lifecycle.mdx +136 -0
  590. package/docs/api/trackers.mdx +5 -0
  591. package/docs/api/tracking-config.mdx +108 -0
  592. package/docs/docs.json +51 -1
  593. package/docs/examples/lip-shaders.mdx +273 -0
  594. package/docs/guides/face-atlas-template.svg +1 -0
  595. package/docs/guides/face-atlas-textures.mdx +186 -0
  596. package/docs/guides/face-texture-template.svg +1 -0
  597. package/docs/guides/harness-debug-ui.mdx +4 -4
  598. package/docs/guides/lip-effect-textures.mdx +368 -0
  599. package/docs/guides/lip-uv-template.png +0 -0
  600. package/docs/guides/lip-uv-template.svg +1 -0
  601. package/docs/guides/makeup-design-textures.mdx +109 -0
  602. package/docs/introduction.mdx +1 -2
  603. package/package.json +23 -1
  604. package/dist/DebuggerUI-B6bP6P9r.cjs +0 -1
  605. package/dist/DebuggerUI-BjOMr8q_.js +0 -269
  606. package/dist/FaceMeshRenderer-C5l6VLdO.cjs +0 -155
  607. package/dist/FaceMeshRenderer-wjAHrJzP.js +0 -1270
  608. package/dist/FaceRetouch-BkJzoA79.cjs +0 -134
  609. package/dist/FaceRetouch-DwbKQJAN.js +0 -551
  610. package/dist/components/FaceWarp3D/FaceWarp3DHead.d.ts +0 -15
  611. package/dist/components/FaceWarp3D/defaults.d.ts +0 -37
  612. package/dist/components/FaceWarp3D/warp.d.ts +0 -13
  613. package/dist/contexts-ByhzppYl.js +0 -663
  614. package/dist/contexts-Dr62It_K.cjs +0 -1
  615. package/dist/debug-ui/face-warp-3d/index.d.ts +0 -6
  616. package/dist/getFaceInfo-C4QpCQIY.js +0 -118
  617. package/dist/getFaceInfo-fA1bFBub.cjs +0 -1
  618. package/dist/index-9dlAQAhy.js +0 -1462
  619. package/dist/index-BjmTe9eM.cjs +0 -1
  620. package/dist/index-BpEf2BBb.cjs +0 -1
  621. package/dist/index-CyUUurQT.cjs +0 -1
  622. package/dist/index-DCiMbxC3.cjs +0 -1
  623. package/dist/index-DXT3WccE.js +0 -2089
  624. package/dist/index-DpI-qo5X.cjs +0 -17
  625. package/dist/index-DyVF4vEW.js +0 -111
  626. package/dist/index-VJ0SJwmG.js +0 -214
  627. package/dist/internal-Cq-TEQ5Y.cjs +0 -1
  628. package/dist/renderLayers-lDtL0_43.cjs +0 -1
  629. package/dist/renderLayers-zrK2pv5O.js +0 -13
  630. package/dist/renderPasses-BOoBSr8z.cjs +0 -21
  631. package/dist/renderPasses-BcquyVtu.js +0 -1500
  632. package/dist/selectors-B8H97CKA.js +0 -59
  633. package/dist/selectors-CZLKT2Iv.cjs +0 -1
  634. package/dist/session-CpkiK5YA.cjs +0 -31
  635. package/dist/session-DLFN_VII.js +0 -363
  636. package/dist/useFaceInfo-BJ8-_MOs.cjs +0 -1
  637. package/dist/useFaceInfo-Dk426LTu.js +0 -62
  638. package/dist/useFaceResults-CtetsO9M.js +0 -19
  639. package/dist/useFaceResults-wBJF3zyp.cjs +0 -1
@@ -0,0 +1,563 @@
1
+ ---
2
+ title: "Head Occluder"
3
+ description: "Depth-only head mesh fitted to the tracked face so 3D accessories pass behind the head; the canonical centimetre frame for authoring accessories; earrings on both ear lobes."
4
+ sidebarTitle: "Head Occluder"
5
+ icon: "user-round"
6
+ ---
7
+
8
+ A 3D accessory attached to the head has parts that pass behind the skull: the
9
+ arms of glasses, the back of a halo, an earring at a turn. Without an occluder
10
+ they draw over the camera image. `HeadOccluder` is a depth-only head mesh
11
+ (`colorWrite: false`, `depthWrite: true`, `renderOrder: -1`) that writes depth
12
+ where the head is, so anything behind it fails the depth test.
13
+
14
+ Import from `@vincentt-xr/sdk/face-effects`.
15
+
16
+ ## Quick start
17
+
18
+ ```tsx
19
+ import { HeadAttachment, HeadBinding } from "@vincentt-xr/sdk/face-effects";
20
+
21
+ <HeadBinding faceIndex={0}>
22
+ <HeadAttachment point="noseBridge">
23
+ {/* centimetres around the nose bridge, facing +Z (out of the face) */}
24
+ <Glasses />
25
+ </HeadAttachment>
26
+ </HeadBinding>;
27
+ ```
28
+
29
+ `HeadBinding` mounts a `FaceTracker` (with `scaleWithFace`) and the occluder;
30
+ its `occluder` prop is `true` by default and accepts the options below.
31
+
32
+ ## The canonical frame
33
+
34
+ The v3 head is authored in the MediaPipe canonical face frame: centimetres,
35
+ `+X` toward the screen's right on a face looking at the camera (MediaPipe's
36
+ left: the person's own right in the mirrored selfie view, their left on
37
+ unmirrored sources; GROUNDING "Left and right"), `+Y` up, `+Z` out of the face
38
+ toward the camera. Its first
39
+ 468 vertices are the canonical face landmarks in landmark order, with a skull,
40
+ brow, neck and ears behind them. The source is
41
+ `assets-src/head-occluder/head-occluder-v3.blend`; the published mesh is
42
+ `https://cdn.vincentt.studio/assets/xr/3d-models/head-occluder-v3.glb`,
43
+ integrity-hashed in the SDK.
44
+
45
+ Every frame `solveCanonicalHeadPose` fits the mesh to the live face:
46
+
47
+ | quantity | source |
48
+ | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
49
+ | scale, rotation, translation | the 3D similarity (Umeyama, `solveSimilarity`) that maps the canonical positions of 31 rigid landmarks onto the same landmarks in world space |
50
+ | live x / y | the feed point unprojected onto the `z = 0` plane, where `FaceTracker` lives |
51
+ | live depth | MediaPipe's landmark `z` (normalized-x units, smaller = closer) × the feed's world width |
52
+ | landmark set | `CANONICAL_RIGID_LANDMARKS`: nose bridge and tip, eye corners, cheeks, temples, forehead, upper face oval; no mouth, no lower jaw |
53
+
54
+ The pose is written as a local transform re-expressed in the parent tracker
55
+ group's frame, so it does not inherit the group's scale heuristic or rotation;
56
+ the group only supplies visibility. Typical residual is 0.3–0.5 cm RMS. The
57
+ pose is EMA-smoothed (`smoothing`, default `0.5`; `1` = none) and snaps on
58
+ reacquire. The mesh hides while the face is lost. `onFit(fit)` receives the
59
+ `HeadPoseFit` (`worldUnitsPerCm`, `rms`, `quaternion`, `translation`) each
60
+ fitted frame, for calibration readouts.
61
+
62
+ Other reference points for authoring, centimetres (the named attachment
63
+ points are in the next section):
64
+
65
+ | point | position |
66
+ | --------------------------- | ------------------- |
67
+ | landmark 4 (tracker origin) | `(0, -0.5, 7.6)` |
68
+ | hairline (10) | `(0, 8.3, 4.5)` |
69
+ | cheeks (50 / 280) | `(±4.8, -0.7, 3.5)` |
70
+ | back of skull | `z ≈ -12` |
71
+
72
+ ## Attachment points — `HeadAttachment`
73
+
74
+ Named places on the head, so an accessory never needs a raw landmark index.
75
+ `leftEar` / `rightEar` / `leftEarLobe` / `rightEarLobe` are the person's OWN
76
+ ears on every feed. The table gives them as on an unmirrored feed (the
77
+ person's left ear at canonical `+X`); on the mirrored webcam they swap, which
78
+ `HeadAttachment` does from the session's mirror state (`mirrored` prop to
79
+ override; `resolveHeadAttachmentPoint(point, mirrored)` for tools):
80
+
81
+ | point | cm (x, y, z), unmirrored | source | typical accessory |
82
+ | -------------- | ------------------------ | -------------------------- | ---------------------- |
83
+ | `headCenter` | `(0, 2.7, -2.2)` | centre of the v3 skull | helmets, halos |
84
+ | `crown` | `(0, 13.26, -3.76)` | top of the v3 skull | hats, crowns |
85
+ | `forehead` | `(0, 6.55, 5.03)` | landmark 151 | headbands, bindis |
86
+ | `noseBridge` | `(0, 2.47, 5.79)` | landmark 6 (nose ridge) | glasses, masks |
87
+ | `noseTip` | `(0, -1.13, 7.48)` | landmark 1 | clown noses, piercings |
88
+ | `chin` | `(0, -9.4, 4.26)` | landmark 152 (neutral jaw) | beards |
89
+ | `leftEar` | `(8.84, 1.37, -3.26)` | centre of a v3 ear volume | headphones, ear cuffs |
90
+ | `rightEar` | `(-8.84, 1.37, -3.26)` | centre of a v3 ear volume | headphones, ear cuffs |
91
+ | `leftEarLobe` | `(9.34, -0.73, -3.0)` | v3 lobe piercing, 2 mm out | earrings (`Earrings`) |
92
+ | `rightEarLobe` | `(-9.34, -0.73, -3.0)` | v3 lobe piercing, 2 mm out | earrings (`Earrings`) |
93
+
94
+ ```tsx
95
+ <HeadBinding faceIndex={1} numFaces={2}>
96
+ <HeadAttachment point="crown" offset={{ position: [0, -1.5, 0], rotation: [-0.25, 0, 0] }}>
97
+ <Hat />
98
+ </HeadAttachment>
99
+ {/* the person's right ear; +X is away from the head on either ear */}
100
+ <HeadAttachment point="rightEar" offset={{ position: [0.6, 0, 0] }}>
101
+ <HeadphoneCup />
102
+ </HeadAttachment>
103
+ {/* a pair of earrings: see Earrings below */}
104
+ <Earrings model={earring.scene} />
105
+ </HeadBinding>
106
+ ```
107
+
108
+ - Children are authored in centimetres around the point, in the head's axes,
109
+ facing `+Z`. Model a GLB with its origin at the attachment point (the nose
110
+ pad of a pair of glasses, the inner brim centre of a hat) and it needs no
111
+ offset.
112
+ - `offset.position` (cm, relative to the point), `offset.rotation` (radians)
113
+ and `offset.scale` (multiplier) all apply about the point.
114
+ - Ear points use the ear frame: children and `offset` are authored with `+X`
115
+ away from the head, and the ear on the screen's left (canonical `−X`) gets
116
+ them mirrored, so one accessory fits either ear on any feed.
117
+ - `chin` is the neutral chin: the fit is rigid and ignores the jaw. Use
118
+ `TrackingAnchor target="face.chin"` for something that must open with the
119
+ mouth.
120
+ - Inside a `CanonicalHeadFrame` several attachments share that frame's fit; on
121
+ its own each runs the canonical fit itself (cheap: a 31-point 3×3 solve).
122
+ - `HEAD_ATTACHMENT_POINTS`, `HEAD_ATTACHMENT_POINT_NAMES`,
123
+ `getHeadAttachmentPoint(point, out?, mirrored?)` and
124
+ `resolveHeadAttachmentPoint(point, mirrored?)` (`{ position, mirror }`) expose
125
+ the table for tools.
126
+
127
+ ## Earrings — `Earrings`
128
+
129
+ One earring, authored once in the ear frame, worn on both ear lobes; the one on the screen's left is
130
+ its mirror image (scale `x = −1` about the head's mid-plane, so a piece turned out and forward on one
131
+ ear is turned out and forward on the other too). `left` / `right` are the person's own ears on every
132
+ feed. It clones the model per ear and runs one fit for both.
133
+
134
+ ```tsx
135
+ import { Earrings, HeadBinding } from "@vincentt-xr/sdk/face-effects";
136
+
137
+ const Pair = ({ left, right }: { left: boolean; right: boolean }) => {
138
+ const gltf = useLoader(GLTFLoader, earringUrl);
139
+ return (
140
+ <HeadBinding faceIndex={0}>
141
+ <Earrings model={gltf.scene.getObjectByName("silver_hoop")} left={left} right={right} />
142
+ </HeadBinding>
143
+ );
144
+ };
145
+ ```
146
+
147
+ | prop | meaning |
148
+ | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
149
+ | `model` | `Object3D` (a GLB's `scene` or one node), cloned per ear: shares geometry and materials, `frustumCulled = false`, `renderOrder` 5 (transparent meshes 6) unless a mesh has one |
150
+ | `children` | JSX instead of / with `model`, mounted once per ear (build objects per mount, never one shared `<primitive>`); or `(side) => …` for a mismatched pair |
151
+ | `left` / `right` | wear one on the person's own left / right ear; default `true`; both `false` renders nothing |
152
+ | `offset` | `{ position, rotation, scale }` about the piercing (cm / radians / multiplier), in the ear frame, mirrored with the screen-left earring |
153
+ | `mirrored` | whether the feed is mirrored; default the session's (the front webcam is) |
154
+ | `swing` | swing on a spring about the piercing with head motion, then settle: `true` (gentle), `SpringSwingOptions`, or `false` (default, rigid); each ear swings on its own |
155
+ | `faceIndex`, `smoothing`, `enabled`, `onFit`, `onTrackingChange` | as on `HeadAttachment`; inside a `CanonicalHeadFrame` the frame's fit is reused |
156
+
157
+ **The anchor.** The lobe point is the piercing as seen from outside: on the v3 occluder's ear
158
+ volume at canonical `+X` (`HEAD_ATTACHMENT_POINTS.leftEarLobe`), 0.8 cm above its lowest point and
159
+ 0.26 cm ahead of its centre, moved 2 mm out of its surface (the `−X` lobe is its mirror). The 2 mm is the clearance the glasses keep from the occluder (coplanar surfaces z-fight
160
+ with a depth-only mesh), so an earring authored outward from the origin is never cut on the near
161
+ side.
162
+
163
+ **Authoring an earring GLB.**
164
+
165
+ - Canonical centimetres, object origin on the piercing, in the ear frame (as for the ear at
166
+ canonical `+X`): `+X` away from the head, `+Y` up (hang it along `−Y`), `+Z` out of the face. In Blender that is `(x, y, z)` =
167
+ canonical `(x, −z, y)` with a `+Y Up` glTF export.
168
+ - Keep visible parts at `x ≥ 0` beside the lobe; 0.8 cm below the piercing the ear volume ends and
169
+ the earring hangs free. Anything inside the ear volume is hidden: wanted for a hoop's wire behind
170
+ the lobe, a cut earring otherwise. Measure against the v3 occluder (the source `.blend` keeps it
171
+ as a reference with the piercing at the origin).
172
+ - Turn a flat piece 25–40° toward `+Z`: the front camera sees an ear almost edge-on.
173
+ - Metals need an environment to reflect: set `scene.environment` (e.g. `RoomEnvironment` through
174
+ `PMREMGenerator`, no network). Without it a metallic GLB renders nearly black.
175
+ - Model a dangling part as a child node whose origin is its hinge (the example drop's pendant and
176
+ heart's charm), so a later swinging dangle can hang from the same lobe anchor.
177
+
178
+ **Example sets** (`/head-occluder?earrings=1`, built from nothing by
179
+ `assets-src/accessories/build_earrings.py`, with a README):
180
+
181
+ | GLB | nodes (origin on the piercing) | size |
182
+ | --------------------------- | ---------------------------------------------------------------- | ------- |
183
+ | `earrings-realistic-v1.glb` | `gold_stud`, `silver_hoop`, `rose_drop` (+ `rose_drop_pendant`) | ~89 KB |
184
+ | `earrings-playful-v1.glb` | `star_stud`, `heart_drop` (+ `heart_drop_charm`), `rainbow_hoop` | ~153 KB |
185
+
186
+ The playful set ships plain `toon_*` PBR materials plus an inverted-hull outline (single-sided
187
+ `toon_outline`); the example swaps the `toon_*` colours for `MeshToonMaterial` with a 3-step ramp.
188
+
189
+ **Limitations.**
190
+
191
+ - With `swing`, the whole earring swings about the piercing; a drop's pendant does not swing on
192
+ its own hook.
193
+ - Hair is not an occluder: hair falling over the ears draws behind the earrings.
194
+ - The occluder's ear is a thick average ear, so a hoop's hidden stretch behind the lobe is longer
195
+ than on a real one, and the piercing can sit a few millimetres off a real lobe; nudge with
196
+ `offset.position`.
197
+
198
+ ## Face index and tracking contract
199
+
200
+ - `faceIndex` on `HeadAttachment`, `CanonicalHeadFrame` and `HeadOccluder`
201
+ defaults to the enclosing `FaceTracker` / `HeadBinding`. Set it only to read
202
+ a different face than the group you are in.
203
+ - The fits read the parent tracker's model and never acquire it, so the
204
+ tracker's `numFaces` always decides how many faces are detected.
205
+ They therefore need an enclosing `FaceTracker` / `HeadBinding`; on a bare
206
+ group `useCanonicalHeadFit` finds no model and keeps the object hidden.
207
+ - **Lost:** the fitted object hides the same frame; nothing is left frozen.
208
+ - **Found / reacquired:** it snaps to the new pose; no easing in from the old
209
+ place.
210
+ - **Face swap:** a jump of more than `LANDMARK_POSE_FIT_SNAP_CM` (20 cm) in one
211
+ frame — another person took the index — snaps instead of sliding across.
212
+ - `onTrackingChange(tracked)` fires once on found and once on lost, never per
213
+ frame. The state machine is the pure `stepLandmarkPoseSmoothing`; its optional
214
+ `snapDistance` is in the fit's source units (default 20 for these centimetre fits).
215
+ - MediaPipe result indices are not identities: with several people, index 1 can
216
+ move to someone else when a face enters or leaves. See
217
+ [Multi-subject](/api/multi-subject) for sticky selection.
218
+
219
+ ## `CanonicalHeadFrame`
220
+
221
+ The same fit applied to a plain group. Children authored in canonical
222
+ centimetres land exactly where the occluder expects them, so a modeller can
223
+ measure an accessory against the `.blend` and ship it without per-scene tuning.
224
+
225
+ ```tsx
226
+ <CanonicalHeadFrame faceIndex={0} offset={{ position: [0, 0.5, 0] }} smoothing={0.35}>
227
+ <primitive object={glasses.scene} />
228
+ </CanonicalHeadFrame>
229
+ ```
230
+
231
+ Props: `faceIndex` (default: the parent tracker's), `offset`, `smoothing`,
232
+ `enabled`, `onFit`, `onTrackingChange`.
233
+ `useCanonicalHeadFit(ref, options)` is the hook behind it, for driving an
234
+ existing `Object3D`.
235
+
236
+ ## Options
237
+
238
+ `HeadOccluder` props, also accepted by `HeadBinding`'s `occluder` object:
239
+
240
+ - `fit`: `"canonical"` (default, v3 head) or `"manual"` (legacy v2 shell).
241
+ - `faceIndex`: which tracked face feeds the fit; defaults to the parent tracker's.
242
+ - `offset`: `{ position?: [x, y, z], rotation?: [rx, ry, rz], scale?: k }` on
243
+ top of the canonical fit. Position in canonical centimetres (rotates with the
244
+ head), rotation in radians after the head rotation, scale as a multiplier.
245
+ - `smoothing`: EMA factor for the fitted pose.
246
+ - `onFit`: per-frame `HeadPoseFit` callback (readouts; no React state at frame rate).
247
+ - `url`: a different mesh. The canonical fit expects a v3-frame mesh.
248
+ - `showDebugMaterial` / `opacity`: draw the occluder visibly for calibration.
249
+ Never ship it on.
250
+ - Manual fit only: `position` (default `[0, 0, -10]`), `rotation`, `scale`
251
+ (default `[0.5, 0.5, 0.5]`), applied verbatim inside the tracker group.
252
+
253
+ ## Render contract
254
+
255
+ - Accessory materials keep `depthTest` on (the default). A transparent
256
+ material still depth-tests against the occluder.
257
+ - The occluder lives inside the same `FaceTracker` and face index as the
258
+ accessory; `HeadBinding` guarantees this.
259
+ - `frustumCulled` is off on the occluder because its bounds move every frame.
260
+ - The occluder is `DoubleSide`: the face region is an open shell, the skull is
261
+ closed, and the two overlap on purpose.
262
+
263
+ ## Shoulder occluder
264
+
265
+ `ShoulderOccluder` (from `@vincentt-xr/sdk/tracking`, under a `BodyTracker`)
266
+ is the same idea for the shoulders and upper torso: a depth-only mesh in a
267
+ canonical **torso** frame — centimetres, origin at the midpoint of the shoulder
268
+ joints, `+X` screen right in the selfie view, `+Y` up, `+Z` toward the camera;
269
+ shoulders at `x = ±18` — fitted every frame from pose landmarks 11 / 12 only
270
+ (`solveShoulderPose`): scale from their distance, roll from the line between
271
+ them, yaw from their depth difference, no pitch. Nothing below the shoulders is
272
+ read: this is a selfie-mode occluder, and hips predicted out of frame inflated
273
+ the torso at close range. `CanonicalTorsoFrame` places accessories authored in
274
+ torso centimetres (a necklace at `[0, -2, 2]`, a strap, wings behind the
275
+ shoulder blades). Mount it beside `HeadBinding` for a full head-and-shoulders
276
+ occluder; the two neck stubs overlap on purpose.
277
+
278
+ ```tsx
279
+ <BodyTracker bodyIndex={0}>
280
+ <ShoulderOccluder offset={{ scale: 1.05 }} />
281
+ <CanonicalTorsoFrame>{/* torso cm */}</CanonicalTorsoFrame>
282
+ </BodyTracker>
283
+ ```
284
+
285
+ Props: `bodyIndex`, `offset`, `smoothing`, `url`, `showDebugMaterial`,
286
+ `opacity`, `onFit`. Asset: `/assets/xr/3d-models/shoulder-occluder-v1.glb`
287
+ (integrity-hashed; published with the same release as the v3 head).
288
+
289
+ ## Neck and shoulders — `neck`
290
+
291
+ The head occluder stops at the neck. `neck` adds a depth-only bust (neck and shoulders) so what
292
+ passes behind the neck and shoulders hides too: a necklace's back, a collar, hair down the back.
293
+
294
+ ```tsx
295
+ <HeadBinding occluder={{ neck: "bust" }}>{/* accessories */}</HeadBinding>
296
+ ```
297
+
298
+ | option | default | meaning |
299
+ | -------------- | -------- | ---------------------------------------------------------------------------------------------- |
300
+ | `type` | `"bust"` | the mesh (`NECK_OCCLUDER_TYPES`) |
301
+ | `follow` | `"head"` | `"head"`: moved by the head fit, no body tracking; `"torso"`: by the torso fit (body tracking) |
302
+ | `shoulderTurn` | 0.25 | with `"head"`: how much of the head's turn the shoulders take |
303
+ | `url` | the CDN | the mesh |
304
+ | `offset` | none | a nudge, head cm (`"head"`) or torso cm (`"torso"`) |
305
+ | `bodyIndex` | 0 | with `"torso"`: the body |
306
+
307
+ **Moved by the head.** The bust hangs from the head: the top of its neck follows the head, and its
308
+ two lower neck bones each bend half of what keeps the shoulders level and facing the camera
309
+ (`neckBoneTwist`). Nothing but the face tracker runs. The shoulders are where an average neck puts
310
+ them, so nudge with `offset` for a long or short neck.
311
+
312
+ **Moved by the torso.** The bust sits on the canonical torso fit (`NECK_BUST_TORSO_POSITION`), like
313
+ `ShoulderOccluder`: the shoulders follow the real ones, at the cost of body tracking.
314
+
315
+ **Credit.** The bust is from ["Complete 3D Reference - Spark AR"](https://sketchfab.com/3d-models/complete-3d-reference-spark-ar-9ecb7f5a38d7497b99ed114ffc0c519a)
316
+ by [jepharaujo](https://sketchfab.com/jepharaujo), [CC BY 4.0](http://creativecommons.org/licenses/by/4.0/),
317
+ moved into the canonical head frame (`assets-src/head-occluder/README.md`). Until
318
+ `neck-occluder-bust-v1.glb` is on the CDN, pass `url` (the example bundles it).
319
+
320
+ ## Swinging — `SpringSwing`
321
+
322
+ Children of `<SpringSwing>` swing about its origin as whatever it sits in moves and turns, then
323
+ settle (spring bones, from `@vincentt-xr/sdk/face-effects`). They hang along the parent's own
324
+ down, so a head tilt tilts them; only motion swings them. `Earrings swing` and `Necklace` use it.
325
+
326
+ ```tsx
327
+ <HeadAttachment point="leftEarLobe">
328
+ <SpringSwing frequency={1.8} damping={0.25} maxAngle={50} length={1.5}>
329
+ <MyCharm />
330
+ </SpringSwing>
331
+ </HeadAttachment>
332
+ ```
333
+
334
+ | prop | default | meaning |
335
+ | ----------- | ------- | -------------------------------------------------------- |
336
+ | `frequency` | 1.8 | swings per second when let go |
337
+ | `damping` | 0.25 | 0..1: how fast a swing dies down (1: no overshoot) |
338
+ | `maxAngle` | 50 | largest swing from rest, degrees |
339
+ | `length` | 1.5 | how far below the pivot the weight sits (parent's units) |
340
+ | `enabled` | true | false: hangs still |
341
+
342
+ It steps in the scene's before-render hook, so it swings from the pose it is drawn at, at any frame
343
+ rate; it rests while hidden. The solver (`SpringJoint`, `SpringChain`) and `SpringSwingDriver` are
344
+ there for your own rigs.
345
+
346
+ ## Necklaces — `Necklace`
347
+
348
+ A necklace on a tracked body: the chain sits on the neck base and upper chest (the canonical torso
349
+ fit), its pendants swing about their bail, and a shoulder occluder hides the chain behind the neck.
350
+ Inside a `BodyTracker` it uses that body; anywhere else it tracks the body itself.
351
+
352
+ ```tsx
353
+ import { Necklace } from "@vincentt-xr/sdk/face-effects";
354
+
355
+ const Worn = () => {
356
+ const gltf = useLoader(GLTFLoader, necklaceUrl);
357
+ return <Necklace model={gltf.scene.getObjectByName("gold_heart")} />;
358
+ };
359
+ ```
360
+
361
+ | prop | default | meaning |
362
+ | --------------------- | ---------------------- | ----------------------------------------------------------------- |
363
+ | `model` | none | the necklace in torso centimetres (cloned) |
364
+ | `swing` | `true` | pendants swing: `true` (gentle, at most 35°), options, or `false` |
365
+ | `swingNodes` | `["pendant", "charm"]` | name parts of the nodes that swing |
366
+ | `occluder` | `true` | mount a `ShoulderOccluder` |
367
+ | `occluderUrl` | the SDK CDN copy | the occluder's mesh |
368
+ | `bodyIndex`, `offset` | `0`, none | the body; a nudge in torso centimetres |
369
+
370
+ **Authoring a necklace GLB.** The torso frame: centimetres, origin between the shoulder joints,
371
+ `+X` screen right, `+Y` up, `+Z` toward the camera (Blender `(x, y, z)` = `(x, −z, y)` with a `+Y Up`
372
+ export). Lay the chain about 6 mm outside the v1 shoulder occluder (the live fit is coarse: closer
373
+ chains vanish into it beside the neck). A pendant is a child node named `…_pendant` (or `…_charm`)
374
+ with its origin on its bail.
375
+
376
+ **Example set** (`/head-occluder?necklace=gold_heart`, built from nothing by
377
+ `assets-src/accessories/build_necklaces.py`): `necklaces-v1.glb` with `gold_heart` (+
378
+ `gold_heart_pendant`), `silver_drop` (+ `silver_drop_pendant`) and `pearl_strand`, ~390 KB.
379
+
380
+ **Limitations.** The chain is rigid (only pendants swing); hair over the shoulders draws behind it;
381
+ the torso fit reads only the shoulders, so a necklace sits where an average neck and chest would be.
382
+
383
+ ## Recipe: a real 3D accessory (glasses, #171)
384
+
385
+ `/head-occluder?glasses=1` attaches a real glasses GLB with the public API only:
386
+
387
+ ```tsx
388
+ import { HeadAttachment, HeadBinding } from "@vincentt-xr/sdk/face-effects";
389
+
390
+ const Glasses = () => {
391
+ const gltf = useLoader(GLTFLoader, glassesUrl);
392
+ const glasses = useMemo(() => {
393
+ const clone = gltf.scene.clone(true); // one Object3D per face
394
+ clone.traverse((child) => {
395
+ if (!(child instanceof THREE.Mesh)) return;
396
+ child.frustumCulled = false;
397
+ // One material or an array (multi-material mesh): handle each.
398
+ const materials = Array.isArray(child.material) ? child.material : [child.material];
399
+ let transparent = false;
400
+ for (const material of materials) {
401
+ if (!material.transparent) continue;
402
+ material.depthWrite = false; // lenses
403
+ transparent = true;
404
+ }
405
+ child.renderOrder = transparent ? 6 : 5; // lenses after the frame
406
+ });
407
+ return clone;
408
+ }, [gltf]);
409
+ return <primitive object={glasses} />;
410
+ };
411
+
412
+ <HeadBinding faceIndex={0}>
413
+ <HeadAttachment point="noseBridge" onTrackingChange={(tracked) => setTracked(tracked)}>
414
+ <Suspense fallback={null}>
415
+ <Glasses />
416
+ </Suspense>
417
+ </HeadAttachment>
418
+ </HeadBinding>;
419
+ ```
420
+
421
+ **Authoring the GLB** (source: `assets-src/accessories/glasses-v1.blend`, with a README):
422
+
423
+ - Model in canonical centimetres with the object origin ON the attachment point — for glasses the
424
+ nose bridge (landmark 6). Then no runtime offset is needed.
425
+ - Face the accessory out of the face: canonical `+Z`, which is Blender's front (`−Y`) with a
426
+ `+Y Up` glTF export (Blender `(x, y, z)` = canonical `(x, −z, y)`).
427
+ - Fit it against the v3 occluder (the `.blend` keeps it as a hidden reference): temples outside the
428
+ skull by ~2 mm and over the ears, lenses ~1.5 cm in front of the eyes.
429
+ - Keep it light: the example glasses are 5.9 k triangles, ~210 KB.
430
+
431
+ **Render order.** The occluder draws first (`renderOrder −1`, depth only). Opaque accessory parts
432
+ come next with depth test and depth write on. Transparent parts (lenses) come last with
433
+ `depthWrite: false`, so they tint what is behind them without hiding the frame or the eyes.
434
+
435
+ **Common failures.**
436
+
437
+ | symptom | cause | fix |
438
+ | ----------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
439
+ | temples draw over the face and hair | no occluder, or it is under a different tracker / face index | keep the accessory and the occluder in one `HeadBinding` |
440
+ | temples never show, even on a turned head | they run inside the skull | widen / splay them to clear the occluder by ~2 mm |
441
+ | flicker along the temples | the accessory is coplanar with the occluder (z-fighting) | keep a 1–2 mm gap |
442
+ | lenses hide the frame or the eyes | transparent material writes depth | `depthWrite: false` and a later `renderOrder` |
443
+ | accessory sits beside the face on images / video | the pre-#169 mirrored tracker origin | fixed; use `HeadAttachment` / `CanonicalHeadFrame` |
444
+ | one face loses its accessory after `numFaces` changes | the pre-#171 one-shot camera registration | fixed in `FaceTracker` |
445
+ | accessory wrong size for a face | average head | `offset.scale` (e.g. `0.95`–`1.05`), `offset.position` in cm |
446
+ | only one earring shows | one `Object3D` mounted on both ears | `<Earrings model={…}>` clones per ear |
447
+ | the near earring is cut beside the lobe | it reaches into the ear volume | author it at `x ≥ 0` from the lobe piercing |
448
+ | metal earrings look black | no environment map | set `scene.environment` |
449
+
450
+ The example's panel switches the occluder off (to show the failure), shows it with the debug
451
+ material, toggles two faces, nudges `offset` lift / depth / scale and `smoothing`, and logs
452
+ `onTrackingChange` per face.
453
+
454
+ ## Audit (#169) — behaviour, defaults, limitations
455
+
456
+ **Fixed in the tracker group (`FaceTracker`).** Two defects made anything
457
+ attached directly to the group (not through the canonical fit) land wrong:
458
+
459
+ 1. _Rotation._ The group applied `face.transform.rotation` — a sign-convention
460
+ reading (looking up/left positive) — as a three.js Euler. That is close to
461
+ the inverse of the head pose: a frontal face read about 8–16° of pitch the
462
+ wrong way, and a 40° head turn put the group about 85° off. The group now
463
+ applies MediaPipe's facial-transformation pose directly
464
+ (`face.transform.quaternion`). Measured against the canonical fit on still
465
+ images (frontal and 40° turns, webcam and image sources): within 1.6–2.5°.
466
+ 2. _Origin on unmirrored sources._ The face model flipped landmark x for
467
+ images, videos and the rear camera — a leftover from when the session drew
468
+ every source mirrored. The session now draws those straight and the model
469
+ analyzes the displayed frame, so the flip put the group at the mirrored
470
+ position (e.g. x = 0.23 instead of 0.77). Landmarks are now used as-is for
471
+ every source kind.
472
+
473
+ **Fixed in the fits.** `HeadOccluder`'s canonical fit (on by default in
474
+ `HeadBinding`) acquired the face model from a child effect, which runs before
475
+ the parent tracker's, so the shared model was initialized with `numFaces: 1`
476
+ and a multi-face `HeadBinding` tracked one face. The fits now only read the
477
+ parent's model.
478
+
479
+ **Production defaults.** `HeadBinding`: `numFaces` 4, `scaleWithFace` on,
480
+ occluder on with `fit: "canonical"`, `smoothing` 0.5. Occluder: depth-only,
481
+ `DoubleSide`, `renderOrder` −1, `frustumCulled` off, integrity-checked GLB that
482
+ fails closed. Accessories: `depthTest` on, authored in canonical centimetres
483
+ through `HeadAttachment` / `CanonicalHeadFrame`.
484
+
485
+ **Known limitations.**
486
+
487
+ - The fit is rigid: jaw opening, smiles and cheeks are not followed by the
488
+ occluder or by `chin`.
489
+ - Weak perspective: live depth comes from MediaPipe's relative landmark z, so
490
+ absolute distance is approximated by scale; a face near the frame edge of a
491
+ wide camera can read 1–3° of extra pitch / yaw.
492
+ - The occluder is an average head. Big hair volumes, hats worn in the camera
493
+ image and very long or short heads leave a few millimetres of mismatch; nudge
494
+ with `offset.scale` / `offset.position`.
495
+ - Beyond about 70° of yaw MediaPipe's landmarks degrade and the fit wobbles.
496
+ - Face indices are per result, not identities.
497
+
498
+ ## Manual visual test plan
499
+
500
+ Open `/head-occluder` with a live camera. Accessories: a halo around the
501
+ crown, glasses arms over the temples, a bridge across the eyes, two earrings.
502
+
503
+ 1. Frontal: the bridge is fully visible; the arms vanish past the temples; the
504
+ halo's back half is hidden.
505
+ 2. Yaw left and right to about 60°: the near arm appears along the temple, the
506
+ far arm stays hidden; the far earring hides behind the jaw; the head does not
507
+ shrink or grow.
508
+ 3. Pitch up and down: the halo's visible arc changes smoothly; no flicker along
509
+ the silhouette.
510
+ 4. Roll: the silhouette follows the tilt.
511
+ 5. Walk toward and away from the camera: the accessories keep their size
512
+ relative to the face.
513
+ 6. Cover the camera: everything hides; uncover: everything snaps back without
514
+ sliding.
515
+ 7. Toggle `show occluder`: the grey head sits on the face with the nose bridge
516
+ at the nose; toggle `fit: manual` to compare with the v2 shell.
517
+ 8. Mirror check: switch to a video source (unmirrored) and repeat 2; with the
518
+ face mesh on, the fit markers stay on their landmarks (no mirrored offset).
519
+ 9. Attachment points: turn on "attachment points + crown hat". Every dot sits
520
+ on its feature (forehead, nose bridge between the eyes, nose tip, chin,
521
+ both ears; the white head-centre dot drifts behind the face as you turn).
522
+ The hat's brim hides behind the skull at the back. Cover and uncover the
523
+ camera: the panel's `hat tracking` line logs one `lost` and one `found`.
524
+ 10. Multiple faces: two people in frame with `HeadBinding faceIndex={0}` and
525
+ `faceIndex={1}` each holding a `HeadAttachment` (no `faceIndex` on the
526
+ attachment): each person gets their own accessory; one leaving does not
527
+ make the other's slide.
528
+ 11. Glasses (`/head-occluder?glasses=1`, live camera): frontal — both lenses over the eyes, the bridge on
529
+ the nose, both temples hidden past the temples of the head. Turn left / right to ~60° — the
530
+ near temple runs back over the ear, the far one stays hidden, no flicker along either. Nod —
531
+ the lenses stay in front of the eyes. Tilt — the frame rolls with the head. Untick the
532
+ occluder — the far temple draws over the face (the failure case). Cover the camera — the
533
+ glasses vanish and the panel logs `lost`; uncover — they snap back (`found`), no slide-in.
534
+ Tick "two faces" with two people — each gets a pair; one leaving does not move the other's.
535
+ Repeat on the webcam (mirrored) and on a video preset (unmirrored).
536
+ 12. Shoulders: turn on the shoulder occluder and torso accessories. The
537
+ necklace's back half, the strap behind the shoulder and the wings' inner
538
+ halves hide; lean and turn the torso: they follow the shoulders, not the head.
539
+
540
+ 13. Earrings (`/head-occluder?earrings=1`, live camera): frontal — both earrings hang from the
541
+ lobes, the near sides whole. Turn left / right to ~60° — the far earring hides behind the head
542
+ and neck, the near one stays whole beside the ear (no flicker at the lobe). Nod and tilt — they
543
+ stay on the lobes. Switch style (realistic / playful) and each earring; the hoops' wire
544
+ disappears behind the lobe. Untick "left ear" — only the earring on your real left ear goes
545
+ (on the screen's left in the mirrored webcam view). Untick the head occluder — the far earring
546
+ draws over the face. Repeat on a video preset (unmirrored): "left ear" is now the person's
547
+ left ear, on the screen's right.
548
+
549
+ 14. Swinging earrings (`/head-occluder?earrings=1&realistic=rose_drop`): shake and nod — the
550
+ drops swing and settle within about a second; tilt — they tilt with the head. Untick "swing" —
551
+ rigid again.
552
+
553
+ 15. Necklaces (`/head-occluder?necklace=gold_heart`): the chain lies around the neck base onto the
554
+ chest, its back hidden behind the neck; the heart hangs from the front and swings as you turn.
555
+ Try silver drop and pearls; untick "pendant swings".
556
+
557
+ 16. Neck (`/head-occluder?neck=head&debug=1&shoulders=0`): the grey bust's shoulders sit on your
558
+ collarbones; turn and tilt your head — the neck bends, the shoulders stay level. `neck=torso`:
559
+ the shoulders follow your real ones.
560
+
561
+ Examples: `/head-occluder`, `/head-occluder?glasses=1`, `/head-occluder?earrings=1`,
562
+ `/head-occluder?necklace=gold_heart`. Related: [Face Binding Anchors](/api/face-binding-anchors)
563
+ for 2D/3D landmark anchoring without occlusion.