@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,136 @@
1
+ ---
2
+ title: "Person Cutout"
3
+ description: "Background replacement as a two-layer ScreenImage composition: any background media below, the person-masked live camera above."
4
+ sidebarTitle: "Person Cutout"
5
+ icon: "user"
6
+ ---
7
+
8
+ `PersonCutout` is the live camera, masked to the person by portrait
9
+ segmentation, rendered as a full-screen `ScreenImage`. Put any background
10
+ surface behind it with a lower `renderOrder` and you have background
11
+ replacement without assembling masks, materials or coordinates yourself.
12
+
13
+ ```tsx
14
+ import { FULL_SCREEN_ANCHORS, PersonCutout, ScreenImage, ScreenSpaceUI } from "@vincentt-xr/sdk";
15
+
16
+ <ScreenSpaceUI>
17
+ {/* 1. Background: image, video texture or GIF — anything ScreenImage shows. */}
18
+ <ScreenImage
19
+ src="/backgrounds/beach.jpg"
20
+ fit="cover"
21
+ anchors={FULL_SCREEN_ANCHORS}
22
+ renderOrder={0}
23
+ />
24
+ {/* 2. Foreground: the camera, person only. */}
25
+ <PersonCutout renderOrder={100} />
26
+ </ScreenSpaceUI>;
27
+ ```
28
+
29
+ ## The composition contract
30
+
31
+ - **Background** is any full-screen surface drawn first: a `ScreenImage`
32
+ (`{ kind: "image" }`, `{ kind: "gif" }`, or `{ kind: "texture" }` with a
33
+ `THREE.VideoTexture`), or a custom shader plane inside
34
+ `<ScreenTransform anchors={FULL_SCREEN_ANCHORS}>`. Give it a `renderOrder`
35
+ below the cut-out's (default 100).
36
+ - **Foreground** is `PersonCutout`: a `ScreenImage` whose `source` is the
37
+ session camera texture and whose `maskTexture` is the portrait segmentation
38
+ mask. It accepts the usual `ScreenImage` props (`opacity`, `fit`, `anchors`,
39
+ `blendMode`, `flipX`, `renderOrder`, `visible`) except `source` and the mask
40
+ props, which it owns.
41
+ - **Ordering** is `renderOrder`; both layers are overlay-style screen planes
42
+ with depth testing off, so only the order matters.
43
+
44
+ ## Alignment: aspect ratio, mirroring, resolution
45
+
46
+ - The camera texture is already cover-cropped to the viewport and mirrored
47
+ for webcams by the session, and the segmentation mask is produced in that
48
+ same feed space. `PersonCutout` samples the mask through the image's own
49
+ fit transform (`fit="cover"` by default), so mask and camera stay aligned
50
+ under any aspect ratio and any further crop or flip you apply.
51
+ - Background media is not mirrored. If a background has to match a mirrored
52
+ webcam (a sign you are sitting in front of), set `flipX` on that
53
+ `ScreenImage`.
54
+ - The mask is a render-size canvas texture with a half-pixel blur, so edges
55
+ are soft at the display resolution. The segmentation `quality` option on
56
+ the model trades edge detail for cost.
57
+
58
+ ## Mask, opacity, invert
59
+
60
+ The SDK mask carries its signal in RGB: white (255) on the person, black on
61
+ the background, with alpha 255 everywhere (three's `alphaMap` reads the green
62
+ channel, which is how `VideoBackground` consumes the same texture). The
63
+ cut-out reads `maskChannel="green"`, keeping the person and dropping the
64
+ background. `invert` flips that to show only the background with the person
65
+ cut out.
66
+ `opacity` fades the whole person layer. `usePersonMaskTexture()` returns the
67
+ raw mask texture with its `status` for custom compositions, and `ScreenImage`
68
+ itself now accepts `maskTexture`, `maskChannel` (`alpha` | `red` | `green` |
69
+ `luminance`), `maskInvert`, `maskFeather` and `maskErode` for any image.
70
+
71
+ ## Edge quality: feather and erode
72
+
73
+ The segmenter's mask is hard-edged and sits a texel or two outside the person,
74
+ so the raw cut-out carries a fringe of the source background (green-screen
75
+ spill, a light halo on dark backgrounds). Two props clean it up:
76
+
77
+ - `maskFeather` — radius in mask texels of a 3×3 blur over the mask. `0` keeps
78
+ the hard edge. Texel units keep the softness the same on screen whatever
79
+ resolution the mask arrives at.
80
+ - `maskErode` — `0..1` of the feather width to shrink the kept region by. The
81
+ blurred edge is re-thresholded, so the silhouette moves inward and the fringe
82
+ falls outside it. It does nothing without feather.
83
+
84
+ `PersonCutout` defaults to `maskFeather={4}` and `maskErode={0.7}`, chosen on
85
+ the SDK's green-screen clips with the 720-px portrait mask. Raise erode when
86
+ spill remains, lower it when fingers or hair tips disappear. Neither prop fixes
87
+ the mask trailing a fast-moving arm; that is the segmenter's temporal lag.
88
+
89
+ ## Loading and fallback
90
+
91
+ The segmentation model downloads on first use. `PersonCutout` reports
92
+ `loading` → `ready` | `error` through `onStatusChange`. While not ready it
93
+ follows `fallback`: `"camera"` (default) draws the unmasked camera so the
94
+ experience degrades to a plain feed, `"hidden"` draws nothing so only the
95
+ background shows. On error the same fallback applies and `error` carries
96
+ the reason.
97
+
98
+ ## When to use this instead of 3D
99
+
100
+ - **Use this 2D path** for background replacement, virtual backgrounds,
101
+ person-in-a-scene stickers, and any effect that only needs "the person
102
+ versus the rest of the frame". It is one quad, one mask, no geometry.
103
+ - **Use the face mesh** when something must stick to the face surface with
104
+ correct perspective and shading (lipstick, face paint, UV-mapped textures).
105
+ - **Use the head occluder** when 3D objects must disappear behind the head
106
+ (glasses arms, hats seen from the side). A 2D mask cannot occlude in depth.
107
+ - The 2D mask also covers the body, hair and clothes, which neither the face
108
+ mesh nor the head occluder does.
109
+
110
+ ## Performance
111
+
112
+ One extra full-screen quad with a masked shader; the segmentation model
113
+ runs at its own `targetFps` (24 by default). Share the model: `VideoBackground`
114
+ with `segmentation="portrait"`, `usePersonMask` overlays and `PersonCutout`
115
+ all consume the same instance.
116
+
117
+ ## Manual visual test plan
118
+
119
+ Run `/segmentation?mode=cutout` in the playground:
120
+
121
+ | Case | Source / background | Expect |
122
+ | ------------------------ | --------------------------------------- | ------------------------------------------------------------------------------- |
123
+ | Image background | video source, Image | Person on the photo; no camera background visible around the edges |
124
+ | Video background | video source, Video | Background plays behind the person; both layers keep playing |
125
+ | GIF background | video source, GIF | GIF animates behind the person |
126
+ | Shader background | video source, Shader | Animated plane behind the person; person edges unaffected |
127
+ | Opacity | any, opacity 0.5 | Person fades over the background; background unchanged |
128
+ | Show background only | any, invert | Person region shows the background through the camera layer |
129
+ | Edge feather / erode | video source, feather 0 vs 4, erode 0.7 | Feather 0 shows a green fringe on sleeves; the defaults remove it |
130
+ | Aspect / orientation | resize the pane, rotate device | Person stays aligned with the camera; background re-covers the screen |
131
+ | Mirrored webcam | webcam | Person mirrored like the feed; text on a background not mirrored unless `flipX` |
132
+ | Movement | "Person Shaking Head", "Person ThumbUp" | Mask follows head and hands; thin fingers may soften |
133
+ | Lighting | webcam, bright vs dim | Mask holds under both; dark clothes on dark background is the hard case |
134
+ | Loading, fallback camera | reload | Plain camera until `ready`, then the background appears |
135
+ | Loading, fallback hidden | reload | Only the background until `ready` |
136
+ | Multi-person | "Two People Smiling" | Both people kept; the segmenter is person-class |
@@ -0,0 +1,274 @@
1
+ ---
2
+ title: "Pin to Face Mesh"
3
+ description: "Pin content to a point on the live face surface: it follows the head and the skin under it through expressions, turning with the skin. Named piercing presets for the nose, septum, lip and brow."
4
+ sidebarTitle: "Pin to Face Mesh"
5
+ icon: "thumbtack"
6
+ ---
7
+
8
+ `PinToFaceMesh` pins content to a point on the face. It follows the head and the skin under it
9
+ through expressions:
10
+
11
+ - a sticker on the cheek rides a smile;
12
+ - a stud by the mouth follows the corner as it moves;
13
+ - the content turns with the skin.
14
+
15
+ It is part of the face-character pipeline ([#194](https://github.com/vincentt-xr/sdk/issues/194),
16
+ #198) and runs on a [`FaceRig`](/api/external-face-mesh#facerig).
17
+
18
+ The generic [`PinToMesh`](/api/behavior-components) resolves its point once against a static mesh.
19
+ That is still the tool for a static mesh; this one follows a surface that moves every frame.
20
+
21
+ Import from `@vincentt-xr/sdk/face-effects`.
22
+
23
+ ## Quick start
24
+
25
+ ```tsx
26
+ import { PinToFaceMesh } from "@vincentt-xr/sdk/face-effects";
27
+ import { FaceTracker } from "@vincentt-xr/sdk/tracking";
28
+
29
+ <FaceTracker>
30
+ <PinToFaceMesh anchor="face.leftCheek" offset={{ position: [0, 0, 0.1] }}>
31
+ <mesh>
32
+ <circleGeometry args={[1.2, 32]} />
33
+ <meshBasicMaterial color="hotpink" />
34
+ </mesh>
35
+ </PinToFaceMesh>
36
+ </FaceTracker>;
37
+ ```
38
+
39
+ Author the content in **centimetres** around its origin. The pin's frame is:
40
+
41
+ - **X** along the face, toward the screen's right on a face looking at the camera;
42
+ - **Y** up;
43
+ - **Z** out of the skin.
44
+
45
+ ## Anchors
46
+
47
+ | `anchor` | Where |
48
+ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
49
+ | `"face.leftCheek"` … | A face target (`FACE_PIN_TARGETS`): left and right are the person's own on every feed. Composites project onto the skin. |
50
+ | `{ landmark: 278 }` | A MediaPipe face landmark, 0–467 (MediaPipe's side; never swapped). |
51
+ | `{ point: [x, y, z] }` | A point in the canonical head frame (cm, `+X` = MediaPipe's left; never swapped), e.g. measured in the head-occluder `.blend`. It binds to the skin under it. |
52
+ | `{ triangle, weights }` | An exact surface point: a canonical face triangle and barycentric weights. |
53
+
54
+ Every anchor is bound once to the canonical face surface. A `point` that lies off the skin keeps its
55
+ offset in the pin frame. An unknown name or an out-of-range index throws, listing the valid forms.
56
+
57
+ A named left / right anchor follows the person's real side (GROUNDING "Left and right"): the
58
+ canonical face's sides are MediaPipe's, which the mirrored webcam swaps, so `PinToFaceMesh` binds
59
+ `facePinAnchorForFeed(anchor, mirrored)` with the session's mirror state. Pass `mirrored` to
60
+ override. `"face.leftCheek"` is on the screen's left in the mirrored selfie view and on its right in
61
+ a video.
62
+
63
+ ## Props
64
+
65
+ | Prop | Default | What it does |
66
+ | ----------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
67
+ | `anchor` | — | Where on the face (see above). |
68
+ | `surface` | `"face"` | `"face"`: the person's real face (shape + expression). `"model"`: the canonical face + expression, as an `ExternalFaceMesh` character wears it. |
69
+ | `orient` | `"surface"` | `"surface"`: turns with the skin (normal averaged over the triangles within 1.2 cm). `"head"`: keeps the head's orientation. |
70
+ | `offset` | — | `{ position (cm), rotation (degrees), scale }` in the pin frame. |
71
+ | `smoothing` | `1` | A per-frame EMA on the pin's position and turn (`1` = none; the rig already smooths the expression). |
72
+ | `onto` | — | A face model to sit on (a ref to the group around an `ExternalFaceMesh`). See below. |
73
+ | rig props | — | `faceIndex`, `expressionSmoothing`, `holdMs`, `neutral`, `neutralMs`, `neutralKey`, `leadMs`, `onTrackingChange` (when it runs its own rig). |
74
+
75
+ **Pins on a character.** A character's skin is never exactly the canonical surface: its cheek may sit
76
+ a few millimetres in front of it. Pass the character as `onto`. Once the model can be hit, the pin
77
+ moves along its rest normal onto that skin, then rides the expression from there.
78
+
79
+ Anchor at the exact spot (a `point`, a landmark or a triangle) rather than at a nearby landmark plus a
80
+ sideways offset. The projection happens at the anchor; a sideways offset can land inside a curved
81
+ cheek.
82
+
83
+ ```tsx
84
+ const character = useRef<THREE.Group>(null);
85
+ <FaceRig>
86
+ <group ref={character}>
87
+ <ExternalFaceMesh model={head.scene} />
88
+ </group>
89
+ <PinToFaceMesh anchor="face.rightCheek" surface="model" onto={character}>
90
+ <Star />
91
+ </PinToFaceMesh>
92
+ </FaceRig>;
93
+ ```
94
+
95
+ **Tracking.** The pin is hidden while the face is lost, holds through short dropouts (the rig's
96
+ `holdMs`), and snaps into place on reacquire.
97
+
98
+ ## Pure pieces
99
+
100
+ - **`bindFacePin(anchor, { patchRadius })`** → `FacePinBinding`, with `triangle`, `weights`,
101
+ `offset` and the normal `patch`.
102
+ - **`stepFacePin(binding, rig, { surface, orient }, out)`** gives the pin's position and quaternion in
103
+ the head frame for this frame.
104
+ - **`projectFacePinOnto(binding, model, headFrame)`** gives how far (cm) the pin must move along its
105
+ normal to sit on a model's skin.
106
+
107
+ ## Piercings
108
+
109
+ `FacePiercing` puts jewellery on a named piercing spot. It is a preset over `PinToFaceMesh`: it
110
+ knows where the hole is on the face mesh and how a stud or a ring sits there, so you never look up a
111
+ landmark.
112
+
113
+ ```tsx
114
+ import { FacePiercing, FaceRig } from "@vincentt-xr/sdk/face-effects";
115
+ import { FaceTracker } from "@vincentt-xr/sdk/tracking";
116
+
117
+ <FaceTracker>
118
+ <FaceRig>
119
+ <FacePiercing preset="nose.left" />
120
+ <FacePiercing preset="septum" />
121
+ <FacePiercing preset="brow.right" kind="stud">
122
+ <primitive object={myStud} />
123
+ </FacePiercing>
124
+ </FaceRig>
125
+ </FaceTracker>;
126
+ ```
127
+
128
+ Without children it draws a plain silver stud or ring sized for the spot. Wrap several piercings in
129
+ one `FaceRig`; on its own each one runs its own rig.
130
+
131
+ ### Spots
132
+
133
+ | `preset` | Where | Classic `kind` | Typical size |
134
+ | -------------- | ----------------------------------------------------------- | -------------- | ------------- |
135
+ | `"nose.left"` | The alar crease of the left nostril. | `"stud"` | 2.5 mm / 8 mm |
136
+ | `"nose.right"` | The same on the right nostril. | `"stud"` | 2.5 mm / 8 mm |
137
+ | `"septum"` | Through the septum, above the base of the nose. | `"ring"` | 3 mm / 10 mm |
138
+ | `"lip.centre"` | Below the centre of the lower lip (labret). | `"stud"` | 3 mm / 9 mm |
139
+ | `"lip.left"` | Below the outer third of the lower lip, left. | `"ring"` | 3 mm / 9 mm |
140
+ | `"lip.right"` | The same on the right. | `"ring"` | 3 mm / 9 mm |
141
+ | `"brow.left"` | The outer third of the left brow; a ring enters at its top. | `"ring"` | 3 mm / 10 mm |
142
+ | `"brow.right"` | The same on the right brow. | `"ring"` | 3 mm / 10 mm |
143
+
144
+ Sizes are a stud's face diameter and a ring's inner diameter (`FACE_PIERCINGS[preset].size`, in
145
+ cm).
146
+
147
+ How each kind sits:
148
+
149
+ - **Stud:** on the skin at the hole, its face out of the skin (the septum bead faces forward, just
150
+ under the nose).
151
+ - **Nostril ring:** through the nostril wing, hanging over the rim.
152
+ - **Septum ring:** through the septum from side to side, hanging below the nose and tipped slightly
153
+ forward.
154
+ - **Lip ring:** in below the lip, wrapping up over its edge.
155
+ - **Brow ring:** in at the top of the brow and out under it, mostly outside the skin, leaning toward
156
+ the temple.
157
+
158
+ Every spot is bound to the face surface, so it rides expressions: the lip spots follow the jaw when
159
+ the mouth opens, the brow spots rise with the brows.
160
+
161
+ **Left and right are the person's real sides on every feed.** The face mesh's own sides are those of
162
+ the face as the tracker sees it, which a mirrored feed (the front webcam) swaps. `FacePiercing` reads
163
+ the session's mirroring (`useXRMirrored`) and takes the other side's placement there, so
164
+ `"nose.left"` is always the person's left nostril: on the screen's left in the mirrored selfie view,
165
+ on its right in a video. Pass `mirrored` to override.
166
+
167
+ ### The piercing frame
168
+
169
+ Author jewellery in centimetres in the piercing frame; it then needs no offset:
170
+
171
+ - the origin is the hole, on the skin;
172
+ - **+Z** is the piercing axis, out of the skin: a stud's face looks along +Z, its back on the origin;
173
+ - **+Y** is up;
174
+ - a ring lies in the **YZ plane**, its wire passing through the origin, and hangs toward −Y (its
175
+ centre at `(0, −r, 0)` for a centre-line radius `r`).
176
+
177
+ In Blender (glTF `+Y Up` export) that is: a stud facing −Y, a ring around the X axis hanging below
178
+ the origin. The example sets in `assets-src/accessories/piercings-v1.blend` follow it.
179
+
180
+ ### Props
181
+
182
+ | Prop | Default | What it does |
183
+ | ----------- | ------------- | -------------------------------------------------------------------------------------------------- |
184
+ | `preset` | — | The spot (`FACE_PIERCING_NAMES`). |
185
+ | `kind` | the spot's | `"stud"` or `"ring"`. |
186
+ | `mirrored` | the session's | Whether the feed is mirrored; decides which mesh side is the person's left. |
187
+ | `occlude` | `true` | Hides what passes behind the skin (a ring's inner half) with a depth-only patch of the live face. |
188
+ | `offset` | — | `{ position (cm), rotation (degrees), scale }` in the piercing frame, mirrored on the other side. |
189
+ | `surface` | `"face"` | As on `PinToFaceMesh`. |
190
+ | `smoothing` | `1` | As on `PinToFaceMesh`. |
191
+ | `onto` | — | A worn character to sit on, as on `PinToFaceMesh` (no skin patch; the character hides the inside). |
192
+ | rig props | — | Used when it runs its own rig, as on `PinToFaceMesh`. |
193
+
194
+ **Metals.** Gold and silver need something to reflect: give the scene an environment map (for
195
+ example three's `RoomEnvironment` through a `PMREMGenerator`, as `/pin-to-face-mesh` does).
196
+
197
+ ### The skin occluder
198
+
199
+ `FaceSurfaceOccluder` is the depth-only mesh of the live face that `FacePiercing` mounts around each
200
+ hole. Use it with your own `PinToFaceMesh` content that passes through the skin:
201
+
202
+ ```tsx
203
+ <FaceRig>
204
+ <FaceSurfaceOccluder around={{ landmark: 334 }} radius={2} />
205
+ <PinToFaceMesh anchor={{ landmark: 334 }}>
206
+ <MyRing />
207
+ </PinToFaceMesh>
208
+ </FaceRig>
209
+ ```
210
+
211
+ It follows the same surface as the pins (face shape, expression, and a `FaceWarp3D` / `FaceMorph`
212
+ surface when inside one). Props: `surface`, `around` (an anchor; the whole face when omitted;
213
+ resolved for the feed like a pin's, so a named `"face.leftCheek"` covers the same cheek as the pin),
214
+ `mirrored` (default the session's), `radius` (cm, default 2.5), `renderOrder` (default `-1`, the
215
+ head occluder's tier), `debug` (a visible wireframe).
216
+
217
+ ### Pure pieces
218
+
219
+ - **`FACE_PIERCINGS`**: the presets, each with `label`, `region`, `side`, `kind`, `size` and a
220
+ `stud` and a `ring` placement (`at`, the hole in canonical cm as on an unmirrored source; `orient`;
221
+ `offset`, the piercing frame in the pin frame).
222
+ - **`resolveFacePiercing(preset, { kind, mirrored })`** gives the exact surface `anchor`, `orient`,
223
+ `offset`, `size` and `flip` (the placement is the mirror image of the left-side authoring) for a
224
+ feed.
225
+ - **`mirrorFacePiercingOffset(offset)`** and **`mirrorFacePiercingPlacement(placement)`** mirror an
226
+ offset or a placement across the face.
227
+
228
+ ## Example
229
+
230
+ `/pin-to-face-mesh` has:
231
+
232
+ - **Accessories:** a forehead gem, a brow ring, a nose stud, a star sticker on the cheek, and a beauty
233
+ mark just outside the mouth corner.
234
+ - **A custom pin with debug controls:** anchor by face target, landmark index or triangle; surface;
235
+ orient; offsets; roll; smoothing. An axes gizmo shows X red, Y green, Z blue.
236
+ - **A live point cloud** of the 468-landmark surface the pins follow.
237
+ - **The facecap character** (local, see [External Face Mesh](/api/external-face-mesh#example)), with
238
+ the accessories projected onto its skin.
239
+ - **Piercings** (off by default): a style chip (realistic gold and silver, or playful stars, hearts,
240
+ gems and candy hoops), a jewellery chip (classic, studs or rings) and a toggle per spot. URL:
241
+ `?p.nose.left=1&p.septum=1&pstyle=playful&pkind=ring`; `?pocclude=0` turns the skin patch off.
242
+
243
+ ## Manual visual test plan
244
+
245
+ Open `/pin-to-face-mesh` on the webcam.
246
+
247
+ 1. **Placement**: the gem sits mid-forehead; the ring through a brow, the stud on a nostril and the
248
+ mark just above a mouth corner, all on the screen's right (landmark / point anchors keep
249
+ MediaPipe's side: your right on the mirrored webcam); the star on your real left cheek, on the
250
+ screen's left (a named anchor, the person's own side). Each sits on the skin, not floating.
251
+ Switch to a video: the star moves to the person's left cheek, now on the screen's right; the
252
+ other pieces stay on the screen's right.
253
+ 2. **Head motion**: turn and tilt. Every piece stays on its spot. The star turns with the cheek and
254
+ shows its edge at a steep angle.
255
+ 3. **Expressions**: smile, and the star rises with the cheek. Open your mouth, and the mark follows
256
+ the corner. Raise your brows, and the ring rises.
257
+ 4. **Custom pin**: switch the anchor between face targets, landmark indices and triangles. The gizmo
258
+ jumps there, Z out of the skin. With orient "head", the gizmo keeps the head's axes. Offsets move
259
+ it in the pin frame.
260
+ 5. **Surface**: tick "show the live face surface". The dots sit on your face and move with it. With
261
+ surface "model", the pin drifts onto the canonical face.
262
+ 6. **Character**: tick "on the facecap character". Every accessory sits on the character's own skin,
263
+ nothing buried, and follows its expression.
264
+ 7. **Dropouts**: cover the camera briefly and the pins hold. Cover it longer and they hide, then snap
265
+ back.
266
+ 8. **Piercings**: turn off the accessories and press "all" under piercings. Each piece sits on its
267
+ spot: studs on the skin, the nostril ring over the rim, the septum ring below the nose, the lip
268
+ rings over the lower lip, the brow rings through the outer brows. No ring shows its inner half.
269
+ 9. **Piercing sides**: on the webcam, the left nostril piece is on the screen's left (your left).
270
+ Switch to a video and it is on the person's left, the screen's right.
271
+ 10. **Piercings through expressions**: open your mouth wide; the lip pieces follow the jaw. Raise your
272
+ brows; the brow rings rise. Turn your head; nothing slides off.
273
+ 11. **Styles**: switch realistic / playful and classic / studs / rings. With realistic, the metals
274
+ reflect. With "skin hides the inside" off, the inner half of each ring appears.
@@ -0,0 +1,114 @@
1
+ ---
2
+ title: "Product Placement AR"
3
+ description: "View-in-your-space AR for product pages on top of Google's model-viewer: capability detection, the ProductViewer wrapper, the useProductAr hook, and the camera handoff with the tracking session."
4
+ sidebarTitle: "Product AR"
5
+ icon: "cube"
6
+ ---
7
+
8
+ Placement AR puts a product on the floor or a wall through the device's
9
+ native path: WebXR (Android Chrome), Scene Viewer (Android) or Quick Look
10
+ (iOS, from a USDZ). It is a different mode from the SDK's camera session,
11
+ which has no world tracking. The SDK wraps Google's `<model-viewer>` for it
12
+ rather than rebuilding it; the rule for every page: **placement AR is
13
+ model-viewer, face/body AR is the session, never both at once.**
14
+
15
+ ```tsx
16
+ import { ProductViewer, useProductAr } from "@vincentt-xr/sdk/product";
17
+
18
+ const Product = () => {
19
+ const ar = useProductAr();
20
+ return (
21
+ <>
22
+ <ProductViewer
23
+ src="/hat.glb"
24
+ iosSrc="/hat.usdz"
25
+ poster="/hat.webp"
26
+ alt="Hat"
27
+ onReady={ar.bind}
28
+ />
29
+ {ar.supportedModes.length > 0 && (
30
+ <button onClick={() => ar.activate()} disabled={!ar.canActivate}>
31
+ View in your space
32
+ </button>
33
+ )}
34
+ </>
35
+ );
36
+ };
37
+ ```
38
+
39
+ ## Install
40
+
41
+ `@google/model-viewer` is an optional peer dependency: add it to the app
42
+ that renders products. `<ProductViewer>` imports it lazily on first render,
43
+ so other pages never pay for it. It bundles its own three.js (it cannot share
44
+ the SDK's), roughly 1 MB; keep it on product routes only.
45
+
46
+ ## Capability
47
+
48
+ `detectXRCapabilities` / `useXRCapabilities` report `placement`:
49
+
50
+ | Field | How it is detected |
51
+ | ------------- | ----------------------------------------------------------------------------------- |
52
+ | `webxr` | `navigator.xr.isSessionSupported("immersive-ar")` |
53
+ | `sceneViewer` | Android Chrome / Samsung Internet user agent |
54
+ | `quickLook` | `<a rel="ar">` support (iOS Safari and WebKit browsers) |
55
+ | `any` | one of the above; otherwise `reason.code` `placement-unsupported` (not recoverable) |
56
+
57
+ Offer "View in AR" only when `any` is true; desktop shows the viewer alone.
58
+
59
+ ## `<ProductViewer>`
60
+
61
+ | Prop | model-viewer attribute |
62
+ | -------------------------------------------------------------------------------------------- | ------------------------------------------------ |
63
+ | `src`, `iosSrc`, `poster`, `alt` | `src`, `ios-src`, `poster`, `alt` |
64
+ | `ar` (default true), `arModes` | `ar`, `ar-modes` (preference order) |
65
+ | `placement: "floor" \| "wall"` | `ar-placement` |
66
+ | `scale: "auto" \| "fixed"` | `ar-scale` (`fixed` = true-to-size, no pinch) |
67
+ | `cameraControls`, `autoRotate`, `loading`, `environmentImage`, `shadowIntensity`, `exposure` | same names, kebab-cased |
68
+ | `attributes` | anything else, passed straight through |
69
+ | `onLoad`, `onError`, `onArStatus`, `onReady(element)` | `load`, `error`, `ar-status` events; the element |
70
+
71
+ Children are slotted into model-viewer (`slot="ar-button"`, `slot="poster"`,
72
+ hotspots).
73
+
74
+ ## `useProductAr()`
75
+
76
+ Returns `{ status, supportedModes, canActivate, reason, loading, error, bind, activate, handleStatus }`.
77
+ `status` is model-viewer's `ar-status` (`not-presenting`, `session-started`,
78
+ `object-placed`, `failed`) or `unavailable` when no mode is supported.
79
+ `activate()` must run from a user gesture.
80
+
81
+ ### Camera handoff
82
+
83
+ Only WebXR runs in the page and needs the camera the tracking session
84
+ holds; Scene Viewer and Quick Look open a native activity and never touch
85
+ it. When the hook runs under an `<XRProvider>` whose session is `running` or
86
+ `paused` on the webcam and the mode about to be used is `webxr`,
87
+ `activate()` stops the session first and restores the same facing and
88
+ lifecycle (a paused session comes back paused) when `ar-status` returns to
89
+ `not-presenting` (or `failed`). `handoffCamera: false` opts out. Stream /
90
+ canvas sources are left alone. The pure form is
91
+ `releaseSessionForAr(session, mode)`. Keep `arModes` on the viewer and
92
+ `modes` on the hook identical; both default to `DEFAULT_PRODUCT_AR_MODES`.
93
+
94
+ ## Assets
95
+
96
+ - GLB for every platform; keep it under a few MB. Compress with meshopt
97
+ (geometry) + WebP (textures); never Draco or KTX2. model-viewer would fetch
98
+ Draco / KTX2 decoders from Google's CDN at view time, and the same GLB fails
99
+ to load in the SDK's own model paths (`defineGltfAsset`, `MeshRenderer`).
100
+ - USDZ for iOS Quick Look via `iosSrc`; without it model-viewer exports one
101
+ on the fly (slower, lower fidelity). The GLB → USDZ step is a publishing
102
+ step (see the asset pipeline issue), never runtime code.
103
+ - Host both on the CDN with long cache headers.
104
+
105
+ ## Manual validation
106
+
107
+ Run `/product-details?model=astronaut`:
108
+
109
+ | Device | Expect |
110
+ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
111
+ | Desktop | viewer with orbit; `supported modes: none`, button disabled |
112
+ | Android Chrome | `scene-viewer` (and `webxr` on ARCore devices); tap → Scene Viewer / WebXR places the astronaut; status log `session-started` → `object-placed` → `not-presenting` |
113
+ | iPhone | `quick-look`; tap → Quick Look opens the USDZ |
114
+ | With a tracking session running | the session reads `stopped` during AR and `running` after |
@@ -0,0 +1,78 @@
1
+ ---
2
+ title: "Product Variants, Hotspots & Dimensions"
3
+ description: "Material variants (colour / size), surface-anchored hotspots with serializable authoring data, and true-size dimension labels on a ProductViewer."
4
+ sidebarTitle: "Product Details"
5
+ icon: "tags"
6
+ ---
7
+
8
+ Builds on `<ProductViewer>` (Product Placement AR). Three details a product
9
+ page needs on the same model: switching looks, pointing at parts, and
10
+ telling the real size.
11
+
12
+ ```tsx
13
+ import {
14
+ ProductViewer,
15
+ ProductHotspot,
16
+ ProductDimensions,
17
+ useProductVariants,
18
+ useProductHotspots,
19
+ useProductDimensions,
20
+ type ProductViewerElement,
21
+ } from "@vincentt-xr/sdk/product";
22
+
23
+ const [el, setEl] = useState<ProductViewerElement | null>(null);
24
+ const variants = useProductVariants(el); // { variants, variant, setVariant }
25
+ const dimensions = useProductDimensions(el); // { size: [w, h, d], center } in metres, null until loaded
26
+ const hotspots = useProductHotspots(el, { initial: fromCms, onChange: save });
27
+
28
+ <ProductViewer src="/shoe.glb" scale="fixed" onReady={(e) => setEl(e)}>
29
+ {hotspots.hotspots.map((h) => (
30
+ <ProductHotspot key={h.id} hotspot={h} onClick={open} />
31
+ ))}
32
+ <ProductDimensions dimensions={dimensions} unit="metric" />
33
+ </ProductViewer>;
34
+ ```
35
+
36
+ ## Variants
37
+
38
+ `useProductVariants(element)` reads the model's `KHR_materials_variants`
39
+ after load and sets `variantName` on the element. Variants change materials
40
+ only, so they carry into AR wherever the platform renders the glTF (WebXR,
41
+ Scene Viewer). Quick Look renders the USDZ as exported: ship one USDZ per
42
+ variant and switch `iosSrc` with the variant, or accept the default look.
43
+
44
+ ## Hotspots
45
+
46
+ `ProductHotspotData = { id, position: [x, y, z], normal: [x, y, z], label?, description? }`
47
+ in model metres; serializable and validated (`parseHotspots`,
48
+ `serializeHotspots`). `<ProductHotspot>` renders a slotted callout model-viewer
49
+ keeps over the surface as the camera orbits, fading it when the surface
50
+ faces away.
51
+
52
+ `useProductHotspots(element, { initial, onChange })` is the authoring and
53
+ runtime state: `placeFromPointer(clientX, clientY, label)` raycasts the
54
+ click onto the model (`positionAndNormalFromPoint`), `add` / `update` /
55
+ `remove` / `clear`, `json` / `importJson`. The debug-ui
56
+ `<ProductHotspotPanel>` wraps it with click-to-place, label editing and a
57
+ JSON copy, so authored data goes back into the app as `initial`.
58
+
59
+ ## Dimensions
60
+
61
+ `useProductDimensions(element)` returns the bounding box (`getDimensions`,
62
+ `getBoundingBoxCenter`) after load. `<ProductDimensions>` labels width,
63
+ height and depth on three box edges, anchored as hotspots (`dimensionLines`
64
+ computes the edges); `unit` is `metric` (cm under 1 m) or `imperial`.
65
+ Pair with `scale="fixed"` on the viewer so AR places the model at that
66
+ size with no pinch-to-resize.
67
+
68
+ ## Manual validation
69
+
70
+ Run `/product-details` (model-viewer's variants shoe):
71
+
72
+ | Case | Steps | Expect |
73
+ | ---------- | ----------------------------------- | -------------------------------------------------------------- |
74
+ | Variants | tap the colourway buttons | the shoe changes material; the panel select follows |
75
+ | Hotspots | "place hotspot", click the shoe | a labelled dot stays on that point while orbiting |
76
+ | Authoring | edit the label, "copy JSON", reload | label persists; JSON matches the panel |
77
+ | Dimensions | toggle, switch unit | W / H / D labels on the box edges, cm ↔ in |
78
+ | AR (phone) | "View in your space" | true-size placement; variant carried into Scene Viewer / WebXR |
@@ -7,7 +7,10 @@ icon: "ruler"
7
7
 
8
8
  Import screen-coordinate helpers from `@vincentt-xr/sdk`. SDK screen pixels use
9
9
  a `720x1280` design canvas by default, center origin, and positive Y upward.
10
- They are not Three.js world units.
10
+ They are not Three.js world units. For the feed (landmark) space, the
11
+ source-media crop, mirroring and world projection, see
12
+ [Coordinate Spaces](/api/coordinate-spaces); this page covers the design-pixel
13
+ helpers.
11
14
 
12
15
  ## Coordinate contract
13
16