@vincentt-xr/sdk 2.0.0-alpha.8 → 2.0.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GROUNDING.md +4643 -170
- package/README.md +1 -0
- package/dist/CanonicalHeadFrame-BHcWyaiK.js +1506 -0
- package/dist/CanonicalHeadFrame-D-_T1OMU.cjs +1 -0
- package/dist/DebuggerUI-7ngnJsBe.js +275 -0
- package/dist/DebuggerUI-CoglgKdO.cjs +1 -0
- package/dist/FaceRetouch-CLoTfrcs.js +1071 -0
- package/dist/FaceRetouch-J1lC1WbS.cjs +134 -0
- package/dist/FaceSurface-CHAMEeG1.cjs +1 -0
- package/dist/FaceSurface-DmP9AEeC.js +27 -0
- package/dist/SegmentationOverlay-D_FWkcyP.cjs +35 -0
- package/dist/SegmentationOverlay-vn5x_knv.js +6237 -0
- package/dist/SkeletonUtils-C2r90MtN.js +21 -0
- package/dist/SkeletonUtils-CddIup1F.cjs +1 -0
- package/dist/TextLabel-XE0rQSDn.cjs +2 -0
- package/dist/TextLabel-c9BCucOI.js +961 -0
- package/dist/assets/gltfLoader.d.ts +16 -0
- package/dist/assets/loaders.d.ts +16 -1
- package/dist/body-pose/index.d.ts +521 -0
- package/dist/body-trigger/__fixtures__/syntheticBody.d.ts +83 -0
- package/dist/body-trigger/frame.d.ts +88 -0
- package/dist/body-trigger/index.d.ts +6 -0
- package/dist/body-trigger/moves.d.ts +235 -0
- package/dist/body-trigger/trigger.d.ts +75 -0
- package/dist/calibration/calibration.d.ts +11 -6
- package/dist/canonicalFace-BHwyCx1c.js +9 -0
- package/dist/canonicalFace-C83I225R.cjs +1 -0
- package/dist/components/BodyInstruction/BodyPoseHint.d.ts +63 -0
- package/dist/components/BodyInstruction/index.d.ts +69 -0
- package/dist/components/BodyInstruction/useBodyPose.d.ts +23 -0
- package/dist/components/BodyTracker/index.d.ts +10 -2
- package/dist/components/BodyTrigger/index.d.ts +49 -0
- package/dist/components/Debugger/DebuggerProvider.d.ts +14 -1
- package/dist/components/Debugger/DebuggerUI.d.ts +3 -1
- package/dist/components/FaceAtlas/FaceAtlasLayer.d.ts +114 -0
- package/dist/components/FaceAtlas/MadeUpCamera.d.ts +80 -0
- package/dist/components/FaceAtlas/constants.d.ts +8 -0
- package/dist/components/FaceAtlas/index.d.ts +7 -0
- package/dist/components/FaceAtlas/useFaceAtlasSurface.d.ts +84 -0
- package/dist/components/FaceAtlas/useFaceSkin.d.ts +84 -0
- package/dist/components/FaceCharacter/ExternalFaceMesh.d.ts +109 -0
- package/dist/components/FaceCharacter/FaceExpressionController.d.ts +53 -0
- package/dist/components/FaceCharacter/FaceMorph.d.ts +71 -0
- package/dist/components/FaceCharacter/FacePiercing.d.ts +65 -0
- package/dist/components/FaceCharacter/FaceReprojection.d.ts +85 -0
- package/dist/components/FaceCharacter/FaceRig.d.ts +38 -0
- package/dist/components/FaceCharacter/FaceSurface.d.ts +49 -0
- package/dist/components/FaceCharacter/FaceSurfaceOccluder.d.ts +39 -0
- package/dist/components/FaceCharacter/PinToFaceMesh.d.ts +68 -0
- package/dist/components/FaceCharacter/index.d.ts +18 -0
- package/dist/components/FaceCharacter/useFaceReprojector.d.ts +10 -0
- package/dist/components/FaceInset/FaceInset.d.ts +68 -0
- package/dist/components/FaceInset/frame.d.ts +94 -0
- package/dist/components/FaceInset/index.d.ts +6 -0
- package/dist/components/FaceInset/material.d.ts +40 -0
- package/dist/components/FaceInset/useFaceInsetTexture.d.ts +37 -0
- package/dist/components/FaceInstruction/FaceExpressionHint.d.ts +43 -0
- package/dist/components/FaceInstruction/index.d.ts +56 -0
- package/dist/components/FaceInstruction/useFaceExpression.d.ts +20 -0
- package/dist/components/FaceLiquify/FaceLiquify.d.ts +49 -0
- package/dist/components/FaceLiquify/debug.d.ts +37 -0
- package/dist/components/FaceLiquify/frame.d.ts +55 -0
- package/dist/components/FaceLiquify/index.d.ts +10 -0
- package/dist/components/FaceLiquify/material.d.ts +39 -0
- package/dist/components/FaceLiquify/pass.d.ts +49 -0
- package/dist/components/FaceLiquify/presence.d.ts +25 -0
- package/dist/components/FaceLiquify/presets.d.ts +82 -0
- package/dist/components/FaceLiquify/selfTest.d.ts +66 -0
- package/dist/components/FaceLiquify/target.d.ts +85 -0
- package/dist/components/FaceLiquify/warp.d.ts +72 -0
- package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +5 -3
- package/dist/components/FaceMesh/canonical/geometryGroups.d.ts +21 -0
- package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +9 -0
- package/dist/components/FaceMesh/index.d.ts +1 -1
- package/dist/components/FaceRetouch/Background.d.ts +3 -1
- package/dist/components/FaceRetouch/FaceRetouch.d.ts +5 -0
- package/dist/components/FaceRetouch/renderState.d.ts +19 -0
- package/dist/components/FaceSwap/FaceMirror.d.ts +46 -0
- package/dist/components/FaceSwap/FaceSwap.d.ts +58 -0
- package/dist/components/FaceSwap/FaceTextureLayer.d.ts +72 -0
- package/dist/components/FaceSwap/faceSwapPlan.d.ts +91 -0
- package/dist/components/FaceSwap/index.d.ts +13 -0
- package/dist/components/FaceSwap/settings.d.ts +300 -0
- package/dist/components/FaceSwap/useFaceTexture.d.ts +35 -0
- package/dist/components/FaceSwap/useLiveFace.d.ts +38 -0
- package/dist/components/FaceSwap/useLiveFaceTexture.d.ts +31 -0
- package/dist/components/FaceWarp3D/FaceWarp3D.d.ts +50 -0
- package/dist/components/FaceWarp3D/index.d.ts +2 -3
- package/dist/components/Faceless/Faceless.d.ts +51 -0
- package/dist/components/Faceless/index.d.ts +2 -0
- package/dist/components/HairLock/HairLock.d.ts +39 -0
- package/dist/components/HairLock/index.d.ts +2 -0
- package/dist/components/HairLock/lockGeometry.d.ts +15 -0
- package/dist/components/HandCutout/index.d.ts +35 -0
- package/dist/components/HandInstruction/HandGestureHint.d.ts +70 -0
- package/dist/components/HandInstruction/index.d.ts +74 -0
- package/dist/components/HandInstruction/useHandGesture.d.ts +22 -0
- package/dist/components/HandRig/ForearmOccluder.d.ts +29 -0
- package/dist/components/HandRig/HandAttachment.d.ts +34 -0
- package/dist/components/HandRig/HandOccluder.d.ts +55 -0
- package/dist/components/HandRig/HandTattoo.d.ts +61 -0
- package/dist/components/HandRig/WristAttachment.d.ts +34 -0
- package/dist/components/HandRig/index.d.ts +101 -0
- package/dist/components/HandRig/useArmMask.d.ts +29 -0
- package/dist/components/HandRig/wristSolve.d.ts +69 -0
- package/dist/components/HandTouch/HandTouch.d.ts +62 -0
- package/dist/components/HandTouch/Touchable.d.ts +36 -0
- package/dist/components/HandTouch/index.d.ts +2 -0
- package/dist/components/HeadBinding/index.d.ts +14 -0
- package/dist/components/HeadOccluder/CanonicalHeadFrame.d.ts +22 -0
- package/dist/components/HeadOccluder/Earrings.d.ts +55 -0
- package/dist/components/HeadOccluder/HeadAttachment.d.ts +38 -0
- package/dist/components/HeadOccluder/NeckOccluder.d.ts +64 -0
- package/dist/components/HeadOccluder/earringPlacement.d.ts +31 -0
- package/dist/components/HeadOccluder/headAttachmentPoints.d.ts +69 -0
- package/dist/components/HeadOccluder/index.d.ts +57 -3
- package/dist/components/HeadOccluder/useCanonicalHeadFit.d.ts +36 -0
- package/dist/components/HeadOccluder/useLandmarkPoseFit.d.ts +80 -0
- package/dist/components/Instruction/HintStage.d.ts +29 -0
- package/dist/components/Instruction/InstructionCue.d.ts +126 -0
- package/dist/components/Instruction/gestureHold.d.ts +20 -0
- package/dist/components/Instruction/ghost.d.ts +129 -0
- package/dist/components/Instruction/hintBlend.d.ts +19 -0
- package/dist/components/Instruction/hintLook.d.ts +81 -0
- package/dist/components/Instruction/hintLoop.d.ts +36 -0
- package/dist/components/Instruction/index.d.ts +41 -0
- package/dist/components/Instruction/useGhostModel.d.ts +33 -0
- package/dist/components/Instruction/useInstructionHold.d.ts +72 -0
- package/dist/components/LipEffect/LipEffect.d.ts +22 -2
- package/dist/components/LipEffect/LipEffectMaterial.d.ts +62 -10
- package/dist/components/LipEffect/LipEffects.d.ts +5 -2
- package/dist/components/LipEffect/defaults.d.ts +21 -2
- package/dist/components/LipEffect/index.d.ts +1 -1
- package/dist/components/LipEffect/lipShading.d.ts +73 -0
- package/dist/components/LipEffect/settings.d.ts +117 -13
- package/dist/components/LipEffect/shader.d.ts +39 -0
- package/dist/components/LipEffect/types.d.ts +82 -10
- package/dist/components/LipEffect/useLipDesignTextures.d.ts +6 -0
- package/dist/components/LipEffect/uvGuide.d.ts +31 -16
- package/dist/components/Makeup/Blush.d.ts +18 -0
- package/dist/components/Makeup/Brows.d.ts +20 -0
- package/dist/components/Makeup/Contour.d.ts +17 -0
- package/dist/components/Makeup/Eyeliner.d.ts +20 -0
- package/dist/components/Makeup/Eyeshadow.d.ts +20 -0
- package/dist/components/Makeup/Highlighter.d.ts +18 -0
- package/dist/components/Makeup/MakeupDesign.d.ts +37 -0
- package/dist/components/Makeup/MakeupRegion.d.ts +132 -0
- package/dist/components/Makeup/constants.d.ts +44 -0
- package/dist/components/Makeup/design.d.ts +106 -0
- package/dist/components/Makeup/designSamples.d.ts +42 -0
- package/dist/components/Makeup/eyes.d.ts +114 -0
- package/dist/components/Makeup/fields.d.ts +10 -0
- package/dist/components/Makeup/geometry.d.ts +106 -0
- package/dist/components/Makeup/index.d.ts +26 -0
- package/dist/components/Makeup/looks.d.ts +28 -0
- package/dist/components/Makeup/material.d.ts +239 -0
- package/dist/components/Makeup/settings.d.ts +54 -0
- package/dist/components/Makeup/shades.d.ts +143 -0
- package/dist/components/Makeup/shapes.d.ts +27 -0
- package/dist/components/Makeup/skinTone.d.ts +135 -0
- package/dist/components/Makeup/types.d.ts +110 -0
- package/dist/components/Makeup/useMakeupSkinTone.d.ts +40 -0
- package/dist/components/Necklace/Necklace.d.ts +44 -0
- package/dist/components/Necklace/index.d.ts +1 -0
- package/dist/components/ParticleEmitter/ParticleEmitter.d.ts +69 -0
- package/dist/components/ParticleEmitter/index.d.ts +1 -0
- package/dist/components/ShoulderOccluder/index.d.ts +43 -0
- package/dist/components/ShoulderOccluder/useCanonicalTorsoFit.d.ts +24 -0
- package/dist/components/SpringSwing/SpringSwing.d.ts +22 -0
- package/dist/components/SpringSwing/index.d.ts +1 -0
- package/dist/components/XRScene/renderOutputTarget.d.ts +12 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/config/index.d.ts +0 -1
- package/dist/context-DTxSQvp4.js +13 -0
- package/dist/context-hA0Rb2Xa.cjs +1 -0
- package/dist/contexts-BH7PdKFS.cjs +1 -0
- package/dist/contexts-jak8-tND.js +667 -0
- package/dist/coordinates/index.d.ts +2 -0
- package/dist/coordinates/side.d.ts +40 -0
- package/dist/debug-ui/default-setting.cjs +2 -2
- package/dist/debug-ui/face-swap-settings/index.d.ts +22 -0
- package/dist/debug-ui/hierarchy-panel/index.d.ts +3 -2
- package/dist/debug-ui/index.d.ts +4 -3
- package/dist/debug-ui/media-source/index.d.ts +1 -1
- package/dist/debug-ui/media-source/session.d.ts +30 -2
- package/dist/debug-ui/media-source.cjs +1 -1
- package/dist/debug-ui/media-source.js +1 -1
- package/dist/debug-ui/object-inspector-panel/index.d.ts +3 -2
- package/dist/debug-ui/product-hotspots/index.d.ts +3 -2
- package/dist/debug-ui/scene-editor/hierarchy-panel.d.ts +3 -1
- package/dist/debug-ui/scene-editor/inspector-panel.d.ts +3 -1
- package/dist/debug-ui/screen-image-settings/index.d.ts +3 -1
- package/dist/debug-ui/screen-text-settings/ScreenTextSettingsPanel.d.ts +1 -1
- package/dist/debug-ui/screen-text-settings/types.d.ts +2 -0
- package/dist/debug-ui/settings-panel/index.d.ts +6 -1
- package/dist/debug-ui/shared/debugWindow.d.ts +51 -0
- package/dist/debug-ui/xr-diagnostics/index.d.ts +3 -2
- package/dist/debug-ui.cjs +3 -3
- package/dist/debug-ui.js +2250 -2472
- package/dist/entries/all.d.ts +3 -1
- package/dist/entries/core.d.ts +3 -2
- package/dist/entries/face-effects.d.ts +114 -8
- package/dist/entries/instructions.d.ts +48 -0
- package/dist/entries/internal.d.ts +2 -1
- package/dist/entries/low-level.d.ts +28 -1
- package/dist/entries/particles.d.ts +11 -0
- package/dist/entries/tracking.d.ts +37 -2
- package/dist/face-atlas/attributes.d.ts +30 -0
- package/dist/face-atlas/eyes.d.ts +272 -0
- package/dist/face-atlas/faceAtlas.generated.d.ts +46 -0
- package/dist/face-atlas/glsl/atlasVertex.d.ts +46 -0
- package/dist/face-atlas/glsl/common.d.ts +55 -0
- package/dist/face-atlas/glsl/design.d.ts +49 -0
- package/dist/face-atlas/glsl/eyes.d.ts +73 -0
- package/dist/face-atlas/glsl/finish.d.ts +24 -0
- package/dist/face-atlas/glsl/format.d.ts +4 -0
- package/dist/face-atlas/glsl/index.d.ts +59 -0
- package/dist/face-atlas/glsl/shading.d.ts +15 -0
- package/dist/face-atlas/glsl/shapes.d.ts +66 -0
- package/dist/face-atlas/glsl/sparkle.d.ts +19 -0
- package/dist/face-atlas/glsl/uniforms.d.ts +106 -0
- package/dist/face-atlas/guide.d.ts +51 -0
- package/dist/face-atlas/index.d.ts +25 -0
- package/dist/face-atlas/lead.d.ts +117 -0
- package/dist/face-atlas/madeUpCamera.d.ts +125 -0
- package/dist/face-atlas/masks.d.ts +53 -0
- package/dist/face-atlas/obj.d.ts +69 -0
- package/dist/face-atlas/polylines.d.ts +63 -0
- package/dist/face-atlas/probe/FaceSkinProbe.d.ts +208 -0
- package/dist/face-atlas/probe/__fixtures__/emulate.d.ts +9 -0
- package/dist/face-atlas/probe/__fixtures__/face.d.ts +24 -0
- package/dist/face-atlas/probe/constants.d.ts +137 -0
- package/dist/face-atlas/probe/glsl.d.ts +43 -0
- package/dist/face-atlas/probe/lightFit.d.ts +108 -0
- package/dist/face-atlas/probe/schedule.d.ts +44 -0
- package/dist/face-atlas/probe/selfTest.d.ts +87 -0
- package/dist/face-atlas/probe/stats.d.ts +143 -0
- package/dist/face-atlas/probe/targets.d.ts +70 -0
- package/dist/face-atlas/probe/unwrap.d.ts +76 -0
- package/dist/face-atlas/quality.d.ts +28 -0
- package/dist/face-atlas/regions.d.ts +31 -0
- package/dist/face-atlas/registry.d.ts +252 -0
- package/dist/face-atlas/renderState.d.ts +86 -0
- package/dist/face-atlas/selfOcclusion.d.ts +62 -0
- package/dist/face-atlas/shading.d.ts +406 -0
- package/dist/face-atlas/shapes.d.ts +86 -0
- package/dist/face-atlas/sides.d.ts +41 -0
- package/dist/face-atlas/skinMask.d.ts +35 -0
- package/dist/face-atlas/surface.d.ts +155 -0
- package/dist/face-atlas/topology.d.ts +44 -0
- package/dist/face-character/__fixtures__/faceImageDetections.d.ts +25 -0
- package/dist/face-character/__fixtures__/faceNode.d.ts +22 -0
- package/dist/face-character/bindFaceModel.d.ts +106 -0
- package/dist/face-character/canonicalFace.d.ts +17 -0
- package/dist/face-character/canonicalFaceGeometry.d.ts +11 -0
- package/dist/face-character/canonicalFacePositions.d.ts +7 -0
- package/dist/face-character/driveFaceModel.d.ts +57 -0
- package/dist/face-character/expressionOutputs.d.ts +45 -0
- package/dist/face-character/faceExpressions.d.ts +104 -0
- package/dist/face-character/faceImageLandmarker.d.ts +93 -0
- package/dist/face-character/faceMeshBinding.d.ts +62 -0
- package/dist/face-character/faceMorph.d.ts +77 -0
- package/dist/face-character/faceMorphs.d.ts +46 -0
- package/dist/face-character/facePhoto.d.ts +138 -0
- package/dist/face-character/facePiercings.d.ts +116 -0
- package/dist/face-character/facePin.d.ts +131 -0
- package/dist/face-character/faceReprojection.d.ts +273 -0
- package/dist/face-character/faceReprojector.d.ts +171 -0
- package/dist/face-character/faceRig.d.ts +176 -0
- package/dist/face-character/faceSwapPresence.d.ts +85 -0
- package/dist/face-character/faceTexture.d.ts +169 -0
- package/dist/face-character/faceTextureBaker.d.ts +86 -0
- package/dist/face-character/faceTextureGuide.d.ts +106 -0
- package/dist/face-character/faceTextureStats.d.ts +298 -0
- package/dist/face-character/faceTransfer.d.ts +396 -0
- package/dist/face-character/faceTransferGeometry.d.ts +109 -0
- package/dist/face-character/faceTransferSelfTest.d.ts +94 -0
- package/dist/face-character/faceWarp3D.d.ts +101 -0
- package/dist/face-character/faceless.d.ts +79 -0
- package/dist/face-character/featureWarp.d.ts +28 -0
- package/dist/face-character/liveFaceRegistry.d.ts +370 -0
- package/dist/face-character/liveValue.d.ts +12 -0
- package/dist/face-character/memo.d.ts +15 -0
- package/dist/face-effects.cjs +2252 -83
- package/dist/face-effects.js +14234 -1231
- package/dist/face-expression/index.d.ts +182 -0
- package/dist/face-info/landmarks.d.ts +17 -3
- package/dist/face-info/types.d.ts +20 -3
- package/dist/gestures/definitions.d.ts +15 -2
- package/dist/gestures/index.d.ts +1 -1
- package/dist/gestures/measures.d.ts +21 -8
- package/dist/getFaceInfo-B1otSDMX.cjs +1 -0
- package/dist/getFaceInfo-Cu4xDWiL.js +62 -0
- package/dist/hand/armFit.d.ts +46 -0
- package/dist/hand/armMask.d.ts +178 -0
- package/dist/hand/handCutout.d.ts +23 -0
- package/dist/hand/handCutoutRegistry.d.ts +7 -0
- package/dist/hand/handGestures.d.ts +524 -0
- package/dist/hand/handPose.d.ts +98 -0
- package/dist/hand/handRigSolver.d.ts +159 -0
- package/dist/hand/handTattoo.d.ts +81 -0
- package/dist/hand/handTouch.d.ts +240 -0
- package/dist/hand/wrist.d.ts +44 -0
- package/dist/hand/wristFilter.d.ts +44 -0
- package/dist/hooks/selectors.d.ts +8 -0
- package/dist/hooks/useFaceModelAcquisition.d.ts +38 -0
- package/dist/hooks/useTrackerContext.d.ts +6 -0
- package/dist/index-B1_TzJaI.js +1104 -0
- package/dist/index-BavF06C6.js +190 -0
- package/dist/index-BfFmpddl.cjs +21 -0
- package/dist/index-BuBzneeW.cjs +46 -0
- package/dist/index-CGsQWodV.cjs +1 -0
- package/dist/index-CIe7eCMH.js +3200 -0
- package/dist/index-CfSF8LXa.cjs +1 -0
- package/dist/index-D5GTzOzD.cjs +1 -0
- package/dist/index-DBhQzvVa.js +314 -0
- package/dist/index-DE17y0ZI.cjs +1 -0
- package/dist/index-JII7huPk.js +442 -0
- package/dist/index-tpCr9CLj.cjs +1 -0
- package/dist/{renderPasses-NnKZVfBy.js → index-w1S7fI2B.js} +219 -247
- package/dist/index-zGaqrz_K.js +188 -0
- package/dist/instructions.cjs +30 -0
- package/dist/instructions.js +1507 -0
- package/dist/{internal-vsfNQycj.js → internal-B90P-clC.js} +138 -118
- package/dist/internal-Cjinca64.cjs +1 -0
- package/dist/internal.cjs +1 -1
- package/dist/internal.js +15 -10
- package/dist/iris/compute.d.ts +7 -5
- package/dist/iris/types.d.ts +6 -4
- package/dist/{landmarkMask-CbTFzBYG.js → landmarkMask-BFDyBnKM.js} +6 -6
- package/dist/landmarks-BlUqf5MZ.cjs +1 -0
- package/dist/landmarks-bftdwq6Z.js +76 -0
- package/dist/loaders-BGAUACsd.js +363 -0
- package/dist/loaders-BJ1_QCHt.cjs +1 -0
- package/dist/low-level.cjs +1 -1
- package/dist/low-level.js +666 -602
- package/dist/main.cjs +1 -1
- package/dist/main.js +866 -1182
- package/dist/models/Body/index.d.ts +2 -0
- package/dist/models/Face/constants.d.ts +8 -0
- package/dist/models/Face/index.d.ts +3 -11
- package/dist/models/Face/rotation.d.ts +18 -3
- package/dist/models/Hand/HandTracking.d.ts +17 -1
- package/dist/models/Segmentation/index.d.ts +2 -0
- package/dist/models/nodeSource.d.ts +9 -0
- package/dist/particles/emission.d.ts +24 -0
- package/dist/particles/eyes.d.ts +24 -0
- package/dist/particles/glsl.d.ts +14 -0
- package/dist/particles/index.d.ts +10 -0
- package/dist/particles/motion.d.ts +42 -0
- package/dist/particles/presets.d.ts +12 -0
- package/dist/particles/ring.d.ts +58 -0
- package/dist/particles/selfTest.d.ts +53 -0
- package/dist/particles/settings.d.ts +127 -0
- package/dist/particles/shapes.d.ts +29 -0
- package/dist/particles/spawner.d.ts +60 -0
- package/dist/particles/system.d.ts +64 -0
- package/dist/particles.cjs +122 -0
- package/dist/particles.js +774 -0
- package/dist/product.cjs +1 -1
- package/dist/product.js +29 -29
- package/dist/{providers-C0Dlhh9Z.js → providers-C8rE26Uf.js} +127 -126
- package/dist/providers-DHsrhDI2.cjs +62 -0
- package/dist/render/renderPasses.d.ts +8 -0
- package/dist/render/sceneBeforeRender.d.ts +12 -0
- package/dist/{renderGroups-CN1cGFUo.js → renderGroups-B38pUaX2.js} +1 -1
- package/dist/{renderGroups-O4KmaMl9.cjs → renderGroups-Cb_4Ar1Q.cjs} +1 -1
- package/dist/renderPasses-B6l8IpJv.js +1290 -0
- package/dist/renderPasses-dqmkft4P.cjs +158 -0
- package/dist/renderState-CJNmj5jz.js +39 -0
- package/dist/renderState-apSfg4eR.cjs +1 -0
- package/dist/scene-object.cjs +1 -1
- package/dist/scene-object.js +2 -2
- package/dist/segmentation-Cb3ouK6Z.js +1758 -0
- package/dist/segmentation-D9pYO6aR.cjs +1 -0
- package/dist/segmentation2d/types.d.ts +6 -0
- package/dist/select-Ck5LGz-J.cjs +1 -0
- package/dist/select-pYRo_win.js +233 -0
- package/dist/selectors-C4X71aoD.cjs +1 -0
- package/dist/selectors-DmNaKIwE.js +196 -0
- package/dist/session-BrH8G7iJ.cjs +31 -0
- package/dist/session-DgA_z6O1.js +418 -0
- package/dist/{settings-aQk845NJ.js → settings-BJ7FMBsO.js} +53 -15
- package/dist/settings-C63FMBlF.cjs +1 -0
- package/dist/similarityFit-BFqHND2e.cjs +1 -0
- package/dist/similarityFit-Bbz-R8AY.js +91 -0
- package/dist/spring/index.d.ts +2 -0
- package/dist/spring/spring.d.ts +69 -0
- package/dist/spring/swing.d.ts +54 -0
- package/dist/tracking.cjs +10 -1
- package/dist/tracking.js +1002 -855
- package/dist/trigger-D0Pm9noT.cjs +49 -0
- package/dist/trigger-IQeys0oS.js +2128 -0
- package/dist/types/face.d.ts +20 -1
- package/dist/types/hand-tracking.d.ts +9 -0
- package/dist/types/nodes.d.ts +20 -1
- package/dist/types/segmentation.d.ts +5 -0
- package/dist/updateThrottle-BseecYag.js +4 -0
- package/dist/updateThrottle-Of5Y4SVa.cjs +1 -0
- package/dist/useFaceInfo-BHDNCvsJ.cjs +1 -0
- package/dist/useFaceInfo-J4x7LsqL.js +76 -0
- package/dist/useFaceResultReader-BvEo5REG.js +61 -0
- package/dist/useFaceResultReader-DuaL1KJG.cjs +1 -0
- package/dist/useInstructionHold-DOu-RpCM.js +53 -0
- package/dist/useInstructionHold-DwJY1Alr.cjs +1 -0
- package/dist/useLandmarkPoseFit-Bg-h9BPb.cjs +1 -0
- package/dist/useLandmarkPoseFit-Bmb3h6Mw.js +87 -0
- package/dist/{useXRCapabilities-B1R2ghy-.cjs → useXRCapabilities-Cr3RzuAW.cjs} +1 -1
- package/dist/{useXRCapabilities-C68v__wB.js → useXRCapabilities-Cxmlmpbd.js} +1 -1
- package/dist/utils/canonicalRigidLandmarks.d.ts +8 -0
- package/dist/utils/headOccluderFit.d.ts +42 -0
- package/dist/utils/integrity.d.ts +17 -0
- package/dist/utils/resolveNumFaces.d.ts +13 -0
- package/dist/utils/shoulderOccluderFit.d.ts +38 -0
- package/dist/utils/similarityFit.d.ts +23 -0
- package/dist/uv-BMFt19bg.cjs +1 -0
- package/dist/{index-CsUdQ-pn.js → uv-DJU_XfmN.js} +15 -249
- package/docs/SDK_DOCUMENTATION.md +1 -2
- package/docs/api/adaptive-quality.mdx +1 -1
- package/docs/api/body-instructions.mdx +285 -0
- package/docs/api/body-triggers.mdx +234 -0
- package/docs/api/camera-permission.mdx +1 -1
- package/docs/api/coordinate-spaces.mdx +7 -4
- package/docs/api/cross-camera.mdx +3 -2
- package/docs/api/debug-ui-scene-editor.mdx +23 -2
- package/docs/api/external-face-mesh.mdx +231 -0
- package/docs/api/face-actions.mdx +20 -16
- package/docs/api/face-attribute-expression.mdx +1 -1
- package/docs/api/face-binding-anchors.mdx +4 -2
- package/docs/api/face-character.mdx +157 -0
- package/docs/api/face-effects.mdx +3 -0
- package/docs/api/face-expression-controller.mdx +153 -0
- package/docs/api/face-info.mdx +17 -11
- package/docs/api/face-inset.mdx +204 -0
- package/docs/api/face-instructions.mdx +183 -0
- package/docs/api/face-liquify.mdx +196 -0
- package/docs/api/face-mesh.mdx +4 -7
- package/docs/api/face-morph.mdx +117 -0
- package/docs/api/face-painting.mdx +7 -0
- package/docs/api/face-reprojection.mdx +154 -0
- package/docs/api/face-retouching.mdx +18 -10
- package/docs/api/face-swap.mdx +350 -0
- package/docs/api/face-warp-3d.mdx +166 -0
- package/docs/api/faceless.mdx +143 -0
- package/docs/api/gestures.mdx +68 -32
- package/docs/api/hair.mdx +97 -0
- package/docs/api/hand-instructions.mdx +222 -0
- package/docs/api/hand-rig.mdx +535 -0
- package/docs/api/hand-touch.mdx +162 -0
- package/docs/api/head-occluder.mdx +563 -0
- package/docs/api/holistic-tracker.mdx +6 -1
- package/docs/api/instructions.mdx +323 -0
- package/docs/api/iris-tracking.mdx +24 -19
- package/docs/api/made-up-camera.mdx +131 -0
- package/docs/api/makeup-skin-tone.mdx +135 -0
- package/docs/api/makeup.mdx +353 -0
- package/docs/api/multi-subject.mdx +4 -1
- package/docs/api/particles.mdx +155 -0
- package/docs/api/person-cutout.mdx +1 -1
- package/docs/api/pin-to-face-mesh.mdx +274 -0
- package/docs/api/product-ar.mdx +5 -2
- package/docs/api/segmentation-overlay.mdx +1 -1
- package/docs/docs.json +29 -1
- package/docs/examples/lip-shaders.mdx +82 -33
- package/docs/guides/face-atlas-template.svg +1 -0
- package/docs/guides/face-atlas-textures.mdx +186 -0
- package/docs/guides/face-texture-template.svg +1 -0
- package/docs/guides/harness-debug-ui.mdx +4 -4
- package/docs/guides/lip-effect-textures.mdx +178 -102
- package/docs/guides/lip-uv-template.png +0 -0
- package/docs/guides/lip-uv-template.svg +1 -1
- package/docs/guides/makeup-design-textures.mdx +109 -0
- package/docs/introduction.mdx +1 -2
- package/package.json +11 -1
- package/dist/DebuggerUI-C-ldiozL.js +0 -269
- package/dist/DebuggerUI-CWX5EtQv.cjs +0 -1
- package/dist/FaceMeshRenderer-BEEXZwS6.cjs +0 -158
- package/dist/FaceMeshRenderer-UuH5sTXG.js +0 -1322
- package/dist/FaceRetouch-C7h7x9kd.js +0 -683
- package/dist/FaceRetouch-DqftT26Y.cjs +0 -134
- package/dist/GLTFLoader-C5q63sKO.js +0 -1633
- package/dist/GLTFLoader-Cb_CRwmG.cjs +0 -1
- package/dist/SegmentationOverlay-DQuW3dsc.js +0 -133
- package/dist/SegmentationOverlay-aWVod8Kl.cjs +0 -1
- package/dist/components/FaceWarp3D/FaceWarp3DHead.d.ts +0 -15
- package/dist/components/FaceWarp3D/defaults.d.ts +0 -37
- package/dist/components/FaceWarp3D/warp.d.ts +0 -13
- package/dist/contexts-CO0sd4JQ.cjs +0 -1
- package/dist/contexts-FzlnnMYD.js +0 -669
- package/dist/debug-ui/face-warp-3d/index.d.ts +0 -6
- package/dist/getFaceInfo-BkZfaQs-.js +0 -118
- package/dist/getFaceInfo-ahPxQFGu.cjs +0 -1
- package/dist/index--RgGzZ6X.cjs +0 -47
- package/dist/index-CHVbH0hz.js +0 -214
- package/dist/index-CeVkgsag.cjs +0 -1
- package/dist/index-CnGox6Xr.js +0 -3054
- package/dist/index-DKBAh6hV.cjs +0 -1
- package/dist/index-DsZwTfG0.cjs +0 -1
- package/dist/index-Dw6tj2Mi.js +0 -144
- package/dist/index-OCPjOaeP.cjs +0 -1
- package/dist/index-s9pF4zkG.js +0 -2053
- package/dist/internal-BYza1h8_.cjs +0 -1
- package/dist/measures-9dQPdw96.js +0 -154
- package/dist/measures-KfJzpvod.cjs +0 -1
- package/dist/providers-YNwkmNeK.cjs +0 -62
- package/dist/renderPasses-Cg-zqmEz.cjs +0 -21
- package/dist/screenTransform-BenfCtZt.js +0 -44
- package/dist/screenTransform-BiXdpVf0.cjs +0 -1
- package/dist/segmentation-9PhSvc-R.cjs +0 -1
- package/dist/segmentation-CeOTKemr.js +0 -5
- package/dist/selectors-C5G1PMYL.js +0 -195
- package/dist/selectors-Du_PsVnW.cjs +0 -1
- package/dist/session-BBr0yN8h.cjs +0 -31
- package/dist/session-Cy0m7l7-.js +0 -363
- package/dist/settings-DRR7-snV.cjs +0 -1
- package/dist/useFaceInfo-Blf7FCu3.js +0 -303
- package/dist/useFaceInfo-C5mO8NQY.cjs +0 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Face Warp 3D"
|
|
3
|
+
description: "Reshape the live face with blend shapes — bigger eyes, a longer nose, chubby cheeks — using the camera image itself as the texture."
|
|
4
|
+
sidebarTitle: "Face Warp 3D"
|
|
5
|
+
icon: "face-grin-tongue-wink"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`FaceWarp3D` reshapes the person's real face with blend shapes (shape keys), as Spark AR's face mesh
|
|
9
|
+
deformation did: bigger eyes, a longer nose, chubby cheeks, a big forehead.
|
|
10
|
+
|
|
11
|
+
- **Real pixels.** Every pixel is the camera image itself, moved, so the result is photoreal and
|
|
12
|
+
the person's own expression carries on underneath.
|
|
13
|
+
- **Weight 0** leaves the camera image untouched.
|
|
14
|
+
|
|
15
|
+
It is part of the face-character pipeline ([#194](https://github.com/vincentt-xr/sdk/issues/194)).
|
|
16
|
+
Import from `@vincentt-xr/sdk/face-effects`.
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { FaceWarp3D } from "@vincentt-xr/sdk/face-effects";
|
|
22
|
+
import { FaceTracker } from "@vincentt-xr/sdk/tracking";
|
|
23
|
+
|
|
24
|
+
<FaceTracker>
|
|
25
|
+
<FaceWarp3D deformation={gltf.scene} weights={{ bigEyes: 0.8, longNose: 0.3 }} />
|
|
26
|
+
</FaceTracker>;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## FaceWarp3D or FaceMorph?
|
|
30
|
+
|
|
31
|
+
They are different effects.
|
|
32
|
+
|
|
33
|
+
| | `FaceWarp3D` | [`FaceMorph`](/api/face-morph) |
|
|
34
|
+
| ------------ | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
35
|
+
| What you see | The person, photoreal: their own skin, hair and expression, reshaped | Another object (a ball, a box, a character shape) wearing the camera face |
|
|
36
|
+
| How | Shape keys move the camera's own pixels; weight 0 = the image untouched | A mesh is rendered, textured with the unwrapped camera face |
|
|
37
|
+
| Best for | Big eyes, a big nose, chubby or slim faces, chibi or alien proportions, your face shaped like a character | Turning into a shape, transformation sweeps, stylised heads |
|
|
38
|
+
| Avoid for | Changing the skull or hair (face only) | Realistic heads (their skull shows the model's material, not hair) |
|
|
39
|
+
|
|
40
|
+
Use one face effect per face; they all draw over the face.
|
|
41
|
+
|
|
42
|
+
## Authoring blend shapes
|
|
43
|
+
|
|
44
|
+
Shape keys live on a model in the canonical head frame (centimetres, Y up, Z out of the face), exported
|
|
45
|
+
as glTF morph targets.
|
|
46
|
+
|
|
47
|
+
- **On the canonical face (exact).** Sculpt on the reference mesh
|
|
48
|
+
`assets-src/face-character/canonical-face-reference.glb` in the SDK repo, or export
|
|
49
|
+
`createCanonicalFaceGeometry()` with three's `GLTFExporter`. Its 468 vertices are the face
|
|
50
|
+
landmarks, in order. Every key applies exactly, and key names become the `weights` names.
|
|
51
|
+
- **On any other mesh (transferred).** A head in the same frame, such as Snap's face + skull mesh
|
|
52
|
+
with a sculpted key, has its keys transferred: each point of the face takes the offset at its
|
|
53
|
+
closest point on the mesh's base surface.
|
|
54
|
+
- **A model's own shape.** A model without shape keys gives one key, `"shape"`, measured along the
|
|
55
|
+
face's normal: the face takes the model's proportions. The facecap example reads best this way.
|
|
56
|
+
|
|
57
|
+
### In Blender
|
|
58
|
+
|
|
59
|
+
1. **Import.** File → Import → glTF 2.0, with default settings. Leave its location, rotation and
|
|
60
|
+
scale as they are.
|
|
61
|
+
2. **Add a key.** Object Data properties → Shape Keys: click `+` once for the Basis, then `+` again
|
|
62
|
+
for your key. Rename it (`bigEyes`).
|
|
63
|
+
3. **Sculpt.** With the key selected, sculpt or edit the mesh, with X symmetry on for a balanced face.
|
|
64
|
+
Slide the key's value to preview.
|
|
65
|
+
4. **Keep the vertices.** Never add, delete, merge or reorder them: no remesh, no "merge by
|
|
66
|
+
distance", no applied subdivision. Blender's glTF import and export keep the vertices and their
|
|
67
|
+
order (tested).
|
|
68
|
+
5. **Export.** File → Export → glTF 2.0 (`.glb`), with Data → Shape Keys on and Apply Modifiers off.
|
|
69
|
+
+Y up is the default.
|
|
70
|
+
6. **More keys.** One file can carry many keys (up to `FACE_WARP_MAX_KEYS`, 16, apply). Give each its
|
|
71
|
+
own slider through `weights`.
|
|
72
|
+
|
|
73
|
+
The warp mesh is the face with the eyes and mouth covered, so keys can move the eyes and lips too.
|
|
74
|
+
Two **skirt** rings past the face's edge stretch the surrounding hair, ears and neck pixels. That lets
|
|
75
|
+
the edge of the face move (puffed cheeks, a smaller chin) without uncovering the original or leaving
|
|
76
|
+
a seam.
|
|
77
|
+
|
|
78
|
+
## Props
|
|
79
|
+
|
|
80
|
+
| Prop | Default | What it does |
|
|
81
|
+
| -------------- | ------- | --------------------------------------------------------------------------------- |
|
|
82
|
+
| `deformation` | `null` | The model with shape keys (see above). `null` shows the face mesh only. |
|
|
83
|
+
| `weights` | — | A weight per shape key, by name. A key left out is at 1. Also a ref. |
|
|
84
|
+
| `weight` | `1` | Overall strength, multiplying every key. Also a ref. |
|
|
85
|
+
| `expression` | `1` | The face's own expression: 0 freezes it, more than 1 exaggerates it. Also a ref. |
|
|
86
|
+
| `subdivisions` | `2` | Face mesh density (2 ≈ 7,500 vertices; smoother sculpts). |
|
|
87
|
+
| `opacity` | `1` | Opacity of the warped face. |
|
|
88
|
+
| `onKeys` | — | Receives the shape-key names found on `deformation`, for sliders. |
|
|
89
|
+
| rig props | — | `faceIndex`, `smoothing`, `holdMs`, `neutral` … (when it runs its own `FaceRig`). |
|
|
90
|
+
|
|
91
|
+
## Animating without re-rendering
|
|
92
|
+
|
|
93
|
+
`weights`, `weight` and `expression` also take a ref (`LiveValue<T>`), read every frame. Drive them from
|
|
94
|
+
`useFrame`, or from a `FaceExpressionController` `set` output, without re-rendering React:
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
const keys = useRef({ bigEyes: 0 });
|
|
98
|
+
useFrame(({ clock }) => {
|
|
99
|
+
keys.current.bigEyes = (Math.sin(clock.elapsedTime) + 1) / 2;
|
|
100
|
+
});
|
|
101
|
+
<FaceWarp3D deformation={gltf.scene} weights={keys} />;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## How it works
|
|
105
|
+
|
|
106
|
+
1. **Live face.** Every frame the CPU writes the live face (`FaceRigState.local`, 471 points with the
|
|
107
|
+
eye and mouth centres) into a small float texture. That is all the per-frame CPU work.
|
|
108
|
+
2. **Deformation, on the GPU.** The vertex shader interpolates each vertex's live point, then adds
|
|
109
|
+
the shape keys' offsets (a float texture) times their weights:
|
|
110
|
+
`position = live + weight · Σ key · offset`. Skirt vertices follow their edge vertex with a
|
|
111
|
+
fading share of its move.
|
|
112
|
+
3. **Projective texture.** The shader projects each vertex's undeformed live position to the
|
|
113
|
+
screen. The camera image is drawn full-screen in the same space, so that point is the camera
|
|
114
|
+
texel under it. Every fragment samples there, which gives an exact identity at weight 0 even
|
|
115
|
+
while the head moves.
|
|
116
|
+
|
|
117
|
+
**Limitation (shared with Spark AR):** shrinking a feature far inside the face (a tiny mouth) can
|
|
118
|
+
show the original pixels that were there. Enlarging is always clean.
|
|
119
|
+
|
|
120
|
+
**Pure pieces:**
|
|
121
|
+
|
|
122
|
+
- `createFaceWarpMesh`, `bindFaceWarpDeformation`;
|
|
123
|
+
- `stepFaceWarp3D`, the CPU reference of the shader;
|
|
124
|
+
- `createFaceWarpGpuData` and `writeFaceWarpLiveTexels`, what the shader reads;
|
|
125
|
+
- `createCanonicalFaceGeometry`, `subdivideFaceUnwrap` and `createClosestPointSearch`.
|
|
126
|
+
|
|
127
|
+
## Migrating from the old FaceWarp3D
|
|
128
|
+
|
|
129
|
+
The 2.0.0-alpha.9 FaceWarp3D replaces the proportion sliders. These are removed:
|
|
130
|
+
|
|
131
|
+
- `FaceWarp3DSettings`, `FACE_WARP_3D_PRESET` and `DEFAULT_FACE_WARP_3D_SETTINGS`;
|
|
132
|
+
- `CanonicalFaceMeshRenderer`'s `faceWarp3D` prop;
|
|
133
|
+
- `FaceWarp3DHead`;
|
|
134
|
+
- the `FaceWarp3DSettingsPanel` debug panel.
|
|
135
|
+
|
|
136
|
+
To get the same looks, sculpt them as shape keys on the canonical face and give each a weight.
|
|
137
|
+
|
|
138
|
+
## Example
|
|
139
|
+
|
|
140
|
+
`/face-warp` in its 3D mode (`?mode=3d`; the old `/face-warp-3d` redirects there) has three sources:
|
|
141
|
+
|
|
142
|
+
- **facecap:** its own shape (local; the default when present);
|
|
143
|
+
- **demo:** shape keys sculpted in code on the canonical face (big eyes, long nose, chubby cheeks,
|
|
144
|
+
tiny mouth, big forehead), with one slider each;
|
|
145
|
+
- **Lens Studio head:** the chibi shape key, sculpted on Snap's face + skull + ears mesh
|
|
146
|
+
(local, git-ignored).
|
|
147
|
+
|
|
148
|
+
It also has controls for weight (or a looping animation, driven through a ref), expression and
|
|
149
|
+
opacity.
|
|
150
|
+
|
|
151
|
+
## Manual visual test plan
|
|
152
|
+
|
|
153
|
+
Open `/face-warp?mode=3d` on the webcam.
|
|
154
|
+
|
|
155
|
+
1. **Weight 0**: the image is untouched. No edge, band or shimmer, even while you move.
|
|
156
|
+
2. **Big eyes**: your eyes grow, your lids still blink, and your gaze still moves.
|
|
157
|
+
3. **Long nose / chubby cheeks / big forehead**: each reads clearly from the front and stays
|
|
158
|
+
photoreal (your own skin and hair). The edge of the face blends into the hair, ears and neck.
|
|
159
|
+
4. **Expressions**: talk, smile and raise your brows with keys on. Your expression carries through
|
|
160
|
+
the shape. `expression` 0 freezes it; 2 exaggerates it.
|
|
161
|
+
5. **Lens Studio head**: the cheeks puff and the forehead swells into the hair, with no double chin
|
|
162
|
+
or seam.
|
|
163
|
+
6. **Head turn**: turn and tilt. The warp stays on the face and the skirt follows.
|
|
164
|
+
7. **Animate**: the warp breathes in and out smoothly.
|
|
165
|
+
8. **Dropout**: cover the camera. The warp holds briefly, hides when the face is lost, and comes
|
|
166
|
+
back.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Faceless (experimental)"
|
|
3
|
+
description: "Erase the eyes, brows, nose and mouth with the person's own skin, or even the whole face into a mannequin. Every tracked face, with makeup, glasses and liquify on top."
|
|
4
|
+
sidebarTitle: "Faceless"
|
|
5
|
+
icon: "face-meh-blank"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`Faceless` erases a face's features with the person's own skin. The face keeps its real light, colour
|
|
9
|
+
and outline; only the eyes, brows, nose and mouth are gone.
|
|
10
|
+
|
|
11
|
+
- **Two looks.** `"real"` erases the features and keeps the rest of the face as the camera sees it,
|
|
12
|
+
with grain matched to the skin's own texture. `"smooth"` evens the whole face into a mannequin.
|
|
13
|
+
- **Blinks and an open mouth never show.** The erase covers the eye and mouth openings too.
|
|
14
|
+
- **It is the face.** It draws in the face layer, so makeup, designs, glasses and hats draw over it,
|
|
15
|
+
and `FaceLiquify` warps it.
|
|
16
|
+
|
|
17
|
+
Experimental: its props and look may change in a later alpha. Import from
|
|
18
|
+
`@vincentt-xr/sdk/face-effects`.
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { VideoBackground, XRScene } from "@vincentt-xr/sdk";
|
|
24
|
+
import { Faceless } from "@vincentt-xr/sdk/face-effects";
|
|
25
|
+
|
|
26
|
+
<XRScene>
|
|
27
|
+
<VideoBackground />
|
|
28
|
+
<Faceless />
|
|
29
|
+
</XRScene>;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
It starts the face model itself; no `FaceTracker` is needed.
|
|
33
|
+
|
|
34
|
+
## Looks, amount and grain
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<Faceless style="smooth" />;
|
|
38
|
+
<Faceless amount={0.5} />;
|
|
39
|
+
<Faceless grain={0} />;
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- **`style`**: `"real"` (default) or `"smooth"`.
|
|
43
|
+
- **`amount`**: 0 is the real face, 1 is faceless. Pass a ref (`{ current: n }`) to fade it every
|
|
44
|
+
frame without re-rendering.
|
|
45
|
+
- **`grain`**: 0..1, `"real"` only. 1 (default) matches the fine detail measured on the person's own
|
|
46
|
+
cheeks, forehead and chin; 0 leaves the erased skin smooth. There is no grain in the eye and mouth
|
|
47
|
+
openings or on the lips, which stretch on screen when they open.
|
|
48
|
+
|
|
49
|
+
## Faces
|
|
50
|
+
|
|
51
|
+
- **Every tracked face** goes faceless, up to four. `faceIndex` picks one; `numFaces` sets how many
|
|
52
|
+
faces the face model tracks.
|
|
53
|
+
- Inside a `FaceTracker`, it follows that tracker's face.
|
|
54
|
+
- A face fades in with its first result and out shortly after it is lost.
|
|
55
|
+
|
|
56
|
+
## Hands in front (experimental)
|
|
57
|
+
|
|
58
|
+
With `HandCutout` in the scene, a hand over the face stays in front of the faceless face.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { HandCutout, HandTracker } from "@vincentt-xr/sdk/tracking";
|
|
62
|
+
|
|
63
|
+
<>
|
|
64
|
+
<HandTracker>
|
|
65
|
+
<HandCutout />
|
|
66
|
+
</HandTracker>
|
|
67
|
+
<Faceless />
|
|
68
|
+
</>;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Props
|
|
72
|
+
|
|
73
|
+
| Prop | Default | Meaning |
|
|
74
|
+
| ------------- | ------------------ | ------------------------------------------------------------------------------ |
|
|
75
|
+
| `style` | `"real"` | `"real"`: features erased with the own skin; `"smooth"`: the whole face evened |
|
|
76
|
+
| `amount` | 1 | 0 the real face … 1 faceless, or a ref read every frame |
|
|
77
|
+
| `grain` | 1 | Grain on the erased skin, 0..1 (`"real"` only) |
|
|
78
|
+
| `faceIndex` | every tracked face | Only this face (default: the enclosing `FaceTracker`'s face, else every face) |
|
|
79
|
+
| `numFaces` | 1 | Faces the face model tracks when this starts it |
|
|
80
|
+
| `smoothing` | the live face's | Landmark smoothing 0..1 |
|
|
81
|
+
| `quality` | `"auto"` | Mesh level and statistics rate, as face swap's |
|
|
82
|
+
| `active` | true | False: nothing drawn |
|
|
83
|
+
| `renderOrder` | −2 | The face layer |
|
|
84
|
+
|
|
85
|
+
## Your own layer
|
|
86
|
+
|
|
87
|
+
`useFacelessTexture(faceIndex, options)` returns the faceless face texture for your own
|
|
88
|
+
`FaceTextureLayer`, for example to fade it with your own logic or draw it on another face:
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import { FaceTextureLayer, useFacelessTexture } from "@vincentt-xr/sdk/face-effects";
|
|
92
|
+
|
|
93
|
+
const Blank = () => {
|
|
94
|
+
const face = useFacelessTexture(0, { style: "smooth" });
|
|
95
|
+
return (
|
|
96
|
+
<FaceTextureLayer
|
|
97
|
+
face={face}
|
|
98
|
+
faceIndex={0}
|
|
99
|
+
preset="raw"
|
|
100
|
+
ownEyes={false}
|
|
101
|
+
ownMouth={false}
|
|
102
|
+
unseen="cover"
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- `ownEyes` and `ownMouth` off draw the erased eye and mouth openings.
|
|
109
|
+
- `unseen="cover"` also covers the parts the camera sees edge-on (nostril undersides, the lips'
|
|
110
|
+
seam); with the default `"fade"` the camera shows through there.
|
|
111
|
+
|
|
112
|
+
Lower level: `FacelessTexture` is the composite pass (`update(renderer, liveFace, { style, grain })`,
|
|
113
|
+
`dispose()`), with its masks from `createFacelessMask` and `createFacelessStretchMask` and its shader
|
|
114
|
+
`FACELESS_FRAGMENT`.
|
|
115
|
+
|
|
116
|
+
## Limits
|
|
117
|
+
|
|
118
|
+
- **Beards and stubble** under the erased mouth are replaced by smooth skin; the stubble around it
|
|
119
|
+
stays.
|
|
120
|
+
- **Real glasses** are part of the camera image: the lenses are erased with the eyes, the frames
|
|
121
|
+
outside the eye area stay. Draw 3D glasses over the faceless face instead.
|
|
122
|
+
- **Cost.** One composite per face per new face result, at the live face texture's size. Check phone
|
|
123
|
+
performance before shipping a multi-face effect.
|
|
124
|
+
|
|
125
|
+
## Example
|
|
126
|
+
|
|
127
|
+
`/face-reprojection` in the SDK playground, mode "faceless", has both looks, the amount and grain
|
|
128
|
+
sliders, hands in front and the face count. Settings are in the URL: `?mode=faceless`,
|
|
129
|
+
`?fstyle=smooth`, `?famount=0.5`, `?grain=0`. The two-people clip shows two faces.
|
|
130
|
+
|
|
131
|
+
## Manual visual test plan
|
|
132
|
+
|
|
133
|
+
Open `/face-reprojection?mode=faceless` on the webcam.
|
|
134
|
+
|
|
135
|
+
1. **Real**: eyes, brows, nose and mouth are gone. No brow line, lash line, lip line or nostril
|
|
136
|
+
remains; the erased skin has the face's own colour, light and fine texture.
|
|
137
|
+
2. **Smooth**: the whole face is even skin, with no feature or line showing through.
|
|
138
|
+
3. **Blink and open the mouth wide**: nothing shows, and no streaks appear.
|
|
139
|
+
4. **Turn the head** far left and right, and tilt: the erase stays on the features with no edge
|
|
140
|
+
sliding off the face.
|
|
141
|
+
5. **Amount**: 0 is the real face, 0.5 a half fade, 1 faceless.
|
|
142
|
+
6. **Hands**: with hands in front, a hand over the mouth stays in front of the face.
|
|
143
|
+
7. **Two faces**: on the two-people clip, both faces are faceless.
|
package/docs/api/gestures.mdx
CHANGED
|
@@ -9,7 +9,9 @@ icon: "hand-sparkles"
|
|
|
9
9
|
open palm, wave, hand raise, nod, head shake, mouth open, smile, blink,
|
|
10
10
|
brow raise, arm raise and T-pose, plus your own. One engine handles the
|
|
11
11
|
thresholds, hysteresis, hold, cooldown, confidence and tracking loss, so
|
|
12
|
-
scenes stop re-implementing them.
|
|
12
|
+
scenes stop re-implementing them. For full-body poses and moves (jump,
|
|
13
|
+
squat, wave, clap, punch, kick, steps, march) use
|
|
14
|
+
[Body Triggers](/api/body-triggers), which run on the same engine.
|
|
13
15
|
|
|
14
16
|
```tsx
|
|
15
17
|
import { GestureListener, useGesture } from "@vincentt-xr/sdk/tracking";
|
|
@@ -30,29 +32,29 @@ any tracker.
|
|
|
30
32
|
|
|
31
33
|
## Built-in gestures
|
|
32
34
|
|
|
33
|
-
| Name | Kind | Measures
|
|
34
|
-
| ---------------------------------- | ---- |
|
|
35
|
-
| `mouthOpen` | face | `jawOpen` blendshape
|
|
36
|
-
| `smile` | face | mean of `mouthSmileLeft` / `mouthSmileRight`
|
|
37
|
-
| `blink` | face | both eyes closed (min of the `eyeBlink` blendshapes)
|
|
38
|
-
| `browRaise` | face | max of the brow-up blendshapes
|
|
39
|
-
| `headNod` | face | pitch oscillation: 3 turning points ≥ 0.12 rad within 1.5 s
|
|
40
|
-
| `headShake` | face | yaw oscillation: 3 turning points ≥ 0.15 rad within 1.5 s
|
|
41
|
-
| `pinch` | hand | thumb–index tip gap relative to palm size (1 = touching)
|
|
42
|
-
| `grab` | hand | mean curl of index..pinky (1 = fist)
|
|
43
|
-
| `openPalm` | hand | mean extension of index..pinky
|
|
44
|
-
| `handRaised` | hand | wrist height in the frame (0 bottom, 1 top)
|
|
45
|
-
| `oneFinger` | hand | index extended, middle..pinky curled (pointing)
|
|
46
|
-
| `peaceSign` | hand | index + middle extended, ring + pinky curled
|
|
47
|
-
| `threeFingers` | hand | index + middle + ring extended, pinky curled
|
|
48
|
-
| `fourFingers` | hand | index..pinky extended, thumb tucked
|
|
49
|
-
| `fist` | hand | all four curled and the thumb tucked
|
|
50
|
-
| `palm` | hand | all four extended and the thumb out
|
|
51
|
-
| `thumbUp` / `thumbDown` | hand | thumb out and pointing up / down, fingers curled
|
|
52
|
-
| `wave` | hand | wrist x oscillation: 3 turning points ≥ 0.08 within 1.2 s
|
|
53
|
-
| `armRaisedLeft` / `armRaisedRight` | body | wrist above its shoulder, in shoulder widths
|
|
54
|
-
| `armRaised` / `bothArmsRaised` | body | either / both wrists above their shoulders
|
|
55
|
-
| `tPose` | body | both arms level and outstretched by a shoulder width
|
|
35
|
+
| Name | Kind | Measures | Default enter / exit / hold / cooldown |
|
|
36
|
+
| ---------------------------------- | ---- | -------------------------------------------------------------------------------------- | -------------------------------------- |
|
|
37
|
+
| `mouthOpen` | face | `jawOpen` blendshape | 0.5 / 0.35 / 0 / 0 |
|
|
38
|
+
| `smile` | face | mean of `mouthSmileLeft` / `mouthSmileRight` | 0.4 / 0.25 / 0 / 0 |
|
|
39
|
+
| `blink` | face | both eyes closed (min of the `eyeBlink` blendshapes) | 0.55 / 0.4 / 50 ms / 0 |
|
|
40
|
+
| `browRaise` | face | max of the brow-up blendshapes | 0.45 / 0.3 / 0 / 0 |
|
|
41
|
+
| `headNod` | face | pitch oscillation: 3 turning points ≥ 0.12 rad within 1.5 s | 0.99 / 0.3 / 0 / 600 ms |
|
|
42
|
+
| `headShake` | face | yaw oscillation: 3 turning points ≥ 0.15 rad within 1.5 s | 0.99 / 0.3 / 0 / 600 ms |
|
|
43
|
+
| `pinch` | hand | thumb–index tip gap relative to palm size (1 = touching) | 0.75 / 0.5 / 0 / 0 |
|
|
44
|
+
| `grab` | hand | mean curl of index..pinky (1 = fist) | 0.7 / 0.45 / 0 / 0 |
|
|
45
|
+
| `openPalm` | hand | mean extension of index..pinky | 0.7 / 0.45 / 0 / 0 |
|
|
46
|
+
| `handRaised` | hand | wrist height in the frame (0 bottom, 1 top) | 0.7 / 0.6 / 0 / 0 |
|
|
47
|
+
| `oneFinger` | hand | index extended, middle..pinky curled (pointing) | 0.65 / 0.45 / 0 / 0 |
|
|
48
|
+
| `peaceSign` | hand | index + middle extended, ring + pinky curled | 0.65 / 0.45 / 0 / 0 |
|
|
49
|
+
| `threeFingers` | hand | index + middle + ring extended, pinky curled | 0.65 / 0.45 / 0 / 0 |
|
|
50
|
+
| `fourFingers` | hand | index..pinky extended, thumb tucked | 0.65 / 0.45 / 0 / 0 |
|
|
51
|
+
| `fist` | hand | all four curled and the thumb tucked | 0.65 / 0.45 / 0 / 0 |
|
|
52
|
+
| `palm` | hand | all four extended and the thumb out | 0.65 / 0.45 / 0 / 0 |
|
|
53
|
+
| `thumbUp` / `thumbDown` | hand | thumb out and pointing up / down, fingers curled | 0.6 / 0.4 / 0 / 0 |
|
|
54
|
+
| `wave` | hand | wrist x oscillation: 3 turning points ≥ 0.08 within 1.2 s | 0.99 / 0.3 / 0 / 600 ms |
|
|
55
|
+
| `armRaisedLeft` / `armRaisedRight` | body | the person's own left / right wrist above its shoulder, in shoulder widths, every feed | 0.3 / 0.15 / 0 / 0 |
|
|
56
|
+
| `armRaised` / `bothArmsRaised` | body | either / both wrists above their shoulders | 0.3 / 0.15 / 0 / 0 |
|
|
57
|
+
| `tPose` | body | both arms level and outstretched by a shoulder width | 0.6 / 0.4 / 150 ms / 0 |
|
|
56
58
|
|
|
57
59
|
Hand measures are scale-free (divided by the palm size) and body measures
|
|
58
60
|
are in shoulder widths, so distance from the camera does not change the
|
|
@@ -140,6 +142,32 @@ Temporal gestures add `createMemory` and read it in `measure`; the built-in
|
|
|
140
142
|
`OscillationTracker` (on `/low-level`) counts direction reversals for nods,
|
|
141
143
|
shakes and waves.
|
|
142
144
|
|
|
145
|
+
**Sides.** `measure(input, memory, nowMs, context)` also gets the feed
|
|
146
|
+
(`GestureContext` `{ mirrored }`). Body input keeps MediaPipe's labels
|
|
147
|
+
(`POSE_JOINTS.leftWrist` is MediaPipe's left: the person's right on the
|
|
148
|
+
mirrored webcam), so read a person's side through the feed:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
import { personSide } from "@vincentt-xr/sdk";
|
|
152
|
+
import { POSE_JOINTS } from "@vincentt-xr/sdk/low-level";
|
|
153
|
+
import { defineGesture } from "@vincentt-xr/sdk/tracking";
|
|
154
|
+
|
|
155
|
+
const leftHandOnHead = defineGesture({
|
|
156
|
+
name: "leftHandOnHead",
|
|
157
|
+
kind: "body",
|
|
158
|
+
description: "The person's own left wrist above the nose.",
|
|
159
|
+
measure: (pose, _memory, _now, context) => {
|
|
160
|
+
if (!pose || pose.length < 33) return null;
|
|
161
|
+
const label = personSide("left", context?.mirrored ?? false);
|
|
162
|
+
const wrist = pose[label === "left" ? POSE_JOINTS.leftWrist : POSE_JOINTS.rightWrist];
|
|
163
|
+
return { value: wrist.y > pose[0].y ? 1 : 0, confidence: 1 };
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Face input is a `FaceInfo`, which carries `mirrored`; hand input is already
|
|
169
|
+
the person's hand (`hand: "left"`).
|
|
170
|
+
|
|
143
171
|
## Relation to the other gesture APIs
|
|
144
172
|
|
|
145
173
|
- `<GestureTrigger>` fires once on a **named static hand pose** from the
|
|
@@ -149,6 +177,12 @@ shakes and waves.
|
|
|
149
177
|
- `useFaceAction` is the face-only predecessor with the same hysteresis idea;
|
|
150
178
|
the face gestures here reuse its measurements, and add cooldown,
|
|
151
179
|
confidence, loss grace and the temporal nod / shake.
|
|
180
|
+
- `<BodyTrigger>` / `useBodyTrigger` fire on **full-body poses and moves**
|
|
181
|
+
with this same lifecycle: BodyInstruction's poses (T-pose, hands up, hands
|
|
182
|
+
on hips, arms crossed, squat …) and moves over time (jump, squat reps, wave,
|
|
183
|
+
clap, punch, arm flap, kick, step left / right, march). Left / right are the
|
|
184
|
+
person's own sides on every camera, and leg moves need the whole body in
|
|
185
|
+
view. See [Body Triggers](/api/body-triggers).
|
|
152
186
|
|
|
153
187
|
## Tracking loss and confidence
|
|
154
188
|
|
|
@@ -163,11 +197,13 @@ complete on return.
|
|
|
163
197
|
|
|
164
198
|
Run `/gestures`:
|
|
165
199
|
|
|
166
|
-
| Case | Steps | Expect
|
|
167
|
-
| ------------- | --------------------------------------- |
|
|
168
|
-
| Hysteresis | hold a half pinch around the threshold | Row stays active until the value drops below the exit threshold
|
|
169
|
-
| Hold | set hold 300 ms on `pinch`, tap quickly | No begin for taps shorter than 300 ms
|
|
170
|
-
| Cooldown | `headNod`, nod twice quickly | One begin; the second counts after 600 ms
|
|
171
|
-
| Tracking loss | cover the hand mid-pinch | Row shows "lost" then ends with `lost` after the grace window
|
|
172
|
-
| Confidence | set min confidence above 1 | Gesture never begins
|
|
173
|
-
| Body | "Person Fullbody" clip, raise an arm | `armRaised` / side rows activate
|
|
200
|
+
| Case | Steps | Expect |
|
|
201
|
+
| ------------- | --------------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
202
|
+
| Hysteresis | hold a half pinch around the threshold | Row stays active until the value drops below the exit threshold |
|
|
203
|
+
| Hold | set hold 300 ms on `pinch`, tap quickly | No begin for taps shorter than 300 ms |
|
|
204
|
+
| Cooldown | `headNod`, nod twice quickly | One begin; the second counts after 600 ms |
|
|
205
|
+
| Tracking loss | cover the hand mid-pinch | Row shows "lost" then ends with `lost` after the grace window |
|
|
206
|
+
| Confidence | set min confidence above 1 | Gesture never begins |
|
|
207
|
+
| Body | "Person Fullbody" clip, raise an arm | `armRaised` / side rows activate |
|
|
208
|
+
| Body sides | webcam, raise your real left arm | `armRaisedLeft` activates, not `armRaisedRight`; same on a clip for the person's left arm |
|
|
209
|
+
| Body triggers | see [Body Triggers](/api/body-triggers) | The "body triggers" section lights and counts poses and moves |
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Hair (experimental)"
|
|
3
|
+
description: "Locks of hair that swing with the head: pigtails, ponytails, strands, on spring chains, rooted on the tracked head, with the real hair's mask beside them."
|
|
4
|
+
sidebarTitle: "Hair"
|
|
5
|
+
icon: "wind"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`HairLock` adds a lock of hair to a tracked head: a pigtail, a ponytail, a strand. It swings as the
|
|
9
|
+
head turns and nods, then settles.
|
|
10
|
+
|
|
11
|
+
- **Procedural.** No model to make: a tapered tube along a chain of springs, its colour, length,
|
|
12
|
+
thickness and swing all props.
|
|
13
|
+
- **On the head.** Rooted in the canonical head frame, in centimetres; a `HeadBinding`'s occluder
|
|
14
|
+
hides the part that passes behind the head.
|
|
15
|
+
- **With the head.** It hangs along the head's own down, so a head tilt tilts it; only motion swings
|
|
16
|
+
it.
|
|
17
|
+
|
|
18
|
+
Experimental: its props and look may change in a later alpha. Import from
|
|
19
|
+
`@vincentt-xr/sdk/face-effects`.
|
|
20
|
+
|
|
21
|
+
## Quick start: pigtails
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { VideoBackground, XRScene } from "@vincentt-xr/sdk";
|
|
25
|
+
import { HairLock, HeadBinding } from "@vincentt-xr/sdk/face-effects";
|
|
26
|
+
|
|
27
|
+
<XRScene>
|
|
28
|
+
<VideoBackground />
|
|
29
|
+
<HeadBinding faceIndex={0}>
|
|
30
|
+
<HairLock position={[8, 8.5, -3.5]} direction={[0.55, -0.7, -0.45]} />
|
|
31
|
+
<HairLock position={[-8, 8.5, -3.5]} direction={[-0.55, -0.7, -0.45]} />
|
|
32
|
+
</HeadBinding>
|
|
33
|
+
</XRScene>;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
A high ponytail, rising over the crown before it falls (it shows from the front):
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<HairLock position={[0, 12.8, -6.5]} direction={[0, 0.8, -0.6]} length={26} segments={10} />
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Placing a lock
|
|
43
|
+
|
|
44
|
+
The head frame: centimetres, +X MediaPipe's left (the screen's right on an unmirrored feed), +Y up,
|
|
45
|
+
+Z out of the face; the ears are at x ≈ ±8.8, the crown at y ≈ 13.3 (`HEAD_ATTACHMENT_POINTS`).
|
|
46
|
+
`position` is the root, `direction` the way the lock leaves it; from there it curves down toward its
|
|
47
|
+
tip. Put roots on or just outside the head: inside it, the occluder hides them.
|
|
48
|
+
|
|
49
|
+
## Props
|
|
50
|
+
|
|
51
|
+
| Prop | Default | Meaning |
|
|
52
|
+
| ---------------------------------- | ------------- | -------------------------------------------------------------------- |
|
|
53
|
+
| `position` | `[0, 0, 0]` | The root, head centimetres |
|
|
54
|
+
| `direction` | `[0, -1, 0]` | The way it leaves the root (head frame) |
|
|
55
|
+
| `length` | 16 | Length, cm |
|
|
56
|
+
| `segments` | 8 | Joints along it (2–32): more is smoother and floppier |
|
|
57
|
+
| `thickness` | `[1.2, 0.3]` | Radius at the root and the tip, cm (one number: even) |
|
|
58
|
+
| `color` | `"#3b2416"` | Any three.js colour |
|
|
59
|
+
| `frequency`, `damping`, `maxAngle` | 1.4, 0.45, 25 | The swing: swings per second, how fast it settles, degrees per joint |
|
|
60
|
+
| `enabled` | true | False: it hangs still |
|
|
61
|
+
| `faceIndex` | 0 | The face, when it runs its own head fit |
|
|
62
|
+
|
|
63
|
+
Inside a `CanonicalHeadFrame` (a `HeadBinding`) it reuses that fit; anywhere else under a
|
|
64
|
+
`FaceTracker` it runs its own. It is hidden while the face is lost and until the first fit.
|
|
65
|
+
|
|
66
|
+
The swing is the shared spring solver (`SpringChain`, the same as swinging earrings and necklace
|
|
67
|
+
pendants): see [Head occluder → Swinging](/api/head-occluder).
|
|
68
|
+
|
|
69
|
+
## The real hair
|
|
70
|
+
|
|
71
|
+
`useHairMask()` (MediaPipe's hair segmenter) with `SegmentationOverlay label="hair"` shows where the
|
|
72
|
+
person's real hair is, as a 2D layer: see [Segmentation overlay](/api/segmentation-overlay).
|
|
73
|
+
|
|
74
|
+
## Limits
|
|
75
|
+
|
|
76
|
+
- A smooth tube, no strands or texture; flat colour.
|
|
77
|
+
- Locks pass through each other and through the shoulders; only the head occluder hides them.
|
|
78
|
+
- The swing follows the head, not gravity: lying down, the locks still hang along the head.
|
|
79
|
+
|
|
80
|
+
## Example
|
|
81
|
+
|
|
82
|
+
`/hair` in the SDK playground: pigtails, a high ponytail or both; swing on or off; the hair mask;
|
|
83
|
+
and a customise panel (colour, length, thickness, joints, swing) with the JSX to paste. Settings are
|
|
84
|
+
in the URL: `?style=both`, `?mask=1`, `?lock={"color":"#c0392b","lengthScale":1.5}`.
|
|
85
|
+
|
|
86
|
+
## Manual visual test plan
|
|
87
|
+
|
|
88
|
+
Open `/hair` on the webcam.
|
|
89
|
+
|
|
90
|
+
1. **Pigtails**: they hang beside your head; shake your head and nod: they swing and settle within
|
|
91
|
+
a couple of seconds; tilt: they tilt with you.
|
|
92
|
+
2. **Occlusion**: turn your head: the part behind the head hides.
|
|
93
|
+
3. **Ponytail**: it rises over the crown and swings out to the sides as you turn.
|
|
94
|
+
4. **Hair mask**: your real hair turns pink; the locks draw over it.
|
|
95
|
+
5. **Customise**: change colour, length, thickness and swing; the code shown matches what you see;
|
|
96
|
+
reset brings the start back.
|
|
97
|
+
6. **Phone**: about 30 fps on a mid-range phone with both styles on.
|