@vincentt-xr/sdk 2.0.0-alpha.7 → 2.0.0-alpha.8
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 +1109 -13
- package/dist/{DebuggerUI-BjOMr8q_.js → DebuggerUI-C-ldiozL.js} +1 -1
- package/dist/{DebuggerUI-B6bP6P9r.cjs → DebuggerUI-CWX5EtQv.cjs} +1 -1
- package/dist/FaceMeshRenderer-BEEXZwS6.cjs +158 -0
- package/dist/FaceMeshRenderer-UuH5sTXG.js +1322 -0
- package/dist/FaceRetouch-C7h7x9kd.js +683 -0
- package/dist/FaceRetouch-DqftT26Y.cjs +134 -0
- package/dist/GLTFLoader-C5q63sKO.js +1633 -0
- package/dist/GLTFLoader-Cb_CRwmG.cjs +1 -0
- package/dist/SegmentationOverlay-DQuW3dsc.js +133 -0
- package/dist/SegmentationOverlay-aWVod8Kl.cjs +1 -0
- package/dist/assets/cache.d.ts +99 -0
- package/dist/assets/estimate.d.ts +11 -0
- package/dist/assets/index.d.ts +7 -0
- package/dist/assets/loaders.d.ts +28 -0
- package/dist/assets/react.d.ts +33 -0
- package/dist/calibration/calibration.d.ts +70 -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/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/BodyTracker/index.d.ts +9 -0
- package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +33 -3
- package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +12 -0
- package/dist/components/FaceMesh/canonical/shaders.d.ts +1 -1
- package/dist/components/FaceMesh/index.d.ts +1 -1
- package/dist/components/GestureListener/index.d.ts +11 -0
- package/dist/components/HandTracker/index.d.ts +10 -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/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 +7 -1
- package/dist/components/LipEffect/LipEffectMaterial.d.ts +43 -7
- package/dist/components/LipEffect/LipEffects.d.ts +9 -0
- package/dist/components/LipEffect/defaults.d.ts +27 -4
- package/dist/components/LipEffect/index.d.ts +11 -3
- package/dist/components/LipEffect/settings.d.ts +271 -0
- package/dist/components/LipEffect/types.d.ts +56 -9
- package/dist/components/LipEffect/useLipDesignTextures.d.ts +11 -0
- package/dist/components/LipEffect/uvGuide.d.ts +59 -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/XRProvider/index.d.ts +16 -2
- 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 +3 -0
- package/dist/constants/index.d.ts +4 -1
- package/dist/contexts-CO0sd4JQ.cjs +1 -0
- package/dist/{contexts-ByhzppYl.js → contexts-FzlnnMYD.js} +252 -246
- package/dist/coordinates/feed.d.ts +52 -0
- package/dist/coordinates/index.d.ts +5 -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/gesture-settings/index.d.ts +14 -0
- package/dist/debug-ui/holistic-tracker-settings/index.d.ts +16 -0
- package/dist/debug-ui/index.d.ts +14 -0
- 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.cjs +1 -1
- package/dist/debug-ui/media-source.js +1 -1
- package/dist/debug-ui/product-hotspots/index.d.ts +24 -0
- package/dist/debug-ui/segmentation-overlay-settings/index.d.ts +12 -0
- package/dist/debug-ui/xr-diagnostics/index.d.ts +25 -0
- package/dist/debug-ui.cjs +3 -3
- package/dist/debug-ui.js +2057 -1687
- package/dist/detector-K8aej4MB.js +59 -0
- package/dist/detector-ijypGtse.cjs +1 -0
- package/dist/entries/core.d.ts +18 -1
- package/dist/entries/face-effects.d.ts +11 -3
- package/dist/entries/low-level.d.ts +22 -3
- package/dist/entries/product.d.ts +11 -0
- package/dist/entries/tracking.d.ts +24 -1
- package/dist/face-effects.cjs +155 -1
- package/dist/face-effects.js +1134 -2197
- package/dist/gestures/definitions.d.ts +85 -0
- package/dist/gestures/detector.d.ts +87 -0
- package/dist/gestures/index.d.ts +8 -0
- package/dist/gestures/measures.d.ts +101 -0
- package/dist/gestures/settings.d.ts +49 -0
- package/dist/{getFaceInfo-C4QpCQIY.js → getFaceInfo-BkZfaQs-.js} +5 -5
- package/dist/{getFaceInfo-fA1bFBub.cjs → getFaceInfo-ahPxQFGu.cjs} +1 -1
- package/dist/hooks/selectors.d.ts +68 -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/useGesture.d.ts +32 -0
- package/dist/hooks/useIrisTracking.d.ts +45 -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--RgGzZ6X.cjs +47 -0
- package/dist/{index-VJ0SJwmG.js → index-CHVbH0hz.js} +4 -4
- package/dist/index-CeVkgsag.cjs +1 -0
- package/dist/index-CnGox6Xr.js +3054 -0
- package/dist/{index-ByoNj0QP.js → index-CsUdQ-pn.js} +113 -111
- package/dist/{index-BjmTe9eM.cjs → index-DKBAh6hV.cjs} +1 -1
- package/dist/index-DsZwTfG0.cjs +1 -0
- package/dist/index-Dw6tj2Mi.js +144 -0
- package/dist/index-OCPjOaeP.cjs +1 -0
- package/dist/{index-DXT3WccE.js → index-s9pF4zkG.js} +1065 -1101
- package/dist/internal-BYza1h8_.cjs +1 -0
- package/dist/{internal-Dmk1cTXq.js → internal-vsfNQycj.js} +15 -16
- package/dist/internal.cjs +1 -1
- package/dist/internal.js +2 -2
- package/dist/iris/compute.d.ts +25 -0
- package/dist/iris/index.d.ts +4 -0
- package/dist/iris/lead.d.ts +19 -0
- package/dist/iris/types.d.ts +87 -0
- package/dist/landmarkMask-CbTFzBYG.js +224 -0
- package/dist/landmarkMask-u7es2k4X.cjs +1 -0
- package/dist/low-level.cjs +1 -1
- package/dist/low-level.js +1085 -634
- package/dist/main.cjs +1 -1
- package/dist/main.js +1519 -465
- package/dist/measures-9dQPdw96.js +154 -0
- package/dist/measures-KfJzpvod.cjs +1 -0
- package/dist/models/Base/index.d.ts +49 -0
- package/dist/models/Body/index.d.ts +1 -1
- package/dist/models/Face/index.d.ts +1 -1
- package/dist/models/Hand/GestureTracking.d.ts +1 -1
- package/dist/models/Hand/HandTracking.d.ts +1 -1
- package/dist/models/Holistic/index.d.ts +49 -0
- package/dist/models/Holistic/result.d.ts +68 -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/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-C0Dlhh9Z.js +365 -0
- package/dist/providers-YNwkmNeK.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/{renderGroups-KZk6eRiY.js → renderGroups-CN1cGFUo.js} +1 -1
- package/dist/{renderGroups-80H3DpTl.cjs → renderGroups-O4KmaMl9.cjs} +1 -1
- package/dist/renderPasses-Cg-zqmEz.cjs +21 -0
- package/dist/renderPasses-NnKZVfBy.js +1460 -0
- package/dist/scene-object.cjs +1 -1
- package/dist/scene-object.js +2 -2
- package/dist/screenTransform-BenfCtZt.js +44 -0
- package/dist/screenTransform-BiXdpVf0.cjs +1 -0
- package/dist/segmentation-9PhSvc-R.cjs +1 -0
- package/dist/segmentation-CeOTKemr.js +5 -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 +46 -0
- package/dist/selectors-C5G1PMYL.js +195 -0
- package/dist/selectors-Du_PsVnW.cjs +1 -0
- package/dist/{session-CpkiK5YA.cjs → session-BBr0yN8h.cjs} +7 -7
- package/dist/{session-DLFN_VII.js → session-Cy0m7l7-.js} +76 -76
- package/dist/settings-DRR7-snV.cjs +1 -0
- package/dist/settings-aQk845NJ.js +73 -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 +1 -1
- package/dist/tracking.js +1056 -383
- package/dist/types/compositor.d.ts +21 -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 +27 -2
- package/dist/types/segmentation.d.ts +19 -0
- package/dist/types/session.d.ts +41 -3
- package/dist/useFaceInfo-Blf7FCu3.js +303 -0
- package/dist/useFaceInfo-C5mO8NQY.cjs +1 -0
- package/dist/useXRCapabilities-B1R2ghy-.cjs +1 -0
- package/dist/useXRCapabilities-C68v__wB.js +30 -0
- package/dist/utils/fns.d.ts +6 -3
- package/dist/utils/integrity.d.ts +4 -1
- package/dist/utils/updateThrottle.d.ts +2 -0
- package/dist/utils/useStableUniforms.d.ts +18 -0
- package/docs/api/adaptive-quality.mdx +104 -0
- package/docs/api/asset-lifecycle.mdx +78 -0
- package/docs/api/camera-permission.mdx +142 -0
- package/docs/api/coordinate-spaces.mdx +165 -0
- package/docs/api/cross-camera.mdx +88 -0
- package/docs/api/diagnostics-calibration.mdx +97 -0
- package/docs/api/face-effects.mdx +6 -0
- package/docs/api/face-mesh.mdx +4 -2
- package/docs/api/gestures.mdx +173 -0
- package/docs/api/holistic-tracker.mdx +159 -0
- package/docs/api/iris-tracking.mdx +242 -0
- package/docs/api/multi-subject.mdx +95 -0
- package/docs/api/person-cutout.mdx +136 -0
- package/docs/api/product-ar.mdx +111 -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 +23 -1
- package/docs/examples/lip-shaders.mdx +224 -0
- package/docs/guides/lip-effect-textures.mdx +292 -0
- package/docs/guides/lip-uv-template.png +0 -0
- package/docs/guides/lip-uv-template.svg +1 -0
- package/package.json +13 -1
- 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/contexts-Dr62It_K.cjs +0 -1
- package/dist/index-9dlAQAhy.js +0 -1462
- package/dist/index-BpEf2BBb.cjs +0 -1
- package/dist/index-CyUUurQT.cjs +0 -1
- package/dist/index-DCiMbxC3.cjs +0 -1
- package/dist/index-DpI-qo5X.cjs +0 -17
- package/dist/index-DyVF4vEW.js +0 -111
- 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/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
|
@@ -6,6 +6,27 @@ export type XRLayerConfig = {
|
|
|
6
6
|
zIndex: number;
|
|
7
7
|
};
|
|
8
8
|
export type XRMediaSourceKind = "image" | "video";
|
|
9
|
+
/** Which camera a webcam bind asks for: the front (`user`) or the rear (`environment`). */
|
|
10
|
+
export type XRCameraFacing = "user" | "environment";
|
|
11
|
+
/**
|
|
12
|
+
* Every kind of media a session can bind. `webcam` is a mirrored live camera
|
|
13
|
+
* (the front camera by default); `rear-camera` is a live camera drawn
|
|
14
|
+
* straight, like `image` / `video`. The mirror decision follows the kind
|
|
15
|
+
* (`isMirroredSourceKind`), so consumers never need to know the facing.
|
|
16
|
+
*/
|
|
17
|
+
export type XRSessionSourceKind = "webcam" | "rear-camera" | XRMediaSourceKind;
|
|
18
|
+
/** Device orientation as the session sees it (from `screen.orientation`, falling back to the viewport aspect). */
|
|
19
|
+
export type XROrientation = {
|
|
20
|
+
type: "portrait" | "landscape";
|
|
21
|
+
/** Clockwise screen rotation in degrees (0, 90, 180, 270); 0 when unknown. */
|
|
22
|
+
angle: 0 | 90 | 180 | 270;
|
|
23
|
+
};
|
|
24
|
+
/** How a webcam bind chooses and presents the camera. */
|
|
25
|
+
export type XRCameraRequest = {
|
|
26
|
+
facingMode?: XRCameraFacing;
|
|
27
|
+
deviceId?: string;
|
|
28
|
+
mirrored?: boolean;
|
|
29
|
+
};
|
|
9
30
|
export type XRMediaLayout = {
|
|
10
31
|
source: {
|
|
11
32
|
width: number;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { NormalizedLandmark } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { TrackerPoint } from './common';
|
|
3
|
+
/** Which hands the holistic tracker publishes. Holistic is single-person: at most one left and one right hand. */
|
|
4
|
+
export type HolisticHandsOption = "both" | "left" | "right" | "none";
|
|
5
|
+
export type HolisticHandSide = "left" | "right";
|
|
6
|
+
export type HolisticTrackingStatus = "loading" | "ready" | "error";
|
|
7
|
+
/**
|
|
8
|
+
* Inference backend. `"auto"` (default) starts on the GPU and falls back to
|
|
9
|
+
* the CPU the first time the graph fails to run there: MediaPipe's holistic
|
|
10
|
+
* face-blendshape stage has no WebGL implementation, so with
|
|
11
|
+
* `outputFaceBlendshapes` the GPU path fails on the first frame.
|
|
12
|
+
*/
|
|
13
|
+
export type HolisticDelegate = "auto" | "GPU" | "CPU";
|
|
14
|
+
/** The backend actually running inference. */
|
|
15
|
+
export type HolisticActiveDelegate = "GPU" | "CPU";
|
|
16
|
+
/**
|
|
17
|
+
* Options the first acquirer passes to `XRModel.HOLISTIC_TRACKER`. The
|
|
18
|
+
* model-creation options (`modelUrl`, confidences, `outputFaceBlendshapes`)
|
|
19
|
+
* are fixed for the model's lifetime; the runtime subset
|
|
20
|
+
* (`HolisticRuntimeOptions`) can be changed live through `node.setOptions`.
|
|
21
|
+
*/
|
|
22
|
+
export type HolisticModelOptions = HolisticRuntimeOptions & {
|
|
23
|
+
/**
|
|
24
|
+
* Override the `.task` asset. Pre-release default: MediaPipe's published
|
|
25
|
+
* holistic landmarker on `storage.googleapis.com`, integrity-verified; the
|
|
26
|
+
* SDK CDN copy is not published yet and will become the default when it is.
|
|
27
|
+
* Set this to a self-hosted copy to drop the third-party dependency; a custom
|
|
28
|
+
* URL is fetched best-effort.
|
|
29
|
+
*/
|
|
30
|
+
modelUrl?: string;
|
|
31
|
+
/** Face detector confidence, 0..1. MediaPipe default 0.5. */
|
|
32
|
+
minFaceDetectionConfidence?: number;
|
|
33
|
+
/** Face presence confidence for the landmark stage, 0..1. MediaPipe default 0.5. */
|
|
34
|
+
minFacePresenceConfidence?: number;
|
|
35
|
+
/** Pose detector confidence, 0..1. MediaPipe default 0.5. */
|
|
36
|
+
minPoseDetectionConfidence?: number;
|
|
37
|
+
/** Pose presence confidence for the landmark stage, 0..1. MediaPipe default 0.5. */
|
|
38
|
+
minPosePresenceConfidence?: number;
|
|
39
|
+
/** Hand landmark confidence, 0..1. MediaPipe default 0.5. */
|
|
40
|
+
minHandLandmarksConfidence?: number;
|
|
41
|
+
/** Emit the 52 face blendshape scores. Default `true`. */
|
|
42
|
+
outputFaceBlendshapes?: boolean;
|
|
43
|
+
/** Inference backend policy. Default `"auto"`. */
|
|
44
|
+
delegate?: HolisticDelegate;
|
|
45
|
+
/** Inference cap (fps). Read by the session at run time; overrides `perf.targetFps`. */
|
|
46
|
+
targetFps?: number;
|
|
47
|
+
};
|
|
48
|
+
/** Options that can change while the model is running (last writer wins). */
|
|
49
|
+
export type HolisticRuntimeOptions = {
|
|
50
|
+
/** Hands to publish. Default `"both"`. */
|
|
51
|
+
hands?: HolisticHandsOption;
|
|
52
|
+
/**
|
|
53
|
+
* Longest side (px) of the frame handed to MediaPipe. The feed is
|
|
54
|
+
* downscaled to this before inference; outputs are normalized so consumers
|
|
55
|
+
* never see it. Default 768.
|
|
56
|
+
*/
|
|
57
|
+
analysisMaxDimension?: number;
|
|
58
|
+
/** Keep a lost face / hand / pose for this long (ms) before dropping it. Default 250. */
|
|
59
|
+
holdMs?: number;
|
|
60
|
+
/** While held, extrapolate along the last velocity for up to this long (ms). Default 0. */
|
|
61
|
+
predictMs?: number;
|
|
62
|
+
};
|
|
63
|
+
/** Live face stream: landmarks in MediaPipe image space, like `FaceTracker`'s `detectionResults`. */
|
|
64
|
+
export type HolisticFaceResult = {
|
|
65
|
+
/** 478 landmarks, normalized 0..1, top-left origin, Y down; `z` is tracker-relative depth. */
|
|
66
|
+
landmarks: NormalizedLandmark[];
|
|
67
|
+
/** Blendshape name → score (0..1). Empty when `outputFaceBlendshapes` is false. */
|
|
68
|
+
blendshapes: Record<string, number>;
|
|
69
|
+
/** 1 while detected; decays linearly to 0 over `holdMs` while held. */
|
|
70
|
+
confidence: number;
|
|
71
|
+
/** True when the stream is being replayed from memory after a dropout. */
|
|
72
|
+
held: boolean;
|
|
73
|
+
};
|
|
74
|
+
/** Live hand stream in SDK tracker coordinates, like `HandTracker`'s `coordinates`. */
|
|
75
|
+
export type HolisticHandResult = {
|
|
76
|
+
/**
|
|
77
|
+
* The person's anatomical side on every source. Holistic labels follow the
|
|
78
|
+
* image, so the SDK swaps them on the mirrored webcam feed; this matches
|
|
79
|
+
* what `HandTracker` reports on the same feed.
|
|
80
|
+
*/
|
|
81
|
+
handedness: HolisticHandSide;
|
|
82
|
+
/** 21 joints, center origin, X right, Y up, Z toward the viewer. */
|
|
83
|
+
landmarks: TrackerPoint[];
|
|
84
|
+
/** 21 joints in MediaPipe's metric world space (metres, wrist-relative, Y down). Not converted. */
|
|
85
|
+
worldLandmarks: TrackerPoint[];
|
|
86
|
+
/** 1 while detected; decays linearly to 0 over `holdMs` while held. */
|
|
87
|
+
confidence: number;
|
|
88
|
+
held: boolean;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Live pose stream in SDK tracker coordinates, like `BodyTracker`'s
|
|
92
|
+
* `getLandmarks2D()`. Unlike `BodyTracker`, left/right indices are the
|
|
93
|
+
* person's anatomical sides on every source (swapped on the mirrored webcam
|
|
94
|
+
* feed), so they agree with `leftHand` / `rightHand`.
|
|
95
|
+
*/
|
|
96
|
+
export type HolisticPoseResult = {
|
|
97
|
+
/** 33 landmarks, center origin, X right, Y up, Z toward the viewer. */
|
|
98
|
+
landmarks: TrackerPoint[];
|
|
99
|
+
/** 33 landmarks in MediaPipe's metric world space (metres, hip-relative, Y down). Not converted. */
|
|
100
|
+
worldLandmarks: TrackerPoint[];
|
|
101
|
+
/** Per-landmark visibility from MediaPipe (0..1), aligned with `landmarks`. */
|
|
102
|
+
visibility: number[];
|
|
103
|
+
/** Mean landmark visibility while detected; decays linearly to 0 over `holdMs` while held. */
|
|
104
|
+
confidence: number;
|
|
105
|
+
held: boolean;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* The unified holistic result. One object per model instance, mutated in
|
|
109
|
+
* place every frame; read it inside `useFrame` and treat it as read-only.
|
|
110
|
+
* A stream is `null` when it is neither detected nor held.
|
|
111
|
+
*/
|
|
112
|
+
export type HolisticResult = {
|
|
113
|
+
/** Bumped on every publish; `0` until the first inference. */
|
|
114
|
+
version: number;
|
|
115
|
+
/** `performance.now()` of the last publish. */
|
|
116
|
+
timestampMs: number;
|
|
117
|
+
face: HolisticFaceResult | null;
|
|
118
|
+
leftHand: HolisticHandResult | null;
|
|
119
|
+
rightHand: HolisticHandResult | null;
|
|
120
|
+
pose: HolisticPoseResult | null;
|
|
121
|
+
};
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/model.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { XRSessionSourceKind } from './compositor';
|
|
2
2
|
/**
|
|
3
3
|
* Session-level performance config, set via `<XRProvider perf={...}>`. Trades
|
|
4
4
|
* tracking fidelity for lower GPU/CPU load and heat. Every field is optional;
|
|
@@ -29,12 +29,30 @@ export type XRPerfConfig = {
|
|
|
29
29
|
* the tight native-selfie framing users expect; set `1` for the widest FOV.
|
|
30
30
|
*/
|
|
31
31
|
cameraZoom?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Multiplier (0.25..1) on every tracker's analysis resolution. Lower =
|
|
34
|
+
* cheaper inference, coarser landmarks. The adaptive-quality controller
|
|
35
|
+
* drives it per tier; set it directly only with `quality={false}`.
|
|
36
|
+
*/
|
|
37
|
+
analysisScale?: number;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Session lifecycle behaviour, set via `<XRProvider lifecycle={...}>`.
|
|
41
|
+
*/
|
|
42
|
+
export type XRLifecycleConfig = {
|
|
43
|
+
/**
|
|
44
|
+
* Pause the whole session (blit loop, every model, the video element) while
|
|
45
|
+
* the tab is hidden and resume it when it returns. Off by default: a hidden
|
|
46
|
+
* tab already throttles RAF, and some flows (recording, picture-in-picture)
|
|
47
|
+
* must keep running. Turn it on for battery-sensitive single-page apps.
|
|
48
|
+
*/
|
|
49
|
+
pauseWhenHidden?: boolean;
|
|
32
50
|
};
|
|
33
51
|
export type RunModelParams = {
|
|
34
52
|
sourceCanvas: OffscreenCanvas | HTMLCanvasElement;
|
|
35
53
|
renderWidth: number;
|
|
36
54
|
renderHeight: number;
|
|
37
|
-
getSource?: () =>
|
|
55
|
+
getSource?: () => XRSessionSourceKind | undefined;
|
|
38
56
|
/**
|
|
39
57
|
* Cap the model's inference rate to this many frames per second. The model's
|
|
40
58
|
* RAF loop still runs at display rate, but the (expensive) MediaPipe detect
|
|
@@ -43,4 +61,6 @@ export type RunModelParams = {
|
|
|
43
61
|
* smoothness. See `session.perf.targetFps` and the per-tracker `targetFps`.
|
|
44
62
|
*/
|
|
45
63
|
targetFps?: number;
|
|
64
|
+
/** Multiplier on the model's analysis resolution (0.25..1); default 1. */
|
|
65
|
+
analysisScale?: number;
|
|
46
66
|
};
|
package/dist/types/nodes.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { FaceLandmarkerResult } from '@mediapipe/tasks-vision';
|
|
1
|
+
import { FaceLandmarkerResult, HolisticLandmarkerResult } from '@mediapipe/tasks-vision';
|
|
2
2
|
import { Texture, Camera } from 'three';
|
|
3
3
|
import { TrackerPoint } from './common';
|
|
4
4
|
import { Face, FaceRawTrackingData } from './face';
|
|
5
5
|
import { GestureData } from './gesture-tracking';
|
|
6
6
|
import { HandData } from './hand-tracking';
|
|
7
|
-
import {
|
|
7
|
+
import { HolisticActiveDelegate, HolisticResult, HolisticRuntimeOptions, HolisticTrackingStatus } from './holistic';
|
|
8
|
+
import { SemanticMask } from '../segmentation2d/types';
|
|
9
|
+
import { SegmentationData, SemanticSegmentationStatus } from './segmentation';
|
|
8
10
|
export type XRModelNodeSegmentation = {
|
|
9
11
|
backgroundSegmentationMask?: Texture;
|
|
10
12
|
getMaskCanvas: () => HTMLCanvasElement | null;
|
|
@@ -16,6 +18,29 @@ export type XRModelNodeSegmentation = {
|
|
|
16
18
|
*/
|
|
17
19
|
setInputSource: (source: CanvasImageSource | null | undefined) => void;
|
|
18
20
|
};
|
|
21
|
+
/** Live state of `XRModel.SEMANTIC_SEGMENTATION`; functions read the model's current values. */
|
|
22
|
+
export type XRModelNodeSemanticSegmentation = {
|
|
23
|
+
/** Stable mask object in feed space, mutated in place; `version` 0 until the first inference. */
|
|
24
|
+
getMask: () => SemanticMask;
|
|
25
|
+
getStatus: () => SemanticSegmentationStatus;
|
|
26
|
+
getError: () => Error | null;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Live state of `XRModel.HOLISTIC_TRACKER`. One node object per model
|
|
30
|
+
* instance; every function reads the current value.
|
|
31
|
+
*/
|
|
32
|
+
export type XRModelNodeHolisticTracking = {
|
|
33
|
+
/** Unified, dropout-bridged result. Stable object mutated in place; `version` 0 until the first inference. */
|
|
34
|
+
getResult: () => HolisticResult;
|
|
35
|
+
/** The last raw MediaPipe result, unbridged and unconverted. */
|
|
36
|
+
getRawResult: () => HolisticLandmarkerResult | undefined;
|
|
37
|
+
getStatus: () => HolisticTrackingStatus;
|
|
38
|
+
getError: () => Error | null;
|
|
39
|
+
/** The backend running inference; `"CPU"` after an automatic fallback. */
|
|
40
|
+
getDelegate: () => HolisticActiveDelegate;
|
|
41
|
+
/** Change the runtime-tunable options without re-initializing the model. */
|
|
42
|
+
setOptions: (options: HolisticRuntimeOptions) => void;
|
|
43
|
+
};
|
|
19
44
|
export type XRModelNodeBodyTracking = {
|
|
20
45
|
getLandmarks2D: (bodyIndex?: number) => TrackerPoint[] | undefined;
|
|
21
46
|
};
|
|
@@ -29,3 +29,22 @@ export type SegmentationModelOptions = {
|
|
|
29
29
|
*/
|
|
30
30
|
quality?: SegmentationQuality;
|
|
31
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* Category-segmentation presets served by `XRModel.SEMANTIC_SEGMENTATION`.
|
|
34
|
+
* `hair` runs MediaPipe's Hair Segmenter (`bg` / `hair`); `multiclass` runs
|
|
35
|
+
* the Selfie Multiclass model (`bg`, `hair`, `body_skin`, `face_skin`,
|
|
36
|
+
* `clothes`, `others`). One preset per session: the first acquirer decides.
|
|
37
|
+
*/
|
|
38
|
+
export declare const SEMANTIC_SEGMENTATION_PRESETS: readonly ["hair", "multiclass"];
|
|
39
|
+
export type SemanticSegmentationPreset = (typeof SEMANTIC_SEGMENTATION_PRESETS)[number];
|
|
40
|
+
export type SemanticSegmentationModelOptions = {
|
|
41
|
+
preset?: SemanticSegmentationPreset;
|
|
42
|
+
/**
|
|
43
|
+
* Override the model asset URL. Defaults to the SDK CDN path for the
|
|
44
|
+
* preset, which is integrity-verified; a custom URL is fetched best-effort.
|
|
45
|
+
*/
|
|
46
|
+
modelUrl?: string;
|
|
47
|
+
/** Process-canvas scale relative to the feed: low 0.5, medium 0.75, high 1. Default medium. */
|
|
48
|
+
quality?: SegmentationQuality;
|
|
49
|
+
};
|
|
50
|
+
export type SemanticSegmentationStatus = "loading" | "ready" | "error";
|
package/dist/types/session.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { XRMediaSource, XRModel } from '../constants';
|
|
2
|
-
import { XRMediaSourceKind } from './compositor';
|
|
2
|
+
import { XRCameraFacing, XRCameraRequest, XRMediaSourceKind } from './compositor';
|
|
3
3
|
import { BodyModelOptions } from './body';
|
|
4
4
|
import { FaceModelOptions } from './face';
|
|
5
|
-
import {
|
|
5
|
+
import { HolisticModelOptions } from './holistic';
|
|
6
|
+
import { SegmentationModelOptions, SemanticSegmentationModelOptions } from './segmentation';
|
|
6
7
|
export declare enum SessionStatus {
|
|
7
8
|
ACTIVE = "ACTIVE",
|
|
8
9
|
DISABLED = "DISABLED"
|
|
@@ -18,6 +19,19 @@ export type Session = {
|
|
|
18
19
|
type SetMediaSourceWebcamParams = {
|
|
19
20
|
source: XRMediaSource.WEBCAM;
|
|
20
21
|
sourceKind?: "webcam";
|
|
22
|
+
/**
|
|
23
|
+
* Which camera to open: `user` (front, default) or `environment` (rear).
|
|
24
|
+
* Binding again with a different facing swaps the camera mid-session.
|
|
25
|
+
*/
|
|
26
|
+
facingMode?: XRCameraFacing;
|
|
27
|
+
/** A specific camera from `enumerateDevices()`; beats `facingMode` when set. */
|
|
28
|
+
deviceId?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Mirror override. Default: the front camera is mirrored (`sourceKind`
|
|
31
|
+
* `"webcam"`), the rear camera is drawn straight (`sourceKind`
|
|
32
|
+
* `"rear-camera"`). Set explicitly for a camera whose facing is unknown.
|
|
33
|
+
*/
|
|
34
|
+
mirrored?: boolean;
|
|
21
35
|
};
|
|
22
36
|
type SetMediaSourceStreamParams = {
|
|
23
37
|
source: XRMediaSource.STREAM;
|
|
@@ -44,9 +58,15 @@ export type RegisterXRPipelineParams = Array<{
|
|
|
44
58
|
} | {
|
|
45
59
|
model: XRModel.FACE_TRACKER;
|
|
46
60
|
options?: FaceModelOptions;
|
|
61
|
+
} | {
|
|
62
|
+
model: XRModel.HOLISTIC_TRACKER;
|
|
63
|
+
options?: HolisticModelOptions;
|
|
47
64
|
} | {
|
|
48
65
|
model: XRModel.BACKGROUND_SEGMENTATION;
|
|
49
66
|
options?: SegmentationModelOptions;
|
|
67
|
+
} | {
|
|
68
|
+
model: XRModel.SEMANTIC_SEGMENTATION;
|
|
69
|
+
options?: SemanticSegmentationModelOptions;
|
|
50
70
|
}>;
|
|
51
71
|
/**
|
|
52
72
|
* Public XR session surface. Returned by `useXRContext().session` and used
|
|
@@ -62,7 +82,10 @@ export type RegisterXRPipelineParams = Array<{
|
|
|
62
82
|
* Lifecycle:
|
|
63
83
|
*
|
|
64
84
|
* idle ──setMediaSource──> media-bound ──start──> running ──stop──> stopped
|
|
65
|
-
* ↑
|
|
85
|
+
* ↑ │ ↑ │
|
|
86
|
+
* │ pause │ │ resume │
|
|
87
|
+
* │ ▼ │ │
|
|
88
|
+
* │ paused ─┘ │
|
|
66
89
|
* └────────────reset──────────────────────┘
|
|
67
90
|
*/
|
|
68
91
|
export type XRSession = {
|
|
@@ -83,6 +106,21 @@ export type XRSession = {
|
|
|
83
106
|
* `stop()` + clear the model registry. Returns the session to `idle`.
|
|
84
107
|
*/
|
|
85
108
|
reset: () => Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Suspend a `running` session without releasing the camera: the feed loop
|
|
111
|
+
* stops, every model pauses, the video element pauses. No-op in any other
|
|
112
|
+
* state. `resume()` (or `start()`) continues with no rebind.
|
|
113
|
+
*/
|
|
114
|
+
pause: () => void;
|
|
115
|
+
/** Continue a `paused` session. No-op in any other state. */
|
|
116
|
+
resume: () => Promise<void>;
|
|
117
|
+
/**
|
|
118
|
+
* Open another camera (`facingMode` / `deviceId`, optional `mirrored`
|
|
119
|
+
* override) and keep going: models, lifecycle and scene stay; a
|
|
120
|
+
* `media-bound` / `stopped` session is started. Resolves to the facing the
|
|
121
|
+
* session ended up with (a single-camera device answers with what it has).
|
|
122
|
+
*/
|
|
123
|
+
switchCamera: (request?: XRCameraRequest) => Promise<XRCameraFacing>;
|
|
86
124
|
/**
|
|
87
125
|
* @deprecated Prefer `useXRModel(modelName, options)`. Kept as an
|
|
88
126
|
* additive shim for backwards compatibility — multiple calls are
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { useMemo as I, useEffect as N, useCallback as k, useRef as U } from "react";
|
|
2
|
+
import { Vector2 as X, Raycaster as S, Ray as Y, Vector3 as L } from "three";
|
|
3
|
+
import { D as d, a as y } from "./screenTransform-BenfCtZt.js";
|
|
4
|
+
import { n as j, t as A, X as p } from "./index-CnGox6Xr.js";
|
|
5
|
+
import { useThree as D } from "@react-three/fiber";
|
|
6
|
+
import { g as B, u as J } from "./getFaceInfo-BkZfaQs-.js";
|
|
7
|
+
import { u as V } from "./index-CsUdQ-pn.js";
|
|
8
|
+
const a = (e, n) => {
|
|
9
|
+
if (!Number.isFinite(e) || e <= 0) throw new RangeError(`${n} must be positive`);
|
|
10
|
+
return e;
|
|
11
|
+
}, q = (e, n) => {
|
|
12
|
+
const t = a(n.width, "root.width"), s = a(n.height, "root.height");
|
|
13
|
+
return !Number.isFinite(e.width) || !Number.isFinite(e.height) || e.width <= 0 || e.height <= 0 ? 0 : Math.min(e.width / t, e.height / s);
|
|
14
|
+
}, b = (e, n, t, s) => n.width <= 0 || n.height <= 0 ? Object.assign(s, { x: 0, y: 0 }) : (a(t.width, "root.width"), a(t.height, "root.height"), s.x = (e.x / n.width - 0.5) * t.width, s.y = (0.5 - e.y / n.height) * t.height, s), P = (e, n, t, s) => n.width <= 0 || n.height <= 0 ? Object.assign(s, { x: 0, y: 0 }) : (a(t.width, "root.width"), a(t.height, "root.height"), s.x = (e.x / t.width + 0.5) * n.width, s.y = (0.5 - e.y / t.height) * n.height, s), O = ({
|
|
15
|
+
parentSize: e,
|
|
16
|
+
referencePixelsPerUnit: n = y,
|
|
17
|
+
root: t = d
|
|
18
|
+
}) => q(e, t) * (y / a(n, "referencePixelsPerUnit")), re = (e, n) => e * O(n), ce = (e, n) => {
|
|
19
|
+
const t = O(n);
|
|
20
|
+
return t === 0 ? 0 : e / t;
|
|
21
|
+
}, oe = ({
|
|
22
|
+
point: e,
|
|
23
|
+
parentSize: n,
|
|
24
|
+
referencePixelsPerUnit: t = y,
|
|
25
|
+
root: s = d,
|
|
26
|
+
target: i = { x: 0, y: 0 }
|
|
27
|
+
}) => {
|
|
28
|
+
if (n.width <= 0 || n.height <= 0) return Object.assign(i, { x: 0, y: 0 });
|
|
29
|
+
const r = y / a(t, "referencePixelsPerUnit");
|
|
30
|
+
return i.x = e.x * (n.width / a(s.width, "root.width")) * r, i.y = e.y * (n.height / a(s.height, "root.height")) * r, i;
|
|
31
|
+
}, he = ({
|
|
32
|
+
point: e,
|
|
33
|
+
parentSize: n,
|
|
34
|
+
referencePixelsPerUnit: t = y,
|
|
35
|
+
root: s = d,
|
|
36
|
+
target: i = { x: 0, y: 0 }
|
|
37
|
+
}) => {
|
|
38
|
+
if (n.width <= 0 || n.height <= 0) return Object.assign(i, { x: 0, y: 0 });
|
|
39
|
+
const r = y / a(t, "referencePixelsPerUnit");
|
|
40
|
+
return i.x = e.x / (n.width / a(s.width, "root.width") * r), i.y = e.y / (n.height / a(s.height, "root.height") * r), i;
|
|
41
|
+
}, xe = ({
|
|
42
|
+
point: e,
|
|
43
|
+
rect: n,
|
|
44
|
+
root: t = d,
|
|
45
|
+
target: s = { x: 0, y: 0 }
|
|
46
|
+
}) => b({ x: e.x - n.left, y: e.y - n.top }, n, t, s), ae = ({
|
|
47
|
+
point: e,
|
|
48
|
+
rect: n,
|
|
49
|
+
root: t = d,
|
|
50
|
+
target: s = { x: 0, y: 0 }
|
|
51
|
+
}) => (P(e, n, t, s), s.x += n.left, s.y += n.top, s), _ = ({
|
|
52
|
+
point: e,
|
|
53
|
+
root: n = d,
|
|
54
|
+
target: t = { x: 0, y: 0 },
|
|
55
|
+
viewportSize: s
|
|
56
|
+
}) => b(
|
|
57
|
+
{ x: e.x * s.width, y: e.y * s.height },
|
|
58
|
+
s,
|
|
59
|
+
n,
|
|
60
|
+
t
|
|
61
|
+
), K = ({
|
|
62
|
+
point: e,
|
|
63
|
+
root: n = d,
|
|
64
|
+
target: t = { x: 0, y: 0 },
|
|
65
|
+
viewportSize: s
|
|
66
|
+
}) => s.width <= 0 || s.height <= 0 ? Object.assign(t, { x: 0, y: 0 }) : (P(e, s, n, t), t.x /= s.width, t.y /= s.height, t), de = ({
|
|
67
|
+
point: e,
|
|
68
|
+
root: n = d,
|
|
69
|
+
target: t = { x: 0, y: 0 },
|
|
70
|
+
viewportSize: s
|
|
71
|
+
}) => _({
|
|
72
|
+
point: { x: (e.x + 1) / 2, y: (1 - e.y) / 2 },
|
|
73
|
+
viewportSize: s,
|
|
74
|
+
root: n,
|
|
75
|
+
target: t
|
|
76
|
+
}), le = ({
|
|
77
|
+
layout: e,
|
|
78
|
+
mirrored: n = !1,
|
|
79
|
+
point: t,
|
|
80
|
+
root: s = d,
|
|
81
|
+
target: i = { x: 0, y: 0 }
|
|
82
|
+
}) => {
|
|
83
|
+
if (e.scale <= 0) return Object.assign(i, { x: 0, y: 0 });
|
|
84
|
+
const r = e.offsetX + t.x * e.scale;
|
|
85
|
+
return b(
|
|
86
|
+
{
|
|
87
|
+
x: n ? e.destination.width - r : r,
|
|
88
|
+
y: e.offsetY + t.y * e.scale
|
|
89
|
+
},
|
|
90
|
+
e.destination,
|
|
91
|
+
s,
|
|
92
|
+
i
|
|
93
|
+
);
|
|
94
|
+
}, ue = ({
|
|
95
|
+
layout: e,
|
|
96
|
+
mirrored: n = !1,
|
|
97
|
+
point: t,
|
|
98
|
+
root: s = d,
|
|
99
|
+
target: i = { x: 0, y: 0 }
|
|
100
|
+
}) => {
|
|
101
|
+
if (e.scale <= 0) return Object.assign(i, { x: 0, y: 0 });
|
|
102
|
+
P(t, e.destination, s, i);
|
|
103
|
+
const r = n ? e.destination.width - i.x : i.x;
|
|
104
|
+
return i.x = (r - e.offsetX) / e.scale, i.y = (i.y - e.offsetY) / e.scale, i;
|
|
105
|
+
}, w = new L(), g = new X(), R = new S(), fe = ({
|
|
106
|
+
camera: e,
|
|
107
|
+
point: n,
|
|
108
|
+
root: t = d,
|
|
109
|
+
target: s = { x: 0, y: 0, depth: 0 },
|
|
110
|
+
viewportSize: i
|
|
111
|
+
}) => (a(t.width, "root.width"), a(t.height, "root.height"), w.set(n.x, n.y, n.z).project(e), s.x = w.x * t.width / 2, s.y = w.y * t.height / 2, s.depth = w.z, s), ye = ({
|
|
112
|
+
camera: e,
|
|
113
|
+
point: n,
|
|
114
|
+
root: t = d,
|
|
115
|
+
target: s = new Y(),
|
|
116
|
+
viewportSize: i
|
|
117
|
+
}) => (a(t.width, "root.width"), a(t.height, "root.height"), g.set(n.x * 2 / t.width, n.y * 2 / t.height), R.setFromCamera(g, e), s.copy(R.ray)), me = (e, n) => j({ x: e.x, y: e.y, z: e.z ?? 0 }, n), H = (e, n = { x: 0, y: 0 }) => {
|
|
118
|
+
const t = A(e);
|
|
119
|
+
return n.x = t.x, n.y = t.y, n.z = t.z, n;
|
|
120
|
+
}, we = (e, n, t = { x: 0, y: 0 }) => (t.x = e.x * n.width, t.y = e.y * n.height, t), Te = (e, n, t = { x: 0, y: 0 }) => n.width <= 0 || n.height <= 0 ? Object.assign(t, { x: 0, y: 0 }) : (t.x = e.x / n.width, t.y = e.y / n.height, t), be = (e, n, t = {}) => _({
|
|
121
|
+
point: e,
|
|
122
|
+
viewportSize: n,
|
|
123
|
+
root: t.root,
|
|
124
|
+
target: t.target
|
|
125
|
+
}), Pe = (e, n, t = {}) => {
|
|
126
|
+
const s = t.target ?? { x: 0, y: 0 };
|
|
127
|
+
return K({ point: e, viewportSize: n, root: t.root, target: s }), s;
|
|
128
|
+
}, W = { selection: "index", index: 0 }, $ = Object.freeze({
|
|
129
|
+
face: { max: 10, default: 1, option: "numFaces" },
|
|
130
|
+
hand: { max: 2, default: 2, option: null },
|
|
131
|
+
gesture: { max: 1, default: 1, option: null },
|
|
132
|
+
body: { max: 1, default: 1, option: null },
|
|
133
|
+
holistic: { max: 1, default: 1, option: null }
|
|
134
|
+
}), C = { center: null }, f = (e, n) => Math.hypot(e.x - n.x, e.y - n.y), M = (e, n, t) => {
|
|
135
|
+
if (!e.length) return null;
|
|
136
|
+
switch (n) {
|
|
137
|
+
case "largest":
|
|
138
|
+
return e.reduce((s, i) => i.size > s.size ? i : s);
|
|
139
|
+
case "nearest-center":
|
|
140
|
+
return e.reduce(
|
|
141
|
+
(s, i) => f(i.center, { x: 0.5, y: 0.5 }) < f(s.center, { x: 0.5, y: 0.5 }) ? i : s
|
|
142
|
+
);
|
|
143
|
+
case "leftmost":
|
|
144
|
+
return e.reduce((s, i) => i.center.x < s.center.x ? i : s);
|
|
145
|
+
case "rightmost":
|
|
146
|
+
return e.reduce((s, i) => i.center.x > s.center.x ? i : s);
|
|
147
|
+
default:
|
|
148
|
+
return e.find((s) => s.index === t) ?? null;
|
|
149
|
+
}
|
|
150
|
+
}, G = (e, n = W, t = C) => {
|
|
151
|
+
const s = n.index ?? 0;
|
|
152
|
+
if (n.selection !== "sticky") {
|
|
153
|
+
const c = M(e, n.selection, s);
|
|
154
|
+
return {
|
|
155
|
+
index: (c == null ? void 0 : c.index) ?? null,
|
|
156
|
+
reason: c ? n.selection : "none",
|
|
157
|
+
memory: c ? { center: { ...c.center }, label: c.label } : t
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const i = n.stickyRadius ?? 0.2;
|
|
161
|
+
if (t.center) {
|
|
162
|
+
const c = t.center, x = e.filter((l) => f(l.center, c) <= i).sort((l, m) => f(l.center, c) - f(m.center, c)), h = (t.label ? x.find((l) => l.label === t.label) : void 0) ?? x[0];
|
|
163
|
+
if (h)
|
|
164
|
+
return {
|
|
165
|
+
index: h.index,
|
|
166
|
+
reason: "sticky",
|
|
167
|
+
memory: { center: { ...h.center }, label: h.label }
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
const r = M(e, n.fallback ?? "largest", s);
|
|
171
|
+
return {
|
|
172
|
+
index: (r == null ? void 0 : r.index) ?? null,
|
|
173
|
+
reason: r ? "sticky-fallback" : "none",
|
|
174
|
+
// Keep the old memory on a miss so a brief dropout does not forget the subject.
|
|
175
|
+
memory: r ? { center: { ...r.center }, label: r.label } : t
|
|
176
|
+
};
|
|
177
|
+
}, Fe = (e) => e.map((n, t) => {
|
|
178
|
+
let s = 1 / 0, i = -1 / 0, r = 1 / 0, c = -1 / 0;
|
|
179
|
+
for (const o of n)
|
|
180
|
+
o.x < s && (s = o.x), o.x > i && (i = o.x), o.y < r && (r = o.y), o.y > c && (c = o.y);
|
|
181
|
+
const x = n.length > 0 && Number.isFinite(s);
|
|
182
|
+
return {
|
|
183
|
+
index: t,
|
|
184
|
+
center: x ? { x: (s + i) / 2, y: (r + c) / 2 } : { x: 0.5, y: 0.5 },
|
|
185
|
+
size: x ? i - s : 0
|
|
186
|
+
};
|
|
187
|
+
}), Ee = (e) => e.map((n, t) => {
|
|
188
|
+
const s = (n.coordinates ?? []).map((h) => H(h));
|
|
189
|
+
let i = 1 / 0, r = -1 / 0, c = 1 / 0, x = -1 / 0;
|
|
190
|
+
for (const h of s)
|
|
191
|
+
h.x < i && (i = h.x), h.x > r && (r = h.x), h.y < c && (c = h.y), h.y > x && (x = h.y);
|
|
192
|
+
const o = s.length > 0;
|
|
193
|
+
return {
|
|
194
|
+
index: t,
|
|
195
|
+
center: o ? { x: (i + r) / 2, y: (c + x) / 2 } : { x: 0.5, y: 0.5 },
|
|
196
|
+
size: o ? Math.max(r - i, x - c) : 0,
|
|
197
|
+
...n.label ? { label: n.label } : {}
|
|
198
|
+
};
|
|
199
|
+
}), ge = (e, n, t = 0.35) => {
|
|
200
|
+
const s = [];
|
|
201
|
+
for (const c of e)
|
|
202
|
+
for (const x of n) {
|
|
203
|
+
const o = f(c.center, x.center);
|
|
204
|
+
o <= t && s.push({ primaryIndex: c.index, secondaryIndex: x.index, distance: o });
|
|
205
|
+
}
|
|
206
|
+
s.sort((c, x) => c.distance - x.distance);
|
|
207
|
+
const i = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set();
|
|
208
|
+
return s.filter((c) => i.has(c.primaryIndex) || r.has(c.secondaryIndex) ? !1 : (i.add(c.primaryIndex), r.add(c.secondaryIndex), !0));
|
|
209
|
+
}, Q = ({
|
|
210
|
+
active: e = !0,
|
|
211
|
+
holdMs: n = 250,
|
|
212
|
+
numFaces: t = 1,
|
|
213
|
+
targetFps: s,
|
|
214
|
+
throttleMs: i = 16
|
|
215
|
+
} = {}) => {
|
|
216
|
+
const { camera: r } = D(), c = Number.isFinite(t) ? Math.min($.face.max, Math.max(1, Math.round(t))) : 1, x = s !== void 0 && Number.isFinite(s) && s > 0 ? s : void 0, o = I(
|
|
217
|
+
() => ({
|
|
218
|
+
numFaces: c,
|
|
219
|
+
...x ? { targetFps: x } : {}
|
|
220
|
+
}),
|
|
221
|
+
[c, x]
|
|
222
|
+
), { node: h, ready: l } = V(
|
|
223
|
+
p.FACE_TRACKER,
|
|
224
|
+
o,
|
|
225
|
+
e
|
|
226
|
+
);
|
|
227
|
+
N(() => {
|
|
228
|
+
if (h)
|
|
229
|
+
for (let u = 0; u < o.numFaces; u += 1)
|
|
230
|
+
h.setCamera(r, u);
|
|
231
|
+
}, [o.numFaces, r, h]);
|
|
232
|
+
const m = k(
|
|
233
|
+
(u) => {
|
|
234
|
+
if (!h) return [];
|
|
235
|
+
const F = [];
|
|
236
|
+
for (let T = 0; T < u.faceLandmarks.length; T += 1) {
|
|
237
|
+
const E = B(h, u, T);
|
|
238
|
+
E && F.push(E);
|
|
239
|
+
}
|
|
240
|
+
return F;
|
|
241
|
+
},
|
|
242
|
+
[h]
|
|
243
|
+
);
|
|
244
|
+
return J({
|
|
245
|
+
enabled: e && l,
|
|
246
|
+
holdMs: Number.isFinite(n) ? Math.max(0, n) : 250,
|
|
247
|
+
node: h,
|
|
248
|
+
prepare: m,
|
|
249
|
+
throttleMs: Number.isFinite(i) ? Math.max(0, i) : 16
|
|
250
|
+
});
|
|
251
|
+
}, Z = 4, Re = ({
|
|
252
|
+
faceIndex: e = 0,
|
|
253
|
+
numFaces: n,
|
|
254
|
+
subject: t,
|
|
255
|
+
...s
|
|
256
|
+
} = {}) => {
|
|
257
|
+
const i = Number.isFinite(e) ? Math.max(0, Math.round(e)) : 0, r = Q({
|
|
258
|
+
...s,
|
|
259
|
+
numFaces: Math.max(n ?? (t ? Z : i + 1), i + 1)
|
|
260
|
+
}), c = U(C), x = JSON.stringify(t ?? null), o = I(() => {
|
|
261
|
+
if (!t) return null;
|
|
262
|
+
const h = r.map((l, m) => ({
|
|
263
|
+
index: m,
|
|
264
|
+
center: { x: l.bounds.centerX, y: l.bounds.centerY },
|
|
265
|
+
size: l.bounds.width
|
|
266
|
+
}));
|
|
267
|
+
return G(h, t, c.current);
|
|
268
|
+
}, [r, x]);
|
|
269
|
+
return N(() => {
|
|
270
|
+
o && (c.current = o.memory);
|
|
271
|
+
}, [o]), t ? o && o.index !== null ? r[o.index] ?? null : null : r[i] ?? null;
|
|
272
|
+
};
|
|
273
|
+
export {
|
|
274
|
+
W as D,
|
|
275
|
+
C as E,
|
|
276
|
+
$ as X,
|
|
277
|
+
ge as a,
|
|
278
|
+
Z as b,
|
|
279
|
+
Re as c,
|
|
280
|
+
xe as d,
|
|
281
|
+
re as e,
|
|
282
|
+
Fe as f,
|
|
283
|
+
ae as g,
|
|
284
|
+
ue as h,
|
|
285
|
+
K as i,
|
|
286
|
+
Ee as j,
|
|
287
|
+
oe as k,
|
|
288
|
+
ye as l,
|
|
289
|
+
le as m,
|
|
290
|
+
_ as n,
|
|
291
|
+
he as o,
|
|
292
|
+
ce as p,
|
|
293
|
+
be as q,
|
|
294
|
+
me as r,
|
|
295
|
+
G as s,
|
|
296
|
+
de as t,
|
|
297
|
+
Q as u,
|
|
298
|
+
we as v,
|
|
299
|
+
fe as w,
|
|
300
|
+
Pe as x,
|
|
301
|
+
H as y,
|
|
302
|
+
Te as z
|
|
303
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const T=require("react"),R=require("three"),l=require("./screenTransform-BiXdpVf0.cjs"),F=require("./index-CeVkgsag.cjs"),j=require("@react-three/fiber"),w=require("./getFaceInfo-ahPxQFGu.cjs"),q=require("./index-OCPjOaeP.cjs"),h=(e,n)=>{if(!Number.isFinite(e)||e<=0)throw new RangeError(`${n} must be positive`);return e},B=(e,n)=>{const t=h(n.width,"root.width"),i=h(n.height,"root.height");return!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0?0:Math.min(e.width/t,e.height/i)},m=(e,n,t,i)=>n.width<=0||n.height<=0?Object.assign(i,{x:0,y:0}):(h(t.width,"root.width"),h(t.height,"root.height"),i.x=(e.x/n.width-.5)*t.width,i.y=(.5-e.y/n.height)*t.height,i),P=(e,n,t,i)=>n.width<=0||n.height<=0?Object.assign(i,{x:0,y:0}):(h(t.width,"root.width"),h(t.height,"root.height"),i.x=(e.x/t.width+.5)*n.width,i.y=(.5-e.y/t.height)*n.height,i),I=({parentSize:e,referencePixelsPerUnit:n=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT})=>B(e,t)*(l.DEFAULT_REFERENCE_PIXELS_PER_UNIT/h(n,"referencePixelsPerUnit")),J=(e,n)=>e*I(n),V=(e,n)=>{const t=I(n);return t===0?0:e/t},p=({point:e,parentSize:n,referencePixelsPerUnit:t=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT,root:i=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:s={x:0,y:0}})=>{if(n.width<=0||n.height<=0)return Object.assign(s,{x:0,y:0});const r=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT/h(t,"referencePixelsPerUnit");return s.x=e.x*(n.width/h(i.width,"root.width"))*r,s.y=e.y*(n.height/h(i.height,"root.height"))*r,s},H=({point:e,parentSize:n,referencePixelsPerUnit:t=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT,root:i=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:s={x:0,y:0}})=>{if(n.width<=0||n.height<=0)return Object.assign(s,{x:0,y:0});const r=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT/h(t,"referencePixelsPerUnit");return s.x=e.x/(n.width/h(i.width,"root.width")*r),s.y=e.y/(n.height/h(i.height,"root.height")*r),s},K=({point:e,rect:n,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:i={x:0,y:0}})=>m({x:e.x-n.left,y:e.y-n.top},n,t,i),$=({point:e,rect:n,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:i={x:0,y:0}})=>(P(e,n,t,i),i.x+=n.left,i.y+=n.top,i),S=({point:e,root:n=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:t={x:0,y:0},viewportSize:i})=>m({x:e.x*i.width,y:e.y*i.height},i,n,t),L=({point:e,root:n=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:t={x:0,y:0},viewportSize:i})=>i.width<=0||i.height<=0?Object.assign(t,{x:0,y:0}):(P(e,i,n,t),t.x/=i.width,t.y/=i.height,t),W=({point:e,root:n=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:t={x:0,y:0},viewportSize:i})=>S({point:{x:(e.x+1)/2,y:(1-e.y)/2},viewportSize:i,root:n,target:t}),z=({layout:e,mirrored:n=!1,point:t,root:i=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:s={x:0,y:0}})=>{if(e.scale<=0)return Object.assign(s,{x:0,y:0});const r=e.offsetX+t.x*e.scale;return m({x:n?e.destination.width-r:r,y:e.offsetY+t.y*e.scale},e.destination,i,s)},G=({layout:e,mirrored:n=!1,point:t,root:i=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:s={x:0,y:0}})=>{if(e.scale<=0)return Object.assign(s,{x:0,y:0});P(t,e.destination,i,s);const r=n?e.destination.width-s.x:s.x;return s.x=(r-e.offsetX)/e.scale,s.y=(s.y-e.offsetY)/e.scale,s},y=new R.Vector3,C=new R.Vector2,A=new R.Raycaster,Q=({camera:e,point:n,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:i={x:0,y:0,depth:0},viewportSize:s})=>(h(t.width,"root.width"),h(t.height,"root.height"),y.set(n.x,n.y,n.z).project(e),i.x=y.x*t.width/2,i.y=y.y*t.height/2,i.depth=y.z,i),Z=({camera:e,point:n,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:i=new R.Ray,viewportSize:s})=>(h(t.width,"root.width"),h(t.height,"root.height"),C.set(n.x*2/t.width,n.y*2/t.height),A.setFromCamera(C,e),i.copy(A.ray)),v=(e,n)=>F.normalizedTrackerPointToTrackerPoint({x:e.x,y:e.y,z:e.z??0},n),b=(e,n={x:0,y:0})=>{const t=F.trackerPointToNormalizedTrackerPoint(e);return n.x=t.x,n.y=t.y,n.z=t.z,n},ee=(e,n,t={x:0,y:0})=>(t.x=e.x*n.width,t.y=e.y*n.height,t),ne=(e,n,t={x:0,y:0})=>n.width<=0||n.height<=0?Object.assign(t,{x:0,y:0}):(t.x=e.x/n.width,t.y=e.y/n.height,t),te=(e,n,t={})=>S({point:e,viewportSize:n,root:t.root,target:t.target}),ie=(e,n,t={})=>{const i=t.target??{x:0,y:0};return L({point:e,viewportSize:n,root:t.root,target:i}),i},D={selection:"index",index:0},g=Object.freeze({face:{max:10,default:1,option:"numFaces"},hand:{max:2,default:2,option:null},gesture:{max:1,default:1,option:null},body:{max:1,default:1,option:null},holistic:{max:1,default:1,option:null}}),O={center:null},f=(e,n)=>Math.hypot(e.x-n.x,e.y-n.y),M=(e,n,t)=>{if(!e.length)return null;switch(n){case"largest":return e.reduce((i,s)=>s.size>i.size?s:i);case"nearest-center":return e.reduce((i,s)=>f(s.center,{x:.5,y:.5})<f(i.center,{x:.5,y:.5})?s:i);case"leftmost":return e.reduce((i,s)=>s.center.x<i.center.x?s:i);case"rightmost":return e.reduce((i,s)=>s.center.x>i.center.x?s:i);default:return e.find(i=>i.index===t)??null}},X=(e,n=D,t=O)=>{const i=n.index??0;if(n.selection!=="sticky"){const c=M(e,n.selection,i);return{index:(c==null?void 0:c.index)??null,reason:c?n.selection:"none",memory:c?{center:{...c.center},label:c.label}:t}}const s=n.stickyRadius??.2;if(t.center){const c=t.center,d=e.filter(a=>f(a.center,c)<=s).sort((a,E)=>f(a.center,c)-f(E.center,c)),x=(t.label?d.find(a=>a.label===t.label):void 0)??d[0];if(x)return{index:x.index,reason:"sticky",memory:{center:{...x.center},label:x.label}}}const r=M(e,n.fallback??"largest",i);return{index:(r==null?void 0:r.index)??null,reason:r?"sticky-fallback":"none",memory:r?{center:{...r.center},label:r.label}:t}},se=e=>e.map((n,t)=>{let i=1/0,s=-1/0,r=1/0,c=-1/0;for(const o of n)o.x<i&&(i=o.x),o.x>s&&(s=o.x),o.y<r&&(r=o.y),o.y>c&&(c=o.y);const d=n.length>0&&Number.isFinite(i);return{index:t,center:d?{x:(i+s)/2,y:(r+c)/2}:{x:.5,y:.5},size:d?s-i:0}}),re=e=>e.map((n,t)=>{const i=(n.coordinates??[]).map(x=>b(x));let s=1/0,r=-1/0,c=1/0,d=-1/0;for(const x of i)x.x<s&&(s=x.x),x.x>r&&(r=x.x),x.y<c&&(c=x.y),x.y>d&&(d=x.y);const o=i.length>0;return{index:t,center:o?{x:(s+r)/2,y:(c+d)/2}:{x:.5,y:.5},size:o?Math.max(r-s,d-c):0,...n.label?{label:n.label}:{}}}),ce=(e,n,t=.35)=>{const i=[];for(const c of e)for(const d of n){const o=f(c.center,d.center);o<=t&&i.push({primaryIndex:c.index,secondaryIndex:d.index,distance:o})}i.sort((c,d)=>c.distance-d.distance);const s=new Set,r=new Set;return i.filter(c=>s.has(c.primaryIndex)||r.has(c.secondaryIndex)?!1:(s.add(c.primaryIndex),r.add(c.secondaryIndex),!0))},k=({active:e=!0,holdMs:n=250,numFaces:t=1,targetFps:i,throttleMs:s=16}={})=>{const{camera:r}=j.useThree(),c=Number.isFinite(t)?Math.min(g.face.max,Math.max(1,Math.round(t))):1,d=i!==void 0&&Number.isFinite(i)&&i>0?i:void 0,o=T.useMemo(()=>({numFaces:c,...d?{targetFps:d}:{}}),[c,d]),{node:x,ready:a}=q.useXRModel(F.XRModel.FACE_TRACKER,o,e);T.useEffect(()=>{if(x)for(let u=0;u<o.numFaces;u+=1)x.setCamera(r,u)},[o.numFaces,r,x]);const E=T.useCallback(u=>{if(!x)return[];const N=[];for(let _=0;_<u.faceLandmarks.length;_+=1){const U=w.getFaceInfoFromResults(x,u,_);U&&N.push(U)}return N},[x]);return w.useFaceResultReader({enabled:e&&a,holdMs:Number.isFinite(n)?Math.max(0,n):250,node:x,prepare:E,throttleMs:Number.isFinite(s)?Math.max(0,s):16})},Y=4,oe=({faceIndex:e=0,numFaces:n,subject:t,...i}={})=>{const s=Number.isFinite(e)?Math.max(0,Math.round(e)):0,r=k({...i,numFaces:Math.max(n??(t?Y:s+1),s+1)}),c=T.useRef(O),d=JSON.stringify(t??null),o=T.useMemo(()=>{if(!t)return null;const x=r.map((a,E)=>({index:E,center:{x:a.bounds.centerX,y:a.bounds.centerY},size:a.bounds.width}));return X(x,t,c.current)},[r,d]);return T.useEffect(()=>{o&&(c.current=o.memory)},[o]),t?o&&o.index!==null?r[o.index]??null:null:r[s]??null};exports.DEFAULT_POLICY_NUM_FACES=Y;exports.DEFAULT_SUBJECT_POLICY=D;exports.EMPTY_SUBJECT_MEMORY=O;exports.XR_MAX_SUBJECTS=g;exports.associateSubjects=ce;exports.clientToScreenPixels=K;exports.faceCandidates=se;exports.feedToScreenPixels=te;exports.feedToTracker=v;exports.feedToViewport=ee;exports.jointCandidates=re;exports.mediaToScreenPixels=z;exports.normalizedToScreenPixels=S;exports.screenPixelsToClient=$;exports.screenPixelsToFeed=ie;exports.screenPixelsToMedia=G;exports.screenPixelsToNormalized=L;exports.screenPixelsToScreenSpace=p;exports.screenPixelsToUnits=J;exports.screenPointToRay=Z;exports.screenSpaceToScreenPixels=H;exports.screenUnitsToPixels=V;exports.selectSubject=X;exports.trackerPointToScreenPixels=W;exports.trackerToFeed=b;exports.useFaceInfo=oe;exports.useFaceInfos=k;exports.viewportToFeed=ne;exports.worldToScreenPixels=Q;
|