@vincentt-xr/sdk 2.0.0-alpha.1 → 2.0.0-alpha.3
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 +1614 -21
- package/dist/{DebuggerUI-CatYc-RG.cjs → DebuggerUI-B45_Gb9d.cjs} +1 -1
- package/dist/{DebuggerUI-gLMKiVwJ.js → DebuggerUI-xp4bg3gH.js} +1 -1
- package/dist/FaceMeshRenderer-CALA4k49.js +1195 -0
- package/dist/FaceMeshRenderer-D4PFqsb3.cjs +155 -0
- package/dist/FaceRetouch-Bq2rtPlV.cjs +134 -0
- package/dist/FaceRetouch-DF5UsOsZ.js +551 -0
- package/dist/audio/AudioEngine.d.ts +3 -1
- package/dist/audio/AudioPlayer.d.ts +29 -0
- package/dist/audio/AudioPlayerLogic.d.ts +4 -0
- package/dist/audio/index.d.ts +2 -0
- package/dist/components/Axes/index.d.ts +6 -0
- package/dist/components/FaceMesh/FaceMeshRenderer.d.ts +17 -0
- package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +17 -1
- package/dist/components/FaceMesh/canonical/FaceMeshMaterial.d.ts +25 -0
- package/dist/components/FaceMesh/canonical/assets.d.ts +3 -0
- package/dist/components/FaceMesh/canonical/geometryGroups.d.ts +9 -0
- package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +2 -0
- package/dist/components/FaceMesh/canonical/shaders.d.ts +2 -0
- package/dist/components/FaceMesh/deform.d.ts +3 -0
- package/dist/components/FaceMesh/index.d.ts +5 -0
- package/dist/components/FaceMesh/material/defaults.d.ts +70 -0
- package/dist/components/FaceMesh/material/index.d.ts +1 -0
- package/dist/components/FaceMesh/material/options.d.ts +5 -1
- package/dist/components/FaceMesh/material/support.d.ts +7 -2
- package/dist/components/FaceMesh/material/textures.d.ts +4 -0
- package/dist/components/FaceMesh/material/types.d.ts +2 -2
- package/dist/components/FaceRetouch/Background.d.ts +5 -6
- package/dist/components/FaceRetouch/FaceRetouch.d.ts +47 -0
- package/dist/components/FaceRetouch/index.d.ts +2 -8
- package/dist/components/FaceRetouch/landmarkMask.d.ts +0 -5
- package/dist/components/FaceRetouch/useFaceRetouchMask.d.ts +3 -7
- package/dist/components/FaceTracker/index.d.ts +5 -3
- package/dist/components/FaceWarp3D/FaceWarp3DHead.d.ts +1 -1
- package/dist/components/HandJoints2D/index.d.ts +1 -1
- package/dist/components/HandTracking2D/HandVisual.d.ts +1 -1
- package/dist/components/HandTracking2D/index.d.ts +1 -1
- package/dist/components/HandTracking2DController/index.d.ts +1 -1
- package/dist/components/HandTracking3D/index.d.ts +1 -1
- package/dist/components/LightObject/index.d.ts +20 -0
- package/dist/components/LookAt/index.d.ts +23 -0
- package/dist/components/MeshRenderer/index.d.ts +59 -0
- package/dist/components/PerspectiveCamera/index.d.ts +2 -8
- package/dist/components/PinToMesh/index.d.ts +47 -0
- package/dist/components/RenderGroupLayer/index.d.ts +6 -0
- package/dist/components/SceneObjectRenderer/index.d.ts +16 -0
- package/dist/components/Screen2D/ScreenTransformFrame.d.ts +11 -0
- package/dist/components/Screen2D/ScreenTransformHelpers.d.ts +19 -0
- package/dist/components/Screen2D/ScreenTransformInteraction.d.ts +18 -0
- package/dist/components/Screen2D/index.d.ts +5 -0
- package/dist/components/ScreenGlass/defaults.d.ts +3 -0
- package/dist/components/ScreenGlass/index.d.ts +5 -0
- package/dist/components/ScreenGlass/shaders.d.ts +2 -0
- package/dist/components/ScreenGlass/types.d.ts +10 -0
- package/dist/components/ScreenGradient/defaults.d.ts +5 -0
- package/dist/components/ScreenGradient/index.d.ts +5 -0
- package/dist/components/ScreenGradient/shaders.d.ts +2 -0
- package/dist/components/ScreenGradient/types.d.ts +19 -0
- package/dist/components/ScreenImage/ScreenImage.d.ts +4 -0
- package/dist/components/ScreenImage/components/DynamicTextureSync.d.ts +9 -0
- package/dist/components/ScreenImage/components/ScreenImageBody.d.ts +9 -0
- package/dist/components/ScreenImage/components/ScreenImageFrame.d.ts +9 -0
- package/dist/components/ScreenImage/components/ScreenImageTransformFrame.d.ts +9 -0
- package/dist/components/ScreenImage/fit.d.ts +52 -0
- package/dist/components/ScreenImage/index.d.ts +8 -87
- package/dist/components/ScreenImage/materials/ScreenImageBlendMaterial.d.ts +9 -0
- package/dist/components/ScreenImage/materials/ScreenImageMatcap.d.ts +3 -0
- package/dist/components/ScreenImage/source.d.ts +19 -0
- package/dist/components/ScreenImage/types.d.ts +37 -0
- package/dist/components/ScreenImage/utils/ScreenImageConstants.d.ts +9 -0
- package/dist/components/ScreenImage/utils/ScreenImageHelpers.d.ts +4 -0
- package/dist/components/ScreenShape/geometry.d.ts +5 -0
- package/dist/components/ScreenShape/index.d.ts +5 -0
- package/dist/components/ScreenShape/types.d.ts +41 -0
- package/dist/components/ScreenSpaceUI/ScreenTransformGuide.d.ts +15 -0
- package/dist/components/ScreenSpaceUI/ScreenTransformOverlayGuide.d.ts +9 -0
- package/dist/components/ScreenSpaceUI/index.d.ts +2 -0
- package/dist/components/ScreenText/components/ScreenTextBody.d.ts +2 -0
- package/dist/components/ScreenText/components/ScreenTextTransformFrame.d.ts +9 -0
- package/dist/components/ScreenText/constants.d.ts +5 -0
- package/dist/components/ScreenText/index.d.ts +6 -20
- package/dist/components/ScreenText/types.d.ts +31 -0
- package/dist/components/ScreenText/utils/ScreenTextHelpers.d.ts +14 -0
- package/dist/components/ScreenText/utils/ScreenTextMappings.d.ts +17 -0
- package/dist/components/SequentialRenderPasses/index.d.ts +6 -0
- package/dist/components/TextLabel/TextLabel.d.ts +5 -0
- package/dist/components/TextLabel/alignment.d.ts +4 -0
- package/dist/components/TextLabel/bend.d.ts +9 -0
- package/dist/components/TextLabel/canvas/buildTextLabelTexture.d.ts +4 -0
- package/dist/components/TextLabel/canvas/canvasTypography.d.ts +13 -0
- package/dist/components/TextLabel/canvas/drawBackground.d.ts +21 -0
- package/dist/components/TextLabel/canvas/drawEffects.d.ts +34 -0
- package/dist/components/TextLabel/canvas/drawText.d.ts +19 -0
- package/dist/components/TextLabel/components/TextLabelMesh.d.ts +13 -0
- package/dist/components/TextLabel/constants.d.ts +2 -0
- package/dist/components/TextLabel/hooks/useTextLabelTexture.d.ts +7 -0
- package/dist/components/TextLabel/index.d.ts +2 -161
- package/dist/components/TextLabel/layout/measurement.d.ts +8 -0
- package/dist/components/TextLabel/layout/resolveTextLayout.d.ts +25 -0
- package/dist/components/TextLabel/layout/wrapText.d.ts +6 -0
- package/dist/components/TextLabel/types.d.ts +227 -0
- package/dist/components/TrackingAnchor/index.d.ts +18 -2
- package/dist/components/Transform3D/index.d.ts +30 -0
- package/dist/components/XRMediaSurface/index.d.ts +6 -6
- package/dist/components/XRViewport/XRViewport.d.ts +11 -0
- package/dist/components/XRViewport/components/HiddenMedia.d.ts +7 -0
- package/dist/components/XRViewport/components/MediaAssetPicker.d.ts +8 -0
- package/dist/components/XRViewport/components/MediaControlStack.d.ts +13 -0
- package/dist/components/XRViewport/components/XRViewportLayers.d.ts +30 -0
- package/dist/components/XRViewport/constants.d.ts +24 -0
- package/dist/components/XRViewport/contexts.d.ts +6 -0
- package/dist/components/XRViewport/hooks/useViewportExternalFaces.d.ts +13 -0
- package/dist/components/XRViewport/hooks/useViewportMediaSource.d.ts +16 -0
- package/dist/components/XRViewport/hooks/useViewportMediaTexture.d.ts +10 -0
- package/dist/components/XRViewport/hooks/useViewportPipeline.d.ts +41 -0
- package/dist/components/XRViewport/hooks/useViewportRenderState.d.ts +47 -0
- package/dist/components/XRViewport/index.d.ts +3 -118
- package/dist/components/XRViewport/layout.d.ts +16 -0
- package/dist/components/XRViewport/slots.d.ts +16 -0
- package/dist/components/XRViewport/types.d.ts +89 -0
- package/dist/components/XRViewport/useViewportSize.d.ts +3 -0
- package/dist/components/index.d.ts +12 -0
- package/dist/contexts-D5TQcwmv.js +660 -0
- package/dist/contexts-Dv1SA0bS.cjs +1 -0
- package/dist/debug-ui/component-editor/index.d.ts +19 -0
- package/dist/debug-ui/face-mesh-renderer-settings/index.d.ts +8 -0
- package/dist/debug-ui/face-retouch/index.d.ts +11 -0
- package/dist/debug-ui/hand-joints-2d/index.d.ts +1 -1
- package/dist/debug-ui/hand-tracking-2d/index.d.ts +1 -1
- package/dist/debug-ui/hand-tracking-2d-controller/index.d.ts +1 -1
- package/dist/debug-ui/hand-tracking-3d/index.d.ts +1 -1
- package/dist/debug-ui/hierarchy-panel/index.d.ts +29 -0
- package/dist/debug-ui/index.d.ts +25 -2
- package/dist/debug-ui/layer-panel/index.d.ts +3 -2
- package/dist/debug-ui/media-source/index.d.ts +2 -0
- package/dist/debug-ui/media-source/session.d.ts +12 -0
- package/dist/debug-ui/media-source.cjs +1 -1
- package/dist/debug-ui/media-source.js +6 -4
- package/dist/debug-ui/mesh-renderer-settings/index.d.ts +6 -0
- package/dist/debug-ui/object-inspector-panel/index.d.ts +25 -0
- package/dist/debug-ui/pin-to-mesh-settings/index.d.ts +10 -0
- package/dist/debug-ui/scene-editor/context.d.ts +38 -0
- package/dist/debug-ui/scene-editor/hierarchy-panel.d.ts +9 -0
- package/dist/debug-ui/scene-editor/index.d.ts +11 -0
- package/dist/debug-ui/scene-editor/inspector-panel.d.ts +7 -0
- package/dist/debug-ui/scene-editor/store-utils.d.ts +2 -0
- package/dist/debug-ui/scene-editor/viewport-toolbar.d.ts +4 -0
- package/dist/debug-ui/scene-editor/viewport.d.ts +21 -0
- package/dist/debug-ui/screen-glass-settings/index.d.ts +6 -0
- package/dist/debug-ui/screen-gradient-settings/GradientStopsEditor.d.ts +5 -0
- package/dist/debug-ui/screen-gradient-settings/index.d.ts +6 -0
- package/dist/debug-ui/screen-gradient-settings/styles.d.ts +3 -0
- package/dist/debug-ui/screen-image-settings/index.d.ts +4 -2
- package/dist/debug-ui/screen-shape-settings/index.d.ts +6 -0
- package/dist/debug-ui/screen-text-settings/NumberField.d.ts +9 -0
- package/dist/debug-ui/screen-text-settings/ScreenTextSettingsPanel.d.ts +3 -0
- package/dist/debug-ui/screen-text-settings/controls/NestedSection.d.ts +7 -0
- package/dist/debug-ui/screen-text-settings/controls/Section.d.ts +8 -0
- package/dist/debug-ui/screen-text-settings/controls/icons.d.ts +4 -0
- package/dist/debug-ui/screen-text-settings/index.d.ts +2 -122
- package/dist/debug-ui/screen-text-settings/sections/BackgroundSection.d.ts +8 -0
- package/dist/debug-ui/screen-text-settings/sections/ContentSection.d.ts +5 -0
- package/dist/debug-ui/screen-text-settings/sections/EffectsSection.d.ts +25 -0
- package/dist/debug-ui/screen-text-settings/sections/StyleSection.d.ts +5 -0
- package/dist/debug-ui/screen-text-settings/sections/TransformSection.d.ts +5 -0
- package/dist/debug-ui/screen-text-settings/sections/background/BackgroundFillControls.d.ts +2 -0
- package/dist/debug-ui/screen-text-settings/sections/background/BackgroundSizeControls.d.ts +2 -0
- package/dist/debug-ui/screen-text-settings/sections/background/BackgroundStrokeControls.d.ts +2 -0
- package/dist/debug-ui/screen-text-settings/sections/background/types.d.ts +7 -0
- package/dist/debug-ui/screen-text-settings/sections/effects/BendEffectSection.d.ts +4 -0
- package/dist/debug-ui/screen-text-settings/sections/effects/EffectChrome.d.ts +21 -0
- package/dist/debug-ui/screen-text-settings/sections/effects/GlowEffectSection.d.ts +4 -0
- package/dist/debug-ui/screen-text-settings/sections/effects/InnerShadowEffectSection.d.ts +4 -0
- package/dist/debug-ui/screen-text-settings/sections/effects/OutlineEffectSection.d.ts +4 -0
- package/dist/debug-ui/screen-text-settings/sections/effects/ShadowEffectSection.d.ts +4 -0
- package/dist/debug-ui/screen-text-settings/sections/effects/types.d.ts +14 -0
- package/dist/debug-ui/screen-text-settings/settings.d.ts +90 -0
- package/dist/debug-ui/screen-text-settings/styles.d.ts +26 -0
- package/dist/debug-ui/screen-text-settings/transform.d.ts +6 -0
- package/dist/debug-ui/screen-text-settings/types.d.ts +9 -0
- package/dist/debug-ui/shared/ScreenTransformSection.d.ts +6 -3
- package/dist/debug-ui/transform-3d-settings/index.d.ts +11 -0
- package/dist/debug-ui.cjs +3 -13
- package/dist/debug-ui.js +7735 -4896
- package/dist/drawNormalizedCrop-B-7zU-Xw.cjs +1 -0
- package/dist/drawNormalizedCrop-CRdIDyl1.js +44 -0
- package/dist/entries/all.d.ts +1 -0
- package/dist/entries/core.d.ts +53 -6
- package/dist/entries/face-effects.d.ts +10 -8
- package/dist/entries/internal.d.ts +1 -1
- package/dist/entries/low-level.d.ts +21 -4
- package/dist/entries/scene-object.d.ts +10 -0
- package/dist/entries/tracking.d.ts +25 -2
- package/dist/face-action/index.d.ts +34 -0
- package/dist/face-attribute-expression/index.d.ts +10 -0
- package/dist/face-effects.cjs +1 -342
- package/dist/face-effects.js +1391 -2767
- package/dist/face-info/blendshapes.d.ts +3 -0
- package/dist/face-info/derive.d.ts +8 -0
- package/dist/face-info/drawFaceCrop.d.ts +10 -0
- package/dist/face-info/getFaceInfo.d.ts +8 -0
- package/dist/face-info/index.d.ts +8 -0
- package/dist/face-info/landmarks.d.ts +21 -0
- package/dist/face-info/types.d.ts +52 -0
- package/dist/getFaceInfo-Cjcgcc4w.js +118 -0
- package/dist/getFaceInfo-oQcP40Ha.cjs +1 -0
- package/dist/{handJoints2d.d.ts → hand/handJoints2d.d.ts} +1 -1
- package/dist/{handTracking2d.d.ts → hand/handTracking2d.d.ts} +1 -1
- package/dist/{handTracking2dController.d.ts → hand/handTracking2dController.d.ts} +1 -1
- package/dist/{handTracking3d.d.ts → hand/handTracking3d.d.ts} +1 -1
- package/dist/hooks/faceResults.d.ts +1 -1
- package/dist/hooks/useCalibrationFaceTracker.d.ts +1 -1
- package/dist/hooks/useFaceAction.d.ts +3 -0
- package/dist/hooks/useFaceAttributeExpression.d.ts +16 -0
- package/dist/hooks/useFaceDetection.d.ts +18 -0
- package/dist/hooks/useFaceInfo.d.ts +7 -0
- package/dist/hooks/useFaceInfos.d.ts +15 -0
- package/dist/hooks/useFaceResultReader.d.ts +10 -0
- package/dist/hooks/useFrameCapture.d.ts +18 -0
- package/dist/hooks/useMediaRecorder.d.ts +14 -2
- package/dist/hooks/useOwnedTexture.d.ts +6 -0
- package/dist/hooks/useTrackerContext.d.ts +2 -2
- package/dist/hooks/useXRModel.d.ts +5 -0
- package/dist/hooks/useXRSession/facade.d.ts +3 -0
- package/dist/hooks/useXRSession/registry.d.ts +9 -0
- package/dist/index-Be-S7uSm.cjs +1 -0
- package/dist/index-D4bLzBr6.cjs +1 -0
- package/dist/index-DdWBnI7A.cjs +17 -0
- package/dist/index-DpVIEBHw.js +2068 -0
- package/dist/index-DqhqBi7O.cjs +1 -0
- package/dist/index-HxT9XEuh.js +111 -0
- package/dist/{index-safCs_af.js → index-JygePOwo.js} +565 -508
- package/dist/index-N7C6fNah.js +214 -0
- package/dist/index-UU5ODHGU.cjs +1 -0
- package/dist/{index-BGNbrc4C.js → index-YMUaJU7U.js} +217 -126
- package/dist/{internal-Cae1ps15.js → internal-D7NxAsc6.js} +86 -80
- package/dist/internal-i2JkM85N.cjs +1 -0
- package/dist/internal.cjs +1 -1
- package/dist/internal.js +2 -2
- package/dist/low-level.cjs +1 -1
- package/dist/low-level.js +1138 -86
- package/dist/main.cjs +1 -73
- package/dist/main.js +545 -1693
- package/dist/material/MaterialFill.d.ts +20 -0
- package/dist/material/MeshMaterial.d.ts +14 -0
- package/dist/material/index.d.ts +2 -0
- package/dist/models/Body/index.d.ts +1 -1
- package/dist/models/Face/index.d.ts +1 -0
- package/dist/models/Face/rotation.d.ts +3 -0
- package/dist/render/renderGroups.d.ts +47 -0
- package/dist/render/renderPasses.d.ts +18 -0
- package/dist/renderGroups-JEXqSACh.js +152 -0
- package/dist/renderGroups-uXXsFpvw.cjs +1 -0
- package/dist/renderLayers-lDtL0_43.cjs +1 -0
- package/dist/renderLayers-zrK2pv5O.js +13 -0
- package/dist/renderPasses-CVWt0t8m.cjs +21 -0
- package/dist/renderPasses-CdGZeHHL.js +1500 -0
- package/dist/scene-object/index.d.ts +146 -0
- package/dist/scene-object/runtimeRegistry.d.ts +14 -0
- package/dist/scene-object.cjs +1 -0
- package/dist/scene-object.js +40 -0
- package/dist/{screenImageSettings.d.ts → screen-image/screenImageSettings.d.ts} +9 -2
- package/dist/{screenTextSettings.d.ts → screen-text/screenTextSettings.d.ts} +18 -2
- package/dist/screen2d/coordinates.d.ts +87 -0
- package/dist/screen2d/index.d.ts +3 -0
- package/dist/screen2d/screenTransform.d.ts +47 -0
- package/dist/screen2d/smoothing.d.ts +5 -0
- package/dist/{selectors-BLl2JUWW.cjs → selectors-2QvO5RYY.cjs} +1 -1
- package/dist/{selectors-CXd_x-6t.js → selectors-twqYByYZ.js} +6 -6
- package/dist/services/MetricsCollector/index.d.ts +7 -1
- package/dist/services/MetricsCollector/utils.d.ts +1 -1
- package/dist/session-BChR4TgK.cjs +31 -0
- package/dist/session-C1StwN0f.js +363 -0
- package/dist/texture/animatedTexture.d.ts +63 -0
- package/dist/texture/animationMath.d.ts +8 -0
- package/dist/texture/gifReader.d.ts +17 -0
- package/dist/texture/gifTextureSource.d.ts +16 -0
- package/dist/texture/sourceResolver.d.ts +30 -0
- package/dist/tracking.cjs +1 -1
- package/dist/tracking.js +580 -321
- package/dist/types/face.d.ts +1 -13
- package/dist/types/index.d.ts +0 -1
- package/dist/types/nodes.d.ts +2 -1
- package/dist/types/session.d.ts +2 -0
- package/dist/types/tracking.d.ts +8 -2
- package/dist/types/util-types.d.ts +1 -1
- package/dist/useFaceInfo-DOJCGlDG.js +62 -0
- package/dist/useFaceInfo-DSUmuzzO.cjs +1 -0
- package/dist/useFaceResults-B1BSGUAW.cjs +1 -0
- package/dist/useFaceResults-CBmhT5E8.js +19 -0
- package/dist/utils/drawNormalizedCrop.d.ts +22 -0
- package/dist/utils/integrity.d.ts +4 -25
- package/dist/utils/landmarkBounds.d.ts +1 -1
- package/dist/utils/logger.d.ts +2 -2
- package/docs/MIGRATION_GUIDE.md +589 -0
- package/docs/SDK_DOCUMENTATION.md +1155 -0
- package/docs/api/audio.mdx +36 -0
- package/docs/api/behavior-components.mdx +164 -0
- package/docs/api/capture-recording.mdx +103 -0
- package/docs/api/debug-ui-scene-editor.mdx +249 -0
- package/docs/api/face-actions.mdx +104 -0
- package/docs/api/face-attribute-expression.mdx +87 -0
- package/docs/api/face-binding-anchors.mdx +53 -0
- package/docs/api/face-effects.mdx +19 -0
- package/docs/api/face-info.mdx +112 -0
- package/docs/api/face-mesh.mdx +98 -0
- package/docs/api/face-painting.mdx +33 -0
- package/docs/api/face-retouching.mdx +73 -0
- package/docs/api/material-render-state.mdx +132 -0
- package/docs/api/runtime-3d.mdx +311 -0
- package/docs/api/scene-object-store.mdx +213 -0
- package/docs/api/screen-image.mdx +65 -0
- package/docs/api/screen-shape.mdx +64 -0
- package/docs/api/screen-space-coordinates.mdx +41 -0
- package/docs/api/screen-text.mdx +39 -0
- package/docs/api/texture-sources.mdx +74 -0
- package/docs/api/trackers.mdx +46 -0
- package/docs/docs.json +70 -0
- package/docs/examples/scene-object-recipes.mdx +194 -0
- package/docs/guides/harness-debug-ui.mdx +139 -0
- package/docs/inspector/hierarchy-panel.mdx +51 -0
- package/docs/inspector/object-inspector-panel.mdx +51 -0
- package/docs/introduction.mdx +121 -0
- package/docs/scene-objects/overview.mdx +127 -0
- package/docs/scene-objects/render-groups.mdx +77 -0
- package/docs/scene-objects/runtime-rendering.mdx +75 -0
- package/docs/texture-api-consumer.md +84 -0
- package/package.json +38 -8
- package/dist/MediaSourceSwitcher-C-xYg0nQ.js +0 -317
- package/dist/MediaSourceSwitcher-Cq3g4IKw.cjs +0 -31
- package/dist/components/FaceRetouch/defaults.d.ts +0 -13
- package/dist/components/FaceRetouch/retouchRegions.d.ts +0 -23
- package/dist/components/FaceRetouch/useFaceRetouchRegions.d.ts +0 -12
- package/dist/defaults-BLpcN3pG.cjs +0 -1
- package/dist/defaults-LtY4M7dg.js +0 -55
- package/dist/index-BXyObVHF.cjs +0 -1
- package/dist/index-CY3bUAcW.js +0 -12
- package/dist/index-C_Duh13c.cjs +0 -1
- package/dist/index-D8fpPQkC.cjs +0 -1
- package/dist/index-DxshgBu0.cjs +0 -1
- package/dist/index-O-2crZ3M.js +0 -1102
- package/dist/internal-BjyhBP8i.cjs +0 -1
- package/dist/modules/XRClient/index.d.ts +0 -9
- package/dist/modules/index.d.ts +0 -1
- package/dist/screenImageSettings-6NRg4cx9.js +0 -39
- package/dist/screenImageSettings-y_B4_767.cjs +0 -1
- package/dist/services/ApiService.d.ts +0 -12
- package/dist/types/client.d.ts +0 -3
- package/dist/useFaceResults-cpsSmKKc.js +0 -81
- package/dist/useFaceResults-hVUJYSEY.cjs +0 -1
- package/dist/useXRModel-3DcUa28n.cjs +0 -1
- package/dist/useXRModel-BMJE1hrk.js +0 -28
- /package/dist/{layerStack.d.ts → render/layerStack.d.ts} +0 -0
- /package/dist/{screenImagePresets.d.ts → screen-image/screenImagePresets.d.ts} +0 -0
- /package/dist/{screenTextPresets.d.ts → screen-text/screenTextPresets.d.ts} +0 -0
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** MediaPipe Face Landmarker blendshape category names. */
|
|
2
|
+
export declare const FACE_BLENDSHAPE_NAMES: readonly ["_neutral", "browDownLeft", "browDownRight", "browInnerUp", "browOuterUpLeft", "browOuterUpRight", "cheekPuff", "cheekSquintLeft", "cheekSquintRight", "eyeBlinkLeft", "eyeBlinkRight", "eyeLookDownLeft", "eyeLookDownRight", "eyeLookInLeft", "eyeLookInRight", "eyeLookOutLeft", "eyeLookOutRight", "eyeLookUpLeft", "eyeLookUpRight", "eyeSquintLeft", "eyeSquintRight", "eyeWideLeft", "eyeWideRight", "jawForward", "jawLeft", "jawOpen", "jawRight", "mouthClose", "mouthDimpleLeft", "mouthDimpleRight", "mouthFrownLeft", "mouthFrownRight", "mouthFunnel", "mouthLeft", "mouthLowerDownLeft", "mouthLowerDownRight", "mouthPressLeft", "mouthPressRight", "mouthPucker", "mouthRight", "mouthRollLower", "mouthRollUpper", "mouthShrugLower", "mouthShrugUpper", "mouthSmileLeft", "mouthSmileRight", "mouthStretchLeft", "mouthStretchRight", "mouthUpperUpLeft", "mouthUpperUpRight", "noseSneerLeft", "noseSneerRight"];
|
|
3
|
+
export type FaceBlendshapeName = (typeof FACE_BLENDSHAPE_NAMES)[number];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Category, NormalizedLandmark } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { FaceBlendshapeName } from './blendshapes';
|
|
3
|
+
import { FaceInfo } from './types';
|
|
4
|
+
export declare const DEFAULT_FACE_EXPRESSION_THRESHOLD = 0.5;
|
|
5
|
+
export declare const writeFaceBlendshapes: (categories: readonly Category[] | undefined, target: Record<string, number>) => Record<string, number>;
|
|
6
|
+
export declare const getFaceBlendshape: (faceInfo: FaceInfo, name: FaceBlendshapeName) => number;
|
|
7
|
+
export declare const hasFaceExpression: (faceInfo: FaceInfo, name: FaceBlendshapeName, threshold?: number) => boolean;
|
|
8
|
+
export declare const getFaceEyeDistance: (landmarks: readonly NormalizedLandmark[]) => number;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CropOutputSize } from '../utils/drawNormalizedCrop';
|
|
2
|
+
import { FaceInfo } from './types';
|
|
3
|
+
export type DrawFaceCropOptions = {
|
|
4
|
+
source: CanvasImageSource;
|
|
5
|
+
face: FaceInfo;
|
|
6
|
+
canvas: HTMLCanvasElement;
|
|
7
|
+
outputSize: CropOutputSize;
|
|
8
|
+
padding?: number;
|
|
9
|
+
};
|
|
10
|
+
export declare const drawFaceCrop: ({ source, face, canvas, outputSize, padding, }: DrawFaceCropOptions) => boolean;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FaceLandmarkerResult } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { XRModelNodeFaceTracking } from '../types/nodes';
|
|
3
|
+
import { FaceInfo, FaceInfoTarget } from './types';
|
|
4
|
+
/** Creates reusable storage for allocation-free `getFaceInfo` reads in `useFrame`. */
|
|
5
|
+
export declare const createFaceInfoTarget: () => FaceInfoTarget;
|
|
6
|
+
export declare const getFaceInfoFromResults: (node: XRModelNodeFaceTracking, results: FaceLandmarkerResult, faceIndex?: number, target?: FaceInfoTarget) => FaceInfo | null;
|
|
7
|
+
/** Reads the current face. Pass a reusable target on per-frame hot paths. */
|
|
8
|
+
export declare const getFaceInfo: (node: XRModelNodeFaceTracking, faceIndex?: number, target?: FaceInfoTarget) => FaceInfo | null;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { DEFAULT_FACE_EXPRESSION_THRESHOLD, getFaceBlendshape, getFaceEyeDistance, hasFaceExpression, } from './derive';
|
|
2
|
+
export { FACE_BLENDSHAPE_NAMES } from './blendshapes';
|
|
3
|
+
export { createFaceInfoTarget, getFaceInfo } from './getFaceInfo';
|
|
4
|
+
export { drawFaceCrop } from './drawFaceCrop';
|
|
5
|
+
export type { DrawFaceCropOptions } from './drawFaceCrop';
|
|
6
|
+
export { FACE_LANDMARK_INDICES } from './landmarks';
|
|
7
|
+
export type { FaceBlendshapeName } from './blendshapes';
|
|
8
|
+
export type { FaceInfo, FaceInfoTarget, FaceVector3 } from './types';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { NormalizedLandmark } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { FaceCustomAnchorPoint, FaceTarget } from '../types/tracking';
|
|
3
|
+
/** MediaPipe canonical face-mesh indices. Left/right follow the person's perspective. */
|
|
4
|
+
export declare const FACE_LANDMARK_INDICES: {
|
|
5
|
+
readonly "face.forehead": 10;
|
|
6
|
+
readonly "face.noseTip": 1;
|
|
7
|
+
readonly "face.chin": 152;
|
|
8
|
+
readonly "face.leftEyeOuter": 263;
|
|
9
|
+
readonly "face.rightEyeOuter": 33;
|
|
10
|
+
readonly "face.leftCheek": 425;
|
|
11
|
+
readonly "face.rightCheek": 205;
|
|
12
|
+
readonly "face.mouthCenter": 13;
|
|
13
|
+
readonly "face.leftEarlobe": 454;
|
|
14
|
+
readonly "face.rightEarlobe": 234;
|
|
15
|
+
};
|
|
16
|
+
/** Resolves a semantic face target in normalized tracker-input coordinates. */
|
|
17
|
+
export declare const resolveFaceAnchorPoint: (faceTarget: FaceTarget, landmarks: readonly NormalizedLandmark[], customAnchorPoint?: FaceCustomAnchorPoint, target?: NormalizedLandmark) => NormalizedLandmark | null;
|
|
18
|
+
export declare const FACE_EYE_DISTANCE_LANDMARKS: {
|
|
19
|
+
readonly left: 263;
|
|
20
|
+
readonly right: 33;
|
|
21
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { NormalizedLandmark } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { FaceBounds } from '../types/face';
|
|
3
|
+
import { FaceBlendshapeName } from './blendshapes';
|
|
4
|
+
export type FaceVector3 = Readonly<{
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
z: number;
|
|
8
|
+
}>;
|
|
9
|
+
export type FaceInfo = {
|
|
10
|
+
/** Current result-array index. This is not a persistent identity. */
|
|
11
|
+
readonly index: number;
|
|
12
|
+
/** MediaPipe landmarks in normalized tracker-input coordinates; top-left origin. */
|
|
13
|
+
readonly landmarks: readonly NormalizedLandmark[];
|
|
14
|
+
/** Axis-aligned bounds in the same normalized tracker-input coordinates. */
|
|
15
|
+
readonly bounds: Readonly<FaceBounds>;
|
|
16
|
+
readonly pose: {
|
|
17
|
+
/** Three.js world position from the existing face tracker. */
|
|
18
|
+
readonly position: FaceVector3;
|
|
19
|
+
/** Radians: X pitch (+up), Y yaw (+left), Z roll. */
|
|
20
|
+
readonly rotation: FaceVector3;
|
|
21
|
+
/** Smoothed uniform sizing heuristic used by the face occluder/tracker anchor. */
|
|
22
|
+
readonly scale: FaceVector3;
|
|
23
|
+
};
|
|
24
|
+
/** Outer-eye distance in normalized tracker-input coordinates. */
|
|
25
|
+
readonly eyeDistance: number;
|
|
26
|
+
/** MediaPipe blendshape category names mapped to scores in [0, 1]. */
|
|
27
|
+
readonly blendshapes: Readonly<Partial<Record<FaceBlendshapeName, number>>>;
|
|
28
|
+
};
|
|
29
|
+
export type FaceInfoTarget = {
|
|
30
|
+
index: number;
|
|
31
|
+
landmarks: readonly NormalizedLandmark[];
|
|
32
|
+
bounds: FaceBounds;
|
|
33
|
+
pose: {
|
|
34
|
+
position: {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
z: number;
|
|
38
|
+
};
|
|
39
|
+
rotation: {
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
z: number;
|
|
43
|
+
};
|
|
44
|
+
scale: {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
z: number;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
eyeDistance: number;
|
|
51
|
+
blendshapes: Record<string, number>;
|
|
52
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { useState as X, useEffect as Y } from "react";
|
|
2
|
+
import { F as A } from "./index-YMUaJU7U.js";
|
|
3
|
+
const E = (e, t = {
|
|
4
|
+
minX: 0,
|
|
5
|
+
minY: 0,
|
|
6
|
+
maxX: 0,
|
|
7
|
+
maxY: 0,
|
|
8
|
+
width: 0,
|
|
9
|
+
height: 0,
|
|
10
|
+
centerX: 0,
|
|
11
|
+
centerY: 0
|
|
12
|
+
}) => {
|
|
13
|
+
if (e.length === 0)
|
|
14
|
+
return t.minX = 0, t.minY = 0, t.maxX = 0, t.maxY = 0, t.width = 0, t.height = 0, t.centerX = 0, t.centerY = 0, t;
|
|
15
|
+
let n = 1, s = 1, i = 0, o = 0;
|
|
16
|
+
for (let l = 0; l < e.length; l++) {
|
|
17
|
+
const { x: c, y: r } = e[l];
|
|
18
|
+
c < n && (n = c), r < s && (s = r), c > i && (i = c), r > o && (o = r);
|
|
19
|
+
}
|
|
20
|
+
const a = Math.max(0, i - n), u = Math.max(0, o - s);
|
|
21
|
+
return t.minX = n, t.minY = s, t.maxX = i, t.maxY = o, t.width = a, t.height = u, t.centerX = n + a * 0.5, t.centerY = s + u * 0.5, t;
|
|
22
|
+
}, L = (e, t) => e.map((n) => ({
|
|
23
|
+
landmarks: n,
|
|
24
|
+
bounds: E(n)
|
|
25
|
+
})), D = {
|
|
26
|
+
publishedCount: 0,
|
|
27
|
+
// -Infinity, not 0: the first non-empty frame must publish regardless of its
|
|
28
|
+
// timestamp (a frame at now=0 would otherwise be throttled against 0).
|
|
29
|
+
lastPublishAt: -1 / 0,
|
|
30
|
+
lastNonEmptyAt: -1
|
|
31
|
+
}, N = (e, t, n, s, i) => {
|
|
32
|
+
if (t > 0) {
|
|
33
|
+
const o = { ...e, lastNonEmptyAt: n };
|
|
34
|
+
return n - e.lastPublishAt >= s ? {
|
|
35
|
+
action: "publish",
|
|
36
|
+
state: { publishedCount: t, lastPublishAt: n, lastNonEmptyAt: n }
|
|
37
|
+
} : { action: "none", state: o };
|
|
38
|
+
}
|
|
39
|
+
return e.publishedCount === 0 ? { action: "none", state: e } : e.lastNonEmptyAt >= 0 && n - e.lastNonEmptyAt < i ? { action: "none", state: e } : {
|
|
40
|
+
action: "clear",
|
|
41
|
+
// Reset the throttle anchor so the next reacquired face publishes at once.
|
|
42
|
+
state: { publishedCount: 0, lastPublishAt: -1 / 0, lastNonEmptyAt: e.lastNonEmptyAt }
|
|
43
|
+
};
|
|
44
|
+
}, B = ({
|
|
45
|
+
enabled: e,
|
|
46
|
+
holdMs: t,
|
|
47
|
+
node: n,
|
|
48
|
+
onFrame: s,
|
|
49
|
+
prepare: i,
|
|
50
|
+
throttleMs: o
|
|
51
|
+
}) => {
|
|
52
|
+
const [a, u] = X([]);
|
|
53
|
+
return Y(() => {
|
|
54
|
+
if (!e || !n) {
|
|
55
|
+
u((h) => h.length === 0 ? h : []);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
let l = 0, c, r = D;
|
|
59
|
+
const d = (h, m, f) => {
|
|
60
|
+
const { action: x, state: F } = N(r, h, m, o, t);
|
|
61
|
+
r = F, x === "publish" ? u(f) : x === "clear" && u((b) => b.length === 0 ? b : []);
|
|
62
|
+
}, y = () => {
|
|
63
|
+
l = requestAnimationFrame(y), s == null || s();
|
|
64
|
+
const h = performance.now(), m = n.getDetectionResults();
|
|
65
|
+
if (!m) {
|
|
66
|
+
d(0, h, []), c = m;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (m === c) return;
|
|
70
|
+
c = m;
|
|
71
|
+
const f = i(m);
|
|
72
|
+
d(f.length, h, f);
|
|
73
|
+
};
|
|
74
|
+
return l = requestAnimationFrame(y), () => cancelAnimationFrame(l);
|
|
75
|
+
}, [e, t, n, s, i, o]), a;
|
|
76
|
+
}, R = 0.5, S = (e, t) => {
|
|
77
|
+
for (const n in t) delete t[n];
|
|
78
|
+
if (e)
|
|
79
|
+
for (const n of e) t[n.categoryName] = n.score;
|
|
80
|
+
return t;
|
|
81
|
+
}, C = (e, t) => e.blendshapes[t] ?? 0, T = (e, t, n = R) => C(e, t) >= n, P = (e) => {
|
|
82
|
+
const t = e[A.left], n = e[A.right];
|
|
83
|
+
return !t || !n ? 0 : Math.hypot(t.x - n.x, t.y - n.y);
|
|
84
|
+
}, _ = () => ({
|
|
85
|
+
index: 0,
|
|
86
|
+
landmarks: [],
|
|
87
|
+
bounds: { minX: 0, minY: 0, maxX: 0, maxY: 0, width: 0, height: 0, centerX: 0, centerY: 0 },
|
|
88
|
+
pose: {
|
|
89
|
+
position: { x: 0, y: 0, z: 0 },
|
|
90
|
+
rotation: { x: 0, y: 0, z: 0 },
|
|
91
|
+
scale: { x: 0, y: 0, z: 0 }
|
|
92
|
+
},
|
|
93
|
+
eyeDistance: 0,
|
|
94
|
+
blendshapes: {}
|
|
95
|
+
}), p = (e, t) => {
|
|
96
|
+
t.x = e.x, t.y = e.y, t.z = e.z;
|
|
97
|
+
}, w = (e, t, n = 0, s) => {
|
|
98
|
+
var u, l, c;
|
|
99
|
+
const i = (u = t.faceLandmarks) == null ? void 0 : u[n], o = e.getFace(n);
|
|
100
|
+
if (!i || !o) return null;
|
|
101
|
+
const a = s ?? _();
|
|
102
|
+
return a.index = n, a.landmarks = i, E(i, a.bounds), p(o.transform.position, a.pose.position), p(o.transform.rotation, a.pose.rotation), p(o.transform.scale, a.pose.scale), a.eyeDistance = P(i), S((c = (l = t.faceBlendshapes) == null ? void 0 : l[n]) == null ? void 0 : c.categories, a.blendshapes), a;
|
|
103
|
+
}, q = (e, t = 0, n) => {
|
|
104
|
+
const s = e.getDetectionResults();
|
|
105
|
+
return s ? w(e, s, t, n) : null;
|
|
106
|
+
};
|
|
107
|
+
export {
|
|
108
|
+
R as D,
|
|
109
|
+
C as a,
|
|
110
|
+
P as b,
|
|
111
|
+
E as c,
|
|
112
|
+
_ as d,
|
|
113
|
+
q as e,
|
|
114
|
+
w as g,
|
|
115
|
+
T as h,
|
|
116
|
+
L as p,
|
|
117
|
+
B as u
|
|
118
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const x=require("react"),b=require("./index-DqhqBi7O.cjs"),E=(e,t={minX:0,minY:0,maxX:0,maxY:0,width:0,height:0,centerX:0,centerY:0})=>{if(e.length===0)return t.minX=0,t.minY=0,t.maxX=0,t.maxY=0,t.width=0,t.height=0,t.centerX=0,t.centerY=0,t;let n=1,s=1,i=0,o=0;for(let l=0;l<e.length;l++){const{x:a,y:r}=e[l];a<n&&(n=a),r<s&&(s=r),a>i&&(i=a),r>o&&(o=r)}const c=Math.max(0,i-n),u=Math.max(0,o-s);return t.minX=n,t.minY=s,t.maxX=i,t.maxY=o,t.width=c,t.height=u,t.centerX=n+c*.5,t.centerY=s+u*.5,t},_=(e,t)=>e.map(n=>({landmarks:n,bounds:E(n)})),C={publishedCount:0,lastPublishAt:-1/0,lastNonEmptyAt:-1},I=(e,t,n,s,i)=>{if(t>0){const o={...e,lastNonEmptyAt:n};return n-e.lastPublishAt>=s?{action:"publish",state:{publishedCount:t,lastPublishAt:n,lastNonEmptyAt:n}}:{action:"none",state:o}}return e.publishedCount===0?{action:"none",state:e}:e.lastNonEmptyAt>=0&&n-e.lastNonEmptyAt<i?{action:"none",state:e}:{action:"clear",state:{publishedCount:0,lastPublishAt:-1/0,lastNonEmptyAt:e.lastNonEmptyAt}}},L=({enabled:e,holdMs:t,node:n,onFrame:s,prepare:i,throttleMs:o})=>{const[c,u]=x.useState([]);return x.useEffect(()=>{if(!e||!n){u(h=>h.length===0?h:[]);return}let l=0,a,r=C;const d=(h,m,f)=>{const{action:A,state:S}=I(r,h,m,o,t);r=S,A==="publish"?u(f):A==="clear"&&u(y=>y.length===0?y:[])},F=()=>{l=requestAnimationFrame(F),s==null||s();const h=performance.now(),m=n.getDetectionResults();if(!m){d(0,h,[]),a=m;return}if(m===a)return;a=m;const f=i(m);d(f.length,h,f)};return l=requestAnimationFrame(F),()=>cancelAnimationFrame(l)},[e,t,n,s,i,o]),c},R=.5,P=(e,t)=>{for(const n in t)delete t[n];if(e)for(const n of e)t[n.categoryName]=n.score;return t},X=(e,t)=>e.blendshapes[t]??0,T=(e,t,n=R)=>X(e,t)>=n,Y=e=>{const t=e[b.FACE_EYE_DISTANCE_LANDMARKS.left],n=e[b.FACE_EYE_DISTANCE_LANDMARKS.right];return!t||!n?0:Math.hypot(t.x-n.x,t.y-n.y)},D=()=>({index:0,landmarks:[],bounds:{minX:0,minY:0,maxX:0,maxY:0,width:0,height:0,centerX:0,centerY:0},pose:{position:{x:0,y:0,z:0},rotation:{x:0,y:0,z:0},scale:{x:0,y:0,z:0}},eyeDistance:0,blendshapes:{}}),p=(e,t)=>{t.x=e.x,t.y=e.y,t.z=e.z},N=(e,t,n=0,s)=>{var u,l,a;const i=(u=t.faceLandmarks)==null?void 0:u[n],o=e.getFace(n);if(!i||!o)return null;const c=s??D();return c.index=n,c.landmarks=i,E(i,c.bounds),p(o.transform.position,c.pose.position),p(o.transform.rotation,c.pose.rotation),p(o.transform.scale,c.pose.scale),c.eyeDistance=Y(i),P((a=(l=t.faceBlendshapes)==null?void 0:l[n])==null?void 0:a.categories,c.blendshapes),c},B=(e,t=0,n)=>{const s=e.getDetectionResults();return s?N(e,s,t,n):null};exports.DEFAULT_FACE_EXPRESSION_THRESHOLD=R;exports.computeLandmarkBounds=E;exports.createFaceInfoTarget=D;exports.getFaceBlendshape=X;exports.getFaceEyeDistance=Y;exports.getFaceInfo=B;exports.getFaceInfoFromResults=N;exports.hasFaceExpression=T;exports.prepareCalibrationFaceResults=_;exports.useFaceResultReader=L;
|
|
@@ -7,7 +7,7 @@ export type CalibrationMediaSourceKind = "webcam" | XRMediaSourceKind;
|
|
|
7
7
|
* `FaceTrackingResult`s (landmarks + axis-aligned bounds). Source-kind is
|
|
8
8
|
* accepted for future per-source handling; results stay in display space.
|
|
9
9
|
*/
|
|
10
|
-
export declare const prepareCalibrationFaceResults: (faceLandmarks: NormalizedLandmark[][],
|
|
10
|
+
export declare const prepareCalibrationFaceResults: (faceLandmarks: NormalizedLandmark[][], selectedSource: CalibrationMediaSourceKind) => FaceTrackingResult[];
|
|
11
11
|
/**
|
|
12
12
|
* Per-frame publish state for the face-results reader. Pure so the hold +
|
|
13
13
|
* throttle timing can be unit-tested without a RAF/React harness.
|
|
@@ -18,6 +18,6 @@ export declare const useCalibrationFaceTracker: ({ enabled, displayMirrored, ima
|
|
|
18
18
|
}) => {
|
|
19
19
|
activeDelegate: "GPU";
|
|
20
20
|
faces: import('../types').FaceTrackingResult[];
|
|
21
|
-
status: "
|
|
21
|
+
status: "idle" | "ready" | "error" | "initializing";
|
|
22
22
|
error: string | null;
|
|
23
23
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FaceAttributeExpressionResult } from '../face-attribute-expression';
|
|
2
|
+
import { FaceInfo } from '../face-info';
|
|
3
|
+
export declare const DEFAULT_FACE_ATTRIBUTE_EXPRESSION_MODEL_URL = "https://huggingface.co/opencv/facial_expression_recognition/resolve/main/facial_expression_recognition_mobilefacenet_2022july_int8.onnx";
|
|
4
|
+
export type FaceAttributeExpressionStatus = "idle" | "loading" | "ready" | "error";
|
|
5
|
+
export type UseFaceAttributeExpressionOptions = {
|
|
6
|
+
active?: boolean;
|
|
7
|
+
targetFps?: number;
|
|
8
|
+
minConfidence?: number;
|
|
9
|
+
modelUrl?: string;
|
|
10
|
+
};
|
|
11
|
+
export type UseFaceAttributeExpressionResult = {
|
|
12
|
+
status: FaceAttributeExpressionStatus;
|
|
13
|
+
result: FaceAttributeExpressionResult | null;
|
|
14
|
+
error: Error | null;
|
|
15
|
+
};
|
|
16
|
+
export declare const useFaceAttributeExpression: (face: FaceInfo | null, { active, targetFps, minConfidence, modelUrl, }?: UseFaceAttributeExpressionOptions) => UseFaceAttributeExpressionResult;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FaceInfo } from '../face-info';
|
|
2
|
+
import { UseFaceInfosOptions } from './useFaceInfos';
|
|
3
|
+
export type FaceDetectionPhase = "begin" | "stay" | "end" | "none";
|
|
4
|
+
export type UseFaceDetectionOptions = UseFaceInfosOptions & {
|
|
5
|
+
faceIndex?: number;
|
|
6
|
+
};
|
|
7
|
+
export type FaceDetectionState = {
|
|
8
|
+
face: FaceInfo | null;
|
|
9
|
+
faces: FaceInfo[];
|
|
10
|
+
faceCount: number;
|
|
11
|
+
detected: boolean;
|
|
12
|
+
justDetected: boolean;
|
|
13
|
+
justLost: boolean;
|
|
14
|
+
phase: FaceDetectionPhase;
|
|
15
|
+
};
|
|
16
|
+
export declare const getFaceDetectionPhase: (wasDetected: boolean, detected: boolean) => FaceDetectionPhase;
|
|
17
|
+
/** Face presence/count lifecycle over the shared FaceInfo reader. */
|
|
18
|
+
export declare const useFaceDetection: ({ faceIndex, numFaces, ...options }?: UseFaceDetectionOptions) => FaceDetectionState;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FaceInfo } from '../face-info';
|
|
2
|
+
import { UseFaceInfosOptions } from './useFaceInfos';
|
|
3
|
+
export type UseFaceInfoOptions = UseFaceInfosOptions & {
|
|
4
|
+
faceIndex?: number;
|
|
5
|
+
};
|
|
6
|
+
/** Single-face selector over `useFaceInfos`; it does not create another reader loop. */
|
|
7
|
+
export declare const useFaceInfo: ({ faceIndex, numFaces, ...options }?: UseFaceInfoOptions) => FaceInfo | null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FaceInfo } from '../face-info';
|
|
2
|
+
export type UseFaceInfosOptions = {
|
|
3
|
+
/** Pauses this consumer's model interest when false. Default true. */
|
|
4
|
+
active?: boolean;
|
|
5
|
+
/** Maximum faces requested from the shared model. Default 1. */
|
|
6
|
+
numFaces?: number;
|
|
7
|
+
/** Optional inference-rate cap. */
|
|
8
|
+
targetFps?: number;
|
|
9
|
+
/** Minimum milliseconds between React result publications. Default 16. */
|
|
10
|
+
throttleMs?: number;
|
|
11
|
+
/** Keep the last result through brief missed detections. Default 250. */
|
|
12
|
+
holdMs?: number;
|
|
13
|
+
};
|
|
14
|
+
/** React reader for all current faces. Must run inside XRProvider and the R3F Canvas. */
|
|
15
|
+
export declare const useFaceInfos: ({ active, holdMs, numFaces, targetFps, throttleMs, }?: UseFaceInfosOptions) => FaceInfo[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FaceLandmarkerResult } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { XRModelNodeFaceTracking } from '../types/nodes';
|
|
3
|
+
export declare const useFaceResultReader: <T>({ enabled, holdMs, node, onFrame, prepare, throttleMs, }: {
|
|
4
|
+
node: XRModelNodeFaceTracking | null;
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
throttleMs: number;
|
|
7
|
+
holdMs: number;
|
|
8
|
+
onFrame?: () => void;
|
|
9
|
+
prepare: (results: FaceLandmarkerResult) => T[];
|
|
10
|
+
}) => T[];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type CaptureStatus = "idle" | "capturing" | "completed" | "error";
|
|
2
|
+
export type FrameCaptureEvents = {
|
|
3
|
+
onCaptureStart?: () => void;
|
|
4
|
+
onCaptureComplete?: (dataUrl: string) => void;
|
|
5
|
+
onError?: (error: Error) => void;
|
|
6
|
+
};
|
|
7
|
+
export type UseFrameCaptureOptions = FrameCaptureEvents & {
|
|
8
|
+
/** Override the XR session capture function for custom renderers or tests. */
|
|
9
|
+
captureFrame?: () => string;
|
|
10
|
+
};
|
|
11
|
+
export declare const runFrameCapture: (captureFrame: () => string, events?: FrameCaptureEvents) => Promise<string>;
|
|
12
|
+
export declare const useFrameCapture: (options?: UseFrameCaptureOptions) => {
|
|
13
|
+
status: CaptureStatus;
|
|
14
|
+
capturePhoto: () => Promise<string | null>;
|
|
15
|
+
clear: () => void;
|
|
16
|
+
dataUrl: string | null;
|
|
17
|
+
error: Error | null;
|
|
18
|
+
};
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export type RecordingStatus = "idle" | "starting" | "recording" | "paused" | "stopping" | "completed" | "error";
|
|
2
|
+
export type RecordingEvent = "start" | "started" | "pause" | "resume" | "stop" | "complete" | "fail" | "clear";
|
|
3
|
+
/** Pure lifecycle mapping, exported so apps and tests can share the SDK convention. */
|
|
4
|
+
export declare const recordingStatusForEvent: (event: RecordingEvent) => RecordingStatus;
|
|
1
5
|
export interface UseMediaRecorderOptions {
|
|
2
6
|
/**
|
|
3
7
|
* Add an audio track to the recording. `true` opens the default microphone;
|
|
@@ -10,7 +14,14 @@ export interface UseMediaRecorderOptions {
|
|
|
10
14
|
mimeType?: string;
|
|
11
15
|
bitsPerSecond?: number;
|
|
12
16
|
onData?: (chunk: Blob) => void;
|
|
17
|
+
/** @deprecated Use `onRecordingComplete`. */
|
|
13
18
|
onStop?: (blob: Blob) => void;
|
|
19
|
+
onRecordingStart?: () => void;
|
|
20
|
+
onRecordingPause?: () => void;
|
|
21
|
+
onRecordingResume?: () => void;
|
|
22
|
+
onRecordingStop?: () => void;
|
|
23
|
+
onRecordingComplete?: (blob: Blob) => void;
|
|
24
|
+
onError?: (error: Error) => void;
|
|
14
25
|
/**
|
|
15
26
|
* Record this exact stream as-is (no track assembly, no getUserMedia). Use
|
|
16
27
|
* when you've already composed the stream you want (e.g. canvas + music).
|
|
@@ -24,10 +35,11 @@ export interface UseMediaRecorderOptions {
|
|
|
24
35
|
* input, plus an optional audio track per `audio` — picks the first supported
|
|
25
36
|
* codec, and begins recording. `stop()` finalizes; the `Blob` lands on
|
|
26
37
|
* `recordedBlob` (and `onStop`). Pass `passThroughStream` to record a
|
|
27
|
-
* pre-composed stream verbatim.
|
|
38
|
+
* pre-composed stream verbatim, then call `start()` without an argument.
|
|
28
39
|
*/
|
|
29
40
|
export declare function useMediaRecorder(opts?: UseMediaRecorderOptions): {
|
|
30
|
-
|
|
41
|
+
status: RecordingStatus;
|
|
42
|
+
start: (inputStream?: MediaStream, timeslice?: number) => Promise<void>;
|
|
31
43
|
stop: () => void;
|
|
32
44
|
pause: () => void;
|
|
33
45
|
resume: () => void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Texture } from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* Own a texture for exactly as long as the current React binding uses it.
|
|
4
|
+
* Replacement disposes the previous texture; unmount disposes the final one.
|
|
5
|
+
*/
|
|
6
|
+
export declare const useOwnedTexture: (texture: Texture | null | undefined) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TrackerType, TrackingTarget } from '../types/tracking';
|
|
1
|
+
import { FaceCustomAnchorPoint, TrackerType, TrackingTarget } from '../types/tracking';
|
|
2
2
|
import * as THREE from "three";
|
|
3
3
|
/**
|
|
4
4
|
* Per-frame resolver for a tracker's landmarks/joints.
|
|
@@ -12,7 +12,7 @@ import * as THREE from "three";
|
|
|
12
12
|
* Returning `null` means "this landmark is not currently detected" —
|
|
13
13
|
* the anchor should hide its children for that frame.
|
|
14
14
|
*/
|
|
15
|
-
export type TrackerLandmarkResolver = (target: TrackingTarget) => {
|
|
15
|
+
export type TrackerLandmarkResolver = (target: TrackingTarget, customAnchorPoint?: FaceCustomAnchorPoint) => {
|
|
16
16
|
position: THREE.Vector3;
|
|
17
17
|
quaternion?: THREE.Quaternion;
|
|
18
18
|
} | null;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { XRModel } from '../constants';
|
|
2
|
+
/**
|
|
3
|
+
* Serialize model options to a value-stable key. Exported for tests: the
|
|
4
|
+
* acquire effect must key on this, not on the options object's identity.
|
|
5
|
+
*/
|
|
6
|
+
export declare function serializeModelOptions(options?: Record<string, unknown>): string;
|
|
2
7
|
export type UseXRModelResult<T extends Record<string, unknown>> = {
|
|
3
8
|
ready: boolean;
|
|
4
9
|
node: T | null;
|
|
@@ -15,13 +15,16 @@ export type SessionFacade = {
|
|
|
15
15
|
registerXRPipeline: (params: RegisterXRPipelineParams) => Promise<void>;
|
|
16
16
|
getModelNode: <T extends Record<string, unknown>>(modelCode: XRModel) => T;
|
|
17
17
|
captureFrame: () => string;
|
|
18
|
+
getInputFrame: () => OffscreenCanvas | HTMLCanvasElement | null;
|
|
18
19
|
_setRenderTarget: (canvas: HTMLCanvasElement) => Promise<void>;
|
|
19
20
|
_setRenderSize: (width: number, height: number) => Promise<void>;
|
|
20
21
|
_setR3FState: (state: {
|
|
21
22
|
renderer: WebGLRenderer;
|
|
22
23
|
scene: Scene;
|
|
23
24
|
camera: Camera;
|
|
25
|
+
renderFrame?: () => void;
|
|
24
26
|
}) => void;
|
|
27
|
+
_renderFrame: () => void;
|
|
25
28
|
_getVideoElement: () => HTMLVideoElement | undefined;
|
|
26
29
|
/** Update the session perf config (targetFps / camRes). Applied to models on
|
|
27
30
|
* their next run; camRes takes effect on the next media (re)bind. */
|
|
@@ -25,6 +25,15 @@ export type ModelRegistry = {
|
|
|
25
25
|
* always-on behavior.
|
|
26
26
|
*/
|
|
27
27
|
setActive: (modelName: XRModel, ownerId: string, active: boolean) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Pause every model without changing owner activity. Used when the session is
|
|
30
|
+
* stopped or a static source has completed its one-shot detection pulse.
|
|
31
|
+
*/
|
|
32
|
+
suspendAll: () => void;
|
|
33
|
+
/**
|
|
34
|
+
* Clear session suspension and resume only models with active owners.
|
|
35
|
+
*/
|
|
36
|
+
resumeActive: () => void;
|
|
28
37
|
/**
|
|
29
38
|
* Direct accessor — returns the registered model instance, or undefined.
|
|
30
39
|
* Does NOT throw. The session facade's `getModelNode` wraps this with the
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const w=require("react/jsx-runtime"),_=require("@react-three/fiber"),p=require("react"),H=require("three"),O=require("./renderLayers-lDtL0_43.cjs"),S=require("./index-DqhqBi7O.cjs");function D(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const a=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,a.get?a:{enumerable:!0,get:()=>e[n]})}}return r.default=e,Object.freeze(r)}const h=D(H),q=["face.center","face.forehead","face.noseTip","face.chin","face.leftEyeOuter","face.rightEyeOuter","face.leftCheek","face.rightCheek","face.mouthCenter","face.leftEye","face.rightEye","face.leftEarlobe","face.rightEarlobe","face.custom"],v=["hand.wrist","hand.thumbTip","hand.indexTip","hand.middleTip","hand.ringTip","hand.pinkyTip","hand.indexBase","hand.middleBase","hand.ringBase","hand.pinkyBase"],z=["body.head","body.neck","body.leftShoulder","body.rightShoulder","body.leftElbow","body.rightElbow","body.leftWrist","body.rightWrist","body.leftHip","body.rightHip","body.leftKnee","body.rightKnee","body.leftAnkle","body.rightAnkle"],A=e=>e.startsWith("face.")?"face":e.startsWith("hand.")?"hand":e.startsWith("body.")?"body":null,N={target:"face.center",customAnchorPoint:{x:0,y:0,z:0},offset:{x:0,y:0,z:0},smoothing:0,followFaceRoll:!1},R=(e,r,n)=>r+n*(e-r),E=(e,r)=>1/(1+1/(2*Math.PI*e)/r),C=(e,r,n,a,T,t)=>{if(!e.initialized||n<=0)return e.pos.copy(r),e.prevRaw.copy(r),e.dxHat.set(0,0,0),e.initialized=!0,e;const c=E(t,n),u=["x","y","z"];for(const o of u){const l=(r[o]-e.prevRaw[o])/n,i=R(l,e.dxHat[o],c);e.dxHat[o]=i;const f=a+T*Math.abs(i),d=E(f,n);e.pos[o]=R(r[o],e.pos[o],d),e.prevRaw[o]=r[o]}return e},m=(e,r,n,a)=>C(e,r,n,a*.1,.5,1),F=({target:e,customAnchorPoint:r,offset:n,smoothing:a=0,children:T})=>{const t=S.useTrackerContext(),c=p.useRef(null),u=p.useRef(!1),o=p.useRef(new h.Vector3),l=p.useRef({pos:new h.Vector3,prevRaw:new h.Vector3,dxHat:new h.Vector3,initialized:!1}),i=A(e),f=t!==null&&i!==null&&t.type!==i,d=t===null,b=d||f||i===null;return p.useEffect(()=>{d?console.warn(`[TrackingAnchor] target "${e}" requires a FaceTracker / HandTracker / BodyTracker ancestor; rendering null.`):f?console.warn(`[TrackingAnchor] target "${e}" namespace does not match parent tracker type "${t==null?void 0:t.type}"; rendering null.`):i===null&&console.warn(`[TrackingAnchor] target "${e}" is not a recognized face/hand/body landmark; rendering null.`)},[e,i,d,f,t==null?void 0:t.type]),_.useFrame((G,k)=>{if(b||!c.current||!t)return;const y=t.resolveLandmark(e,r);if(!y){c.current.visible=!1,u.current=!1,l.current.initialized=!1;return}c.current.visible=!0;const s=o.current.copy(y.position),g=c.current.parent;if(g){g.updateMatrixWorld();const x=new h.Matrix4().copy(g.matrixWorld).invert();s.applyMatrix4(x)}n&&(s.x+=n[0],s.y+=n[1],s.z+=n[2]),a>0?(m(l.current,s,u.current?k:0,a),c.current.position.copy(l.current.pos)):c.current.position.copy(s),u.current=!0,y.quaternion&&c.current.quaternion.copy(y.quaternion)}),b?null:w.jsx("group",{ref:c,renderOrder:O.RENDER_LAYERS.TRACKED,children:T})};exports.BODY_TARGETS=z;exports.DEFAULT_TRACKING_ANCHOR=N;exports.FACE_TARGETS=q;exports.HAND_TARGETS=v;exports.TrackingAnchor=F;exports.getTargetNamespace=A;exports.stepTrackingSmoothing=m;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var Re=Object.defineProperty;var Me=(n,s,e)=>s in n?Re(n,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[s]=e;var h=(n,s,e)=>Me(n,typeof s!="symbol"?s+"":s,e);const ie=require("react/jsx-runtime"),b=require("react"),_=require("@mediapipe/tasks-vision"),P=require("three");function Te(n){const s=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const e in n)if(e!=="default"){const t=Object.getOwnPropertyDescriptor(n,e);Object.defineProperty(s,e,t.get?t:{enumerable:!0,get:()=>n[e]})}}return s.default=n,Object.freeze(s)}const D=Te(P);var x=(n=>(n.WEBCAM="webcam",n.STREAM="stream",n.CANVAS="canvas",n))(x||{}),L=(n=>(n.HAND_TRACKER="vincentt.xr.hand-tracker",n.GESTURE_TRACKER="vincentt.xr.gesture-tracker",n.FACE_TRACKER="vincentt.xr.face-tracker",n.BODY_TRACKER="vincentt.xr.body-tracker",n.BACKGROUND_SEGMENTATION="vincentt.xr.background-segmentation",n))(L||{});class I extends Error{constructor(s){super(s),this.name="VincenttXRError"}}const xe=(n,s)=>s,E={apiBaseUrl:xe(void 0,"https://api.vincentt.studio"),assetStorageEndpoint:"https://cdn.vincentt.studio",sdkAssetsBaseUrl:"https://cdn.vincentt.studio/assets/sdk/face/v1",loggerPrefix:"[vincentt-xr]:",sessionCheckInterval:3e4};class Fe{constructor(s){h(this,"options");const e={verbose:!1,prefix:E.loggerPrefix};this.options={...e,...s}}log(...s){const{verbose:e,prefix:t}=this.options;e&&console.info(t,...s)}error(...s){const{verbose:e,prefix:t}=this.options;e&&console.error(t,...s)}}const B=n=>n*2-1,Y=new D.Vector3,Q=new D.Vector3,q=({x:n,y:s,z:e},t,a)=>{Y.set((n-.5)*2,(.5-s)*2,-e),Y.unproject(t),Q.copy(Y).sub(t.position).normalize();const r=-t.position.z/Q.z;return a.copy(t.position).addScaledVector(Q,r),a},Ae=(n,s)=>q(n,s,new D.Vector3),be=(n,s,e=.2)=>e*s+(1-e)*n;class ${constructor(s){h(this,"canvas");this.maxDimension=s}draw(s){const e=s.width,t=s.height,a=Math.min(1,this.maxDimension/Math.max(e,t));if(a>=1)return s;const r=Math.max(1,Math.round(e*a)),o=Math.max(1,Math.round(t*a));(!this.canvas||this.canvas.width!==r||this.canvas.height!==o)&&(this.canvas=new OffscreenCanvas(r,o));const u=this.canvas.getContext("2d");return u?(u.setTransform(1,0,0,1,0,0),u.clearRect(0,0,r,o),u.drawImage(s,0,0,r,o),this.canvas):s}dispose(){this.canvas=void 0}}const Ee={"/assets/xr/models/face_tracking.task":"sha384-tYQh+yJE8llY+zO4RviZmWaSKs5W9tsB0ix5rjQVpF5/CLTqmwtP7bYtkUi2w65P","/assets/xr/models/hand_tracking.task":"sha384-uWvruVKd887ov8k43S+DBHCsi7UXXS+CKvvdM1PX00rjPzx/B0QrAPfJ1U9yKcze","/assets/xr/models/gesture_tracking.task":"sha384-2zuseP9JKKWAYlWQGKA2N+ooabB8V/yIxu23Mv8mtY7SowcySB+xKiOmqBhVvlUC","/assets/xr/models/body_tracking.task":"sha384-3Wk9dvRYo36b3Nc9xVjKamb4wCKt9FwiPjcHKfrvyJL/jXoGs+uRLnii6yjWLKul","/assets/xr/models/segmentation.tflite":"sha384-A2bQ8+iZyQM3KIGVBUf0FyetqxuynyKpjsjCE8uzoJEnj1ghCu6ge2daiRffAiS5","/assets/xr/3d-models/head-occluder-v2.glb":"sha384-+0G60Q6EBVE6hpITxGzQgofAeKexPltpsfPq5T5et9GGBjRhFP5HOdsKAhe73OaI","/assets/sdk/face/v1/canonical_face_model.obj":"sha384-xP8YM/72TXKvbMptXB9a8JUlUf3MZQ8uLurExrsZc05v6/P5RrsaNGMUYS/BZx8A","/opencv/facial_expression_recognition/resolve/main/facial_expression_recognition_mobilefacenet_2022july_int8.onnx":"sha384-g8mtFubiIc/yhqi591RsxD76AJLw2CfYgKhKbVkIiFlwBmIyG7ZAIVyGPXafrDGB"};async function re(n){const s=await fetch(n);if(!s.ok)throw new Error(`fetchAndVerify: ${s.status} ${n}`);const e=await s.arrayBuffer(),t=De(n);if(!t){if(Ie(n))throw new Error(`[xr-sdk integrity] no SRI hash for SDK asset ${n}`);return console.warn(`[xr-sdk integrity] no SRI hash for ${n} — passing through`),e}const a=await _e(e);if(a!==t)throw new Error(`[xr-sdk integrity] SRI mismatch for ${n}: expected ${t}, got ${a}`);return e}function Ie(n){try{return new URL(n).origin===new URL(E.assetStorageEndpoint).origin}catch{return!1}}async function H(n){const s=await re(n);return new Uint8Array(s)}function De(n){try{const s=new URL(n);return Ee[s.pathname]}catch{return}}async function _e(n){const s=await crypto.subtle.digest("SHA-384",n),e=new Uint8Array(s);let t="";for(let a=0;a<e.byteLength;a++)t+=String.fromCharCode(e[a]);return`sha384-${btoa(t)}`}class G{constructor(){h(this,"disposed",!1);h(this,"paused",!1);h(this,"rafId",null);h(this,"targetFrameIntervalMs",0);h(this,"lastInferenceMs",0)}setTargetFps(s){this.targetFrameIntervalMs=s&&s>0?1e3/s:0}shouldRunInference(){if(this.targetFrameIntervalMs<=0)return!0;const s=performance.now();return s-this.lastInferenceMs<this.targetFrameIntervalMs?!1:(this.lastInferenceMs=s,!0)}async initialize(s){}async run(s){}getModelNode(){return{}}async getPerformanceData(){return{name:this.constructor.name,processingTime:null}}pause(){this.paused=!0,this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}resume(){this.paused=!1}dispose(){this.disposed=!0,this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}}const Pe=768;class Oe extends G{constructor(){super();h(this,"landmarker",null);h(this,"processingTime",null);h(this,"coordinates");h(this,"sourceCanvas");h(this,"downscaler",new $(Pe))}async getBodyData(){if(!this.landmarker||!this.sourceCanvas)return;const e=this.downscaler.draw(this.sourceCanvas),t=performance.now(),a=this.landmarker.detectForVideo(e,t),r=performance.now();this.processingTime=r-t;const o=a.landmarks,u=[];if(o)return o.forEach((m,d)=>{u[d]||(u[d]=[]),m.forEach(S=>{const M=B(S.x),R=B(1-S.y),F=B(S.z);u[d].push({x:M,y:R,z:F})})}),{coordinatesList:u}}async processBodyTracking(){if(!(this.disposed||this.paused||!this.landmarker)){if(this.shouldRunInference()){const e=await this.getBodyData();e&&(this.coordinates=e.coordinatesList)}this.disposed||this.paused||(this.rafId=requestAnimationFrame(this.processBodyTracking.bind(this)))}}resume(){this.paused&&(super.resume(),this.processBodyTracking())}dispose(){if(super.dispose(),this.landmarker){try{this.landmarker.close()}catch{}this.landmarker=null}this.sourceCanvas=void 0,this.downscaler.dispose(),this.coordinates=void 0}getLandmarks2D(e=0){if(this.coordinates)return this.coordinates[e]}async initialize(e){const t=await _.FilesetResolver.forVisionTasks(new URL("/assets/xr/wasm",E.assetStorageEndpoint).toString()),a=await H(new URL("/assets/xr/models/body_tracking.task",E.assetStorageEndpoint).toString());this.landmarker=await _.PoseLandmarker.createFromOptions(t,{baseOptions:{modelAssetBuffer:a,delegate:"GPU"},runningMode:"VIDEO",numPoses:(e==null?void 0:e.numPoses)||1})}async run({sourceCanvas:e,targetFps:t}){this.sourceCanvas=e,this.setTargetFps(t),this.rafId===null&&await this.processBodyTracking()}getModelNode(){return{getLandmarks2D:this.getLandmarks2D.bind(this)}}async getPerformanceData(){return{name:this.constructor.name,processingTime:this.processingTime}}}const Ue=.11,ze=.004,Le=(n,s)=>s.set(n.x,-n.y,n.z);class Be extends G{constructor(){super();h(this,"landmarker",null);h(this,"processingTime",null);h(this,"sourceCanvas");h(this,"analysisCanvas");h(this,"getSource");h(this,"detectionResults");h(this,"numFaces",1);h(this,"cameras",[]);h(this,"faces",[]);h(this,"leftCheekScratch",[]);h(this,"rightCheekScratch",[]);h(this,"landmarkScratch",{x:0,y:0,z:0,visibility:0});h(this,"rotMatrixScratch",new D.Matrix4);h(this,"rotQuatScratch",new D.Quaternion);h(this,"rotEulerScratch",new D.Euler)}landmarkForSource(e,t){return t?(this.landmarkScratch.x=1-e.x,this.landmarkScratch.y=e.y,this.landmarkScratch.z=e.z,this.landmarkScratch.visibility=e.visibility,this.landmarkScratch):e}extractAndUpdateFaceData(e){var a;if(!e.faceLandmarks.length){this.faces=[];return}const t=e.faceLandmarks.length;for(this.faces.length>t&&(this.faces.length=t,this.leftCheekScratch.length=t,this.rightCheekScratch.length=t);this.faces.length<t;)this.faces.push({transform:{position:new D.Vector3,rotation:new D.Vector3,scale:new D.Vector3},gestures:{}}),this.leftCheekScratch.push(new D.Vector3),this.rightCheekScratch.push(new D.Vector3);for(let r=0;r<t;r+=1){if(!this.cameras[r])continue;const o=this.faces[r],u=(a=this.getSource)==null?void 0:a.call(this),m=!(u==="webcam"||!u),d=e.faceLandmarks[r],S=e.facialTransformationMatrixes[r];this.rotMatrixScratch.fromArray(S.data),this.rotQuatScratch.setFromRotationMatrix(this.rotMatrixScratch),this.rotQuatScratch.set(-this.rotQuatScratch.x,this.rotQuatScratch.y,this.rotQuatScratch.z,this.rotQuatScratch.w),this.rotEulerScratch.setFromQuaternion(this.rotQuatScratch,"XYZ"),Le(this.rotEulerScratch,o.transform.rotation),q(this.landmarkForSource(d[4],m),this.cameras[r],o.transform.position),q(this.landmarkForSource(d[50],m),this.cameras[r],this.leftCheekScratch[r]),q(this.landmarkForSource(d[280],m),this.cameras[r],this.rightCheekScratch[r]);const R=this.leftCheekScratch[r].distanceTo(this.rightCheekScratch[r])*Ue,F=Math.abs(D.MathUtils.radToDeg(this.rotEulerScratch.y)),g=R+F*ze,f=o.transform.scale.x,w=be(isNaN(f)?0:f,g);o.transform.scale.set(w,w,w);const p=o.gestures,k=e.faceBlendshapes[r].categories;for(const C of k)p[C.categoryName]=C.score}}async processFaceTracking(){if(this.disposed||this.paused||!this.landmarker||!this.sourceCanvas)return null;if(!this.shouldRunInference()){this.rafId=requestAnimationFrame(this.processFaceTracking.bind(this));return}const e=Ve(this.numFaces),t=this.sourceCanvas.width,a=this.sourceCanvas.height,r=Math.min(1,e/Math.max(t,a)),o=Math.max(1,Math.round(t*r)),u=Math.max(1,Math.round(a*r));(!this.analysisCanvas||this.analysisCanvas.width!==o||this.analysisCanvas.height!==u)&&(this.analysisCanvas=new OffscreenCanvas(o,u));const m=this.analysisCanvas.getContext("2d");if(!m){this.rafId=requestAnimationFrame(this.processFaceTracking.bind(this));return}m.setTransform(1,0,0,1,0,0),m.clearRect(0,0,o,u),m.drawImage(this.sourceCanvas,0,0,o,u);const d=performance.now(),S=this.landmarker.detectForVideo(this.analysisCanvas,d),M=performance.now();this.processingTime=M-d,this.detectionResults=S,this.extractAndUpdateFaceData(S),!(this.disposed||this.paused)&&(this.rafId=requestAnimationFrame(this.processFaceTracking.bind(this)))}resume(){this.paused&&(super.resume(),this.processFaceTracking())}dispose(){if(super.dispose(),this.landmarker){try{this.landmarker.close()}catch{}this.landmarker=null}this.sourceCanvas=void 0,this.analysisCanvas=void 0,this.getSource=void 0,this.detectionResults=void 0,this.processingTime=null,this.cameras=[],this.faces=[],this.leftCheekScratch=[],this.rightCheekScratch=[]}getFace(e=0){return this.faces[e]}getDetectionResults(){return this.detectionResults}getRawFaceTrackingData(e=0){var t,a,r,o;if(this.detectionResults)return{landmarks:(t=this.detectionResults.faceLandmarks)==null?void 0:t[e],blendshapes:(r=(a=this.detectionResults.faceBlendshapes)==null?void 0:a[e])==null?void 0:r.categories,transformationMatrix:(o=this.detectionResults.facialTransformationMatrixes)==null?void 0:o[e]}}async initialize(e){this.numFaces=(e==null?void 0:e.numFaces)||1;const t=await _.FilesetResolver.forVisionTasks(new URL("/assets/xr/wasm",E.assetStorageEndpoint).toString()),a=await H(new URL("/assets/xr/models/face_tracking.task",E.assetStorageEndpoint).toString()),r=await _.FaceLandmarker.createFromOptions(t,{baseOptions:{modelAssetBuffer:a,delegate:"GPU"},minFaceDetectionConfidence:.3,minFacePresenceConfidence:.3,minTrackingConfidence:.3,outputFaceBlendshapes:!0,outputFacialTransformationMatrixes:!0,runningMode:"VIDEO",numFaces:this.numFaces});if(this.disposed){r.close();return}this.landmarker=r}async run({sourceCanvas:e,getSource:t,targetFps:a}){this.sourceCanvas=e,this.getSource=t,this.setTargetFps(a),this.analysisCanvas=void 0,this.rafId===null&&this.processFaceTracking()}getModelNode(){const e=this;return{get detectionResults(){return e.detectionResults},getDetectionResults:this.getDetectionResults.bind(this),getFace:this.getFace.bind(this),getRawFaceTrackingData:this.getRawFaceTrackingData.bind(this),setCamera:(a,r=0)=>{this.cameras[r]=a}}}async getPerformanceData(){return{name:this.constructor.name,processingTime:this.processingTime}}}const Ve=n=>n>1?1024:512;var O=(n=>(n.ClosedFist="closed_fist",n.OpenPalm="open_palm",n.PointingUp="pointing_up",n.ThumbDown="thumb_down",n.ThumbUp="thumb_up",n.Victory="victory",n.ILoveYou="i_love_you",n.None="none",n))(O||{});const Ke=512,Ne={Closed_Fist:O.ClosedFist,Open_Palm:O.OpenPalm,Pointing_Up:O.PointingUp,Thumb_Down:O.ThumbDown,Thumb_Up:O.ThumbUp,Victory:O.Victory,ILoveYou:O.ILoveYou,None:O.None},qe=15;class He extends G{constructor(){super();h(this,"landmarker",null);h(this,"processingTime",null);h(this,"coordinates");h(this,"gesture");h(this,"sourceCanvas");h(this,"downscaler",new $(Ke))}async getGestureData(){if(!this.landmarker||!this.sourceCanvas)return;const e=this.downscaler.draw(this.sourceCanvas),t=performance.now(),a=this.landmarker.recognizeForVideo(e,t),r=performance.now();this.processingTime=r-t;const o=a.landmarks[0],u=[];if(o){const m=a.gestures[0][0].categoryName;return o.forEach(d=>{u.push({x:B(d.x),y:B(1-d.y),z:-d.z})}),{coordinates:u,gesture:Ne[m]}}return{coordinates:void 0,gesture:void 0}}async processGestureTracking(){if(!this.disposed){if(this.shouldRunInference()){const e=await this.getGestureData();e&&(this.coordinates=e.coordinates,this.gesture=e.gesture)}this.disposed||this.paused||(this.rafId=requestAnimationFrame(this.processGestureTracking.bind(this)))}}resume(){this.paused&&(super.resume(),this.processGestureTracking())}dispose(){if(super.dispose(),this.landmarker){try{this.landmarker.close()}catch{}this.landmarker=null}this.sourceCanvas=void 0,this.downscaler.dispose(),this.coordinates=void 0,this.gesture=void 0}async initialize(){const e=await _.FilesetResolver.forVisionTasks(new URL("/assets/xr/wasm",E.assetStorageEndpoint).toString()),t=await H(new URL("/assets/xr/models/gesture_tracking.task",E.assetStorageEndpoint).toString()),a=await _.GestureRecognizer.createFromOptions(e,{baseOptions:{modelAssetBuffer:t,delegate:"GPU"},runningMode:"VIDEO",numHands:1});this.landmarker=a}async run({sourceCanvas:e,targetFps:t}){this.sourceCanvas=e,this.setTargetFps(t??qe),this.rafId===null&&await this.processGestureTracking()}getModelNode(){const e=this;return{get coordinates(){return e.coordinates},get gesture(){return e.gesture}}}async getPerformanceData(){return{name:this.constructor.name,processingTime:this.processingTime}}}const Ge=512;class je extends G{constructor(){super();h(this,"landmarker",null);h(this,"processingTime",null);h(this,"hands");h(this,"coordinates");h(this,"gesture");h(this,"handedness");h(this,"sourceCanvas");h(this,"downscaler",new $(Ge))}async getHandData(){if(!this.landmarker||!this.sourceCanvas)return;const e=this.downscaler.draw(this.sourceCanvas),t=performance.now(),a=this.landmarker.detectForVideo(e,t),r=performance.now();this.processingTime=r-t;const o=[],u=a.handedness??a.handednesses??[];if(a.landmarks.forEach((d,S)=>{var f,w,p;if(!d||d.length===0)return;const M=d.map(k=>({x:B(k.x),y:B(1-k.y),z:-k.z})),R=(p=(w=(f=u[S])==null?void 0:f[0])==null?void 0:w.categoryName)==null?void 0:p.toLowerCase(),F=R==="left"||R==="right"?R:void 0,g=d[0].z<0?"closed_fist":"open_palm";o.push({coordinates:M,gesture:g,handedness:F})}),!o.length)return{hands:void 0,coordinates:void 0,gesture:void 0,handedness:void 0};const m=o[0];return{hands:o,coordinates:m.coordinates,gesture:m.gesture,handedness:m.handedness}}async processHandTracking(){if(!this.disposed){if(this.shouldRunInference()){const e=await this.getHandData();e&&(this.hands=e.hands,this.coordinates=e.coordinates,this.gesture=e.gesture,this.handedness=e.handedness)}this.disposed||this.paused||(this.rafId=requestAnimationFrame(this.processHandTracking.bind(this)))}}resume(){this.paused&&(super.resume(),this.processHandTracking())}dispose(){if(super.dispose(),this.landmarker){try{this.landmarker.close()}catch{}this.landmarker=null}this.sourceCanvas=void 0,this.hands=void 0,this.downscaler.dispose(),this.coordinates=void 0,this.gesture=void 0,this.handedness=void 0}async initialize(){const e=await _.FilesetResolver.forVisionTasks(new URL("/assets/xr/wasm",E.assetStorageEndpoint).toString()),t=await H(new URL("/assets/xr/models/hand_tracking.task",E.assetStorageEndpoint).toString()),a=await _.HandLandmarker.createFromOptions(e,{baseOptions:{modelAssetBuffer:t,delegate:"GPU"},runningMode:"VIDEO",numHands:2});this.landmarker=a}async run({sourceCanvas:e,targetFps:t}){this.sourceCanvas=e,this.setTargetFps(t),this.rafId===null&&await this.processHandTracking()}getModelNode(){const e=this;return{get hands(){return e.hands},get coordinates(){return e.coordinates},get gesture(){return e.gesture},get handedness(){return e.handedness}}}async getPerformanceData(){return{name:this.constructor.name,processingTime:this.processingTime}}}const We=24,Xe=720,Ye=[[255,255,255,255],[0,0,0,0]];class Qe extends G{constructor(){super();h(this,"segmenter",null);h(this,"processingTime",null);h(this,"sourceCanvas");h(this,"processCanvas");h(this,"filterCanvas");h(this,"inputSource");h(this,"inputSourceSize");h(this,"glCanvas");h(this,"drawingUtils");h(this,"useGpuMaskPath",!1);h(this,"maskImageData");h(this,"maskCanvas",null);h(this,"segmentationMaskTexture");h(this,"isMaskSetup",!1);h(this,"isProcessing",!1);h(this,"latestMask",null);h(this,"rawCache",null);h(this,"quality","medium");h(this,"stagingCanvas")}getQualityScaleFactor(){switch(this.quality){case"low":return .5;case"medium":return .75;case"high":return 1;default:return .5}}setInputSource(e){this.inputSource=e,this.inputSourceSize=e?this.readIntrinsicSize(e):void 0}readIntrinsicSize(e){if(e instanceof HTMLVideoElement)return e.videoWidth>0?{width:e.videoWidth,height:e.videoHeight}:void 0;if(e instanceof HTMLImageElement)return e.naturalWidth>0?{width:e.naturalWidth,height:e.naturalHeight}:void 0;const t=e.width,a=e.height;return typeof t=="number"&&t>0&&typeof a=="number"&&a>0?{width:t,height:a}:void 0}ensureProcessCanvasForInput(){if(!this.processCanvas||!this.inputSource)return;const e=this.readIntrinsicSize(this.inputSource);if(!e)return;this.inputSourceSize=e;const t=Math.min(1,Xe/Math.max(e.width,e.height)),a=Math.max(1,Math.round(e.width*t)),r=Math.max(1,Math.round(e.height*t));this.processCanvas.width===a&&this.processCanvas.height===r||(this.processCanvas.width=a,this.processCanvas.height=r,this.glCanvas&&(this.glCanvas.width=a,this.glCanvas.height=r),this.maskImageData=void 0)}async processSegmentation(){if(this.disposed||!this.isProcessing||!this.maskCanvas||!this.processCanvas)return;if(!this.shouldRunInference()){if(this.disposed||this.paused)return;this.rafId=requestAnimationFrame(this.processSegmentation.bind(this));return}const e=this.inputSource??this.sourceCanvas;if(!this.segmenter||!e){if(this.disposed||this.paused)return;this.rafId=requestAnimationFrame(this.processSegmentation.bind(this));return}const t=performance.now();this.ensureProcessCanvasForInput();const a=this.processCanvas.getContext("2d");if(a){const u=this.processCanvas.width,m=this.processCanvas.height;if(a.clearRect(0,0,u,m),this.inputSource&&this.inputSourceSize){const{width:d,height:S}=this.inputSourceSize,M=Math.min(u/d,m/S),R=d*M,F=S*M;a.drawImage(this.inputSource,(u-R)/2,(m-F)/2,R,F)}else a.drawImage(e,0,0,u,m)}const o=this.segmenter.segmentForVideo(this.processCanvas,performance.now()).categoryMask;if(!o){if(this.disposed||this.paused)return;this.rafId=requestAnimationFrame(this.processSegmentation.bind(this));return}if(this.rawCache=null,this.latestMask&&(this.latestMask.close(),this.latestMask=null),this.useGpuMaskPath&&this.drawingUtils&&this.glCanvas)this.drawingUtils.drawCategoryMask(o,Ye),this.latestMask=o.clone(),o.close(),this.blitGlToMask();else{this.latestMask=o.clone();const u=this.readMaskToImageData(o);o.close(),u&&this.blitImageDataToMask(u)}this.segmentationMaskTexture&&(this.isMaskSetup||(this.segmentationMaskTexture.format=P.RGBAFormat,this.segmentationMaskTexture.minFilter=P.LinearFilter,this.segmentationMaskTexture.magFilter=P.LinearFilter,this.segmentationMaskTexture.generateMipmaps=!1,this.isMaskSetup=!0),this.segmentationMaskTexture.needsUpdate=!0),this.processingTime=performance.now()-t,!(this.disposed||this.paused)&&(this.rafId=requestAnimationFrame(this.processSegmentation.bind(this)))}blitGlToMask(){if(!this.maskCanvas||!this.filterCanvas||!this.glCanvas)return;const e=this.maskCanvas.getContext("2d"),t=this.filterCanvas.getContext("2d");!e||!t||(t.filter="blur(0.5px)",t.clearRect(0,0,this.filterCanvas.width,this.filterCanvas.height),t.drawImage(this.glCanvas,0,0,this.filterCanvas.width,this.filterCanvas.height),e.clearRect(0,0,this.maskCanvas.width,this.maskCanvas.height),e.drawImage(this.filterCanvas,0,0,this.maskCanvas.width,this.maskCanvas.height))}readMaskToImageData(e){const t=e.getAsUint8Array(),{width:a,height:r}=e;if(!t||a<=0||r<=0)return null;(!this.maskImageData||this.maskImageData.width!==a||this.maskImageData.height!==r)&&(this.maskImageData=new ImageData(a,r));const o=this.maskImageData.data;for(let u=0;u<t.length;u+=1){const m=t[u]===255?0:255;o[u*4]=255,o[u*4+1]=m,o[u*4+2]=255,o[u*4+3]=m}return this.maskImageData}blitImageDataToMask(e){if(!this.maskCanvas||!this.filterCanvas)return;const t=this.maskCanvas.getContext("2d"),a=this.filterCanvas.getContext("2d");if(!t||!a)return;const r=this.getStagingCanvas(e.width,e.height),o=r.getContext("2d");o&&(o.putImageData(e,0,0),a.filter="blur(0.5px)",a.clearRect(0,0,this.filterCanvas.width,this.filterCanvas.height),a.drawImage(r,0,0,this.filterCanvas.width,this.filterCanvas.height),t.clearRect(0,0,this.maskCanvas.width,this.maskCanvas.height),t.drawImage(this.filterCanvas,0,0,this.maskCanvas.width,this.maskCanvas.height))}getStagingCanvas(e,t){return this.stagingCanvas||(this.stagingCanvas=document.createElement("canvas")),this.stagingCanvas.width!==e&&(this.stagingCanvas.width=e),this.stagingCanvas.height!==t&&(this.stagingCanvas.height=t),this.stagingCanvas}resume(){this.paused&&(super.resume(),this.processSegmentation())}dispose(){if(super.dispose(),this.isProcessing=!1,this.latestMask){try{this.latestMask.close()}catch{}this.latestMask=null}if(this.rawCache=null,this.segmenter){try{this.segmenter.close()}catch{}this.segmenter=null}this.drawingUtils=void 0,this.glCanvas=void 0,this.maskImageData=void 0,this.segmentationMaskTexture&&(this.segmentationMaskTexture.dispose(),this.segmentationMaskTexture=void 0),this.sourceCanvas=void 0,this.inputSource=void 0,this.inputSourceSize=void 0,this.processCanvas=void 0,this.filterCanvas=void 0,this.stagingCanvas=void 0,this.maskCanvas=null}async initialize(e){this.quality=(e==null?void 0:e.quality)??"low";const t=await _.FilesetResolver.forVisionTasks(new URL("/assets/xr/wasm",E.assetStorageEndpoint).toString()),a=await H(new URL("/assets/xr/models/segmentation.tflite",E.assetStorageEndpoint).toString());this.glCanvas=new OffscreenCanvas(1,1);const r=this.glCanvas.getContext("webgl2",{preserveDrawingBuffer:!0});this.segmenter=await _.ImageSegmenter.createFromOptions(t,{baseOptions:{modelAssetBuffer:a,delegate:"GPU"},...r?{canvas:this.glCanvas}:{},outputCategoryMask:!0,outputConfidenceMasks:!1,runningMode:"VIDEO"}),r?(this.drawingUtils=new _.DrawingUtils(r),this.useGpuMaskPath=!0):this.useGpuMaskPath=!1}async run({sourceCanvas:e,renderWidth:t,renderHeight:a,targetFps:r}){var u;if(!e)return;this.setTargetFps(r??We),this.isProcessing=!1,this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null);const o=this.getQualityScaleFactor();this.sourceCanvas=e,this.processCanvas=document.createElement("canvas"),this.processCanvas.width=e.width*o,this.processCanvas.height=e.height*o,this.glCanvas&&(this.glCanvas.width=this.processCanvas.width,this.glCanvas.height=this.processCanvas.height),this.maskImageData=void 0,this.maskCanvas=document.createElement("canvas"),this.maskCanvas.width=t,this.maskCanvas.height=a,this.filterCanvas=document.createElement("canvas"),this.filterCanvas.width=t,this.filterCanvas.height=a,(u=this.segmentationMaskTexture)==null||u.dispose(),this.segmentationMaskTexture=new P.CanvasTexture(this.maskCanvas),this.isMaskSetup=!1,this.rawCache=null,this.isProcessing=!0,this.lastInferenceMs=0,this.rafId=requestAnimationFrame(this.processSegmentation.bind(this))}getRawSegmentationData(){if(this.rawCache)return this.rawCache;if(!this.latestMask)return null;const e=this.latestMask.getAsUint8Array();return this.rawCache={maskData:e,width:this.latestMask.width,height:this.latestMask.height},this.rawCache}getModelNode(){const e=this;return{get backgroundSegmentationMask(){return e.segmentationMaskTexture},getMaskCanvas:()=>e.maskCanvas,getRawSegmentationData:()=>e.getRawSegmentationData(),setInputSource:t=>e.setInputSource(t??void 0)}}async getPerformanceData(){return{name:this.constructor.name,processingTime:this.processingTime}}}const ae={[L.BACKGROUND_SEGMENTATION]:Qe,[L.HAND_TRACKER]:je,[L.GESTURE_TRACKER]:He,[L.FACE_TRACKER]:Be,[L.BODY_TRACKER]:Oe},Ze=async n=>{const s=document.createElement("video");s.srcObject=n,s.muted=!0,s.playsInline=!0,s.autoplay=!0,await new Promise(t=>{s.onloadedmetadata=()=>{s.play(),t()}});const e=s;return await new Promise(t=>{const a=setTimeout(t,150),r=()=>{clearTimeout(a),t()};typeof e.requestVideoFrameCallback=="function"?e.requestVideoFrameCallback(r):requestAnimationFrame(()=>requestAnimationFrame(()=>r()))}),s},$e=n=>{const s=new P.CanvasTexture(n);return s.colorSpace=P.SRGBColorSpace,s.format=P.RGBAFormat,s.minFilter=P.LinearFilter,s.magFilter=P.LinearFilter,s.generateMipmaps=!1,s.needsUpdate=!0,s},Je=(n,s)=>{const e=n.videoWidth,t=n.videoHeight;e>0&&t>0&&(s.width!==e&&(s.width=e),s.height!==t&&(s.height=t));const a=s.getContext("2d",{colorSpace:"srgb"});a.save(),a.scale(-1,1),a.drawImage(n,-s.width,0,s.width,s.height),a.restore()},et=(n,s,e=1)=>{const t=s.getContext("2d",{colorSpace:"srgb"}),a=s.width/s.height,r=n.width/n.height;let o,u;r>a?(u=s.height,o=n.width*(s.height/n.height)):(o=s.width,u=n.height*(s.width/n.width));const m=Number.isFinite(e)&&e>0?e:1;o*=m,u*=m;const d=(s.width-o)/2,S=(s.height-u)/2;t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,s.width,s.height),t.drawImage(n,0,0,n.width,n.height,d,S,o,u)},tt=(n,s,e)=>{const t=new Map;let a=!1;const r=(g,f)=>{var w;try{(w=f.dispose)==null||w.call(f)}catch(p){console.warn(`[xr-sdk registry] dispose threw for ${g}`,p)}};return{acquire:async(g,f,w)=>{let p=t.get(g);if(p)return p.refs.add(f),p.activeRefs.add(f),p.initPromise;const k=s[g];if(!k)throw new Error(`Invalid model: ${g}`);const C=new k,K=new Set([f]),V=new Set([f]),U=(async()=>{await C.initialize(w);const N=t.get(g);if(!N||N.model!==C||N.refs.size===0)return r(g,C),C;e&&await e(g,C);const T=t.get(g);return T&&T.refs.size>0&&n.setPipeline(z=>z.set(g,C)),C})();return p={model:C,refs:K,activeRefs:V,initPromise:U,options:w},t.set(g,p),U.catch(()=>{t.get(g)===p&&(t.delete(g),n.setPipeline(T=>T.delete(g))),r(g,C)}),U},release:(g,f)=>{const w=t.get(g);w&&(w.refs.delete(f),w.activeRefs.delete(f)&&w.refs.size>0&&w.activeRefs.size===0&&w.model.pause(),!(w.refs.size>0)&&(t.delete(g),r(g,w.model),n.setPipeline(p=>p.delete(g))))},setActive:(g,f,w)=>{const p=t.get(g);if(!p||!p.refs.has(f))return;const k=p.activeRefs.size>0;w?p.activeRefs.add(f):p.activeRefs.delete(f);const C=p.activeRefs.size>0;k!==C&&(C&&!a?p.model.resume():p.model.pause())},suspendAll:()=>{a=!0;for(const g of t.values())g.model.pause()},resumeActive:()=>{a=!1;for(const g of t.values())g.activeRefs.size>0&&g.model.resume()},get:g=>{var f;return(f=t.get(g))==null?void 0:f.model},getOptions:g=>{var f;return(f=t.get(g))==null?void 0:f.options},releaseAll:()=>{for(const g of Array.from(t.keys())){const f=t.get(g);f&&(f.refs.clear(),t.delete(g),r(g,f.model))}n.setPipeline(g=>g.clear())}}},st={lifecycle:"idle",ready:!1,error:void 0,cameraTexture:void 0,renderWidth:0,renderHeight:0,source:void 0,sourceKind:void 0,pipeline:new Map},nt=()=>{let n={...st,pipeline:new Map};const s=new Set,e=()=>{s.forEach(t=>t())};return{getSnapshot:()=>n,set:t=>{let a=!1;for(const r of Object.keys(t))if(t[r]!==n[r]){a=!0;break}a&&(n={...n,...t},e())},setPipeline:t=>{const a=new Map(n.pipeline);return t(a),n={...n,pipeline:a},e(),a},subscribe:t=>(s.add(t),()=>{s.delete(t)})}},it=({renderHeight:n,renderWidth:s,videoHeight:e,videoWidth:t})=>({height:n||e,width:s||t}),at=n=>{const s=new Fe({verbose:!0}),e=nt();let t=n;const a=i=>{var l;const c=(l=T.getOptions(i))==null?void 0:l.targetFps;return typeof c=="number"?c:t==null?void 0:t.targetFps};let r,o,u,m,d,S,M,R,F,g,f,w=!1,p=!1,k=0;const C=new Set,K=new Set,V=i=>{const c=e.getSnapshot().cameraTexture;c&&c.dispose();const l=$e(i);return e.set({cameraTexture:l}),l},U=async(i,c)=>{if(C.has(i)||e.getSnapshot().lifecycle!=="running"||!d)return;C.add(i);const l=k;try{await c.run({sourceCanvas:d,renderWidth:e.getSnapshot().renderWidth,renderHeight:e.getSnapshot().renderHeight,getSource:()=>e.getSnapshot().sourceKind,targetFps:a(i)}),p&&(await new Promise(v=>requestAnimationFrame(()=>v())),await new Promise(v=>requestAnimationFrame(()=>v())),p&&k===l&&T.suspendAll())}catch(v){throw C.delete(i),v}},T=tt(e,ae,(i,c)=>U(i,c));e.subscribe(()=>{if(e.getSnapshot().lifecycle!=="running")return;const i=e.getSnapshot().pipeline;for(const[c,l]of i.entries())C.has(c)||U(c,l)});const z=()=>{if(f!==void 0&&(cancelAnimationFrame(f),f=void 0),o){try{o.pause()}catch{}try{o.srcObject=null}catch{}o=void 0}if(u){try{u.getTracks().forEach(i=>i.stop())}catch{}u=void 0}},j=()=>{if(w||!o||!m||!d)return;const i=window.__xr_debugger_metrics;if(i!=null&&i.trackCameraFrame&&i.trackCameraFrame(),(e.getSnapshot().sourceKind??"webcam")==="webcam")Je(o,m);else{const v=m.getContext("2d");if(!v)return;const y=o.videoWidth,A=o.videoHeight;m.width!==y&&(m.width=y),m.height!==A&&(m.height=A),v.setTransform(1,0,0,1,0,0),v.clearRect(0,0,y,A),v.drawImage(o,0,0,y,A)}et(m,d,(t==null?void 0:t.cameraZoom)??1.2);const l=e.getSnapshot().cameraTexture;l&&(l.needsUpdate=!0)},J=()=>{if(!o||!m||!d)return;if(p){j();return}const i=()=>{f=requestAnimationFrame(i),j()};f=requestAnimationFrame(i)},ue=async i=>{if(i.source===x.WEBCAM)try{const c=t!=null&&t.camRes&&t.camRes>0?t.camRes:960;return await navigator.mediaDevices.getUserMedia({video:{facingMode:"user",frameRate:{min:24,ideal:30,max:60},width:{ideal:c}}})}catch(c){const l=c instanceof DOMException?c.name:"",v=l==="NotReadableError"||l==="TrackStartError"?"Camera is already in use by another app or browser tab. Close it and refresh.":l==="NotFoundError"||l==="DevicesNotFoundError"?"No camera was found on this device.":l==="NotAllowedError"||l==="PermissionDeniedError"?"Camera access was blocked. Allow camera permissions in your browser, then refresh.":"Unable to access camera. Allow camera permissions in your browser, then refresh.";throw e.set({error:{error:"PermissionError",message:v}}),new I(c instanceof Error?c.message:"getUserMedia failed")}return i.stream},W=async i=>{const c=await ue(i);u=c;const l=await Ze(c);o=l,m=new OffscreenCanvas(l.videoWidth,l.videoHeight);const{renderWidth:v,renderHeight:y}=e.getSnapshot(),A=it({renderWidth:v,renderHeight:y,videoWidth:l.videoWidth,videoHeight:l.videoHeight});d?(d.width!==A.width||d.height!==A.height)&&(d.width=A.width,d.height=A.height,V(d)):(d=new OffscreenCanvas(A.width,A.height),V(d));const ne=i.source===x.STREAM?i.static===!0:!1;p=ne,r=i.source===x.WEBCAM?{source:x.WEBCAM,sourceKind:"webcam"}:{source:x.STREAM,stream:i.stream,static:ne,sourceKind:i.sourceKind??"webcam"},e.set({source:i.source,sourceKind:r.sourceKind,error:void 0})},X=async i=>{const c=i.sourceKind??"webcam";d=i.canvas;const l=V(d);e.set({cameraTexture:l,source:x.CANVAS,sourceKind:c,renderWidth:d.width,renderHeight:d.height,error:void 0}),r={source:x.CANVAS,canvas:i.canvas,sourceKind:c}},le=(i,c)=>!c||i.source!==c.source?!1:i.source===x.STREAM&&c.source===x.STREAM?i.stream===c.stream&&(i.sourceKind??"webcam")===c.sourceKind:!0,ge=async()=>{if(!d)return;const i=k,c=e.getSnapshot().pipeline;for(const[,l]of c.entries())l.resume();await new Promise(l=>requestAnimationFrame(()=>l())),await new Promise(l=>requestAnimationFrame(()=>l())),p&&k===i&&T.suspendAll()},me=(i,c)=>!c||c.source!==x.CANVAS?!1:i.canvas===c.canvas&&(i.sourceKind??"webcam")===c.sourceKind,fe=async i=>{const c=i.source;if(c!==x.WEBCAM&&c!==x.STREAM)throw new I(`Invalid media source: ${String(c)}`);if(le(i,r)){s.log("Media source unchanged, skipping rebind.");return}k+=1;const{lifecycle:l}=e.getSnapshot();if(l==="idle"||l==="stopped"){await W(i),e.set({lifecycle:"media-bound"}),s.log("Media source set to:",i.source);return}if(l==="media-bound"){z(),await W(i),s.log("Media source rebound to:",i.source);return}w=!0,await new Promise(v=>requestAnimationFrame(()=>v())),z(),await W(i),w=!1,J(),p?await ge():T.resumeActive(),s.log("Media source swapped to:",i.source)},pe=async i=>{if(me(i,r)){s.log("Frame source unchanged, skipping rebind.");return}k+=1;const{lifecycle:c}=e.getSnapshot();if(c==="idle"||c==="stopped"){await X(i),e.set({lifecycle:"media-bound"}),s.log("Frame source set to canvas.");return}if(c==="media-bound"){z(),await X(i),s.log("Frame source rebound to canvas.");return}w=!0,await new Promise(l=>requestAnimationFrame(()=>l())),z(),await X(i),w=!1,s.log("Frame source swapped to canvas.")},ve=async()=>{const{lifecycle:i}=e.getSnapshot();if(i==="running")return;if(i==="idle")throw new I("session.start() called before setMediaSource — call setMediaSource first");if(!d)throw new I("session.start(): media source not bound");const c=(r==null?void 0:r.source)===x.CANVAS;if(!c&&(!o||!m))throw i==="stopped"?new I("session.start() called from stopped state without a media source — call setMediaSource first"):new I("session.start(): media source not bound");c||J(),T.resumeActive(),e.set({lifecycle:"running"}),await new Promise(v=>requestAnimationFrame(()=>v()));const l=e.getSnapshot().pipeline;for(const[v,y]of l.entries())await U(v,y);e.set({ready:!0}),s.log("XR session started.")},ee=async()=>{const{lifecycle:i}=e.getSnapshot();i==="stopped"||i==="idle"||(z(),T.suspendAll(),e.set({lifecycle:"stopped",ready:!1}),s.log("XR session stopped."))},we=async()=>{await ee(),T.releaseAll(),K.clear();const i=e.getSnapshot().cameraTexture;i&&i.dispose(),C.clear(),r=void 0,k+=1,d=void 0,m=void 0,p=!1,e.set({lifecycle:"idle",cameraTexture:void 0,source:void 0}),s.log("XR session reset.")},Ce=async i=>{const c="legacy:registerXRPipeline",l=[];await Promise.all(i.map(async v=>{const{model:y}=v;if(!ae[y])throw new I(`Invalid model: ${y}`);K.has(y)||l.push(y);const A="options"in v?v.options:void 0;await T.acquire(y,c,A)})),l.length>0&&(l.forEach(v=>K.add(v)),s.log("XR pipeline registered."))},Se=i=>{const c=T.get(i);if(!c)throw new I(`Model ${i} is not registered in the pipeline`);return c.getModelNode()},te=async(i,c)=>{i<=0||c<=0||(e.set({renderWidth:i,renderHeight:c}),d&&(d.width!==i||d.height!==c)&&(d.width=i,d.height=c,V(d),p&&j()),s.log(`Source canvas set. Render size: ${i}x${c}`))},ke=async i=>{var y;S=i;const c=(y=i.getBoundingClientRect)==null?void 0:y.call(i),l=c&&c.width>0?Math.round(c.width):i.clientWidth,v=c&&c.height>0?Math.round(c.height):i.clientHeight;await te(l,v)},ye=i=>{M=i.renderer,R=i.scene,F=i.camera,g=i.renderFrame},se=()=>{if(!M||!R||!F)throw new I("XR frame render requested before the R3F state was bound — make sure <XRScene> is mounted");g?g():M.render(R,F)};return{store:e,registry:T,setMediaSource:fe,start:ve,stop:ee,reset:we,setFrameSource:pe,registerXRPipeline:Ce,getModelNode:Se,captureFrame:()=>{if(!S)throw new I("session.captureFrame() called before the XRScene render target was bound — make sure <XRScene> is mounted");if(!M||!R||!F)throw new I("session.captureFrame() called before the R3F state was bound — make sure <XRScene> is mounted");return se(),S.toDataURL("image/png")},getInputFrame:()=>d??null,_setRenderTarget:ke,_setRenderSize:te,_setR3FState:ye,_renderFrame:se,_getVideoElement:()=>o,_setPerf:i=>{if(t=i,e.getSnapshot().lifecycle!=="running"||!d)return;const c=e.getSnapshot().pipeline;for(const[l,v]of c.entries())v.run({sourceCanvas:d,renderWidth:e.getSnapshot().renderWidth,renderHeight:e.getSnapshot().renderHeight,getSource:()=>e.getSnapshot().sourceKind,targetFps:a(l)})}}},rt=n=>{const s=b.useRef(n),e=b.useMemo(()=>at(s.current),[]),t=JSON.stringify(n??{});return b.useEffect(()=>{e._setPerf(n)},[e,t]),e},Z=new Map,ot=()=>({register:(n,s)=>{s?Z.set(n,s):Z.delete(n)},resolve:n=>n?Z.get(n)??null:null}),oe=ot(),ce=b.createContext(null),ct=({children:n})=>{const s=b.useRef(new Map),e=b.useCallback((r,o)=>{o?s.current.set(r,o):s.current.delete(r)},[]),t=b.useCallback(r=>r?s.current.get(r)??null:null,[]),a=b.useMemo(()=>({register:e,resolve:t}),[e,t]);return b.createElement(ce.Provider,{value:a},n)},he=()=>b.useContext(ce)??oe,ht=()=>he().register,dt=()=>he().resolve;oe.register;const de=b.createContext(void 0),ut=()=>{const n=b.useContext(de);if(!n)throw new I("XR context can only be used inside XRProvider, did you forget to wrap your app in <XRProvider>?");return n},lt=({children:n,perf:s})=>{const e=rt(s),t=b.useMemo(()=>({session:e}),[e]);return ie.jsx(de.Provider,{value:t,children:ie.jsx(ct,{children:n})})};exports.XRMediaSource=x;exports.XRModel=L;exports.XRProvider=lt;exports.fetchAndVerify=re;exports.libConfig=E;exports.unprojectToZZero=Ae;exports.unprojectToZZeroInto=q;exports.useRegisterRuntimeObject=ht;exports.useResolveRuntimeObject=dt;exports.useXRContext=ut;
|