@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.
- package/GROUNDING.md +5651 -82
- 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/cache.d.ts +99 -0
- package/dist/assets/estimate.d.ts +11 -0
- package/dist/assets/gltfLoader.d.ts +16 -0
- package/dist/assets/index.d.ts +7 -0
- package/dist/assets/loaders.d.ts +43 -0
- package/dist/assets/react.d.ts +33 -0
- 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 +75 -0
- package/dist/calibration/index.d.ts +6 -0
- package/dist/calibration/storage.d.ts +13 -0
- package/dist/calibration/types.d.ts +53 -0
- package/dist/calibration/useXRCalibration.d.ts +46 -0
- package/dist/camera/CameraPermissionGate.d.ts +26 -0
- package/dist/camera/devices.d.ts +26 -0
- package/dist/camera/index.d.ts +8 -0
- package/dist/camera/permission.d.ts +86 -0
- package/dist/camera/useCameraPermission.d.ts +35 -0
- package/dist/canonicalFace-BHwyCx1c.js +9 -0
- package/dist/canonicalFace-C83I225R.cjs +1 -0
- package/dist/capabilities/detect.d.ts +45 -0
- package/dist/capabilities/index.d.ts +5 -0
- package/dist/capabilities/types.d.ts +120 -0
- package/dist/capabilities/useXRCapabilities.d.ts +18 -0
- package/dist/compat/environment.d.ts +5 -0
- package/dist/compat/index.d.ts +4 -0
- package/dist/compat/run.d.ts +18 -0
- package/dist/compat/scenarios.d.ts +10 -0
- package/dist/compat/types.d.ts +101 -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 +17 -0
- 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 +37 -5
- package/dist/components/FaceMesh/canonical/geometryGroups.d.ts +21 -0
- package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +21 -0
- package/dist/components/FaceMesh/canonical/shaders.d.ts +1 -1
- package/dist/components/FaceMesh/index.d.ts +2 -2
- 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/GestureListener/index.d.ts +11 -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/HandTracker/index.d.ts +10 -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/HolisticTracker/index.d.ts +69 -0
- package/dist/components/HolisticTracker/settings.d.ts +58 -0
- package/dist/components/HolisticTracker/signals.d.ts +49 -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/IrisEffect/IrisMaterial.d.ts +73 -0
- package/dist/components/IrisEffect/index.d.ts +51 -0
- package/dist/components/IrisEffect/settings.d.ts +117 -0
- package/dist/components/LipEffect/LipEffect.d.ts +27 -1
- package/dist/components/LipEffect/LipEffectMaterial.d.ts +95 -7
- package/dist/components/LipEffect/LipEffects.d.ts +12 -0
- package/dist/components/LipEffect/defaults.d.ts +46 -4
- package/dist/components/LipEffect/index.d.ts +11 -3
- package/dist/components/LipEffect/lipShading.d.ts +73 -0
- package/dist/components/LipEffect/settings.d.ts +375 -0
- package/dist/components/LipEffect/shader.d.ts +39 -0
- package/dist/components/LipEffect/types.d.ts +128 -9
- package/dist/components/LipEffect/useLipDesignTextures.d.ts +17 -0
- package/dist/components/LipEffect/uvGuide.d.ts +74 -0
- 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/PersonCutout/index.d.ts +50 -0
- package/dist/components/PersonCutout/personCutout.d.ts +16 -0
- package/dist/components/ScreenImage/components/ScreenImageBody.d.ts +1 -1
- package/dist/components/ScreenImage/index.d.ts +3 -1
- package/dist/components/ScreenImage/materials/ScreenImageBlendMaterial.d.ts +1 -1
- package/dist/components/ScreenImage/materials/ScreenImageMaskMaterial.d.ts +11 -0
- package/dist/components/ScreenImage/source.d.ts +6 -0
- package/dist/components/ScreenImage/types.d.ts +18 -0
- package/dist/components/SegmentationOverlay/SegmentationOverlay.d.ts +37 -0
- package/dist/components/SegmentationOverlay/SegmentationOverlayMaterial.d.ts +31 -0
- package/dist/components/SegmentationOverlay/index.d.ts +9 -0
- package/dist/components/SegmentationOverlay/maskTexture.d.ts +23 -0
- package/dist/components/SegmentationOverlay/providers.d.ts +72 -0
- package/dist/components/SegmentationOverlay/settings.d.ts +65 -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/XRProvider/index.d.ts +16 -2
- package/dist/components/XRScene/renderOutputTarget.d.ts +12 -0
- package/dist/components/XRViewport/hooks/useViewportExternalFaces.d.ts +1 -1
- package/dist/components/XRViewport/hooks/useViewportMediaSource.d.ts +1 -1
- package/dist/components/XRViewport/hooks/useViewportPipeline.d.ts +1 -1
- package/dist/components/index.d.ts +11 -0
- package/dist/config/index.d.ts +0 -1
- package/dist/constants/index.d.ts +4 -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/feed.d.ts +52 -0
- package/dist/coordinates/index.d.ts +7 -0
- package/dist/coordinates/side.d.ts +40 -0
- package/dist/coordinates/spaces.d.ts +49 -0
- package/dist/coordinates/viewport.d.ts +22 -0
- package/dist/coordinates/world.d.ts +15 -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/gesture-settings/index.d.ts +14 -0
- package/dist/debug-ui/hierarchy-panel/index.d.ts +3 -2
- package/dist/debug-ui/holistic-tracker-settings/index.d.ts +16 -0
- package/dist/debug-ui/index.d.ts +18 -3
- package/dist/debug-ui/iris-effect-settings/index.d.ts +12 -0
- package/dist/debug-ui/lip-effect-settings/index.d.ts +15 -0
- 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 +25 -0
- 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/segmentation-overlay-settings/index.d.ts +12 -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 +26 -0
- package/dist/debug-ui.cjs +3 -3
- package/dist/debug-ui.js +2695 -2547
- package/dist/detector-K8aej4MB.js +59 -0
- package/dist/detector-ijypGtse.cjs +1 -0
- package/dist/entries/all.d.ts +3 -1
- package/dist/entries/core.d.ts +20 -2
- package/dist/entries/face-effects.d.ts +123 -9
- package/dist/entries/instructions.d.ts +48 -0
- package/dist/entries/internal.d.ts +2 -1
- package/dist/entries/low-level.d.ts +49 -3
- package/dist/entries/particles.d.ts +11 -0
- package/dist/entries/product.d.ts +11 -0
- package/dist/entries/tracking.d.ts +60 -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 +2324 -1
- package/dist/face-effects.js +14208 -2268
- 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 +98 -0
- package/dist/gestures/detector.d.ts +87 -0
- package/dist/gestures/index.d.ts +8 -0
- package/dist/gestures/measures.d.ts +114 -0
- package/dist/gestures/settings.d.ts +49 -0
- 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 +76 -1
- package/dist/hooks/useCalibrationFaceTracker.d.ts +1 -1
- package/dist/hooks/useFaceInfo.d.ts +13 -1
- package/dist/hooks/useFaceInfos.d.ts +1 -1
- package/dist/hooks/useFaceModelAcquisition.d.ts +38 -0
- package/dist/hooks/useGesture.d.ts +32 -0
- package/dist/hooks/useIrisTracking.d.ts +45 -0
- package/dist/hooks/useTrackerContext.d.ts +6 -0
- package/dist/hooks/useXRDiagnostics.d.ts +81 -0
- package/dist/hooks/useXRModel.d.ts +7 -0
- package/dist/hooks/useXRSession/facade.d.ts +42 -2
- package/dist/hooks/useXRSession/index.d.ts +2 -2
- package/dist/hooks/useXRSession/reason.d.ts +3 -1
- package/dist/hooks/useXRSession/registry.d.ts +14 -0
- package/dist/hooks/useXRSession/store.d.ts +52 -3
- 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/index-w1S7fI2B.js +1432 -0
- package/dist/index-zGaqrz_K.js +188 -0
- package/dist/instructions.cjs +30 -0
- package/dist/instructions.js +1507 -0
- package/dist/{internal-Dmk1cTXq.js → internal-B90P-clC.js} +138 -119
- 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 +27 -0
- package/dist/iris/index.d.ts +4 -0
- package/dist/iris/lead.d.ts +19 -0
- package/dist/iris/types.d.ts +89 -0
- package/dist/landmarkMask-BFDyBnKM.js +224 -0
- package/dist/landmarkMask-u7es2k4X.cjs +1 -0
- 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 +1190 -675
- package/dist/main.cjs +1 -1
- package/dist/main.js +1190 -452
- package/dist/models/Base/index.d.ts +49 -0
- package/dist/models/Body/index.d.ts +3 -1
- package/dist/models/Face/constants.d.ts +8 -0
- package/dist/models/Face/index.d.ts +4 -12
- package/dist/models/Face/rotation.d.ts +18 -3
- package/dist/models/Hand/GestureTracking.d.ts +1 -1
- package/dist/models/Hand/HandTracking.d.ts +17 -1
- package/dist/models/Holistic/index.d.ts +49 -0
- package/dist/models/Holistic/result.d.ts +68 -0
- package/dist/models/Segmentation/index.d.ts +2 -0
- package/dist/models/SemanticSegmentation/index.d.ts +31 -0
- package/dist/models/SemanticSegmentation/presets.d.ts +28 -0
- package/dist/models/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/ProductDimensions.d.ts +16 -0
- package/dist/product/ProductHotspot.d.ts +16 -0
- package/dist/product/ProductViewer.d.ts +9 -0
- package/dist/product/details.d.ts +53 -0
- package/dist/product/index.d.ts +14 -0
- package/dist/product/loadModelViewer.d.ts +4 -0
- package/dist/product/types.d.ts +71 -0
- package/dist/product/useProductAr.d.ts +37 -0
- package/dist/product/useProductDetails.d.ts +60 -0
- package/dist/product.cjs +1 -0
- package/dist/product.js +414 -0
- package/dist/providers-C8rE26Uf.js +366 -0
- package/dist/providers-DHsrhDI2.cjs +62 -0
- package/dist/quality/XRQualityController.d.ts +25 -0
- package/dist/quality/controller.d.ts +33 -0
- package/dist/quality/index.d.ts +6 -0
- package/dist/quality/types.d.ts +100 -0
- package/dist/quality/useXRQuality.d.ts +28 -0
- package/dist/render/renderPasses.d.ts +8 -0
- package/dist/render/sceneBeforeRender.d.ts +12 -0
- package/dist/{renderGroups-KZk6eRiY.js → renderGroups-B38pUaX2.js} +1 -1
- package/dist/{renderGroups-80H3DpTl.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/faceMemory.d.ts +28 -0
- package/dist/segmentation2d/faceRegions.d.ts +24 -0
- package/dist/segmentation2d/index.d.ts +9 -0
- package/dist/segmentation2d/maskUv.d.ts +23 -0
- package/dist/segmentation2d/rasterize.d.ts +14 -0
- package/dist/segmentation2d/types.d.ts +52 -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-BJ7FMBsO.js +111 -0
- 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/subjects/index.d.ts +2 -0
- package/dist/subjects/select.d.ts +62 -0
- package/dist/subjects/types.d.ts +55 -0
- package/dist/tracking-config/apply.d.ts +57 -0
- package/dist/tracking-config/index.d.ts +7 -0
- package/dist/tracking-config/resolve.d.ts +25 -0
- package/dist/tracking-config/storage.d.ts +8 -0
- package/dist/tracking-config/types.d.ts +106 -0
- package/dist/tracking-config/useXRTrackingConfig.d.ts +38 -0
- package/dist/tracking.cjs +10 -1
- package/dist/tracking.js +1326 -506
- package/dist/trigger-D0Pm9noT.cjs +49 -0
- package/dist/trigger-IQeys0oS.js +2128 -0
- package/dist/types/compositor.d.ts +21 -0
- package/dist/types/face.d.ts +20 -1
- package/dist/types/hand-tracking.d.ts +9 -0
- package/dist/types/holistic.d.ts +121 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/model.d.ts +22 -2
- package/dist/types/nodes.d.ts +47 -3
- package/dist/types/segmentation.d.ts +24 -0
- package/dist/types/session.d.ts +41 -3
- 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-Cr3RzuAW.cjs +1 -0
- package/dist/useXRCapabilities-Cxmlmpbd.js +30 -0
- package/dist/utils/canonicalRigidLandmarks.d.ts +8 -0
- package/dist/utils/fns.d.ts +6 -3
- package/dist/utils/headOccluderFit.d.ts +42 -0
- package/dist/utils/integrity.d.ts +21 -1
- 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/utils/updateThrottle.d.ts +2 -0
- package/dist/utils/useStableUniforms.d.ts +18 -0
- package/dist/uv-BMFt19bg.cjs +1 -0
- package/dist/{index-ByoNj0QP.js → uv-DJU_XfmN.js} +15 -247
- package/docs/SDK_DOCUMENTATION.md +1 -2
- package/docs/api/adaptive-quality.mdx +104 -0
- package/docs/api/asset-lifecycle.mdx +78 -0
- package/docs/api/body-instructions.mdx +285 -0
- package/docs/api/body-triggers.mdx +234 -0
- package/docs/api/camera-permission.mdx +142 -0
- package/docs/api/coordinate-spaces.mdx +168 -0
- package/docs/api/cross-camera.mdx +89 -0
- package/docs/api/debug-ui-scene-editor.mdx +23 -2
- package/docs/api/diagnostics-calibration.mdx +97 -0
- 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 +9 -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 +8 -9
- 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 +209 -0
- 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 +164 -0
- package/docs/api/instructions.mdx +323 -0
- package/docs/api/iris-tracking.mdx +247 -0
- 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 +98 -0
- package/docs/api/particles.mdx +155 -0
- package/docs/api/person-cutout.mdx +136 -0
- package/docs/api/pin-to-face-mesh.mdx +274 -0
- package/docs/api/product-ar.mdx +114 -0
- package/docs/api/product-details.mdx +78 -0
- package/docs/api/screen-space-coordinates.mdx +4 -1
- package/docs/api/segmentation-overlay.mdx +301 -0
- package/docs/api/session-lifecycle.mdx +136 -0
- package/docs/api/trackers.mdx +5 -0
- package/docs/api/tracking-config.mdx +108 -0
- package/docs/docs.json +51 -1
- package/docs/examples/lip-shaders.mdx +273 -0
- 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 +368 -0
- package/docs/guides/lip-uv-template.png +0 -0
- package/docs/guides/lip-uv-template.svg +1 -0
- package/docs/guides/makeup-design-textures.mdx +109 -0
- package/docs/introduction.mdx +1 -2
- package/package.json +23 -1
- package/dist/DebuggerUI-B6bP6P9r.cjs +0 -1
- package/dist/DebuggerUI-BjOMr8q_.js +0 -269
- package/dist/FaceMeshRenderer-C5l6VLdO.cjs +0 -155
- package/dist/FaceMeshRenderer-wjAHrJzP.js +0 -1270
- package/dist/FaceRetouch-BkJzoA79.cjs +0 -134
- package/dist/FaceRetouch-DwbKQJAN.js +0 -551
- 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-ByhzppYl.js +0 -663
- package/dist/contexts-Dr62It_K.cjs +0 -1
- package/dist/debug-ui/face-warp-3d/index.d.ts +0 -6
- package/dist/getFaceInfo-C4QpCQIY.js +0 -118
- package/dist/getFaceInfo-fA1bFBub.cjs +0 -1
- package/dist/index-9dlAQAhy.js +0 -1462
- package/dist/index-BjmTe9eM.cjs +0 -1
- package/dist/index-BpEf2BBb.cjs +0 -1
- package/dist/index-CyUUurQT.cjs +0 -1
- package/dist/index-DCiMbxC3.cjs +0 -1
- package/dist/index-DXT3WccE.js +0 -2089
- package/dist/index-DpI-qo5X.cjs +0 -17
- package/dist/index-DyVF4vEW.js +0 -111
- package/dist/index-VJ0SJwmG.js +0 -214
- package/dist/internal-Cq-TEQ5Y.cjs +0 -1
- package/dist/renderLayers-lDtL0_43.cjs +0 -1
- package/dist/renderLayers-zrK2pv5O.js +0 -13
- package/dist/renderPasses-BOoBSr8z.cjs +0 -21
- package/dist/renderPasses-BcquyVtu.js +0 -1500
- package/dist/selectors-B8H97CKA.js +0 -59
- package/dist/selectors-CZLKT2Iv.cjs +0 -1
- package/dist/session-CpkiK5YA.cjs +0 -31
- package/dist/session-DLFN_VII.js +0 -363
- package/dist/useFaceInfo-BJ8-_MOs.cjs +0 -1
- package/dist/useFaceInfo-Dk426LTu.js +0 -62
- package/dist/useFaceResults-CtetsO9M.js +0 -19
- package/dist/useFaceResults-wBJF3zyp.cjs +0 -1
|
@@ -0,0 +1,2128 @@
|
|
|
1
|
+
var Ue = Object.defineProperty;
|
|
2
|
+
var Ce = (e, t, s) => t in e ? Ue(e, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : e[t] = s;
|
|
3
|
+
var x = (e, t, s) => Ce(e, typeof t != "symbol" ? t + "" : t, s);
|
|
4
|
+
import { useCallback as Me, useMemo as j, createContext as Pt, useRef as Y, useEffect as L, useContext as Et, useState as ze } from "react";
|
|
5
|
+
import { p as Le, u as Ke } from "./useFaceResultReader-BvEo5REG.js";
|
|
6
|
+
import { jsx as tt, jsxs as Ut } from "react/jsx-runtime";
|
|
7
|
+
import * as h from "three";
|
|
8
|
+
import { useThree as gt, useFrame as Ct, createPortal as Ge } from "@react-three/fiber";
|
|
9
|
+
import { a as it, X as mt, C as zt, H as Zt, t as Dt, q as Ye, f as Qe } from "./index-CIe7eCMH.js";
|
|
10
|
+
import { a as we, s as te, L as $e } from "./useLandmarkPoseFit-Bmb3h6Mw.js";
|
|
11
|
+
import { c as Xe } from "./SkeletonUtils-C2r90MtN.js";
|
|
12
|
+
import { b as Je, l as Ze, n as ts, H as ee, o as es, p as ss, q as ns, B as se, k as is, a as os, e as G, r as xe, m as rs } from "./index-JII7huPk.js";
|
|
13
|
+
import { b as ne, e as as } from "./selectors-DmNaKIwE.js";
|
|
14
|
+
import { u as Ot } from "./landmarks-bftdwq6Z.js";
|
|
15
|
+
import { g as ls, r as ie, c as cs, s as ve, a as hs } from "./detector-K8aej4MB.js";
|
|
16
|
+
const fi = ({
|
|
17
|
+
node: e,
|
|
18
|
+
enabled: t,
|
|
19
|
+
selectedSource: s,
|
|
20
|
+
throttleMs: n = 16,
|
|
21
|
+
holdMs: i = 250,
|
|
22
|
+
onFrame: o
|
|
23
|
+
}) => {
|
|
24
|
+
const r = Me(
|
|
25
|
+
(a) => Le(a.faceLandmarks ?? []),
|
|
26
|
+
[s]
|
|
27
|
+
);
|
|
28
|
+
return Ke({ enabled: t, holdMs: i, node: e, onFrame: o, prepare: r, throttleMs: n });
|
|
29
|
+
}, us = 7, ps = Object.freeze({
|
|
30
|
+
along: Object.freeze([2, 4, 6, 8]),
|
|
31
|
+
widthAt: 1.5,
|
|
32
|
+
maxWidth: 11,
|
|
33
|
+
minWidth: 2.5,
|
|
34
|
+
maxTurn: 95
|
|
35
|
+
}), ds = (e, t) => {
|
|
36
|
+
const { image: s, world: n } = e;
|
|
37
|
+
if (s.length < 21 || n.length < 21) return null;
|
|
38
|
+
const i = (V) => (s[V].x + 1) / 2 * t, o = (V) => (1 - s[V].y) / 2;
|
|
39
|
+
let r = 0, a = 0, l = 0, u = 0;
|
|
40
|
+
const c = 21;
|
|
41
|
+
for (let V = 0; V < c; V += 1)
|
|
42
|
+
r += i(V), a += o(V), l += n[V].x, u -= n[V].y;
|
|
43
|
+
r /= c, a /= c, l /= c, u /= c;
|
|
44
|
+
let f = 0, p = 0, g = 0;
|
|
45
|
+
for (let V = 0; V < c; V += 1) {
|
|
46
|
+
const N = n[V].x - l, F = -n[V].y - u, C = i(V) - r, Q = o(V) - a;
|
|
47
|
+
f += N * C + F * Q, p += N * Q - F * C, g += N * N + F * F;
|
|
48
|
+
}
|
|
49
|
+
const w = Math.hypot(f, p) / Math.max(g, 1e-12), T = it.wrist, m = it.middleMcp, k = i(T) - i(m), I = o(T) - o(m), _ = Math.hypot(k, I), J = Math.hypot(
|
|
50
|
+
n[T].x - n[m].x,
|
|
51
|
+
n[T].y - n[m].y,
|
|
52
|
+
n[T].z - n[m].z
|
|
53
|
+
);
|
|
54
|
+
return !(w > 0) || _ < 0.3 * J * w ? null : {
|
|
55
|
+
wrist: { x: i(T), y: o(T) },
|
|
56
|
+
toElbow: { x: k / _, y: I / _ },
|
|
57
|
+
unitsPerCm: w,
|
|
58
|
+
aspect: t
|
|
59
|
+
};
|
|
60
|
+
}, nt = (e, t, s) => ({ x: e.x + t.x * s, y: e.y + t.y * s }), fs = (e, t, s = {}) => {
|
|
61
|
+
const n = { ...ps, ...s }, { wrist: i, toElbow: o, unitsPerCm: r, aspect: a } = t, { width: l, height: u } = e;
|
|
62
|
+
if (l <= 0 || u <= 0 || !(r > 0)) return null;
|
|
63
|
+
const c = Math.min(1 / u, a / l), f = n.maxWidth * r, p = n.minWidth * r, g = (S) => {
|
|
64
|
+
const M = S.x / a, b = S.y;
|
|
65
|
+
return M < 0 || b < 0 || M >= 1 || b >= 1 ? null : e.inside(Math.floor(b * u) * l + Math.floor(M * l));
|
|
66
|
+
}, w = (S, M) => {
|
|
67
|
+
if (g(S) === null) return null;
|
|
68
|
+
const b = { x: -M.y, y: M.x };
|
|
69
|
+
let D = null;
|
|
70
|
+
for (let R = 0; R * c <= f / 2; R += 1) {
|
|
71
|
+
if (g(nt(S, b, R * c))) {
|
|
72
|
+
D = R * c;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
if (R > 0 && g(nt(S, b, -R * c))) {
|
|
76
|
+
D = -R * c;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (D === null) return null;
|
|
81
|
+
let O = !1;
|
|
82
|
+
const E = (R) => {
|
|
83
|
+
let Z = D;
|
|
84
|
+
for (; ; ) {
|
|
85
|
+
const pt = g(nt(S, b, Z + R * c));
|
|
86
|
+
if (pt === null)
|
|
87
|
+
return O = !0, Z;
|
|
88
|
+
if (!pt) return Z;
|
|
89
|
+
if (Z += R * c, Math.abs(Z - D) > f)
|
|
90
|
+
return O = !0, Z;
|
|
91
|
+
}
|
|
92
|
+
}, q = E(-1), W = E(1), A = W - q + c;
|
|
93
|
+
return {
|
|
94
|
+
mid: nt(S, b, (q + W) / 2),
|
|
95
|
+
width: A,
|
|
96
|
+
a: nt(S, b, q),
|
|
97
|
+
b: nt(S, b, W),
|
|
98
|
+
ok: !O && A >= p && A <= f
|
|
99
|
+
};
|
|
100
|
+
}, T = (S) => n.along.map((M) => w(nt(i, S, M * r), S)), m = (S) => {
|
|
101
|
+
const M = [i, ...S.filter((y) => !!(y != null && y.ok)).map((y) => y.mid)];
|
|
102
|
+
if (M.length < 3) return null;
|
|
103
|
+
const b = M.reduce((y, R) => y + R.x, 0) / M.length, D = M.reduce((y, R) => y + R.y, 0) / M.length;
|
|
104
|
+
let O = 0, E = 0, q = 0;
|
|
105
|
+
for (const y of M)
|
|
106
|
+
O += (y.x - b) ** 2, E += (y.x - b) * (y.y - D), q += (y.y - D) ** 2;
|
|
107
|
+
const W = 0.5 * Math.atan2(2 * E, O - q), A = { x: Math.cos(W), y: Math.sin(W) };
|
|
108
|
+
return A.x * o.x + A.y * o.y < 0 ? { x: -A.x, y: -A.y } : A;
|
|
109
|
+
}, k = n.maxTurn * Math.PI / 180, I = (S) => Math.atan2(o.x * S.y - o.y * S.x, o.x * S.x + o.y * S.y), _ = (S) => ({
|
|
110
|
+
x: o.x * Math.cos(S) - o.y * Math.sin(S),
|
|
111
|
+
y: o.x * Math.sin(S) + o.y * Math.cos(S)
|
|
112
|
+
}), V = T((() => {
|
|
113
|
+
const S = k + 40 * Math.PI / 180, M = us * r, b = Math.min(1 * Math.PI / 180, c / M), D = Math.ceil(S / b), O = [];
|
|
114
|
+
let E = null;
|
|
115
|
+
for (let y = -D; y <= D + 1; y += 1) {
|
|
116
|
+
const R = y * b, Z = y <= D && g(nt(i, _(R), M)) === !0;
|
|
117
|
+
Z && E === null && (E = R), !Z && E !== null && (E > -D * b && R <= D * b && O.push([E, R - b]), E = null);
|
|
118
|
+
}
|
|
119
|
+
const q = ([y, R]) => (R - y) * M, W = O.filter((y) => q(y) >= p && q(y) <= f * 1.5);
|
|
120
|
+
if (!W.length) return null;
|
|
121
|
+
const A = W.reduce(
|
|
122
|
+
(y, R) => Math.abs((R[0] + R[1]) / 2) < Math.abs((y[0] + y[1]) / 2) ? R : y
|
|
123
|
+
);
|
|
124
|
+
return _((A[0] + A[1]) / 2);
|
|
125
|
+
})() ?? o);
|
|
126
|
+
let N = m(V);
|
|
127
|
+
if (!N || Math.abs(I(N)) > k) return null;
|
|
128
|
+
const F = T(N), C = m(F);
|
|
129
|
+
C && Math.abs(I(C)) <= k && (N = C);
|
|
130
|
+
const Q = C ? F : V, et = Q.filter((S) => !!(S != null && S.ok)), P = w(nt(i, N, n.widthAt * r), N), st = Math.min(...et.map((S) => S.width), P != null && P.ok ? P.width : 1 / 0), ut = P != null && P.ok ? P.mid : nt(i, N, n.widthAt * r), H = Q.filter((S) => !!S).map(({ a: S, b: M, ok: b }) => ({ a: S, b: M, ok: b }));
|
|
131
|
+
return P && H.push({ a: P.a, b: P.b, ok: P.ok }), {
|
|
132
|
+
direction: N,
|
|
133
|
+
bend: I(N),
|
|
134
|
+
width: st / r,
|
|
135
|
+
center: ut,
|
|
136
|
+
confidence: et.length / Math.max(1, n.along.length),
|
|
137
|
+
sections: H
|
|
138
|
+
};
|
|
139
|
+
}, be = Object.freeze({
|
|
140
|
+
smoothing: 0.4,
|
|
141
|
+
holdMs: 400,
|
|
142
|
+
fadeMs: 300,
|
|
143
|
+
maxSkewMs: 70,
|
|
144
|
+
maxShift: 2
|
|
145
|
+
}), ms = 24, gs = 0.5, ys = Math.cos(3 * Math.PI / 180);
|
|
146
|
+
class Ms {
|
|
147
|
+
constructor(t = {}) {
|
|
148
|
+
/** Radians, clockwise on screen, from the hand's axis to the arm's. */
|
|
149
|
+
x(this, "bend", 0);
|
|
150
|
+
/** The arm's width, cm (null until measured). */
|
|
151
|
+
x(this, "width", null);
|
|
152
|
+
/** How far the arm's middle is from the hand's axis, across it, cm (+ = clockwise side). */
|
|
153
|
+
x(this, "shift", 0);
|
|
154
|
+
/** 0..1, how much of the fit applies (found, held or fading). */
|
|
155
|
+
x(this, "weight", 0);
|
|
156
|
+
/** 0..1, how sure the measures are (closed cross-sections, eased): blends the fit with the hand. */
|
|
157
|
+
x(this, "confidence", 0);
|
|
158
|
+
/** The last measure, for drawing. */
|
|
159
|
+
x(this, "last", null);
|
|
160
|
+
x(this, "settings");
|
|
161
|
+
x(this, "history", []);
|
|
162
|
+
/** There is a fit (measured, not yet faded out). */
|
|
163
|
+
x(this, "found", !1);
|
|
164
|
+
/** When a mask first came without the arm since the last fit. */
|
|
165
|
+
x(this, "lostAtMs", null);
|
|
166
|
+
this.settings = { ...be, ...t };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The hand's query at a detection (`HandPose.timestampMs`); `null` when the
|
|
170
|
+
* hand's axis can't be used (it points at the camera): `query` reads null
|
|
171
|
+
* then, and nothing steers by an old axis.
|
|
172
|
+
*/
|
|
173
|
+
pushHand(t, s) {
|
|
174
|
+
const n = this.history[this.history.length - 1];
|
|
175
|
+
n && n.timeMs === t || (this.history.push({ timeMs: t, query: s }), this.history.length > ms && this.history.shift());
|
|
176
|
+
}
|
|
177
|
+
/** The newest hand query (the hand now), null while its axis is unusable. */
|
|
178
|
+
get query() {
|
|
179
|
+
var t;
|
|
180
|
+
return ((t = this.history[this.history.length - 1]) == null ? void 0 : t.query) ?? null;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* The hand hasn't moved over the kept history (within 0.5 cm and 3°): any
|
|
184
|
+
* of its poses matches a mask from within that time.
|
|
185
|
+
*/
|
|
186
|
+
still() {
|
|
187
|
+
const t = this.query;
|
|
188
|
+
if (!t || this.history.length < 2) return !1;
|
|
189
|
+
const s = gs * t.unitsPerCm;
|
|
190
|
+
return this.history.every(
|
|
191
|
+
({ query: n }) => !!n && Math.hypot(n.wrist.x - t.wrist.x, n.wrist.y - t.wrist.y) <= s && n.toElbow.x * t.toElbow.x + n.toElbow.y * t.toElbow.y >= ys
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Measures a new mask (taken at `maskTimeMs`, or now when unknown) against
|
|
196
|
+
* the hand from the same moment (or the newest, while the hand is still).
|
|
197
|
+
* Returns the measure, or null when the arm wasn't found (that starts the
|
|
198
|
+
* hold, then the fade) or no hand pose matches the mask's time (nothing
|
|
199
|
+
* changes: wait for the next mask).
|
|
200
|
+
*/
|
|
201
|
+
measure(t, s, n = {}) {
|
|
202
|
+
const i = this.history.filter((g) => g.query !== null), o = i[i.length - 1];
|
|
203
|
+
let r = s === void 0 ? o : i.reduce(
|
|
204
|
+
(g, w) => !g || Math.abs(w.timeMs - s) < Math.abs(g.timeMs - s) ? w : g,
|
|
205
|
+
void 0
|
|
206
|
+
);
|
|
207
|
+
if (!r) return null;
|
|
208
|
+
if (s !== void 0 && Math.abs(r.timeMs - s) > this.settings.maxSkewMs) {
|
|
209
|
+
const g = this.history[0];
|
|
210
|
+
if (!g || g.timeMs > s || !this.still()) return null;
|
|
211
|
+
r = o;
|
|
212
|
+
}
|
|
213
|
+
const a = fs(t, r.query, n);
|
|
214
|
+
if (this.last = a, !a)
|
|
215
|
+
return this.found && this.lostAtMs === null && (this.lostAtMs = s ?? r.timeMs), null;
|
|
216
|
+
const { wrist: l, unitsPerCm: u } = r.query, c = ((a.center.x - l.x) * -a.direction.y + (a.center.y - l.y) * a.direction.x) / u, f = Math.max(-this.settings.maxShift, Math.min(this.settings.maxShift, c)), p = this.found ? Math.min(1, Math.max(0.01, this.settings.smoothing)) : 1;
|
|
217
|
+
return this.bend += (a.bend - this.bend) * p, this.confidence += (a.confidence - this.confidence) * p, this.width = this.width === null ? a.width : this.width + (a.width - this.width) * p, this.shift += (f - this.shift) * p, this.found = !0, this.lostAtMs = null, a;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Advances the hold and fade (call every frame with `performance.now()`).
|
|
221
|
+
* A fit holds until a mask comes without the arm, then for `holdMs`, then
|
|
222
|
+
* fades over `fadeMs`; no new mask changes nothing.
|
|
223
|
+
*/
|
|
224
|
+
step(t) {
|
|
225
|
+
if (!this.found) {
|
|
226
|
+
this.weight = 0;
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const s = this.lostAtMs === null ? -1 / 0 : t - this.lostAtMs - this.settings.holdMs;
|
|
230
|
+
this.weight = s <= 0 ? 1 : Math.max(0, 1 - s / Math.max(1, this.settings.fadeMs)), this.weight === 0 && this.clear();
|
|
231
|
+
}
|
|
232
|
+
clear() {
|
|
233
|
+
this.found = !1, this.lostAtMs = null, this.confidence = 0, this.bend = 0, this.shift = 0, this.width = null, this.weight = 0;
|
|
234
|
+
}
|
|
235
|
+
/** Forget everything (the hand was lost). */
|
|
236
|
+
reset() {
|
|
237
|
+
this.history.length = 0, this.clear(), this.last = null;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const ws = 15, xs = (e) => {
|
|
241
|
+
Ot(mt.BACKGROUND_SEGMENTATION, { type: "portrait" }, e === "portrait"), Ot(mt.SEMANTIC_SEGMENTATION, { preset: "multiclass" }, e === "skin");
|
|
242
|
+
const t = ne(mt.BACKGROUND_SEGMENTATION), s = ne(mt.SEMANTIC_SEGMENTATION);
|
|
243
|
+
return j(() => {
|
|
244
|
+
if (!e) return null;
|
|
245
|
+
let n = 0, i = 0, o = 0, r, a = -1 / 0, l = null, u = null, c = null, f = -1, p = -1;
|
|
246
|
+
return {
|
|
247
|
+
kind: e,
|
|
248
|
+
get width() {
|
|
249
|
+
return n;
|
|
250
|
+
},
|
|
251
|
+
get height() {
|
|
252
|
+
return i;
|
|
253
|
+
},
|
|
254
|
+
get version() {
|
|
255
|
+
return o;
|
|
256
|
+
},
|
|
257
|
+
get timestampMs() {
|
|
258
|
+
return r;
|
|
259
|
+
},
|
|
260
|
+
// The portrait segmenter's category mask reads 0 on the person, 255 on
|
|
261
|
+
// the background (see `usePersonMask`).
|
|
262
|
+
inside: e === "portrait" ? (g) => l !== null && l[g] <= 127 : (g) => c !== null && c[g] === f,
|
|
263
|
+
refresh: (g) => {
|
|
264
|
+
var T;
|
|
265
|
+
if (e === "portrait") {
|
|
266
|
+
if (!t || g - a < 1e3 / ws) return !1;
|
|
267
|
+
const m = (T = t.getRawSegmentationData) == null ? void 0 : T.call(t);
|
|
268
|
+
return !(m != null && m.maskData) || m === u || m.width <= 0 ? !1 : (a = g, u = m, l = m.maskData, n = m.width, i = m.height, r = m.timestampMs, o += 1, !0);
|
|
269
|
+
}
|
|
270
|
+
const w = s == null ? void 0 : s.getMask();
|
|
271
|
+
return !w || w.version === 0 || w.version === p ? !1 : (p = w.version, f = w.labels.indexOf("body_skin"), c = w.indices, n = w.width, i = w.height, r = w.timestampMs, o += 1, f >= 0);
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
}, [e, t, s]);
|
|
275
|
+
}, d = {
|
|
276
|
+
c: new h.Vector3(),
|
|
277
|
+
y: new h.Vector3(),
|
|
278
|
+
p: new h.Vector3(),
|
|
279
|
+
ndc: new h.Vector3(),
|
|
280
|
+
axis: new h.Vector3(),
|
|
281
|
+
q: new h.Quaternion(),
|
|
282
|
+
m: new h.Matrix4(),
|
|
283
|
+
t: new h.Matrix4(),
|
|
284
|
+
turned: new h.Matrix4(),
|
|
285
|
+
a: { x: 0, y: 0 },
|
|
286
|
+
b: { x: 0, y: 0 }
|
|
287
|
+
}, xt = (e, t, s, n = { x: 0, y: 0 }) => (d.ndc.copy(e).project(t), n.x = (d.ndc.x + 1) / 2 * s, n.y = (1 - d.ndc.y) / 2, n), vs = (e, t) => Math.atan2(e.x * t.y - e.y * t.x, e.x * t.x + e.y * t.y), Se = (e, t, s, n = { x: 0, y: 0 }) => {
|
|
288
|
+
d.c.setFromMatrixPosition(e), d.y.setFromMatrixColumn(e, 1).normalize(), xt(d.c, t, s, d.a);
|
|
289
|
+
const i = Math.max(1e-4, d.c.distanceTo(t.position) * 1e-3);
|
|
290
|
+
xt(d.p.copy(d.c).addScaledVector(d.y, -i), t, s, d.b);
|
|
291
|
+
const o = d.b.x - d.a.x, r = d.b.y - d.a.y, a = Math.hypot(o, r) || 1;
|
|
292
|
+
return n.x = o / a, n.y = r / a, n;
|
|
293
|
+
}, bs = (e, t, s) => {
|
|
294
|
+
d.c.setFromMatrixPosition(e);
|
|
295
|
+
const n = Math.max(1e-4, d.c.distanceTo(t.position) * 1e-3);
|
|
296
|
+
xt(d.c, t, s, d.a);
|
|
297
|
+
const i = (u) => (d.y.setFromMatrixColumn(e, u).normalize(), xt(d.p.copy(d.c).addScaledVector(d.y, n), t, s, d.b), Math.hypot(d.b.x - d.a.x, d.b.y - d.a.y)), o = i(1), r = Math.max(i(0), i(2), 1e-12), a = o / r, l = Math.min(1, Math.max(0, (a - oe) / (Ss - oe)));
|
|
298
|
+
return l * l * (3 - 2 * l);
|
|
299
|
+
}, oe = 0.25, Ss = 0.45, ks = (e, t, s, n, i, o) => {
|
|
300
|
+
const r = -n.y, a = n.x;
|
|
301
|
+
let l = 1 / 0, u = -1 / 0;
|
|
302
|
+
for (let c = 0; c < 24; c += 1) {
|
|
303
|
+
const f = c / 24 * Math.PI * 2;
|
|
304
|
+
d.p.set(t * Math.cos(f), 0, s * Math.sin(f)).applyMatrix4(e), xt(d.p, i, o, d.a);
|
|
305
|
+
const p = d.a.x * r + d.a.y * a;
|
|
306
|
+
l = Math.min(l, p), u = Math.max(u, p);
|
|
307
|
+
}
|
|
308
|
+
return u - l;
|
|
309
|
+
}, As = (e, t, s, n, i, o) => {
|
|
310
|
+
const r = Math.min(1, Math.max(0, i));
|
|
311
|
+
if (r === 0)
|
|
312
|
+
return o.copy(e), 1;
|
|
313
|
+
const a = Se(e, t, s, { x: 0, y: 0 }), l = vs(a, n.up) * r * bs(e, t, s);
|
|
314
|
+
if (d.c.setFromMatrixPosition(e), d.axis.copy(d.c).sub(t.getWorldPosition(d.p)).normalize(), t.isOrthographicCamera && t.getWorldDirection(d.axis), d.q.setFromAxisAngle(d.axis, l), d.m.makeRotationFromQuaternion(d.q), d.t.makeTranslation(d.c.x, d.c.y, d.c.z), d.turned.copy(d.t).multiply(d.m), d.t.makeTranslation(-d.c.x, -d.c.y, -d.c.z), d.turned.multiply(d.t).multiply(e), n.shift !== 0) {
|
|
315
|
+
d.ndc.copy(d.c).project(t);
|
|
316
|
+
const c = -n.up.y * n.shift * r, f = n.up.x * n.shift * r;
|
|
317
|
+
d.p.set(d.ndc.x + c * 2 / s, d.ndc.y - f * 2, d.ndc.z).unproject(t).sub(d.c), d.t.makeTranslation(d.p.x, d.p.y, d.p.z), d.turned.premultiply(d.t);
|
|
318
|
+
}
|
|
319
|
+
o.copy(d.turned);
|
|
320
|
+
let u = 1;
|
|
321
|
+
if (n.width !== null && n.width > 0) {
|
|
322
|
+
const c = ks(
|
|
323
|
+
d.turned,
|
|
324
|
+
n.halfWidth,
|
|
325
|
+
n.halfDepth,
|
|
326
|
+
n.up,
|
|
327
|
+
t,
|
|
328
|
+
s
|
|
329
|
+
);
|
|
330
|
+
if (c > 1e-9) {
|
|
331
|
+
const [f, p] = n.scaleRange ?? [0.85, 1.2];
|
|
332
|
+
u = 1 + (Math.min(p, Math.max(f, n.width / c)) - 1) * r;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return u;
|
|
336
|
+
}, Ts = 0.9, Es = 0.7, ke = (e) => {
|
|
337
|
+
const t = e.restPositions, s = t[it.indexMcp].distanceTo(t[it.pinkyMcp]), n = t[it.wrist].distanceTo(t[it.middleMcp]), i = s * Ts;
|
|
338
|
+
return { width: i, depth: i * Es, palmWidth: s, palmLength: n };
|
|
339
|
+
}, z = {
|
|
340
|
+
inv: new h.Quaternion(),
|
|
341
|
+
x: new h.Vector3(),
|
|
342
|
+
y: new h.Vector3(),
|
|
343
|
+
z: new h.Vector3(),
|
|
344
|
+
basis: new h.Matrix4()
|
|
345
|
+
}, Os = (e, t = { position: new h.Vector3(), quaternion: new h.Quaternion() }) => {
|
|
346
|
+
const s = e.restQuaternions.wrist;
|
|
347
|
+
if (!s) throw new Error('WristAttachment: the rig has no "wrist" node');
|
|
348
|
+
z.inv.copy(s).invert();
|
|
349
|
+
const n = e.restPositions;
|
|
350
|
+
return z.y.subVectors(n[it.middleMcp], n[it.wrist]).applyQuaternion(z.inv).normalize(), z.z.copy(e.restPalmNormal).applyQuaternion(z.inv), z.z.addScaledVector(z.y, -z.z.dot(z.y)).normalize(), z.x.crossVectors(z.y, z.z), z.basis.makeBasis(z.x, z.y, z.z), t.position.set(0, 0, 0), t.quaternion.setFromRotationMatrix(z.basis), t;
|
|
351
|
+
}, _s = 2.5, Rs = 1.25, Vs = 0.15, Is = Object.freeze({
|
|
352
|
+
jump: 35,
|
|
353
|
+
confirmMs: 200,
|
|
354
|
+
confirmSamples: 4,
|
|
355
|
+
smoothing: 0.6
|
|
356
|
+
});
|
|
357
|
+
class Ws {
|
|
358
|
+
constructor(t = {}) {
|
|
359
|
+
x(this, "settings");
|
|
360
|
+
x(this, "q", new h.Quaternion());
|
|
361
|
+
x(this, "has", !1);
|
|
362
|
+
x(this, "pending", null);
|
|
363
|
+
this.settings = { ...Is, ...t };
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Filters this frame's wrist rotation (`target`) at `nowMs`; writes into
|
|
367
|
+
* `out`. `sample` names the hand detection it comes from (its timestamp);
|
|
368
|
+
* omitted, every call counts as one.
|
|
369
|
+
*/
|
|
370
|
+
apply(t, s, n, i) {
|
|
371
|
+
const o = h.MathUtils.degToRad(this.settings.jump);
|
|
372
|
+
if (!this.has)
|
|
373
|
+
return this.q.copy(t), this.has = !0, this.pending = null, n.copy(this.q);
|
|
374
|
+
if (this.q.angleTo(t) > o) {
|
|
375
|
+
const { pending: r } = this;
|
|
376
|
+
return r && r.q.angleTo(t) < o / 2 ? ((i === void 0 || i !== r.lastSample) && (r.samples += 1, r.lastSample = i), s - r.sinceMs >= this.settings.confirmMs && r.samples >= this.settings.confirmSamples && (this.q.copy(t), this.pending = null)) : this.pending = { q: t.clone(), sinceMs: s, samples: 1, lastSample: i }, n.copy(this.q);
|
|
377
|
+
}
|
|
378
|
+
return this.pending = null, this.q.slerp(t, h.MathUtils.clamp(this.settings.smoothing, 0.01, 1)), n.copy(this.q);
|
|
379
|
+
}
|
|
380
|
+
/** Forget the wrist (the hand was lost): the next pose is taken as it is. */
|
|
381
|
+
reset() {
|
|
382
|
+
this.has = !1, this.pending = null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const re = "forearm", Ds = new h.Vector3(1, 1, 1), Fs = 0.2, Ns = 0.45;
|
|
386
|
+
class Bs {
|
|
387
|
+
/** `forearm`: the rig's forearm bone, at rest, a child of the wrist bone. */
|
|
388
|
+
constructor(t, s) {
|
|
389
|
+
x(this, "filter", new Ws());
|
|
390
|
+
/** The arm fit (null without `armMask`). */
|
|
391
|
+
x(this, "arm", null);
|
|
392
|
+
/** The wrist frame this frame, world (rigid). */
|
|
393
|
+
x(this, "world", new h.Matrix4());
|
|
394
|
+
/** Across the arm (X, Z) to fit the arm's width; 1 without a fit. */
|
|
395
|
+
x(this, "crossScale", 1);
|
|
396
|
+
x(this, "size");
|
|
397
|
+
/**
|
|
398
|
+
* The wrist frame in the forearm bone's space (+Y toward the fingers, +Z
|
|
399
|
+
* out of the palm, origin on the wrist joint): where wristwear is authored.
|
|
400
|
+
*/
|
|
401
|
+
x(this, "forearmFrame", new h.Matrix4());
|
|
402
|
+
x(this, "wristFrame", new h.Matrix4());
|
|
403
|
+
/** inverse(wrist frame in the wrist bone) × the forearm's rest (in the wrist bone). */
|
|
404
|
+
x(this, "toForearm", new h.Matrix4());
|
|
405
|
+
x(this, "frame", 0);
|
|
406
|
+
x(this, "solved", -1);
|
|
407
|
+
/** The hand detection behind this frame (`HandPose.timestampMs`), for the filter. */
|
|
408
|
+
x(this, "sample");
|
|
409
|
+
/** The arm's way up on screen and the scale it was aimed with, last frame. */
|
|
410
|
+
x(this, "last", { up: { x: 0, y: 0 }, units: 0 });
|
|
411
|
+
x(this, "w", {
|
|
412
|
+
raw: new h.Matrix4(),
|
|
413
|
+
steady: new h.Matrix4(),
|
|
414
|
+
local: new h.Matrix4(),
|
|
415
|
+
p: new h.Vector3(),
|
|
416
|
+
q: new h.Quaternion(),
|
|
417
|
+
s: new h.Vector3(),
|
|
418
|
+
up: { x: 0, y: 0 }
|
|
419
|
+
});
|
|
420
|
+
this.binding = t, this.forearm = s;
|
|
421
|
+
const { position: n, quaternion: i } = Os(t);
|
|
422
|
+
this.wristFrame.compose(n, i, Ds), this.size = ke(t);
|
|
423
|
+
const o = new h.Matrix4().compose(s.position, s.quaternion, s.scale);
|
|
424
|
+
this.forearmFrame.copy(o).invert().multiply(this.wristFrame), this.toForearm.copy(this.wristFrame).invert().multiply(o);
|
|
425
|
+
}
|
|
426
|
+
/** A new frame (the rig moved; `sample`: its detection): the next `solve` works it out again. */
|
|
427
|
+
tick(t) {
|
|
428
|
+
this.frame += 1, this.sample = t;
|
|
429
|
+
}
|
|
430
|
+
/** The hand was lost: the next pose is taken as it is. */
|
|
431
|
+
reset() {
|
|
432
|
+
this.filter.reset();
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Aims the forearm bone for this frame (once; later calls are free) and
|
|
436
|
+
* returns the wrist frame (world), or null without a wrist bone. Call
|
|
437
|
+
* before render, after the rig has posed the hand.
|
|
438
|
+
*/
|
|
439
|
+
solve(t, s, n = performance.now()) {
|
|
440
|
+
const i = this.binding.bones.wrist;
|
|
441
|
+
if (!i) return null;
|
|
442
|
+
if (this.solved === this.frame) return this.world;
|
|
443
|
+
this.solved = this.frame;
|
|
444
|
+
const { w: o } = this;
|
|
445
|
+
o.raw.multiplyMatrices(i.matrixWorld, this.wristFrame), o.raw.decompose(o.p, o.q, o.s), this.filter.apply(o.q, n, o.q, this.sample), o.steady.compose(o.p, o.q, o.s);
|
|
446
|
+
const r = this.arm, a = r == null ? void 0 : r.tracker, l = a == null ? void 0 : a.query;
|
|
447
|
+
this.crossScale = 1;
|
|
448
|
+
const u = !l && this.last.units > 0;
|
|
449
|
+
if (!r || !a || a.weight <= 0 || !l && !u)
|
|
450
|
+
this.world.copy(o.steady), this.last.units = 0;
|
|
451
|
+
else {
|
|
452
|
+
const c = l ? l.unitsPerCm : this.last.units;
|
|
453
|
+
if (!r.turn)
|
|
454
|
+
Se(o.steady, t, s, o.up);
|
|
455
|
+
else if (l) {
|
|
456
|
+
const { x: p, y: g } = l.toElbow;
|
|
457
|
+
o.up.x = p * Math.cos(a.bend) - g * Math.sin(a.bend), o.up.y = p * Math.sin(a.bend) + g * Math.cos(a.bend);
|
|
458
|
+
} else
|
|
459
|
+
o.up.x = this.last.up.x, o.up.y = this.last.up.y;
|
|
460
|
+
this.last.up.x = o.up.x, this.last.up.y = o.up.y, this.last.units = c;
|
|
461
|
+
const f = h.MathUtils.smoothstep(a.confidence, Fs, Ns);
|
|
462
|
+
this.crossScale = As(
|
|
463
|
+
o.steady,
|
|
464
|
+
t,
|
|
465
|
+
s,
|
|
466
|
+
{
|
|
467
|
+
up: o.up,
|
|
468
|
+
shift: r.fitWidth ? a.shift * c : 0,
|
|
469
|
+
width: r.fitWidth && a.width !== null ? a.width * c : null,
|
|
470
|
+
halfWidth: this.size.width / 2,
|
|
471
|
+
halfDepth: this.size.depth / 2
|
|
472
|
+
},
|
|
473
|
+
a.weight * f,
|
|
474
|
+
this.world
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
return o.local.copy(i.matrixWorld).invert().multiply(this.world).multiply(this.toForearm).decompose(this.forearm.position, this.forearm.quaternion, this.forearm.scale), this.forearm.updateMatrixWorld(!0), this.world;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
const Hs = (e) => {
|
|
481
|
+
const t = e.bones.wrist;
|
|
482
|
+
if (!t) return null;
|
|
483
|
+
const s = t.getObjectByName(re);
|
|
484
|
+
if (s) return s;
|
|
485
|
+
const n = new h.Bone();
|
|
486
|
+
return n.name = re, t.add(n), n;
|
|
487
|
+
}, Ae = Pt(null), Lt = "vincenttHandRigModelMesh", Kt = Pt(null), js = new h.Matrix4(), Ft = new h.Matrix4(), qs = ({
|
|
488
|
+
hand: e,
|
|
489
|
+
model: t,
|
|
490
|
+
modelHand: s = "right",
|
|
491
|
+
smoothing: n = $e,
|
|
492
|
+
fingerLengths: i = "tracked",
|
|
493
|
+
showHeld: o = !0,
|
|
494
|
+
onTrackingChange: r,
|
|
495
|
+
material: a,
|
|
496
|
+
onModel: l,
|
|
497
|
+
active: u = !0,
|
|
498
|
+
armMask: c,
|
|
499
|
+
children: f
|
|
500
|
+
}) => {
|
|
501
|
+
const { node: p } = Ot(mt.HAND_TRACKER, void 0, u), g = as(), { camera: w, size: T } = gt(), m = c ? typeof c == "string" ? { kind: c } : c : null, k = m ? m.kind ?? "skin" : !1, I = xs(k), _ = j(
|
|
502
|
+
() => k ? { tracker: new Ms(), turn: !0, fitWidth: !0, mask: null } : null,
|
|
503
|
+
[k]
|
|
504
|
+
);
|
|
505
|
+
_ && m && (_.mask = I, _.turn = m.turn ?? !0, _.fitWidth = m.fitWidth ?? !0, _.tracker.settings = { ...be, ...ae(m, Ps) });
|
|
506
|
+
const J = Y({});
|
|
507
|
+
J.current = m ? ae(m, Us) : {};
|
|
508
|
+
const V = Y(null), N = j(() => {
|
|
509
|
+
const O = Xe(t);
|
|
510
|
+
return O.traverse((E) => {
|
|
511
|
+
E.frustumCulled = !1, E instanceof h.Mesh && (E.userData[Lt] = !0);
|
|
512
|
+
}), O;
|
|
513
|
+
}, [t]), F = j(() => Je(N, s), [N, s]), C = j(
|
|
514
|
+
() => new Bs(F, Hs(F)),
|
|
515
|
+
[F]
|
|
516
|
+
);
|
|
517
|
+
C.arm = _;
|
|
518
|
+
const Q = Y(1);
|
|
519
|
+
Q.current = T.width / Math.max(1, T.height);
|
|
520
|
+
const et = gt((O) => O.scene);
|
|
521
|
+
L(
|
|
522
|
+
() => we(
|
|
523
|
+
et,
|
|
524
|
+
(O, E, q) => C.solve(q, Q.current)
|
|
525
|
+
),
|
|
526
|
+
[et, C]
|
|
527
|
+
);
|
|
528
|
+
const P = j(() => Ze(F), [F]), st = Y(l);
|
|
529
|
+
st.current = l, L(() => {
|
|
530
|
+
var O;
|
|
531
|
+
return (O = st.current) == null ? void 0 : O.call(st, N);
|
|
532
|
+
}, [N]);
|
|
533
|
+
const ut = j(() => {
|
|
534
|
+
const O = /* @__PURE__ */ new Map();
|
|
535
|
+
return N.traverse((E) => {
|
|
536
|
+
E instanceof h.Mesh && O.set(E, E.material);
|
|
537
|
+
}), O;
|
|
538
|
+
}, [N]);
|
|
539
|
+
L(() => {
|
|
540
|
+
for (const [O, E] of ut) O.material = a ?? E;
|
|
541
|
+
}, [a, ut]);
|
|
542
|
+
const H = Y(void 0), S = Y({
|
|
543
|
+
tracked: !1,
|
|
544
|
+
quaternion: new h.Quaternion(),
|
|
545
|
+
position: new h.Vector3(),
|
|
546
|
+
scale: 1,
|
|
547
|
+
mirrored: !1
|
|
548
|
+
}), M = Y({}), b = Y({}), D = Y({});
|
|
549
|
+
return Ct(() => {
|
|
550
|
+
var Qt, $t, Xt;
|
|
551
|
+
const O = V.current;
|
|
552
|
+
if (!O) return;
|
|
553
|
+
const E = ((Qt = p == null ? void 0 : p.getHandPose) == null ? void 0 : Qt.call(p, e)) ?? (($t = p == null ? void 0 : p.poses) == null ? void 0 : $t[e]) ?? null, q = E && E.world.length >= 21 && E.image.length >= 21 && (o || !E.held), W = S.current;
|
|
554
|
+
if (C.tick(E == null ? void 0 : E.timestampMs), !q) {
|
|
555
|
+
O.visible = !1, C.reset(), _ == null || _.tracker.reset(), te(W, null, n, P) && (r == null || r(!1));
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
if (_) {
|
|
559
|
+
const K = performance.now();
|
|
560
|
+
_.tracker.pushHand(
|
|
561
|
+
E.timestampMs,
|
|
562
|
+
ds(E, T.width / Math.max(1, T.height))
|
|
563
|
+
), I != null && I.refresh(K) && _.tracker.measure(I, I.timestampMs, J.current), _.tracker.step(K);
|
|
564
|
+
}
|
|
565
|
+
const A = ts(F, E, w, g, H.current);
|
|
566
|
+
H.current = A, W.tracked && W.mirrored !== A.mirrored && (W.tracked = !1);
|
|
567
|
+
const y = te(W, A.fit, n, P);
|
|
568
|
+
W.mirrored = A.mirrored, y && (r == null || r(!0));
|
|
569
|
+
const R = h.MathUtils.clamp(n, 0.01, 1), Z = Math.min(R, 0.1), pt = b.current;
|
|
570
|
+
for (const { name: K } of ee) {
|
|
571
|
+
const dt = A.local[K], ct = F.bones[K];
|
|
572
|
+
if (!dt || !ct) continue;
|
|
573
|
+
const ft = (Xt = M.current)[K] ?? (Xt[K] = dt.clone());
|
|
574
|
+
y || R >= 1 ? ft.copy(dt) : ft.slerp(dt, R), ct.quaternion.copy(ft);
|
|
575
|
+
const Jt = i === "tracked" ? A.lengths[K] ?? 1 : 1, Wt = pt[K];
|
|
576
|
+
pt[K] = y || Wt === void 0 ? Jt : Wt + (Jt - Wt) * Z;
|
|
577
|
+
}
|
|
578
|
+
const kt = D.current;
|
|
579
|
+
for (const { name: K, parent: dt } of ee) {
|
|
580
|
+
if (dt !== "wrist") continue;
|
|
581
|
+
const ct = A.knuckles[K];
|
|
582
|
+
if (!ct) continue;
|
|
583
|
+
const ft = kt[K] ?? (kt[K] = ct.clone());
|
|
584
|
+
y ? ft.copy(ct) : ft.lerp(ct, Z);
|
|
585
|
+
}
|
|
586
|
+
es(F, pt, i === "tracked" ? kt : null), ss(
|
|
587
|
+
{ scale: W.scale, quaternion: W.quaternion, translation: W.position },
|
|
588
|
+
W.mirrored,
|
|
589
|
+
Ft
|
|
590
|
+
), O.parent && (O.parent.updateMatrixWorld(), Ft.premultiply(js.copy(O.parent.matrixWorld).invert())), O.matrix.copy(Ft), O.matrixWorldNeedsUpdate = !0, O.visible = !0;
|
|
591
|
+
}), /* @__PURE__ */ tt(Kt.Provider, { value: F, children: /* @__PURE__ */ Ut(Ae.Provider, { value: C, children: [
|
|
592
|
+
/* @__PURE__ */ tt("group", { ref: V, matrixAutoUpdate: !1, visible: !1, children: /* @__PURE__ */ tt("primitive", { object: N }) }),
|
|
593
|
+
f
|
|
594
|
+
] }) });
|
|
595
|
+
}, Ps = ["smoothing", "holdMs", "fadeMs", "maxSkewMs", "maxShift"], Us = ["along", "widthAt", "maxWidth", "minWidth", "maxTurn"], ae = (e, t) => Object.fromEntries(t.filter((s) => e[s] !== void 0).map((s) => [s, e[s]])), Cs = ({ along: e = 1, offset: t, children: s }) => {
|
|
596
|
+
const n = Et(Kt), i = Et(Ae), o = gt((g) => g.scene), r = gt((g) => g.size), a = Y(null), l = j(() => n ? ke(n) : null, [n]), u = Y(1);
|
|
597
|
+
u.current = r.width / Math.max(1, r.height), L(() => {
|
|
598
|
+
if (!i) return;
|
|
599
|
+
const g = new h.Matrix4();
|
|
600
|
+
return we(o, (w, T, m) => {
|
|
601
|
+
const k = a.current;
|
|
602
|
+
if (!k) return;
|
|
603
|
+
i.solve(m, u.current);
|
|
604
|
+
const I = i.crossScale;
|
|
605
|
+
k.matrix.multiplyMatrices(i.forearmFrame, g.makeScale(I, 1, I)), k.matrixWorldNeedsUpdate = !0, k.updateMatrixWorld(!0);
|
|
606
|
+
});
|
|
607
|
+
}, [i, o]);
|
|
608
|
+
const c = !n;
|
|
609
|
+
if (L(() => {
|
|
610
|
+
c && console.warn(
|
|
611
|
+
`${zt.loggerPrefix} WristAttachment must be inside a HandRig or HandOccluder`
|
|
612
|
+
);
|
|
613
|
+
}, [c]), !n || !l || !i) return null;
|
|
614
|
+
const f = i.forearm, p = (t == null ? void 0 : t.position) ?? [0, 0, 0];
|
|
615
|
+
return Ge(
|
|
616
|
+
/* @__PURE__ */ tt("group", { ref: a, matrixAutoUpdate: !1, children: /* @__PURE__ */ tt(
|
|
617
|
+
"group",
|
|
618
|
+
{
|
|
619
|
+
position: [p[0], p[1] - e, p[2]],
|
|
620
|
+
rotation: (t == null ? void 0 : t.rotation) ?? [0, 0, 0],
|
|
621
|
+
scale: (t == null ? void 0 : t.scale) ?? 1,
|
|
622
|
+
children: typeof s == "function" ? s(l) : s
|
|
623
|
+
}
|
|
624
|
+
) }),
|
|
625
|
+
f
|
|
626
|
+
);
|
|
627
|
+
}, zs = -1, Ls = (e, { length: t = _s, scale: s = 1 } = {}) => {
|
|
628
|
+
const n = e.palmLength * t, i = e.palmLength * Vs, o = e.width / 2 * s, r = new h.CylinderGeometry(
|
|
629
|
+
o,
|
|
630
|
+
o * Rs,
|
|
631
|
+
n + i,
|
|
632
|
+
24,
|
|
633
|
+
1,
|
|
634
|
+
!1
|
|
635
|
+
);
|
|
636
|
+
return r.translate(0, (i - n) / 2, 0), r.scale(1, 1, e.depth / e.width), r;
|
|
637
|
+
}, Ks = ({
|
|
638
|
+
length: e,
|
|
639
|
+
scale: t,
|
|
640
|
+
showDebugMaterial: s = !1,
|
|
641
|
+
opacity: n = 0.5
|
|
642
|
+
}) => {
|
|
643
|
+
const i = j(
|
|
644
|
+
() => new h.MeshBasicMaterial({
|
|
645
|
+
color: 13948120,
|
|
646
|
+
colorWrite: !1,
|
|
647
|
+
depthWrite: !0,
|
|
648
|
+
side: h.DoubleSide
|
|
649
|
+
}),
|
|
650
|
+
[]
|
|
651
|
+
);
|
|
652
|
+
return L(() => () => i.dispose(), [i]), L(() => {
|
|
653
|
+
i.colorWrite = s, i.transparent = s, i.opacity = s ? n : 1, i.needsUpdate = !0;
|
|
654
|
+
}, [i, s, n]), /* @__PURE__ */ tt(Cs, { along: 0, children: (o) => /* @__PURE__ */ tt(Gs, { wrist: o, length: e, scale: t, material: i }) });
|
|
655
|
+
}, Gs = ({
|
|
656
|
+
wrist: e,
|
|
657
|
+
length: t,
|
|
658
|
+
scale: s,
|
|
659
|
+
material: n
|
|
660
|
+
}) => {
|
|
661
|
+
const i = j(
|
|
662
|
+
() => Ls(e, { length: t, scale: s }),
|
|
663
|
+
[e, t, s]
|
|
664
|
+
);
|
|
665
|
+
return L(() => () => i.dispose(), [i]), /* @__PURE__ */ tt(
|
|
666
|
+
"mesh",
|
|
667
|
+
{
|
|
668
|
+
name: "ForearmOccluder",
|
|
669
|
+
geometry: i,
|
|
670
|
+
material: n,
|
|
671
|
+
renderOrder: zs,
|
|
672
|
+
frustumCulled: !1
|
|
673
|
+
}
|
|
674
|
+
);
|
|
675
|
+
}, Ys = -1, Nt = "void main() {", jt = "#include <skinning_vertex>", Qs = [
|
|
676
|
+
jt,
|
|
677
|
+
"#ifdef USE_SKINNING",
|
|
678
|
+
" transformed += normalize( objectNormal ) * inflate;",
|
|
679
|
+
"#endif"
|
|
680
|
+
].join(`
|
|
681
|
+
`), $s = (e) => !e.includes(Nt) || !e.includes(jt) ? e : e.replace(Nt, `uniform float inflate;
|
|
682
|
+
${Nt}`).replace(jt, Qs), Xs = () => {
|
|
683
|
+
const e = new h.MeshBasicMaterial({
|
|
684
|
+
color: 13948120,
|
|
685
|
+
colorWrite: !1,
|
|
686
|
+
depthWrite: !0,
|
|
687
|
+
side: h.FrontSide
|
|
688
|
+
}), t = { value: 0 };
|
|
689
|
+
return e.userData.inflate = t, e.onBeforeCompile = (s) => {
|
|
690
|
+
s.uniforms.inflate = t, s.vertexShader = $s(s.vertexShader);
|
|
691
|
+
}, e.customProgramCacheKey = () => "vincentt-hand-occluder", e;
|
|
692
|
+
}, mi = ({
|
|
693
|
+
inflate: e = 0,
|
|
694
|
+
showDebugMaterial: t = !1,
|
|
695
|
+
opacity: s = 0.5,
|
|
696
|
+
onModel: n,
|
|
697
|
+
forearm: i = !1,
|
|
698
|
+
children: o,
|
|
699
|
+
...r
|
|
700
|
+
}) => {
|
|
701
|
+
const a = j(() => Xs(), []);
|
|
702
|
+
L(() => () => a.dispose(), [a]), L(() => {
|
|
703
|
+
a.colorWrite = t, a.transparent = t, a.opacity = t ? s : 1, a.needsUpdate = !0;
|
|
704
|
+
}, [a, t, s]), L(() => {
|
|
705
|
+
a.userData.inflate.value = e;
|
|
706
|
+
}, [a, e]);
|
|
707
|
+
const l = Me(
|
|
708
|
+
(u) => {
|
|
709
|
+
u.traverse((c) => {
|
|
710
|
+
c instanceof h.Mesh && c.userData[Lt] && (c.renderOrder = Ys);
|
|
711
|
+
}), n == null || n(u);
|
|
712
|
+
},
|
|
713
|
+
[n]
|
|
714
|
+
);
|
|
715
|
+
return /* @__PURE__ */ Ut(qs, { ...r, material: a, onModel: l, children: [
|
|
716
|
+
i && /* @__PURE__ */ tt(
|
|
717
|
+
Ks,
|
|
718
|
+
{
|
|
719
|
+
...i === !0 ? {} : i,
|
|
720
|
+
showDebugMaterial: t,
|
|
721
|
+
opacity: s
|
|
722
|
+
}
|
|
723
|
+
),
|
|
724
|
+
o
|
|
725
|
+
] });
|
|
726
|
+
}, Js = 0.55, Zs = 1, tn = [0.1, 0.4], le = ["indexMcp", "middleMcp", "ringMcp", "pinkyMcp"], en = (e, t) => {
|
|
727
|
+
const s = (u) => e.restPositions[it[u]], n = new h.Vector3();
|
|
728
|
+
for (const u of le) n.add(s(u));
|
|
729
|
+
n.multiplyScalar(1 / le.length);
|
|
730
|
+
const i = new h.Vector3().addVectors(s("wrist"), n).multiplyScalar(0.5), o = e.restPalmNormal.clone().normalize();
|
|
731
|
+
t === "back" && o.negate();
|
|
732
|
+
const r = n.clone().sub(s("wrist"));
|
|
733
|
+
r.addScaledVector(o, -r.dot(o)).normalize();
|
|
734
|
+
const a = new h.Vector3().crossVectors(r, o).normalize(), l = Math.sign(s("thumbCmc").clone().sub(i).dot(a)) || 1;
|
|
735
|
+
return {
|
|
736
|
+
origin: i,
|
|
737
|
+
normal: o,
|
|
738
|
+
up: r,
|
|
739
|
+
right: a,
|
|
740
|
+
thumb: a.clone().multiplyScalar(l),
|
|
741
|
+
palm: s("middleMcp").distanceTo(s("wrist"))
|
|
742
|
+
};
|
|
743
|
+
}, sn = {
|
|
744
|
+
basis: new h.Matrix4(),
|
|
745
|
+
shift: new h.Matrix4(),
|
|
746
|
+
centre: new h.Vector3()
|
|
747
|
+
}, nn = (e, t, { size: s, offset: n }, i = new h.Matrix4()) => {
|
|
748
|
+
const { basis: o, shift: r, centre: a } = sn;
|
|
749
|
+
a.copy(e.origin).addScaledVector(e.thumb, (n == null ? void 0 : n[0]) ?? 0).addScaledVector(e.up, (n == null ? void 0 : n[1]) ?? 0), o.makeBasis(e.right, e.up, e.normal).transpose(), r.makeTranslation(-a.x, -a.y, -a.z);
|
|
750
|
+
const l = 1 / Math.max(s, 1e-9);
|
|
751
|
+
return i.makeScale(l, l, l).multiply(o).multiply(r).multiply(t);
|
|
752
|
+
}, on = new h.Matrix4(), ce = (e, t, s) => {
|
|
753
|
+
s.identity();
|
|
754
|
+
for (let n = e; n && n !== t; n = n.parent)
|
|
755
|
+
n.updateMatrix(), s.premultiply(n.matrix);
|
|
756
|
+
return s;
|
|
757
|
+
}, rn = (e, t, s = new h.Matrix4()) => {
|
|
758
|
+
const n = t, i = e.bones.wrist, o = n.isSkinnedMesh && i ? n.skeleton.bones.indexOf(i) : -1;
|
|
759
|
+
return o < 0 ? ce(t, e.root, s) : (ce(i, e.root, s), s.multiply(on.copy(n.skeleton.boneInverses[o])).multiply(n.bindMatrix));
|
|
760
|
+
}, gi = (e, { rotation: t = 0, aspect: s = 1, mirrored: n = !1 } = {}, i = new h.Vector2()) => {
|
|
761
|
+
if (e.z < 0) return null;
|
|
762
|
+
const o = n ? -e.x : e.x, r = Math.cos(t), a = Math.sin(t), l = r * o + a * e.y + 0.5, u = (-a * o + r * e.y) * s + 0.5;
|
|
763
|
+
return l < 0 || l > 1 || u < 0 || u > 1 ? null : i.set(l, u);
|
|
764
|
+
}, an = (
|
|
765
|
+
/* glsl */
|
|
766
|
+
`
|
|
767
|
+
#include <common>
|
|
768
|
+
#include <skinning_pars_vertex>
|
|
769
|
+
#include <logdepthbuf_pars_vertex>
|
|
770
|
+
uniform mat4 decalMatrix;
|
|
771
|
+
varying vec3 vDecal;
|
|
772
|
+
varying float vFacing;
|
|
773
|
+
varying float vMirror;
|
|
774
|
+
void main() {
|
|
775
|
+
// Decal space from the REST surface (before skinning): the art deforms with the skin.
|
|
776
|
+
vDecal = ( decalMatrix * vec4( position, 1.0 ) ).xyz;
|
|
777
|
+
vFacing = normalize( mat3( decalMatrix ) * normal ).z;
|
|
778
|
+
// A mirrored hand (the model's other chirality): the art is flipped back.
|
|
779
|
+
vMirror = determinant( mat3( modelMatrix ) ) < 0.0 ? 1.0 : 0.0;
|
|
780
|
+
#include <begin_vertex>
|
|
781
|
+
#include <skinbase_vertex>
|
|
782
|
+
#include <skinning_vertex>
|
|
783
|
+
#include <project_vertex>
|
|
784
|
+
#include <logdepthbuf_vertex>
|
|
785
|
+
}
|
|
786
|
+
`
|
|
787
|
+
), ln = (
|
|
788
|
+
/* glsl */
|
|
789
|
+
`
|
|
790
|
+
#include <common>
|
|
791
|
+
#include <logdepthbuf_pars_fragment>
|
|
792
|
+
uniform sampler2D map;
|
|
793
|
+
uniform float opacity;
|
|
794
|
+
uniform vec2 turn;
|
|
795
|
+
uniform float aspect;
|
|
796
|
+
uniform vec2 fade;
|
|
797
|
+
varying vec3 vDecal;
|
|
798
|
+
varying float vFacing;
|
|
799
|
+
varying float vMirror;
|
|
800
|
+
void main() {
|
|
801
|
+
#include <logdepthbuf_fragment>
|
|
802
|
+
if ( vDecal.z < 0.0 ) discard;
|
|
803
|
+
vec2 p = vDecal.xy;
|
|
804
|
+
if ( vMirror > 0.5 ) p.x = -p.x;
|
|
805
|
+
vec2 uv = vec2( turn.x * p.x + turn.y * p.y, ( -turn.y * p.x + turn.x * p.y ) * aspect ) + 0.5;
|
|
806
|
+
if ( uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0 ) discard;
|
|
807
|
+
vec4 art = texture2D( map, uv );
|
|
808
|
+
float a = art.a * opacity * smoothstep( fade.x, fade.y, vFacing );
|
|
809
|
+
if ( a < 0.002 ) discard;
|
|
810
|
+
gl_FragColor = vec4( art.rgb, 1.0 );
|
|
811
|
+
#include <colorspace_fragment>
|
|
812
|
+
// Premultiplied: the blend factors (setHandTattooBlend) mix by alpha.
|
|
813
|
+
gl_FragColor = vec4( gl_FragColor.rgb * a, a );
|
|
814
|
+
}
|
|
815
|
+
`
|
|
816
|
+
), Te = (e, t) => {
|
|
817
|
+
e.blending = h.CustomBlending, e.blendEquation = h.AddEquation, e.blendEquationAlpha = h.AddEquation, t === "multiply" ? (e.blendSrc = h.DstColorFactor, e.blendDst = h.OneMinusSrcAlphaFactor, e.blendSrcAlpha = h.ZeroFactor, e.blendDstAlpha = h.OneFactor) : (e.blendSrc = h.OneFactor, e.blendDst = h.OneMinusSrcAlphaFactor, e.blendSrcAlpha = h.OneFactor, e.blendDstAlpha = h.OneMinusSrcAlphaFactor);
|
|
818
|
+
}, cn = (e = "multiply") => {
|
|
819
|
+
const t = new h.ShaderMaterial({
|
|
820
|
+
uniforms: {
|
|
821
|
+
map: { value: null },
|
|
822
|
+
decalMatrix: { value: new h.Matrix4() },
|
|
823
|
+
opacity: { value: 1 },
|
|
824
|
+
turn: { value: new h.Vector2(1, 0) },
|
|
825
|
+
aspect: { value: 1 },
|
|
826
|
+
fade: { value: new h.Vector2(...tn) }
|
|
827
|
+
},
|
|
828
|
+
vertexShader: an,
|
|
829
|
+
fragmentShader: ln,
|
|
830
|
+
transparent: !0,
|
|
831
|
+
depthWrite: !1,
|
|
832
|
+
premultipliedAlpha: !0,
|
|
833
|
+
polygonOffset: !0,
|
|
834
|
+
polygonOffsetFactor: -1,
|
|
835
|
+
polygonOffsetUnits: -1,
|
|
836
|
+
toneMapped: !1
|
|
837
|
+
});
|
|
838
|
+
return Te(t, e), t;
|
|
839
|
+
}, hn = (e) => {
|
|
840
|
+
const [t, s] = ze(null), n = typeof e == "string" ? e : null;
|
|
841
|
+
return L(() => {
|
|
842
|
+
if (!n) return;
|
|
843
|
+
let i = !0, o = null;
|
|
844
|
+
return new h.TextureLoader().load(
|
|
845
|
+
n,
|
|
846
|
+
(r) => {
|
|
847
|
+
if (o = r, !i) {
|
|
848
|
+
r.dispose();
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
r.colorSpace = h.SRGBColorSpace, s({ url: n, texture: r });
|
|
852
|
+
},
|
|
853
|
+
void 0,
|
|
854
|
+
() => console.warn(`${zt.loggerPrefix} HandTattoo could not load ${n}`)
|
|
855
|
+
), () => {
|
|
856
|
+
i = !1, o == null || o.dispose();
|
|
857
|
+
};
|
|
858
|
+
}, [n]), typeof e != "string" ? e : (t == null ? void 0 : t.url) === e ? t.texture : null;
|
|
859
|
+
}, un = (e) => {
|
|
860
|
+
const t = e.image;
|
|
861
|
+
return t != null && t.width && (t != null && t.height) ? t.width / t.height : 1;
|
|
862
|
+
}, yi = ({
|
|
863
|
+
src: e,
|
|
864
|
+
placement: t = "back",
|
|
865
|
+
size: s,
|
|
866
|
+
offset: n,
|
|
867
|
+
rotation: i = 0,
|
|
868
|
+
opacity: o = 0.9,
|
|
869
|
+
blend: r = "multiply",
|
|
870
|
+
renderOrder: a = Zs
|
|
871
|
+
}) => {
|
|
872
|
+
const l = Et(Kt), u = hn(e), c = j(() => {
|
|
873
|
+
if (!l) return [];
|
|
874
|
+
const T = [];
|
|
875
|
+
return l.root.traverse((m) => {
|
|
876
|
+
m instanceof h.Mesh && m.userData[Lt] && T.push(m);
|
|
877
|
+
}), T.map((m) => {
|
|
878
|
+
const k = cn(), I = m;
|
|
879
|
+
let _;
|
|
880
|
+
if (I.isSkinnedMesh) {
|
|
881
|
+
const J = new h.SkinnedMesh(m.geometry, k);
|
|
882
|
+
J.bindMode = I.bindMode, J.bind(I.skeleton, I.bindMatrix), _ = J;
|
|
883
|
+
} else
|
|
884
|
+
_ = new h.Mesh(m.geometry, k);
|
|
885
|
+
return _.name = `${m.name}_tattoo`, _.frustumCulled = !1, _.position.copy(m.position), _.quaternion.copy(m.quaternion), _.scale.copy(m.scale), {
|
|
886
|
+
mesh: _,
|
|
887
|
+
source: m,
|
|
888
|
+
material: k,
|
|
889
|
+
geometryToRoot: rn(l, m)
|
|
890
|
+
};
|
|
891
|
+
});
|
|
892
|
+
}, [l]);
|
|
893
|
+
L(() => {
|
|
894
|
+
var T;
|
|
895
|
+
for (const { mesh: m, source: k } of c) (T = k.parent) == null || T.add(m);
|
|
896
|
+
return () => {
|
|
897
|
+
for (const { mesh: m, material: k } of c)
|
|
898
|
+
m.removeFromParent(), k.dispose();
|
|
899
|
+
};
|
|
900
|
+
}, [c]);
|
|
901
|
+
const f = j(
|
|
902
|
+
() => l ? en(l, t) : null,
|
|
903
|
+
[l, t]
|
|
904
|
+
), p = (n == null ? void 0 : n[0]) ?? 0, g = (n == null ? void 0 : n[1]) ?? 0;
|
|
905
|
+
L(() => {
|
|
906
|
+
if (!f) return;
|
|
907
|
+
const T = s ?? Js * f.palm;
|
|
908
|
+
for (const { mesh: m, material: k, geometryToRoot: I } of c) {
|
|
909
|
+
const _ = k.uniforms;
|
|
910
|
+
nn(
|
|
911
|
+
f,
|
|
912
|
+
I,
|
|
913
|
+
{ size: T, offset: [p, g] },
|
|
914
|
+
_.decalMatrix.value
|
|
915
|
+
), _.map.value = u, _.opacity.value = h.MathUtils.clamp(o, 0, 1), _.turn.value.set(Math.cos(i), Math.sin(i)), _.aspect.value = u ? un(u) : 1, Te(k, r), m.renderOrder = a, m.visible = !!u;
|
|
916
|
+
}
|
|
917
|
+
}, [c, f, u, s, p, g, i, o, r, a]);
|
|
918
|
+
const w = !l;
|
|
919
|
+
return L(() => {
|
|
920
|
+
w && console.warn(`${zt.loggerPrefix} HandTattoo must be inside a HandRig or HandOccluder`);
|
|
921
|
+
}, [w]), null;
|
|
922
|
+
}, bt = [
|
|
923
|
+
"thumbTip",
|
|
924
|
+
"indexTip",
|
|
925
|
+
"middleTip",
|
|
926
|
+
"ringTip",
|
|
927
|
+
"pinkyTip"
|
|
928
|
+
], Ee = Object.freeze({
|
|
929
|
+
palmRadius: 0.5,
|
|
930
|
+
tipRadius: 0.12,
|
|
931
|
+
pinchStart: 0.3,
|
|
932
|
+
pinchEnd: 0.45,
|
|
933
|
+
pinchReady: 0.6,
|
|
934
|
+
smoothing: 0.6
|
|
935
|
+
}), pn = 100, dn = 8, fn = 0.05, he = () => ({
|
|
936
|
+
center: new h.Vector3(),
|
|
937
|
+
velocity: new h.Vector3(),
|
|
938
|
+
radius: 0
|
|
939
|
+
}), Bt = (e) => ({
|
|
940
|
+
hand: e,
|
|
941
|
+
tracked: !1,
|
|
942
|
+
palmLength: 0,
|
|
943
|
+
palm: he(),
|
|
944
|
+
tips: Object.fromEntries(bt.map((t) => [t, he()])),
|
|
945
|
+
pinchDistance: 1 / 0,
|
|
946
|
+
pinching: !1,
|
|
947
|
+
pinch: new h.Vector3(),
|
|
948
|
+
pinchVelocity: new h.Vector3(),
|
|
949
|
+
timeMs: null,
|
|
950
|
+
history: []
|
|
951
|
+
}), at = {
|
|
952
|
+
palm: new h.Vector3(),
|
|
953
|
+
knuckles: new h.Vector3(),
|
|
954
|
+
previous: new h.Vector3(),
|
|
955
|
+
raw: new h.Vector3()
|
|
956
|
+
}, _t = (e, t, s, n, i, o) => {
|
|
957
|
+
if (e.radius = s, n || o <= 0) {
|
|
958
|
+
e.center.copy(t), e.velocity.set(0, 0, 0);
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
961
|
+
at.previous.copy(e.center), e.center.lerp(t, i), at.raw.subVectors(e.center, at.previous).divideScalar(o), e.velocity.lerp(at.raw, 1 - Math.exp(-o / fn));
|
|
962
|
+
}, Oe = (e, t) => {
|
|
963
|
+
const { history: s } = e;
|
|
964
|
+
for (s.length >= dn && s.shift(), s.push({ timeMs: t, point: e.pinch.clone() }); s.length > 2 && t - s[1].timeMs >= pn; ) s.shift();
|
|
965
|
+
const n = s[0], i = (t - n.timeMs) / 1e3;
|
|
966
|
+
i > 0 ? e.pinchVelocity.subVectors(e.pinch, n.point).divideScalar(i) : e.pinchVelocity.set(0, 0, 0);
|
|
967
|
+
}, _e = (e) => (e.tracked = !1, e.pinching = !1, e.pinchDistance = 1 / 0, e.timeMs = null, e.history.length = 0, e.pinchVelocity.set(0, 0, 0), e), ue = (e, t, s, n = {}) => {
|
|
968
|
+
const i = { ...Ee, ...n };
|
|
969
|
+
if (!t || t.length < 21)
|
|
970
|
+
return _e(e);
|
|
971
|
+
if (e.tracked && e.timeMs === s) return e;
|
|
972
|
+
const o = !e.tracked || e.timeMs === null, r = o ? 0 : Math.max(0, (s - e.timeMs) / 1e3), a = h.MathUtils.clamp(i.smoothing, 0.01, 1), l = (p) => t[it[p]], u = l("wrist").distanceTo(l("middleMcp"));
|
|
973
|
+
e.palmLength = o ? u : e.palmLength + (u - e.palmLength) * a, at.knuckles.copy(l("indexMcp")).add(l("middleMcp")).add(l("ringMcp")).add(l("pinkyMcp")).multiplyScalar(0.25), at.palm.copy(l("wrist")).add(at.knuckles).multiplyScalar(0.5), _t(e.palm, at.palm, e.palmLength * i.palmRadius, o, a, r);
|
|
974
|
+
for (const p of bt)
|
|
975
|
+
_t(e.tips[p], l(p), e.palmLength * i.tipRadius, o, a, r);
|
|
976
|
+
const c = e.tips.thumbTip.center, f = e.tips.indexTip.center;
|
|
977
|
+
return e.pinchDistance = c.distanceTo(f) / Math.max(e.palmLength, 1e-9), e.pinching ? e.pinching = e.pinchDistance <= i.pinchEnd : e.pinching = e.pinchDistance < i.pinchStart, e.pinch.addVectors(c, f).multiplyScalar(0.5), Oe(e, s), e.tracked = !0, e.timeMs = s, e;
|
|
978
|
+
}, mn = (e, t, s, n, i) => {
|
|
979
|
+
if (!t)
|
|
980
|
+
return _e(e);
|
|
981
|
+
const o = !e.tracked || e.timeMs === null, r = o ? 0 : Math.max(0, (n - e.timeMs) / 1e3);
|
|
982
|
+
if (!o && r === 0) return e;
|
|
983
|
+
e.palmLength = i, _t(e.palm, t, i, o, 1, r);
|
|
984
|
+
for (const a of bt) _t(e.tips[a], t, 0, o, 1, r);
|
|
985
|
+
return e.pinchDistance = s ? 0 : 1 / 0, e.pinching = s, e.pinch.copy(t), Oe(e, n), e.tracked = !0, e.timeMs = n, e;
|
|
986
|
+
}, Re = Object.freeze({
|
|
987
|
+
gravity: 9,
|
|
988
|
+
damping: 0.4,
|
|
989
|
+
bounce: 0.5,
|
|
990
|
+
friction: 4,
|
|
991
|
+
grabReach: 0.35,
|
|
992
|
+
hoverReach: 0.5,
|
|
993
|
+
tapMs: 350,
|
|
994
|
+
tapSpeed: 1,
|
|
995
|
+
throwScale: 1,
|
|
996
|
+
maxSpeed: 14,
|
|
997
|
+
flat: !0
|
|
998
|
+
}), gn = 1 / 120, yn = 1 / 20, Mn = 0.35, wn = 0.5, xn = 1.08, vn = 1.2, At = new h.Vector3(0, 1, 0), pe = [new h.Vector3(1, 0, 0), new h.Vector3(0, 1, 0), new h.Vector3(0, 0, 1)], bn = ["x", "y", "z"], v = {
|
|
999
|
+
d: new h.Vector3(),
|
|
1000
|
+
n: new h.Vector3(),
|
|
1001
|
+
v: new h.Vector3(),
|
|
1002
|
+
t: new h.Vector3(),
|
|
1003
|
+
q: new h.Quaternion(),
|
|
1004
|
+
q2: new h.Quaternion(),
|
|
1005
|
+
axis: new h.Vector3()
|
|
1006
|
+
}, Sn = (e) => [
|
|
1007
|
+
["palm", e.palm],
|
|
1008
|
+
...bt.map((t) => [t, e.tips[t]])
|
|
1009
|
+
];
|
|
1010
|
+
class kn {
|
|
1011
|
+
constructor(t = {}, s = {}) {
|
|
1012
|
+
x(this, "bodies", []);
|
|
1013
|
+
x(this, "bounds", new h.Box3(new h.Vector3(-2, -2, -1), new h.Vector3(2, 2, 1)));
|
|
1014
|
+
x(this, "settings");
|
|
1015
|
+
/** Simulated time, ms. */
|
|
1016
|
+
x(this, "timeMs", 0);
|
|
1017
|
+
x(this, "nextId", 1);
|
|
1018
|
+
x(this, "pinched", /* @__PURE__ */ new Map());
|
|
1019
|
+
/** What the pointer pressed on, and when (a quick click is a tap). */
|
|
1020
|
+
x(this, "press", null);
|
|
1021
|
+
x(this, "handSettings");
|
|
1022
|
+
this.settings = { ...Re, ...t }, this.handSettings = s;
|
|
1023
|
+
}
|
|
1024
|
+
/** The hand collider settings `pinchReady` is read from. */
|
|
1025
|
+
setHandSettings(t) {
|
|
1026
|
+
this.handSettings = t;
|
|
1027
|
+
}
|
|
1028
|
+
add(t = {}) {
|
|
1029
|
+
const s = Math.max(1e-4, t.size ?? 0.4), n = {
|
|
1030
|
+
id: this.nextId,
|
|
1031
|
+
shape: t.shape ?? "sphere",
|
|
1032
|
+
size: s,
|
|
1033
|
+
radius: s / 2,
|
|
1034
|
+
mass: Math.max(1e-6, t.mass ?? s ** 3),
|
|
1035
|
+
bounce: t.bounce,
|
|
1036
|
+
grabbable: t.grabbable ?? !0,
|
|
1037
|
+
pushable: t.pushable ?? !0,
|
|
1038
|
+
gravity: t.gravity ?? !0,
|
|
1039
|
+
position: new h.Vector3(...t.position ?? [0, 0, 0]),
|
|
1040
|
+
velocity: new h.Vector3(...t.velocity ?? [0, 0, 0]),
|
|
1041
|
+
quaternion: new h.Quaternion(),
|
|
1042
|
+
spin: new h.Vector3(),
|
|
1043
|
+
grabbedBy: null,
|
|
1044
|
+
hoveredBy: null,
|
|
1045
|
+
resting: !1,
|
|
1046
|
+
userData: {},
|
|
1047
|
+
grabOffset: new h.Vector3(),
|
|
1048
|
+
contacts: /* @__PURE__ */ new Set(),
|
|
1049
|
+
tapStart: {}
|
|
1050
|
+
};
|
|
1051
|
+
return this.nextId += 1, this.bodies.push(n), n;
|
|
1052
|
+
}
|
|
1053
|
+
remove(t) {
|
|
1054
|
+
const s = this.bodies.indexOf(t);
|
|
1055
|
+
s >= 0 && this.bodies.splice(s, 1);
|
|
1056
|
+
}
|
|
1057
|
+
/** The nearest grabbable (`any`: any) object whose surface is within `reach` of `point`. */
|
|
1058
|
+
pick(t, s, n = !1) {
|
|
1059
|
+
let i = null, o = 1 / 0;
|
|
1060
|
+
for (const r of this.bodies) {
|
|
1061
|
+
if (!r.grabbable && !n) continue;
|
|
1062
|
+
const a = this.distance(r.position, t) - r.radius;
|
|
1063
|
+
a <= s && a < o && (i = r, o = a);
|
|
1064
|
+
}
|
|
1065
|
+
return i;
|
|
1066
|
+
}
|
|
1067
|
+
/** Advances `dt` seconds with these hands; returns what happened. */
|
|
1068
|
+
step(t, s) {
|
|
1069
|
+
const n = [], i = h.MathUtils.clamp(t, 0, yn);
|
|
1070
|
+
this.timeMs += i * 1e3;
|
|
1071
|
+
const o = /* @__PURE__ */ new Map();
|
|
1072
|
+
for (const l of s) l.tracked && o.set(l.hand, l);
|
|
1073
|
+
this.grabAndRelease(s, o, n);
|
|
1074
|
+
const r = /* @__PURE__ */ new Map(), a = Math.max(1, Math.ceil(i / gn - 1e-9));
|
|
1075
|
+
for (let l = 0; l < a; l += 1) this.substep(i / a, o, r);
|
|
1076
|
+
for (const l of this.bodies) {
|
|
1077
|
+
const u = r.get(l);
|
|
1078
|
+
for (const [c, f] of u ?? []) {
|
|
1079
|
+
if (l.contacts.has(c)) continue;
|
|
1080
|
+
const [p, g] = c.split(":");
|
|
1081
|
+
n.push({ type: "touch", body: l, hand: p, part: g, speed: f });
|
|
1082
|
+
}
|
|
1083
|
+
l.contacts = new Set((u == null ? void 0 : u.keys()) ?? []);
|
|
1084
|
+
}
|
|
1085
|
+
return this.hoverAndTap(o, n), n;
|
|
1086
|
+
}
|
|
1087
|
+
/** Grab / hover reach: palm lengths for a hand; the pointer reaches as far as its sphere. */
|
|
1088
|
+
reach(t, s) {
|
|
1089
|
+
return t.hand === "pointer" ? t.palm.radius : t.palmLength * s;
|
|
1090
|
+
}
|
|
1091
|
+
distance(t, s) {
|
|
1092
|
+
return this.settings.flat ? Math.hypot(t.x - s.x, t.y - s.y) : t.distanceTo(s);
|
|
1093
|
+
}
|
|
1094
|
+
release(t, s, n) {
|
|
1095
|
+
const i = t.grabbedBy;
|
|
1096
|
+
t.grabbedBy = null, s && t.velocity.copy(s.pinchVelocity).multiplyScalar(this.settings.throwScale), t.velocity.clampLength(0, this.settings.maxSpeed), n.push({ type: "release", body: t, hand: i, speed: t.velocity.length() });
|
|
1097
|
+
}
|
|
1098
|
+
grabAndRelease(t, s, n) {
|
|
1099
|
+
for (const i of this.bodies)
|
|
1100
|
+
if (i.grabbedBy && !s.has(i.grabbedBy)) {
|
|
1101
|
+
const o = t.find((r) => r.hand === i.grabbedBy);
|
|
1102
|
+
this.release(i, o, n);
|
|
1103
|
+
}
|
|
1104
|
+
for (const i of t) {
|
|
1105
|
+
const o = i.tracked && i.pinching, r = this.pinched.get(i.hand) ?? !1, a = this.bodies.find((l) => l.grabbedBy === i.hand);
|
|
1106
|
+
if (o && !r && !a) {
|
|
1107
|
+
const l = this.pick(i.pinch, this.reach(i, this.settings.grabReach));
|
|
1108
|
+
l && (l.grabbedBy && n.push({ type: "release", body: l, hand: l.grabbedBy, speed: 0 }), l.grabbedBy = i.hand, l.grabOffset.subVectors(l.position, i.pinch).clampLength(0, l.radius), n.push({ type: "grab", body: l, hand: i.hand }));
|
|
1109
|
+
} else !o && a && this.release(a, i, n);
|
|
1110
|
+
i.hand === "pointer" && this.clickTap(i, o, r, n), this.pinched.set(i.hand, o);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
substep(t, s, n) {
|
|
1114
|
+
const i = this.settings;
|
|
1115
|
+
for (const o of this.bodies) {
|
|
1116
|
+
const r = o.grabbedBy ? s.get(o.grabbedBy) : void 0;
|
|
1117
|
+
r ? (v.t.addVectors(r.pinch, o.grabOffset), o.position.lerp(v.t, 1 - Math.exp(-30 * t)), o.velocity.copy(r.pinchVelocity), o.spin.multiplyScalar(Math.exp(-4 * t))) : (o.gravity && (o.velocity.y -= i.gravity * t), o.velocity.multiplyScalar(Math.exp(-i.damping * t)), o.velocity.clampLength(0, i.maxSpeed), o.spin.multiplyScalar(Math.exp(-i.damping * t)), o.position.addScaledVector(o.velocity, t)), this.turn(o, t), this.walls(o, t, !!r);
|
|
1118
|
+
}
|
|
1119
|
+
this.collideBodies(s), this.collideHands(s, n);
|
|
1120
|
+
}
|
|
1121
|
+
turn(t, s) {
|
|
1122
|
+
const n = t.spin.length() * s;
|
|
1123
|
+
n < 1e-9 || (v.axis.copy(t.spin).normalize(), v.q.setFromAxisAngle(v.axis, n), t.quaternion.premultiply(v.q).normalize());
|
|
1124
|
+
}
|
|
1125
|
+
walls(t, s, n) {
|
|
1126
|
+
const i = this.settings, { min: o, max: r } = this.bounds, a = t.bounce ?? i.bounce;
|
|
1127
|
+
let l = !1;
|
|
1128
|
+
for (const c of bn) {
|
|
1129
|
+
const f = o[c] + t.radius, p = Math.max(f, r[c] - t.radius);
|
|
1130
|
+
t.position[c] < f ? (t.position[c] = f, t.velocity[c] < 0 && (t.velocity[c] = n ? 0 : -t.velocity[c] * a), c === "y" && (l = !0)) : t.position[c] > p && (t.position[c] = p, t.velocity[c] > 0 && (t.velocity[c] = n ? 0 : -t.velocity[c] * a));
|
|
1131
|
+
}
|
|
1132
|
+
if (n) {
|
|
1133
|
+
t.resting = !1;
|
|
1134
|
+
return;
|
|
1135
|
+
}
|
|
1136
|
+
if (!l && t.position.y - (o.y + t.radius) < 1e-4 && t.velocity.y <= 0 && (l = !0), !l) {
|
|
1137
|
+
t.resting = !1;
|
|
1138
|
+
return;
|
|
1139
|
+
}
|
|
1140
|
+
Math.abs(t.velocity.y) < Mn && (t.velocity.y = 0);
|
|
1141
|
+
const u = Math.exp(-i.friction * s);
|
|
1142
|
+
t.velocity.x *= u, t.velocity.z *= u, t.shape === "sphere" ? t.spin.crossVectors(At, t.velocity).divideScalar(t.radius) : (t.spin.multiplyScalar(Math.exp(-10 * s)), this.settleFlat(t, s)), t.resting = t.velocity.lengthSq() < 0.05 * 0.05;
|
|
1143
|
+
}
|
|
1144
|
+
/** Turns a box toward its nearest face-down orientation. */
|
|
1145
|
+
settleFlat(t, s) {
|
|
1146
|
+
let n = 0, i = 0;
|
|
1147
|
+
pe.forEach((o, r) => {
|
|
1148
|
+
const a = v.v.copy(o).applyQuaternion(t.quaternion).y;
|
|
1149
|
+
Math.abs(a) > Math.abs(i) && (n = r, i = a);
|
|
1150
|
+
}), v.v.copy(pe[n]).applyQuaternion(t.quaternion).multiplyScalar(Math.sign(i) || 1), v.q2.setFromUnitVectors(v.v, At).multiply(t.quaternion), t.quaternion.slerp(v.q2, 1 - Math.exp(-10 * s));
|
|
1151
|
+
}
|
|
1152
|
+
collideBodies(t) {
|
|
1153
|
+
const { bodies: s } = this;
|
|
1154
|
+
for (let n = 0; n < s.length; n += 1)
|
|
1155
|
+
for (let i = n + 1; i < s.length; i += 1) {
|
|
1156
|
+
const o = s[n], r = s[i];
|
|
1157
|
+
v.d.subVectors(r.position, o.position);
|
|
1158
|
+
const a = v.d.length(), l = o.radius + r.radius;
|
|
1159
|
+
if (a >= l) continue;
|
|
1160
|
+
const u = o.grabbedBy && t.has(o.grabbedBy) ? 0 : 1 / o.mass, c = r.grabbedBy && t.has(r.grabbedBy) ? 0 : 1 / r.mass;
|
|
1161
|
+
if (u + c === 0) continue;
|
|
1162
|
+
a > 1e-9 ? v.n.copy(v.d).divideScalar(a) : v.n.copy(At);
|
|
1163
|
+
const f = (l - a) / (u + c);
|
|
1164
|
+
o.position.addScaledVector(v.n, -f * u), r.position.addScaledVector(v.n, f * c);
|
|
1165
|
+
const p = v.v.subVectors(r.velocity, o.velocity).dot(v.n);
|
|
1166
|
+
if (p >= 0) continue;
|
|
1167
|
+
const w = -(1 + Math.min(o.bounce ?? this.settings.bounce, r.bounce ?? this.settings.bounce)) * p / (u + c);
|
|
1168
|
+
o.velocity.addScaledVector(v.n, -w * u), r.velocity.addScaledVector(v.n, w * c);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
collideHands(t, s) {
|
|
1172
|
+
const n = this.settings, i = this.handSettings.pinchReady ?? Ee.pinchReady;
|
|
1173
|
+
for (const o of t.values()) {
|
|
1174
|
+
if (o.hand === "pointer" && !o.pinching) continue;
|
|
1175
|
+
const r = o.pinchDistance < i;
|
|
1176
|
+
for (const [a, l] of Sn(o))
|
|
1177
|
+
if (!(l.radius <= 0 || r && (a === "thumbTip" || a === "indexTip")))
|
|
1178
|
+
for (const u of this.bodies) {
|
|
1179
|
+
if (!u.pushable || u.grabbedBy) continue;
|
|
1180
|
+
v.d.subVectors(u.position, l.center), n.flat && (v.d.z = 0);
|
|
1181
|
+
const c = v.d.length(), f = u.radius + l.radius;
|
|
1182
|
+
if (c >= f) continue;
|
|
1183
|
+
c > 1e-9 ? v.n.copy(v.d).divideScalar(c) : v.n.copy(At), u.position.addScaledVector(v.n, f - c), v.v.subVectors(u.velocity, l.velocity);
|
|
1184
|
+
const p = v.v.dot(v.n);
|
|
1185
|
+
p < 0 && (u.velocity.addScaledVector(v.n, -(1 + (u.bounce ?? n.bounce)) * p), u.velocity.clampLength(0, n.maxSpeed)), v.t.copy(v.v).addScaledVector(v.n, -v.v.dot(v.n)).negate(), v.axis.crossVectors(v.n, v.t).divideScalar(-u.radius), u.spin.lerp(v.axis, wn);
|
|
1186
|
+
const g = `${o.hand}:${a}`, w = s.get(u) ?? /* @__PURE__ */ new Map();
|
|
1187
|
+
w.set(g, Math.max(w.get(g) ?? 0, Math.max(0, -p))), s.set(u, w);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
/** The pointer: a press and a quick release on the same object is a tap. */
|
|
1192
|
+
clickTap(t, s, n, i) {
|
|
1193
|
+
const o = this.reach(t, this.settings.grabReach);
|
|
1194
|
+
if (s && !n) {
|
|
1195
|
+
const r = this.pick(t.pinch, o, !0);
|
|
1196
|
+
this.press = r ? { body: r, timeMs: this.timeMs } : null;
|
|
1197
|
+
} else if (!s && n && this.press) {
|
|
1198
|
+
const { body: r, timeMs: a } = this.press;
|
|
1199
|
+
this.press = null, this.distance(r.position, t.pinch) - r.radius <= o && this.timeMs - a <= this.settings.tapMs && this.bodies.includes(r) && i.push({ type: "tap", body: r, hand: t.hand });
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
hoverAndTap(t, s) {
|
|
1203
|
+
const n = this.settings;
|
|
1204
|
+
for (const i of this.bodies) {
|
|
1205
|
+
let o = null;
|
|
1206
|
+
for (const r of t.values()) {
|
|
1207
|
+
const a = r.tips.indexTip, l = this.distance(i.position, a.center) - i.radius;
|
|
1208
|
+
if (l <= this.reach(r, n.hoverReach) && !i.grabbedBy && (o === null || i.hoveredBy === r.hand) && (o = r.hand), r.hand === "pointer") continue;
|
|
1209
|
+
const c = (i.radius + a.radius) * xn, f = (i.radius + a.radius) * vn, p = l + i.radius, g = i.tapStart[r.hand];
|
|
1210
|
+
if (g === void 0 && p < c && !i.grabbedBy) {
|
|
1211
|
+
v.d.subVectors(i.position, a.center), n.flat && (v.d.z = 0);
|
|
1212
|
+
const w = a.velocity.dot(v.d.normalize());
|
|
1213
|
+
i.tapStart[r.hand] = w >= n.tapSpeed * r.palmLength ? this.timeMs : NaN;
|
|
1214
|
+
} else g !== void 0 && (p > f || i.grabbedBy) && (delete i.tapStart[r.hand], !i.grabbedBy && this.timeMs - g <= n.tapMs && s.push({ type: "tap", body: i, hand: r.hand }));
|
|
1215
|
+
}
|
|
1216
|
+
for (const r of Object.keys(i.tapStart))
|
|
1217
|
+
t.has(r) || delete i.tapStart[r];
|
|
1218
|
+
o !== i.hoveredBy && (i.hoveredBy && s.push({ type: "hoverend", body: i, hand: i.hoveredBy }), o && s.push({ type: "hoverstart", body: i, hand: o }), i.hoveredBy = o);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
const An = 0.15, Tn = 0.6, Ve = Pt(null), Mi = () => Et(Ve), En = ["left", "right"], On = new h.Vector3(1, 1, 1), wi = ({
|
|
1223
|
+
hands: e = "both",
|
|
1224
|
+
pointer: t = !1,
|
|
1225
|
+
depth: s = Tn,
|
|
1226
|
+
floor: n = 0,
|
|
1227
|
+
bounds: i,
|
|
1228
|
+
showColliders: o = !1,
|
|
1229
|
+
onEvent: r,
|
|
1230
|
+
paused: a = !1,
|
|
1231
|
+
active: l = !0,
|
|
1232
|
+
children: u,
|
|
1233
|
+
palmRadius: c,
|
|
1234
|
+
tipRadius: f,
|
|
1235
|
+
pinchStart: p,
|
|
1236
|
+
pinchEnd: g,
|
|
1237
|
+
pinchReady: w,
|
|
1238
|
+
smoothing: T,
|
|
1239
|
+
...m
|
|
1240
|
+
}) => {
|
|
1241
|
+
const { node: k } = Ot(mt.HAND_TRACKER, void 0, l), I = gt((M) => M.camera), _ = gt((M) => M.gl), J = Object.fromEntries(
|
|
1242
|
+
Object.entries({ palmRadius: c, tipRadius: f, pinchStart: p, pinchEnd: g, pinchReady: w, smoothing: T }).filter(
|
|
1243
|
+
([, M]) => M !== void 0
|
|
1244
|
+
)
|
|
1245
|
+
), V = j(() => new kn(), []);
|
|
1246
|
+
V.settings = { ...Re, ..._n(m) }, V.setHandSettings(J);
|
|
1247
|
+
const N = Y(J);
|
|
1248
|
+
N.current = J;
|
|
1249
|
+
const F = j(
|
|
1250
|
+
() => ({
|
|
1251
|
+
left: Bt("left"),
|
|
1252
|
+
right: Bt("right"),
|
|
1253
|
+
pointer: Bt("pointer")
|
|
1254
|
+
}),
|
|
1255
|
+
[]
|
|
1256
|
+
), C = j(
|
|
1257
|
+
() => ({
|
|
1258
|
+
left: Zt.map(() => new h.Vector3()),
|
|
1259
|
+
right: Zt.map(() => new h.Vector3())
|
|
1260
|
+
}),
|
|
1261
|
+
[]
|
|
1262
|
+
), Q = j(() => /* @__PURE__ */ new Map(), []), et = Y(r);
|
|
1263
|
+
et.current = r;
|
|
1264
|
+
const P = Y({
|
|
1265
|
+
ndc: null,
|
|
1266
|
+
pressed: !1,
|
|
1267
|
+
clicked: !1,
|
|
1268
|
+
lifted: !1
|
|
1269
|
+
}), st = !!t, ut = (typeof t == "object" ? t.radius : void 0) ?? An;
|
|
1270
|
+
L(() => {
|
|
1271
|
+
if (!st) return;
|
|
1272
|
+
const M = _.domElement, b = P.current, D = M.style.touchAction;
|
|
1273
|
+
M.style.touchAction = "none";
|
|
1274
|
+
const O = (A) => {
|
|
1275
|
+
const y = M.getBoundingClientRect();
|
|
1276
|
+
b.ndc ?? (b.ndc = new h.Vector2()), b.ndc.set(
|
|
1277
|
+
(A.clientX - y.left) / y.width * 2 - 1,
|
|
1278
|
+
1 - (A.clientY - y.top) / y.height * 2
|
|
1279
|
+
);
|
|
1280
|
+
}, E = (A) => {
|
|
1281
|
+
O(A), b.pressed = !0, b.clicked = !0, b.lifted = !1;
|
|
1282
|
+
}, q = () => {
|
|
1283
|
+
b.pressed = !1;
|
|
1284
|
+
}, W = (A) => {
|
|
1285
|
+
b.pressed = !1, A.type === "pointerup" ? A.pointerType !== "mouse" && (b.lifted = !0) : b.ndc = null;
|
|
1286
|
+
};
|
|
1287
|
+
return M.addEventListener("pointermove", O), M.addEventListener("pointerdown", E), window.addEventListener("pointerup", q), M.addEventListener("pointerup", W), M.addEventListener("pointerleave", W), M.addEventListener("pointercancel", W), () => {
|
|
1288
|
+
M.style.touchAction = D, M.removeEventListener("pointermove", O), M.removeEventListener("pointerdown", E), window.removeEventListener("pointerup", q), M.removeEventListener("pointerup", W), M.removeEventListener("pointerleave", W), M.removeEventListener("pointercancel", W), b.ndc = null, b.pressed = !1, b.clicked = !1, b.lifted = !1;
|
|
1289
|
+
};
|
|
1290
|
+
}, [_, st]);
|
|
1291
|
+
const H = j(
|
|
1292
|
+
() => ({
|
|
1293
|
+
lo: new h.Vector3(),
|
|
1294
|
+
hi: new h.Vector3(),
|
|
1295
|
+
point: new h.Vector3(),
|
|
1296
|
+
matrix: new h.Matrix4(),
|
|
1297
|
+
inverse: new h.Matrix4()
|
|
1298
|
+
}),
|
|
1299
|
+
[]
|
|
1300
|
+
);
|
|
1301
|
+
Ct((M, b) => {
|
|
1302
|
+
var O, E, q, W;
|
|
1303
|
+
i ? (V.bounds.min.set(...i.min), V.bounds.max.set(...i.max)) : (Dt({ x: -1, y: -1 }, I, H.lo), Dt({ x: 1, y: 1 }, I, H.hi), V.bounds.min.set(
|
|
1304
|
+
Math.min(H.lo.x, H.hi.x),
|
|
1305
|
+
Math.min(H.lo.y, H.hi.y) + n,
|
|
1306
|
+
-s
|
|
1307
|
+
), V.bounds.max.set(Math.max(H.lo.x, H.hi.x), Math.max(H.lo.y, H.hi.y), s));
|
|
1308
|
+
for (const A of En) {
|
|
1309
|
+
const R = e === "both" || e === A ? ((O = k == null ? void 0 : k.getHandPose) == null ? void 0 : O.call(k, A)) ?? ((E = k == null ? void 0 : k.poses) == null ? void 0 : E[A]) ?? null : null;
|
|
1310
|
+
R && R.world.length >= 21 && R.image.length >= 21 ? (ns(R, I, C[A]), ue(
|
|
1311
|
+
F[A],
|
|
1312
|
+
C[A],
|
|
1313
|
+
R.timestampMs,
|
|
1314
|
+
N.current
|
|
1315
|
+
)) : ue(F[A], null, 0);
|
|
1316
|
+
}
|
|
1317
|
+
const D = P.current;
|
|
1318
|
+
if (mn(
|
|
1319
|
+
F.pointer,
|
|
1320
|
+
st && D.ndc ? Dt({ x: D.ndc.x, y: D.ndc.y }, I, H.point) : null,
|
|
1321
|
+
D.pressed || D.clicked,
|
|
1322
|
+
performance.now(),
|
|
1323
|
+
ut
|
|
1324
|
+
), D.lifted && !D.clicked && (D.ndc = null, D.lifted = !1), D.clicked = !1, !a) {
|
|
1325
|
+
const A = V.step(b, [F.left, F.right, F.pointer]);
|
|
1326
|
+
for (const y of A)
|
|
1327
|
+
(q = Q.get(y.body)) == null || q.onEvent.current(y), (W = et.current) == null || W.call(et, y);
|
|
1328
|
+
}
|
|
1329
|
+
for (const [A, { object: y }] of Q)
|
|
1330
|
+
H.matrix.compose(A.position, A.quaternion, On), y.parent && H.matrix.premultiply(H.inverse.copy(y.parent.matrixWorld).invert()), H.matrix.decompose(y.position, y.quaternion, H.point);
|
|
1331
|
+
});
|
|
1332
|
+
const S = j(
|
|
1333
|
+
() => ({
|
|
1334
|
+
world: V,
|
|
1335
|
+
hands: [F.left, F.right, F.pointer],
|
|
1336
|
+
register: (M, b) => (Q.set(M, b), () => {
|
|
1337
|
+
Q.delete(M);
|
|
1338
|
+
})
|
|
1339
|
+
}),
|
|
1340
|
+
[V, F, Q]
|
|
1341
|
+
);
|
|
1342
|
+
return /* @__PURE__ */ Ut(Ve.Provider, { value: S, children: [
|
|
1343
|
+
u,
|
|
1344
|
+
o && /* @__PURE__ */ tt(Rn, { hands: S.hands })
|
|
1345
|
+
] });
|
|
1346
|
+
}, _n = (e) => Object.fromEntries(Object.entries(e).filter(([, t]) => t !== void 0)), Rn = ({ hands: e }) => {
|
|
1347
|
+
const t = j(
|
|
1348
|
+
() => e.flatMap((o) => [
|
|
1349
|
+
{ hand: o, sphere: o.palm },
|
|
1350
|
+
...bt.map((r) => ({ hand: o, sphere: o.tips[r] }))
|
|
1351
|
+
]),
|
|
1352
|
+
[e]
|
|
1353
|
+
), s = j(() => new h.SphereGeometry(1, 20, 12), []), n = j(
|
|
1354
|
+
() => ({
|
|
1355
|
+
open: new h.MeshBasicMaterial({
|
|
1356
|
+
color: 8246268,
|
|
1357
|
+
transparent: !0,
|
|
1358
|
+
opacity: 0.35,
|
|
1359
|
+
depthWrite: !1
|
|
1360
|
+
}),
|
|
1361
|
+
pinch: new h.MeshBasicMaterial({
|
|
1362
|
+
color: 16020150,
|
|
1363
|
+
transparent: !0,
|
|
1364
|
+
opacity: 0.5,
|
|
1365
|
+
depthWrite: !1
|
|
1366
|
+
})
|
|
1367
|
+
}),
|
|
1368
|
+
[]
|
|
1369
|
+
);
|
|
1370
|
+
L(
|
|
1371
|
+
() => () => {
|
|
1372
|
+
s.dispose(), n.open.dispose(), n.pinch.dispose();
|
|
1373
|
+
},
|
|
1374
|
+
[s, n]
|
|
1375
|
+
);
|
|
1376
|
+
const i = Y([]);
|
|
1377
|
+
return Ct(() => {
|
|
1378
|
+
t.forEach(({ hand: o, sphere: r }, a) => {
|
|
1379
|
+
const l = i.current[a];
|
|
1380
|
+
l && (l.visible = o.tracked && r.radius > 0, l.position.copy(r.center), l.scale.setScalar(Math.max(r.radius, 1e-6)), l.material = o.pinching ? n.pinch : n.open);
|
|
1381
|
+
});
|
|
1382
|
+
}), /* @__PURE__ */ tt("group", { name: "HandTouchColliders", children: t.map((o, r) => /* @__PURE__ */ tt(
|
|
1383
|
+
"mesh",
|
|
1384
|
+
{
|
|
1385
|
+
ref: (a) => {
|
|
1386
|
+
i.current[r] = a;
|
|
1387
|
+
},
|
|
1388
|
+
geometry: s,
|
|
1389
|
+
material: n.open,
|
|
1390
|
+
renderOrder: 10,
|
|
1391
|
+
frustumCulled: !1,
|
|
1392
|
+
visible: !1
|
|
1393
|
+
},
|
|
1394
|
+
r
|
|
1395
|
+
)) });
|
|
1396
|
+
}, rt = (e) => Number.isFinite(e) ? Math.max(0, Math.min(1, e)) : 0, yt = (e, t) => Math.hypot(e.x - t.x, e.y - t.y), U = {
|
|
1397
|
+
wrist: 0,
|
|
1398
|
+
thumbTip: 4,
|
|
1399
|
+
indexBase: 5,
|
|
1400
|
+
indexTip: 8,
|
|
1401
|
+
middleBase: 9,
|
|
1402
|
+
middleTip: 12,
|
|
1403
|
+
ringBase: 13,
|
|
1404
|
+
ringTip: 16,
|
|
1405
|
+
pinkyBase: 17,
|
|
1406
|
+
pinkyTip: 20
|
|
1407
|
+
}, Rt = [
|
|
1408
|
+
[U.indexBase, U.indexTip],
|
|
1409
|
+
[U.middleBase, U.middleTip],
|
|
1410
|
+
[U.ringBase, U.ringTip],
|
|
1411
|
+
[U.pinkyBase, U.pinkyTip]
|
|
1412
|
+
], ht = (e) => e !== void 0 && e.length >= 21, Gt = (e) => ht(e) ? yt(e[U.wrist], e[U.middleBase]) : 0, xi = (e) => {
|
|
1413
|
+
if (!ht(e)) return 0;
|
|
1414
|
+
const t = Gt(e);
|
|
1415
|
+
if (t <= 0) return 0;
|
|
1416
|
+
const s = yt(e[U.thumbTip], e[U.indexTip]) / t;
|
|
1417
|
+
return rt(1 - (s - 0.15) / 0.85);
|
|
1418
|
+
}, Ie = (e, t, s) => {
|
|
1419
|
+
const n = e[U.wrist], i = yt(e[t], n);
|
|
1420
|
+
if (i <= 0) return 0;
|
|
1421
|
+
const o = yt(e[s], n) / i;
|
|
1422
|
+
return rt((1.6 - o) / 0.6);
|
|
1423
|
+
}, Vn = (e, t = [0, 0, 0, 0]) => {
|
|
1424
|
+
for (let s = 0; s < Rt.length; s += 1) {
|
|
1425
|
+
const [n, i] = Rt[s];
|
|
1426
|
+
t[s] = 1 - Ie(e, n, i);
|
|
1427
|
+
}
|
|
1428
|
+
return t;
|
|
1429
|
+
}, We = (e) => {
|
|
1430
|
+
const t = Gt(e);
|
|
1431
|
+
if (t <= 0) return 0;
|
|
1432
|
+
const s = yt(e[U.thumbTip], e[U.indexBase]) / t;
|
|
1433
|
+
return rt((s - 0.45) / 0.5);
|
|
1434
|
+
}, de = (e) => {
|
|
1435
|
+
const t = Gt(e);
|
|
1436
|
+
if (t <= 0) return 0;
|
|
1437
|
+
const s = (e[U.thumbTip].y - e[U.indexBase].y) / t;
|
|
1438
|
+
return Math.max(-1, Math.min(1, s / 0.6));
|
|
1439
|
+
}, In = (e, t) => {
|
|
1440
|
+
if (!ht(e)) return 0;
|
|
1441
|
+
const s = Vn(e);
|
|
1442
|
+
let n = 1;
|
|
1443
|
+
for (let i = 0; i < 4; i += 1) {
|
|
1444
|
+
const o = t.fingers[i];
|
|
1445
|
+
o !== null && (n = Math.min(n, o ? s[i] : 1 - s[i]));
|
|
1446
|
+
}
|
|
1447
|
+
if (t.thumb !== void 0 && t.thumb !== null) {
|
|
1448
|
+
const i = We(e);
|
|
1449
|
+
n = Math.min(n, t.thumb ? i : 1 - i);
|
|
1450
|
+
}
|
|
1451
|
+
return n;
|
|
1452
|
+
}, vi = (e, t) => {
|
|
1453
|
+
if (!ht(e)) return 0;
|
|
1454
|
+
const s = In(e, { fingers: [!1, !1, !1, !1] }), n = rt(t === "up" ? de(e) : -de(e));
|
|
1455
|
+
return Math.min(s, We(e), n);
|
|
1456
|
+
}, Wn = (e) => {
|
|
1457
|
+
if (!ht(e)) return 0;
|
|
1458
|
+
let t = 0;
|
|
1459
|
+
for (const [s, n] of Rt) t += Ie(e, s, n);
|
|
1460
|
+
return t / Rt.length;
|
|
1461
|
+
}, bi = (e) => ht(e) ? 1 - Wn(e) : 0, Si = (e) => ht(e) ? rt((e[U.wrist].y + 1) / 2) : 0, ot = {
|
|
1462
|
+
leftShoulder: 11,
|
|
1463
|
+
rightShoulder: 12,
|
|
1464
|
+
leftElbow: 13,
|
|
1465
|
+
rightElbow: 14,
|
|
1466
|
+
leftWrist: 15,
|
|
1467
|
+
rightWrist: 16,
|
|
1468
|
+
leftHip: 23,
|
|
1469
|
+
rightHip: 24
|
|
1470
|
+
}, De = (e) => e !== void 0 && e.length >= 33, Fe = (e) => yt(e[ot.leftShoulder], e[ot.rightShoulder]), ki = (e, t, s = !1) => {
|
|
1471
|
+
if (!De(e)) return 0;
|
|
1472
|
+
const n = Fe(e);
|
|
1473
|
+
if (n <= 0) return 0;
|
|
1474
|
+
const i = Ye(t, s), o = e[i === "left" ? ot.leftWrist : ot.rightWrist], r = e[i === "left" ? ot.leftShoulder : ot.rightShoulder];
|
|
1475
|
+
return rt((o.y - r.y) / n);
|
|
1476
|
+
}, Ai = (e) => {
|
|
1477
|
+
if (!De(e)) return 0;
|
|
1478
|
+
const t = Fe(e);
|
|
1479
|
+
if (t <= 0) return 0;
|
|
1480
|
+
let s = 1;
|
|
1481
|
+
for (const n of ["left", "right"]) {
|
|
1482
|
+
const i = e[n === "left" ? ot.leftWrist : ot.rightWrist], o = e[n === "left" ? ot.leftShoulder : ot.rightShoulder], r = rt(1 - Math.abs(i.y - o.y) / (t * 0.5)), a = n === "left" ? i.x - o.x : o.x - i.x, l = rt(a / t);
|
|
1483
|
+
s = Math.min(s, r, l);
|
|
1484
|
+
}
|
|
1485
|
+
return s;
|
|
1486
|
+
};
|
|
1487
|
+
class Dn {
|
|
1488
|
+
constructor(t) {
|
|
1489
|
+
x(this, "reversals", []);
|
|
1490
|
+
/** Running extreme in the current direction (max rising, min falling). */
|
|
1491
|
+
x(this, "extreme", null);
|
|
1492
|
+
/** Range seen before the first swing (direction still unknown). */
|
|
1493
|
+
x(this, "low", 0);
|
|
1494
|
+
x(this, "high", 0);
|
|
1495
|
+
x(this, "direction", 0);
|
|
1496
|
+
this.options = t;
|
|
1497
|
+
}
|
|
1498
|
+
reset() {
|
|
1499
|
+
this.reversals = [], this.extreme = null, this.direction = 0;
|
|
1500
|
+
}
|
|
1501
|
+
/** Feed one sample; returns the oscillation progress 0..1. */
|
|
1502
|
+
push(t, s) {
|
|
1503
|
+
const { minAmplitude: n } = this.options;
|
|
1504
|
+
return this.extreme === null ? (this.extreme = t, this.low = t, this.high = t, this.direction = 0, this.progress(s)) : (this.direction === 0 ? t - this.low >= n ? (this.direction = 1, this.extreme = t) : this.high - t >= n ? (this.direction = -1, this.extreme = t) : (this.low = Math.min(this.low, t), this.high = Math.max(this.high, t)) : (this.direction > 0 ? t > this.extreme : t < this.extreme) ? this.extreme = t : Math.abs(this.extreme - t) >= n && (this.reversals.push(s), this.direction = -this.direction, this.extreme = t), this.progress(s));
|
|
1505
|
+
}
|
|
1506
|
+
progress(t) {
|
|
1507
|
+
const { requiredReversals: s, windowMs: n } = this.options;
|
|
1508
|
+
for (; this.reversals.length > 0 && t - this.reversals[0] > n; )
|
|
1509
|
+
this.reversals.shift();
|
|
1510
|
+
return rt(this.reversals.length / s);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
const Ne = {
|
|
1514
|
+
nose: G.nose,
|
|
1515
|
+
leftShoulder: G.leftShoulder,
|
|
1516
|
+
rightShoulder: G.rightShoulder,
|
|
1517
|
+
leftElbow: G.leftElbow,
|
|
1518
|
+
rightElbow: G.rightElbow,
|
|
1519
|
+
leftWrist: G.leftWrist,
|
|
1520
|
+
rightWrist: G.rightWrist,
|
|
1521
|
+
leftIndex: G.leftIndex,
|
|
1522
|
+
rightIndex: G.rightIndex,
|
|
1523
|
+
leftHip: G.leftHip,
|
|
1524
|
+
rightHip: G.rightHip,
|
|
1525
|
+
leftKnee: G.leftKnee,
|
|
1526
|
+
rightKnee: G.rightKnee,
|
|
1527
|
+
leftAnkle: G.leftAnkle,
|
|
1528
|
+
rightAnkle: G.rightAnkle
|
|
1529
|
+
}, Fn = Object.keys(Ne), Nn = [
|
|
1530
|
+
"leftShoulder",
|
|
1531
|
+
"rightShoulder",
|
|
1532
|
+
"leftElbow",
|
|
1533
|
+
"rightElbow",
|
|
1534
|
+
"leftWrist",
|
|
1535
|
+
"rightWrist"
|
|
1536
|
+
], Bn = [
|
|
1537
|
+
"leftShoulder",
|
|
1538
|
+
"rightShoulder",
|
|
1539
|
+
"leftHip",
|
|
1540
|
+
"rightHip",
|
|
1541
|
+
"leftKnee",
|
|
1542
|
+
"rightKnee",
|
|
1543
|
+
"leftAnkle",
|
|
1544
|
+
"rightAnkle"
|
|
1545
|
+
], fe = Object.freeze({
|
|
1546
|
+
/** MediaPipe visibility at or above which a joint counts. */
|
|
1547
|
+
visible: 0.2,
|
|
1548
|
+
/**
|
|
1549
|
+
* How far past the frame edge a joint may sit (frame units: each axis spans
|
|
1550
|
+
* −1..1), so an ankle right at the edge, feet partly cropped, still counts.
|
|
1551
|
+
*/
|
|
1552
|
+
edge: 0.12
|
|
1553
|
+
}), Ti = (e, { mirrored: t = !1, visibility: s, limits: n, aspect: i = 1, view: o } = {}) => {
|
|
1554
|
+
if (e.length < se)
|
|
1555
|
+
throw new Error(
|
|
1556
|
+
`createBodyMoveFrame needs MediaPipe's ${se} pose landmarks (got ${e.length})`
|
|
1557
|
+
);
|
|
1558
|
+
const r = is(e, i), a = os(r, { mirrored: t, visibility: s, limits: n }), l = (o == null ? void 0 : o.visible) ?? fe.visible, u = 1 + ((o == null ? void 0 : o.edge) ?? fe.edge), c = {}, f = {}, p = {};
|
|
1559
|
+
for (const m of Fn) {
|
|
1560
|
+
const k = Ne[Qe(m, t)], I = e[k];
|
|
1561
|
+
c[m] = r[k], f[m] = (s == null ? void 0 : s[k]) ?? 1, p[m] = f[m] >= l && Math.abs(I.x) <= u && Math.abs(I.y) <= u;
|
|
1562
|
+
}
|
|
1563
|
+
const g = (c.leftShoulder.y + c.rightShoulder.y) / 2, w = (c.leftHip.y + c.rightHip.y) / 2, T = c.leftShoulder.x - c.rightShoulder.x;
|
|
1564
|
+
return {
|
|
1565
|
+
shape: a,
|
|
1566
|
+
landmarks: e,
|
|
1567
|
+
joints: c,
|
|
1568
|
+
visibility: f,
|
|
1569
|
+
seen: p,
|
|
1570
|
+
shoulderWidth: a.shoulderWidth,
|
|
1571
|
+
torso: Math.max(0, g - w),
|
|
1572
|
+
leftward: Math.abs(T) > 1e-6 ? T > 0 ? 1 : -1 : t ? -1 : 1,
|
|
1573
|
+
upperInView: Nn.every((m) => p[m]),
|
|
1574
|
+
fullInView: Bn.every((m) => p[m]),
|
|
1575
|
+
mirrored: t,
|
|
1576
|
+
aspect: i
|
|
1577
|
+
};
|
|
1578
|
+
}, Hn = Object.fromEntries(
|
|
1579
|
+
["left", "right"].map((e) => [
|
|
1580
|
+
e,
|
|
1581
|
+
Object.fromEntries(
|
|
1582
|
+
["Shoulder", "Elbow", "Wrist", "Index", "Hip", "Knee", "Ankle"].map((t) => [
|
|
1583
|
+
t,
|
|
1584
|
+
`${e}${t}`
|
|
1585
|
+
])
|
|
1586
|
+
)
|
|
1587
|
+
])
|
|
1588
|
+
), B = (e, t) => Hn[e][t], Mt = (e, t) => e.seen[B(t, "Shoulder")] && e.seen[B(t, "Elbow")] && e.seen[B(t, "Wrist")], qt = Object.freeze({
|
|
1589
|
+
/** `jump`: shoulders, hips and both ankles rise at least this far above standing (torso lengths) … */
|
|
1590
|
+
jumpRise: 0.12,
|
|
1591
|
+
/** … and it lands when both ankles are back within this of the ground. */
|
|
1592
|
+
jumpLand: 0.06,
|
|
1593
|
+
/** Longer in the air than this is not a jump (the camera moved): the move ends and re-levels. */
|
|
1594
|
+
jumpMaxAirMs: 900,
|
|
1595
|
+
/** The standing level follows the body with this time constant (ms), so slow drift never jumps. */
|
|
1596
|
+
jumpLevelMs: 300,
|
|
1597
|
+
/**
|
|
1598
|
+
* `squat`: hips down when the thigh's height falls to this × the shin's
|
|
1599
|
+
* (standing ≈ 1, thighs level ≈ 0), on the straighter leg …
|
|
1600
|
+
*/
|
|
1601
|
+
squatDown: 0.6,
|
|
1602
|
+
/** … and back up (the rep ends, the next can start) above this. */
|
|
1603
|
+
squatUp: 0.85,
|
|
1604
|
+
/** `wave`: the forearm points up (wrist above the elbow by at least this, shoulder widths) … */
|
|
1605
|
+
waveForearmUp: 0.25,
|
|
1606
|
+
/** … and swings side to side by at least this between turning points … */
|
|
1607
|
+
waveAmplitude: 0.3,
|
|
1608
|
+
/** … this many turning points … */
|
|
1609
|
+
waveReversals: 3,
|
|
1610
|
+
/** … within this long (ms). */
|
|
1611
|
+
waveWindowMs: 1500,
|
|
1612
|
+
/** `clap`: the hands were at least this far apart (shoulder widths) … */
|
|
1613
|
+
clapApart: 0.6,
|
|
1614
|
+
/** … then meet within this … */
|
|
1615
|
+
clapTogether: 0.3,
|
|
1616
|
+
/** … in at most this long (ms). */
|
|
1617
|
+
clapWithinMs: 250,
|
|
1618
|
+
/** The clap ends when the hands part past this. */
|
|
1619
|
+
clapRelease: 0.45,
|
|
1620
|
+
/**
|
|
1621
|
+
* `punch`: the arm was bent (shoulder → wrist ÷ upper arm + forearm, 1 =
|
|
1622
|
+
* straight, read in 3D) below this …
|
|
1623
|
+
*/
|
|
1624
|
+
punchBent: 0.75,
|
|
1625
|
+
/** … then straightens past this … */
|
|
1626
|
+
punchStraight: 0.93,
|
|
1627
|
+
/** … within this long (ms) … */
|
|
1628
|
+
punchWithinMs: 200,
|
|
1629
|
+
/** … with the wrist within this of shoulder height (shoulder widths): not a raise or a drop. */
|
|
1630
|
+
punchBand: 0.9,
|
|
1631
|
+
/** `armFlap`: both wrists drop at least this far (shoulder widths) … */
|
|
1632
|
+
flapStroke: 0.7,
|
|
1633
|
+
/** … within this long (ms) … */
|
|
1634
|
+
flapWithinMs: 500,
|
|
1635
|
+
/** … from a top no lower than this relative to the shoulders (arms up like wings, not lowered from the front) … */
|
|
1636
|
+
flapTop: -0.4,
|
|
1637
|
+
/** … with both wrists out past their shoulders by at least this. */
|
|
1638
|
+
flapOut: 0.3,
|
|
1639
|
+
/** `kick`: the foot rises at least this far above the standing foot (torso lengths) … */
|
|
1640
|
+
kickLift: 0.35,
|
|
1641
|
+
/** … the knee at least this far above the standing knee … */
|
|
1642
|
+
kickKnee: 0.15,
|
|
1643
|
+
/**
|
|
1644
|
+
* … and the lower leg swings up: the foot hangs below its knee by at most
|
|
1645
|
+
* this × the standing shin (a march's foot hangs ≈ 1 below the knee) …
|
|
1646
|
+
*/
|
|
1647
|
+
kickShin: 0.6,
|
|
1648
|
+
/** … in at most this long from the foot leaving the ground (ms). */
|
|
1649
|
+
kickWithinMs: 600,
|
|
1650
|
+
/** `stepLeft` / `stepRight`: hips and feet move sideways at least this far (shoulder widths) … */
|
|
1651
|
+
stepShift: 0.5,
|
|
1652
|
+
/** … within this long (ms). */
|
|
1653
|
+
stepWithinMs: 700,
|
|
1654
|
+
/** `march`: a knee or foot rises at least this far above the other one (torso lengths) … */
|
|
1655
|
+
marchLift: 0.2,
|
|
1656
|
+
/** … and comes back down below this … */
|
|
1657
|
+
marchDrop: 0.08,
|
|
1658
|
+
/** … alternating: the other leg lifted at most this long before (ms). */
|
|
1659
|
+
marchWithinMs: 1200
|
|
1660
|
+
}), Ei = (e) => {
|
|
1661
|
+
if (typeof e.measure != "function" || typeof e.createMemory != "function")
|
|
1662
|
+
throw new Error("defineBodyMove needs createMemory and measure functions");
|
|
1663
|
+
return e;
|
|
1664
|
+
};
|
|
1665
|
+
class Vt {
|
|
1666
|
+
constructor(t = 64) {
|
|
1667
|
+
x(this, "times");
|
|
1668
|
+
x(this, "values");
|
|
1669
|
+
x(this, "start", 0);
|
|
1670
|
+
x(this, "count", 0);
|
|
1671
|
+
this.capacity = t, this.times = new Float64Array(t), this.values = new Float64Array(t);
|
|
1672
|
+
}
|
|
1673
|
+
clear() {
|
|
1674
|
+
this.start = 0, this.count = 0;
|
|
1675
|
+
}
|
|
1676
|
+
push(t, s) {
|
|
1677
|
+
const n = (this.start + this.count) % this.capacity;
|
|
1678
|
+
this.times[n] = t, this.values[n] = s, this.count < this.capacity ? this.count += 1 : this.start = (this.start + 1) % this.capacity;
|
|
1679
|
+
}
|
|
1680
|
+
/** Largest value at or after `sinceMs` (−Infinity when none). */
|
|
1681
|
+
max(t) {
|
|
1682
|
+
let s = -1 / 0;
|
|
1683
|
+
for (let n = 0; n < this.count; n += 1) {
|
|
1684
|
+
const i = (this.start + n) % this.capacity;
|
|
1685
|
+
this.times[i] >= t && this.values[i] > s && (s = this.values[i]);
|
|
1686
|
+
}
|
|
1687
|
+
return s;
|
|
1688
|
+
}
|
|
1689
|
+
/** Smallest value at or after `sinceMs` (Infinity when none). */
|
|
1690
|
+
min(t) {
|
|
1691
|
+
let s = 1 / 0;
|
|
1692
|
+
for (let n = 0; n < this.count; n += 1) {
|
|
1693
|
+
const i = (this.start + n) % this.capacity;
|
|
1694
|
+
this.times[i] >= t && this.values[i] < s && (s = this.values[i]);
|
|
1695
|
+
}
|
|
1696
|
+
return s;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
const It = ["left", "right"], wt = (e) => e === "left" ? "right" : "left", vt = (e, t) => t === "either" || t === e, $ = { value: 0, side: null }, jn = {
|
|
1700
|
+
left: { value: 1, side: "left" },
|
|
1701
|
+
right: { value: 1, side: "right" },
|
|
1702
|
+
none: { value: 1, side: null }
|
|
1703
|
+
}, X = (e) => jn[e ?? "none"], lt = {
|
|
1704
|
+
enterThreshold: 0.5,
|
|
1705
|
+
exitThreshold: 0.5,
|
|
1706
|
+
holdMs: 0,
|
|
1707
|
+
lostGraceMs: 250
|
|
1708
|
+
}, Be = (e) => e.seen.leftShoulder && e.seen.rightShoulder && Mt(e, "left") && Mt(e, "right"), He = (e, { side: t }) => e.seen.leftShoulder && e.seen.rightShoulder && (vt("left", t) && Mt(e, "left") || vt("right", t) && Mt(e, "right")), St = (e) => e.fullInView && e.torso > 1e-3, qn = {
|
|
1709
|
+
name: "jump",
|
|
1710
|
+
label: "Jump",
|
|
1711
|
+
description: "Shoulders, hips and both feet rise together above the standing level (a fast rise), then land.",
|
|
1712
|
+
view: "full",
|
|
1713
|
+
limitKeys: ["jumpRise", "jumpLand", "jumpMaxAirMs", "jumpLevelMs"],
|
|
1714
|
+
defaults: { ...lt, cooldownMs: 150 },
|
|
1715
|
+
createMemory: () => ({ level: null, lastMs: 0, airborne: !1, airSinceMs: 0 }),
|
|
1716
|
+
inView: St,
|
|
1717
|
+
measure: (e, t, s, { limits: n }) => {
|
|
1718
|
+
const { joints: i, torso: o } = e, r = (i.leftShoulder.y + i.rightShoulder.y) / 2, a = (i.leftHip.y + i.rightHip.y) / 2, l = i.leftAnkle.y, u = i.rightAnkle.y, c = t.level;
|
|
1719
|
+
if (!c)
|
|
1720
|
+
return t.level = { shoulders: r, hips: a, left: l, right: u }, t.lastMs = s, $;
|
|
1721
|
+
const f = Math.max(0, s - t.lastMs);
|
|
1722
|
+
t.lastMs = s;
|
|
1723
|
+
const p = (w, T) => (w - T) / o;
|
|
1724
|
+
if (t.airborne) {
|
|
1725
|
+
const w = p(l, c.left) <= n.jumpLand && p(u, c.right) <= n.jumpLand, T = s - t.airSinceMs > n.jumpMaxAirMs;
|
|
1726
|
+
return !w && !T ? X(null) : (t.airborne = !1, T && Object.assign(c, { shoulders: r, hips: a, left: l, right: u }), $);
|
|
1727
|
+
}
|
|
1728
|
+
if (p(r, c.shoulders) >= n.jumpRise && p(a, c.hips) >= n.jumpRise && p(l, c.left) >= n.jumpRise && p(u, c.right) >= n.jumpRise)
|
|
1729
|
+
return t.airborne = !0, t.airSinceMs = s, X(null);
|
|
1730
|
+
const g = 1 - Math.exp(-f / Math.max(1, n.jumpLevelMs));
|
|
1731
|
+
return c.shoulders += (r - c.shoulders) * g, c.hips += (a - c.hips) * g, c.left += (l - c.left) * g, c.right += (u - c.right) * g, $;
|
|
1732
|
+
}
|
|
1733
|
+
}, me = (e, t) => {
|
|
1734
|
+
const s = e.joints[B(t, "Hip")], n = e.joints[B(t, "Knee")], i = e.joints[B(t, "Ankle")], o = n.y - i.y;
|
|
1735
|
+
return o > 1e-4 ? (s.y - n.y) / o : null;
|
|
1736
|
+
}, Pn = {
|
|
1737
|
+
name: "squat",
|
|
1738
|
+
label: "Squat",
|
|
1739
|
+
description: "From standing, both thighs drop toward level (the hips sink to the knees), then the body stands back up.",
|
|
1740
|
+
view: "full",
|
|
1741
|
+
limitKeys: ["squatDown", "squatUp"],
|
|
1742
|
+
defaults: { ...lt, cooldownMs: 200 },
|
|
1743
|
+
createMemory: () => ({ ready: !1, down: !1 }),
|
|
1744
|
+
inView: St,
|
|
1745
|
+
measure: (e, t, s, { limits: n }) => {
|
|
1746
|
+
const i = me(e, "left"), o = me(e, "right");
|
|
1747
|
+
if (i === null || o === null) return t.down ? X(null) : $;
|
|
1748
|
+
const r = Math.max(i, o), a = Math.abs(e.joints.leftAnkle.y - e.joints.rightAnkle.y) / e.torso <= 0.25;
|
|
1749
|
+
return t.down ? r < n.squatUp ? X(null) : (t.down = !1, t.ready = !0, $) : (r >= n.squatUp && (t.ready = !0), t.ready && a && r <= n.squatDown ? (t.ready = !1, t.down = !0, X(null)) : $);
|
|
1750
|
+
}
|
|
1751
|
+
}, ge = (e) => {
|
|
1752
|
+
const t = () => new Dn({
|
|
1753
|
+
minAmplitude: e.waveAmplitude,
|
|
1754
|
+
requiredReversals: Math.max(1, Math.round(e.waveReversals)),
|
|
1755
|
+
windowMs: e.waveWindowMs
|
|
1756
|
+
});
|
|
1757
|
+
return {
|
|
1758
|
+
built: { amplitude: e.waveAmplitude, reversals: e.waveReversals, windowMs: e.waveWindowMs },
|
|
1759
|
+
left: t(),
|
|
1760
|
+
right: t(),
|
|
1761
|
+
sample: { value: 0, side: null }
|
|
1762
|
+
};
|
|
1763
|
+
}, Un = {
|
|
1764
|
+
name: "wave",
|
|
1765
|
+
label: "Wave",
|
|
1766
|
+
description: "A forearm held up swings side to side about the elbow: three turning points of 0.3 shoulder widths within 1.5 s.",
|
|
1767
|
+
view: "upper",
|
|
1768
|
+
sided: !0,
|
|
1769
|
+
limitKeys: ["waveForearmUp", "waveAmplitude", "waveReversals", "waveWindowMs"],
|
|
1770
|
+
// Like the hand / face oscillations: begin at full progress, end once the swinging stops.
|
|
1771
|
+
defaults: { enterThreshold: 0.99, exitThreshold: 0.3, cooldownMs: 600, lostGraceMs: 250 },
|
|
1772
|
+
createMemory: () => ge(qt),
|
|
1773
|
+
inView: He,
|
|
1774
|
+
measure: (e, t, s, { side: n, limits: i }) => {
|
|
1775
|
+
const { built: o } = t;
|
|
1776
|
+
(o.amplitude !== i.waveAmplitude || o.reversals !== i.waveReversals || o.windowMs !== i.waveWindowMs) && Object.assign(t, ge(i));
|
|
1777
|
+
const r = e.shoulderWidth;
|
|
1778
|
+
let a = 0, l = null;
|
|
1779
|
+
for (const u of It) {
|
|
1780
|
+
if (!vt(u, n)) continue;
|
|
1781
|
+
const c = t[u], f = e.joints[B(u, "Elbow")], p = e.joints[B(u, "Wrist")];
|
|
1782
|
+
if (!Mt(e, u) || (p.y - f.y) / r < i.waveForearmUp) {
|
|
1783
|
+
c.reset();
|
|
1784
|
+
continue;
|
|
1785
|
+
}
|
|
1786
|
+
const g = c.push((p.x - f.x) / r, s);
|
|
1787
|
+
g > a && (a = g, l = u);
|
|
1788
|
+
}
|
|
1789
|
+
return a <= 0 ? $ : (t.sample.value = a, t.sample.side = l, t.sample);
|
|
1790
|
+
}
|
|
1791
|
+
}, Tt = (e, t, s) => {
|
|
1792
|
+
const n = e.joints[B(t, "Wrist")][s];
|
|
1793
|
+
return e.seen[B(t, "Index")] ? (n + e.joints[B(t, "Index")][s]) / 2 : n;
|
|
1794
|
+
}, Cn = {
|
|
1795
|
+
name: "clap",
|
|
1796
|
+
label: "Clap",
|
|
1797
|
+
description: "The hands come together fast (apart to touching within 0.25 s); ends when they part. Each clap counts.",
|
|
1798
|
+
view: "upper",
|
|
1799
|
+
limitKeys: ["clapApart", "clapTogether", "clapWithinMs", "clapRelease"],
|
|
1800
|
+
defaults: { ...lt, cooldownMs: 100 },
|
|
1801
|
+
createMemory: () => ({ apartAtMs: -1 / 0, clapped: !1 }),
|
|
1802
|
+
inView: Be,
|
|
1803
|
+
measure: (e, t, s, { limits: n }) => {
|
|
1804
|
+
const i = Math.hypot(
|
|
1805
|
+
Tt(e, "left", "x") - Tt(e, "right", "x"),
|
|
1806
|
+
Tt(e, "left", "y") - Tt(e, "right", "y")
|
|
1807
|
+
) / e.shoulderWidth;
|
|
1808
|
+
if (t.clapped) {
|
|
1809
|
+
if (i < n.clapRelease) return X(null);
|
|
1810
|
+
t.clapped = !1;
|
|
1811
|
+
}
|
|
1812
|
+
return i >= n.clapApart && (t.apartAtMs = s), i <= n.clapTogether && s - t.apartAtMs <= n.clapWithinMs ? (t.clapped = !0, t.apartAtMs = -1 / 0, X(null)) : $;
|
|
1813
|
+
}
|
|
1814
|
+
}, zn = (e, t) => {
|
|
1815
|
+
const s = e.joints[B(t, "Shoulder")], n = e.joints[B(t, "Elbow")], i = e.joints[B(t, "Wrist")], o = (a, l) => Math.hypot(a.x - l.x, a.y - l.y, 2 * (a.z - l.z)), r = o(s, n) + o(n, i);
|
|
1816
|
+
return r < 0.1 * e.shoulderWidth ? null : o(s, i) / r;
|
|
1817
|
+
}, Ln = {
|
|
1818
|
+
name: "punch",
|
|
1819
|
+
label: "Punch",
|
|
1820
|
+
description: "An arm snaps from bent to straight (within 0.2 s) at shoulder height, toward the camera or to the side; ends when it bends back.",
|
|
1821
|
+
view: "upper",
|
|
1822
|
+
sided: !0,
|
|
1823
|
+
limitKeys: ["punchBent", "punchStraight", "punchWithinMs", "punchBand"],
|
|
1824
|
+
defaults: { ...lt, cooldownMs: 150 },
|
|
1825
|
+
createMemory: () => ({
|
|
1826
|
+
left: { bentAtMs: -1 / 0, punching: !1 },
|
|
1827
|
+
right: { bentAtMs: -1 / 0, punching: !1 }
|
|
1828
|
+
}),
|
|
1829
|
+
inView: He,
|
|
1830
|
+
measure: (e, t, s, { side: n, limits: i }) => {
|
|
1831
|
+
let o = null;
|
|
1832
|
+
for (const r of It) {
|
|
1833
|
+
const a = t[r];
|
|
1834
|
+
if (!vt(r, n) || !Mt(e, r)) {
|
|
1835
|
+
a.punching = !1, a.bentAtMs = -1 / 0;
|
|
1836
|
+
continue;
|
|
1837
|
+
}
|
|
1838
|
+
const l = zn(e, r);
|
|
1839
|
+
if (l === null) {
|
|
1840
|
+
a.punching && (o ?? (o = r));
|
|
1841
|
+
continue;
|
|
1842
|
+
}
|
|
1843
|
+
const u = e.joints[B(r, "Shoulder")], c = e.joints[B(r, "Wrist")], f = Math.abs(c.y - u.y) / e.shoulderWidth <= i.punchBand;
|
|
1844
|
+
if (a.punching) {
|
|
1845
|
+
if (l >= i.punchStraight - 0.1 && f) {
|
|
1846
|
+
o ?? (o = r);
|
|
1847
|
+
continue;
|
|
1848
|
+
}
|
|
1849
|
+
a.punching = !1;
|
|
1850
|
+
}
|
|
1851
|
+
l <= i.punchBent ? a.bentAtMs = s : l >= i.punchStraight && f && s - a.bentAtMs <= i.punchWithinMs && (a.punching = !0, a.bentAtMs = -1 / 0, o ?? (o = r));
|
|
1852
|
+
}
|
|
1853
|
+
return o ? X(o) : $;
|
|
1854
|
+
}
|
|
1855
|
+
}, Kn = {
|
|
1856
|
+
name: "armFlap",
|
|
1857
|
+
label: "Flap your arms",
|
|
1858
|
+
description: "Both arms, held out to the sides, beat down together (a wing stroke of 0.7 shoulder widths within 0.5 s). Each downstroke counts.",
|
|
1859
|
+
view: "upper",
|
|
1860
|
+
limitKeys: ["flapStroke", "flapWithinMs", "flapTop", "flapOut"],
|
|
1861
|
+
defaults: { ...lt, cooldownMs: 100 },
|
|
1862
|
+
createMemory: () => ({ left: new Vt(), right: new Vt(), flapping: !1 }),
|
|
1863
|
+
inView: Be,
|
|
1864
|
+
measure: (e, t, s, { limits: n }) => {
|
|
1865
|
+
const { left: i, right: o } = e.shape.arms;
|
|
1866
|
+
t.left.push(s, i.up), t.right.push(s, o.up);
|
|
1867
|
+
const r = s - n.flapWithinMs, a = t.left.max(r), l = t.right.max(r), u = Math.min(a - i.up, l - o.up);
|
|
1868
|
+
return t.flapping ? u >= n.flapStroke * 0.5 ? X(null) : (t.flapping = !1, $) : u >= n.flapStroke && Math.min(a, l) >= n.flapTop && i.out >= n.flapOut && o.out >= n.flapOut ? (t.flapping = !0, X(null)) : $;
|
|
1869
|
+
}
|
|
1870
|
+
}, Gn = {
|
|
1871
|
+
name: "kick",
|
|
1872
|
+
label: "Kick",
|
|
1873
|
+
description: "One foot swings up fast (forward or to the side) with the knee lifted and the lower leg raised, not hanging; ends when the foot is down.",
|
|
1874
|
+
view: "full",
|
|
1875
|
+
sided: !0,
|
|
1876
|
+
limitKeys: ["kickLift", "kickKnee", "kickShin", "kickWithinMs"],
|
|
1877
|
+
defaults: { ...lt, cooldownMs: 300 },
|
|
1878
|
+
createMemory: () => ({
|
|
1879
|
+
left: { downAtMs: -1 / 0, kicking: !1 },
|
|
1880
|
+
right: { downAtMs: -1 / 0, kicking: !1 }
|
|
1881
|
+
}),
|
|
1882
|
+
inView: St,
|
|
1883
|
+
measure: (e, t, s, { side: n, limits: i }) => {
|
|
1884
|
+
const { joints: o, torso: r } = e;
|
|
1885
|
+
let a = null;
|
|
1886
|
+
for (const l of It) {
|
|
1887
|
+
const u = t[l], c = o[B(l, "Knee")], f = o[B(l, "Ankle")], p = o[B(wt(l), "Knee")], g = o[B(wt(l), "Ankle")], w = (f.y - g.y) / r;
|
|
1888
|
+
if (u.kicking) {
|
|
1889
|
+
if (w > i.kickLift * 0.4) {
|
|
1890
|
+
a ?? (a = l);
|
|
1891
|
+
continue;
|
|
1892
|
+
}
|
|
1893
|
+
u.kicking = !1;
|
|
1894
|
+
}
|
|
1895
|
+
if (w <= i.kickLift * 0.3 && (u.downAtMs = s), !vt(l, n)) continue;
|
|
1896
|
+
const T = p.y - g.y;
|
|
1897
|
+
if (T <= 1e-4) continue;
|
|
1898
|
+
const m = (c.y - p.y) / r, k = (c.y - f.y) / T;
|
|
1899
|
+
w >= i.kickLift && m >= i.kickKnee && k <= i.kickShin && s - u.downAtMs <= i.kickWithinMs && (u.kicking = !0, a ?? (a = l));
|
|
1900
|
+
}
|
|
1901
|
+
return a ? X(a) : $;
|
|
1902
|
+
}
|
|
1903
|
+
}, Yn = 150, ye = (e) => ({
|
|
1904
|
+
name: e === "left" ? "stepLeft" : "stepRight",
|
|
1905
|
+
label: e === "left" ? "Step to your left" : "Step to your right",
|
|
1906
|
+
description: `Hips and both feet move to the person's own ${e} by half a shoulder width within 0.7 s; ends when the body settles.`,
|
|
1907
|
+
view: "full",
|
|
1908
|
+
limitKeys: ["stepShift", "stepWithinMs"],
|
|
1909
|
+
defaults: { ...lt, cooldownMs: 300 },
|
|
1910
|
+
createMemory: () => ({
|
|
1911
|
+
hips: new Vt(),
|
|
1912
|
+
feet: new Vt(),
|
|
1913
|
+
stepping: !1,
|
|
1914
|
+
peak: 0,
|
|
1915
|
+
peakAtMs: 0
|
|
1916
|
+
}),
|
|
1917
|
+
inView: St,
|
|
1918
|
+
measure: (t, s, n, { limits: i }) => {
|
|
1919
|
+
const { joints: o } = t, r = (e === "left" ? 1 : -1) * t.leftward, a = r * (o.leftHip.x + o.rightHip.x) / 2, l = r * (o.leftAnkle.x + o.rightAnkle.x) / 2, u = t.shoulderWidth;
|
|
1920
|
+
if (s.stepping) {
|
|
1921
|
+
if (a > s.peak && (s.peak = a, s.peakAtMs = n), !(n - s.peakAtMs >= Yn || (s.peak - a) / u > 0.15)) return X(e);
|
|
1922
|
+
s.stepping = !1, s.hips.clear(), s.feet.clear();
|
|
1923
|
+
}
|
|
1924
|
+
s.hips.push(n, a), s.feet.push(n, l);
|
|
1925
|
+
const c = n - i.stepWithinMs, f = (a - s.hips.min(c)) / u, p = (l - s.feet.min(c)) / u;
|
|
1926
|
+
return f >= i.stepShift && p >= i.stepShift * 0.8 ? (s.stepping = !0, s.peak = a, s.peakAtMs = n, X(e)) : $;
|
|
1927
|
+
}
|
|
1928
|
+
}), Qn = {
|
|
1929
|
+
name: "march",
|
|
1930
|
+
label: "March in place",
|
|
1931
|
+
description: "Knees (or feet) lift in turn, marching or running in place. Each alternating lift counts as one step; the first lift only starts the count.",
|
|
1932
|
+
view: "full",
|
|
1933
|
+
limitKeys: ["marchLift", "marchDrop", "marchWithinMs"],
|
|
1934
|
+
defaults: { ...lt, cooldownMs: 0 },
|
|
1935
|
+
createMemory: () => ({
|
|
1936
|
+
up: { left: !1, right: !1 },
|
|
1937
|
+
liftedAtMs: { left: -1 / 0, right: -1 / 0 },
|
|
1938
|
+
stepping: null
|
|
1939
|
+
}),
|
|
1940
|
+
inView: St,
|
|
1941
|
+
measure: (e, t, s, { limits: n }) => {
|
|
1942
|
+
const { joints: i, torso: o } = e;
|
|
1943
|
+
for (const r of It) {
|
|
1944
|
+
const a = i[B(r, "Knee")], l = i[B(r, "Ankle")], u = i[B(wt(r), "Knee")], c = i[B(wt(r), "Ankle")], f = Math.max(a.y - u.y, l.y - c.y) / o;
|
|
1945
|
+
t.up[r] ? f <= n.marchDrop && (t.up[r] = !1) : f >= n.marchLift && (t.up[r] = !0, s - t.liftedAtMs[wt(r)] <= n.marchWithinMs && (t.stepping = r), t.liftedAtMs[r] = s);
|
|
1946
|
+
}
|
|
1947
|
+
return t.stepping && !t.up[t.stepping] && (t.stepping = null), t.stepping ? X(t.stepping) : $;
|
|
1948
|
+
}
|
|
1949
|
+
}, je = {
|
|
1950
|
+
jump: qn,
|
|
1951
|
+
squat: Pn,
|
|
1952
|
+
wave: Un,
|
|
1953
|
+
clap: Cn,
|
|
1954
|
+
punch: Ln,
|
|
1955
|
+
armFlap: Kn,
|
|
1956
|
+
kick: Gn,
|
|
1957
|
+
stepLeft: ye("left"),
|
|
1958
|
+
stepRight: ye("right"),
|
|
1959
|
+
march: Qn
|
|
1960
|
+
}, Oi = Object.keys(je), Yt = (e) => typeof e == "string" ? je[e] : e, $n = (e) => e ? { ...qt, ...e } : qt, Xn = Object.freeze({
|
|
1961
|
+
enterThreshold: 0.6,
|
|
1962
|
+
exitThreshold: 0.25,
|
|
1963
|
+
holdMs: 150,
|
|
1964
|
+
lostGraceMs: 250
|
|
1965
|
+
}), Jn = 80, Zn = (e) => {
|
|
1966
|
+
if (typeof e == "function") return "upper";
|
|
1967
|
+
const t = xe(e);
|
|
1968
|
+
if (t) return t.view === "full" ? "full" : "upper";
|
|
1969
|
+
const s = (n) => n.legs !== void 0 || n.squat !== void 0 || n.wideStance !== void 0 || n.lean !== void 0 && n.lean !== "none" || (n.anyOf ?? []).some(s);
|
|
1970
|
+
return s(e) ? "full" : "upper";
|
|
1971
|
+
}, ti = (e) => {
|
|
1972
|
+
var s;
|
|
1973
|
+
if (e.move !== void 0) return Yt(e.move).name;
|
|
1974
|
+
const t = e.pose;
|
|
1975
|
+
return typeof t == "string" ? t : ((s = xe(t)) == null ? void 0 : s.label) ?? "pose";
|
|
1976
|
+
}, qe = (e, t = {}) => ie(
|
|
1977
|
+
t,
|
|
1978
|
+
ie(
|
|
1979
|
+
e.move !== void 0 ? Yt(e.move).defaults : Xn
|
|
1980
|
+
)
|
|
1981
|
+
), Pe = ({ side: e = "either", limits: t, ...s }) => ({
|
|
1982
|
+
engine: s,
|
|
1983
|
+
context: { side: e, limits: $n(t) }
|
|
1984
|
+
}), _i = (e, t = {}) => {
|
|
1985
|
+
const s = ti(e), n = e.move !== void 0 ? Yt(e.move) : null, i = e.move !== void 0 ? null : e.pose, { engine: o, context: r } = Pe(t), a = cs(s);
|
|
1986
|
+
return {
|
|
1987
|
+
...ve(a),
|
|
1988
|
+
kind: n ? "move" : "pose",
|
|
1989
|
+
view: n ? n.view : Zn(i),
|
|
1990
|
+
inView: !1,
|
|
1991
|
+
side: null,
|
|
1992
|
+
pose: i,
|
|
1993
|
+
move: n,
|
|
1994
|
+
memory: n ? n.createMemory() : null,
|
|
1995
|
+
memoryUsed: !1,
|
|
1996
|
+
detector: a,
|
|
1997
|
+
options: qe(e, o),
|
|
1998
|
+
context: r,
|
|
1999
|
+
sample: null,
|
|
2000
|
+
sampleSide: null,
|
|
2001
|
+
lastSampleMs: null
|
|
2002
|
+
};
|
|
2003
|
+
}, Ri = (e, t, s = {}) => {
|
|
2004
|
+
const { engine: n, context: i } = Pe(s);
|
|
2005
|
+
e.options = qe(t, n), e.context = i;
|
|
2006
|
+
}, Ht = (e) => {
|
|
2007
|
+
e.move && e.memoryUsed && (e.memory = e.move.createMemory(), e.memoryUsed = !1), e.lastSampleMs = null;
|
|
2008
|
+
}, ei = (e, t, s) => {
|
|
2009
|
+
if (e.sampleSide = null, !t) {
|
|
2010
|
+
e.inView = !1, e.sample = null, Ht(e);
|
|
2011
|
+
return;
|
|
2012
|
+
}
|
|
2013
|
+
const n = e.sample ?? { value: 0, confidence: 0 };
|
|
2014
|
+
if (e.sample = n, e.pose !== null) {
|
|
2015
|
+
const a = t.shape.upperBodyVisible;
|
|
2016
|
+
if (e.inView = a && (e.view !== "full" || t.shape.lowerBodyVisible), !a) {
|
|
2017
|
+
Ht(e), n.value = 0, n.confidence = 0;
|
|
2018
|
+
return;
|
|
2019
|
+
}
|
|
2020
|
+
const l = rs(t.shape, e.pose) ? 1 : 0;
|
|
2021
|
+
n.value = e.lastSampleMs === null ? l : n.value + (l - n.value) * (1 - Math.exp(-(s - e.lastSampleMs) / Jn)), n.confidence = 1, e.lastSampleMs = s;
|
|
2022
|
+
return;
|
|
2023
|
+
}
|
|
2024
|
+
const i = e.move, o = e.context;
|
|
2025
|
+
if (e.inView = i.inView ? i.inView(t, o) : i.view === "full" ? t.fullInView && t.torso > 0 : t.upperInView, !e.inView) {
|
|
2026
|
+
Ht(e), n.value = 0, n.confidence = 0;
|
|
2027
|
+
return;
|
|
2028
|
+
}
|
|
2029
|
+
const r = i.measure(t, e.memory, s, o);
|
|
2030
|
+
e.memoryUsed = !0, e.lastSampleMs = s, n.value = Number.isFinite(r.value) ? r.value : 0, n.confidence = 1, e.sampleSide = r.side ?? null;
|
|
2031
|
+
}, Vi = (e, t, s, n = !0) => {
|
|
2032
|
+
(n || !t) && ei(e, t, s);
|
|
2033
|
+
const i = hs(e.detector, e.sample, s, e.options);
|
|
2034
|
+
return i.justBegan && (e.side = e.sampleSide), ve(i, e), e;
|
|
2035
|
+
}, Ii = (e, t) => {
|
|
2036
|
+
const s = t ?? {};
|
|
2037
|
+
return s.name = e.name, s.active = e.active, s.value = e.value, s.confidence = e.confidence, s.tracked = e.tracked, s.phase = e.phase, s.justBegan = e.justBegan, s.justEnded = e.justEnded, s.endReason = e.endReason, s.startedAtMs = e.startedAtMs, s.durationMs = e.durationMs, s.count = e.count, s.kind = e.kind, s.view = e.view, s.inView = e.inView, s.side = e.side, s;
|
|
2038
|
+
}, Wi = (e, t) => ls(e, t) && e.kind === t.kind && e.view === t.view && e.inView === t.inView && e.side === t.side;
|
|
2039
|
+
export {
|
|
2040
|
+
$n as $,
|
|
2041
|
+
yi as A,
|
|
2042
|
+
Js as B,
|
|
2043
|
+
Zs as C,
|
|
2044
|
+
Tn as D,
|
|
2045
|
+
An as E,
|
|
2046
|
+
Ks as F,
|
|
2047
|
+
wi as G,
|
|
2048
|
+
Kt as H,
|
|
2049
|
+
Mi as I,
|
|
2050
|
+
Ee as J,
|
|
2051
|
+
bt as K,
|
|
2052
|
+
je as L,
|
|
2053
|
+
qt as M,
|
|
2054
|
+
Oi as N,
|
|
2055
|
+
Dn as O,
|
|
2056
|
+
fe as P,
|
|
2057
|
+
Ei as Q,
|
|
2058
|
+
fi as R,
|
|
2059
|
+
U as S,
|
|
2060
|
+
Re as T,
|
|
2061
|
+
ot as U,
|
|
2062
|
+
Vn as V,
|
|
2063
|
+
Cs as W,
|
|
2064
|
+
de as X,
|
|
2065
|
+
We as Y,
|
|
2066
|
+
Xn as Z,
|
|
2067
|
+
Vt as _,
|
|
2068
|
+
Ve as a,
|
|
2069
|
+
qe as a0,
|
|
2070
|
+
B as a1,
|
|
2071
|
+
Lt as a2,
|
|
2072
|
+
Xs as a3,
|
|
2073
|
+
$s as a4,
|
|
2074
|
+
tn as a5,
|
|
2075
|
+
rn as a6,
|
|
2076
|
+
en as a7,
|
|
2077
|
+
nn as a8,
|
|
2078
|
+
gi as a9,
|
|
2079
|
+
cn as aa,
|
|
2080
|
+
Te as ab,
|
|
2081
|
+
Os as ac,
|
|
2082
|
+
ps as ad,
|
|
2083
|
+
ds as ae,
|
|
2084
|
+
fs as af,
|
|
2085
|
+
xs as ag,
|
|
2086
|
+
be as ah,
|
|
2087
|
+
Ms as ai,
|
|
2088
|
+
ks as aj,
|
|
2089
|
+
As as ak,
|
|
2090
|
+
Se as al,
|
|
2091
|
+
vs as am,
|
|
2092
|
+
xt as an,
|
|
2093
|
+
re as ao,
|
|
2094
|
+
Bs as ap,
|
|
2095
|
+
Ae as aq,
|
|
2096
|
+
Hs as ar,
|
|
2097
|
+
Is as as,
|
|
2098
|
+
Ws as at,
|
|
2099
|
+
kn as au,
|
|
2100
|
+
Bt as av,
|
|
2101
|
+
mn as aw,
|
|
2102
|
+
ue as ax,
|
|
2103
|
+
ki as b,
|
|
2104
|
+
vi as c,
|
|
2105
|
+
In as d,
|
|
2106
|
+
Si as e,
|
|
2107
|
+
bi as f,
|
|
2108
|
+
Wn as g,
|
|
2109
|
+
xi as h,
|
|
2110
|
+
_i as i,
|
|
2111
|
+
Ri as j,
|
|
2112
|
+
Vi as k,
|
|
2113
|
+
Wi as l,
|
|
2114
|
+
Ai as m,
|
|
2115
|
+
Ti as n,
|
|
2116
|
+
qs as o,
|
|
2117
|
+
Ls as p,
|
|
2118
|
+
Rs as q,
|
|
2119
|
+
Yt as r,
|
|
2120
|
+
Ii as s,
|
|
2121
|
+
_s as t,
|
|
2122
|
+
Vs as u,
|
|
2123
|
+
Es as v,
|
|
2124
|
+
Ts as w,
|
|
2125
|
+
ke as x,
|
|
2126
|
+
Ys as y,
|
|
2127
|
+
mi as z
|
|
2128
|
+
};
|