@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
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { FaceInfo } from '../face-info';
|
|
2
|
+
import { TrackerPoint } from '../types/common';
|
|
3
|
+
import { GestureDetectorOptions, GestureSample } from './detector';
|
|
4
|
+
import { OscillationTracker } from './measures';
|
|
5
|
+
export type GestureKind = "face" | "hand" | "body";
|
|
6
|
+
/** What each tracker hands a definition per frame. */
|
|
7
|
+
export type GestureInputOf<K extends GestureKind> = K extends "face" ? FaceInfo | null : ReadonlyArray<TrackerPoint> | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* A gesture: which tracker it reads, how to turn one frame of that tracker
|
|
10
|
+
* into a `{ value, confidence }` sample, and its default detector options.
|
|
11
|
+
* Temporal gestures keep per-instance memory (`createMemory`).
|
|
12
|
+
*/
|
|
13
|
+
export type GestureDefinition<K extends GestureKind = GestureKind, M = unknown> = {
|
|
14
|
+
name: string;
|
|
15
|
+
kind: K;
|
|
16
|
+
description: string;
|
|
17
|
+
/** Overrides of `DEFAULT_GESTURE_DETECTOR_OPTIONS` for this gesture. */
|
|
18
|
+
defaults?: Partial<GestureDetectorOptions>;
|
|
19
|
+
createMemory?: () => M;
|
|
20
|
+
/** `null` when the tracker has no subject this frame. Confidence 1 unless the source knows better. */
|
|
21
|
+
measure: (input: GestureInputOf<K>, memory: M, nowMs: number) => GestureSample;
|
|
22
|
+
};
|
|
23
|
+
type OscillationMemory = {
|
|
24
|
+
tracker: OscillationTracker;
|
|
25
|
+
wasPresent: boolean;
|
|
26
|
+
};
|
|
27
|
+
export declare const GESTURES: {
|
|
28
|
+
readonly mouthOpen: GestureDefinition<"face", undefined>;
|
|
29
|
+
readonly smile: GestureDefinition<"face", undefined>;
|
|
30
|
+
readonly blink: GestureDefinition<"face", undefined>;
|
|
31
|
+
readonly browRaise: GestureDefinition<"face", undefined>;
|
|
32
|
+
readonly headNod: {
|
|
33
|
+
name: string;
|
|
34
|
+
kind: "face";
|
|
35
|
+
description: string;
|
|
36
|
+
defaults: Partial<GestureDetectorOptions>;
|
|
37
|
+
createMemory: () => OscillationMemory;
|
|
38
|
+
measure: (face: FaceInfo | null, memory: OscillationMemory, nowMs: number) => GestureSample;
|
|
39
|
+
};
|
|
40
|
+
readonly headShake: {
|
|
41
|
+
name: string;
|
|
42
|
+
kind: "face";
|
|
43
|
+
description: string;
|
|
44
|
+
defaults: Partial<GestureDetectorOptions>;
|
|
45
|
+
createMemory: () => OscillationMemory;
|
|
46
|
+
measure: (face: FaceInfo | null, memory: OscillationMemory, nowMs: number) => GestureSample;
|
|
47
|
+
};
|
|
48
|
+
readonly pinch: GestureDefinition<"hand", undefined>;
|
|
49
|
+
readonly grab: GestureDefinition<"hand", undefined>;
|
|
50
|
+
readonly openPalm: GestureDefinition<"hand", undefined>;
|
|
51
|
+
readonly handRaised: GestureDefinition<"hand", undefined>;
|
|
52
|
+
readonly oneFinger: GestureDefinition<"hand", undefined>;
|
|
53
|
+
readonly peaceSign: GestureDefinition<"hand", undefined>;
|
|
54
|
+
readonly threeFingers: GestureDefinition<"hand", undefined>;
|
|
55
|
+
readonly fourFingers: GestureDefinition<"hand", undefined>;
|
|
56
|
+
readonly fist: GestureDefinition<"hand", undefined>;
|
|
57
|
+
readonly palm: GestureDefinition<"hand", undefined>;
|
|
58
|
+
readonly thumbUp: GestureDefinition<"hand", undefined>;
|
|
59
|
+
readonly thumbDown: GestureDefinition<"hand", undefined>;
|
|
60
|
+
readonly wave: {
|
|
61
|
+
name: string;
|
|
62
|
+
kind: "hand";
|
|
63
|
+
description: string;
|
|
64
|
+
defaults: Partial<GestureDetectorOptions>;
|
|
65
|
+
createMemory: () => OscillationMemory;
|
|
66
|
+
measure: (hand: readonly TrackerPoint[] | undefined, memory: OscillationMemory, nowMs: number) => GestureSample;
|
|
67
|
+
};
|
|
68
|
+
readonly armRaisedLeft: GestureDefinition<"body", undefined>;
|
|
69
|
+
readonly armRaisedRight: GestureDefinition<"body", undefined>;
|
|
70
|
+
readonly armRaised: GestureDefinition<"body", undefined>;
|
|
71
|
+
readonly bothArmsRaised: GestureDefinition<"body", undefined>;
|
|
72
|
+
readonly tPose: GestureDefinition<"body", undefined>;
|
|
73
|
+
};
|
|
74
|
+
export type BuiltInGestureName = keyof typeof GESTURES;
|
|
75
|
+
export declare const GESTURE_NAMES: BuiltInGestureName[];
|
|
76
|
+
/** Any definition, whichever tracker it reads (memory type erased). */
|
|
77
|
+
export type AnyGestureDefinition = {
|
|
78
|
+
[K in GestureKind]: GestureDefinition<K, any>;
|
|
79
|
+
}[GestureKind];
|
|
80
|
+
/** A built-in name or a custom definition. */
|
|
81
|
+
export type GestureRef = BuiltInGestureName | AnyGestureDefinition;
|
|
82
|
+
export declare const resolveGestureDefinition: (gesture: GestureRef) => AnyGestureDefinition;
|
|
83
|
+
/** Create a custom gesture with the same contract as the built-ins. */
|
|
84
|
+
export declare const defineGesture: <K extends GestureKind, M = undefined>(definition: GestureDefinition<K, M>) => GestureDefinition<K, M>;
|
|
85
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One gesture engine for every tracker: a scalar signal in, lifecycle out.
|
|
3
|
+
*
|
|
4
|
+
* A gesture definition measures a value (0..1, "how much") and a confidence
|
|
5
|
+
* (0..1, "how sure") each frame. The detector turns that stream into a
|
|
6
|
+
* stable `active` flag with hysteresis (enter above `enterThreshold`, leave
|
|
7
|
+
* below `exitThreshold`), a minimum hold before it begins, a cooldown after
|
|
8
|
+
* it ends, a confidence gate, and a grace window that survives brief
|
|
9
|
+
* tracking loss. Pure and allocation-free so it is unit-testable without a
|
|
10
|
+
* renderer; the hooks drive it from `useFrame`.
|
|
11
|
+
*/
|
|
12
|
+
export type GestureDetectorOptions = {
|
|
13
|
+
/** Value at or above which the gesture may begin. Default 0.5. */
|
|
14
|
+
enterThreshold: number;
|
|
15
|
+
/** Value at or below which an active gesture ends. Default `enterThreshold - 0.15` (hysteresis). */
|
|
16
|
+
exitThreshold: number;
|
|
17
|
+
/** The value must stay above `enterThreshold` for this long (ms) before `begin`. Default 0. */
|
|
18
|
+
holdMs: number;
|
|
19
|
+
/** After `end`, no new `begin` for this long (ms). Default 0. */
|
|
20
|
+
cooldownMs: number;
|
|
21
|
+
/** Samples with confidence below this are treated as tracking loss. Default 0.5. */
|
|
22
|
+
minConfidence: number;
|
|
23
|
+
/**
|
|
24
|
+
* While active, tracking loss (no sample or low confidence) is tolerated
|
|
25
|
+
* for this long (ms) before the gesture ends with `endReason: "lost"`;
|
|
26
|
+
* `0` ends on the first lost frame. Default 250, the SDK's hold window.
|
|
27
|
+
*/
|
|
28
|
+
lostGraceMs: number;
|
|
29
|
+
};
|
|
30
|
+
export declare const DEFAULT_GESTURE_DETECTOR_OPTIONS: GestureDetectorOptions;
|
|
31
|
+
/** Fill defaults and keep the pair consistent (`exit <= enter`, nothing negative). */
|
|
32
|
+
export declare const resolveGestureDetectorOptions: (options?: Partial<GestureDetectorOptions>, defaults?: GestureDetectorOptions) => GestureDetectorOptions;
|
|
33
|
+
/** One frame of measurement. `null` means the tracker has no subject this frame. */
|
|
34
|
+
export type GestureSample = {
|
|
35
|
+
value: number;
|
|
36
|
+
confidence: number;
|
|
37
|
+
} | null;
|
|
38
|
+
export type GesturePhase = "begin" | "stay" | "end" | "none";
|
|
39
|
+
export type GestureEndReason = "released" | "lost" | null;
|
|
40
|
+
export type GestureState = {
|
|
41
|
+
name: string;
|
|
42
|
+
/** Hysteresis-stable activity. */
|
|
43
|
+
active: boolean;
|
|
44
|
+
/** Last reliable measured value (0..1); kept through loss grace. */
|
|
45
|
+
value: number;
|
|
46
|
+
/** Last sample confidence (0 while the subject is missing). */
|
|
47
|
+
confidence: number;
|
|
48
|
+
/** True when a reliable sample arrived this frame. */
|
|
49
|
+
tracked: boolean;
|
|
50
|
+
phase: GesturePhase;
|
|
51
|
+
justBegan: boolean;
|
|
52
|
+
justEnded: boolean;
|
|
53
|
+
/** Why the last `end` happened: the value dropped, or tracking was lost. */
|
|
54
|
+
endReason: GestureEndReason;
|
|
55
|
+
/** `nowMs` of the current activation's `begin`, or null. */
|
|
56
|
+
startedAtMs: number | null;
|
|
57
|
+
/**
|
|
58
|
+
* Milliseconds since `begin` as of the last published change (an ending
|
|
59
|
+
* gesture carries its full length). Not a per-frame clock: read
|
|
60
|
+
* `startedAtMs` against your own clock for a live duration.
|
|
61
|
+
*/
|
|
62
|
+
durationMs: number;
|
|
63
|
+
/** Number of `begin` events so far. */
|
|
64
|
+
count: number;
|
|
65
|
+
};
|
|
66
|
+
export type GestureDetectorState = GestureState & {
|
|
67
|
+
holdStartedAtMs: number | null;
|
|
68
|
+
lostSinceMs: number | null;
|
|
69
|
+
cooldownUntilMs: number;
|
|
70
|
+
beganLastStep: boolean;
|
|
71
|
+
};
|
|
72
|
+
export declare const createGestureDetectorState: (name: string) => GestureDetectorState;
|
|
73
|
+
/**
|
|
74
|
+
* Advance the detector by one frame. Mutates and returns `state`.
|
|
75
|
+
*
|
|
76
|
+
* - No sample / confidence below `minConfidence` = tracking loss: an
|
|
77
|
+
* inactive gesture resets its hold; an active one survives for
|
|
78
|
+
* `lostGraceMs` (value frozen), then ends with `endReason: "lost"`.
|
|
79
|
+
* - Inactive: value >= `enterThreshold` for `holdMs` (and past the cooldown) → `begin`.
|
|
80
|
+
* - Active: value <= `exitThreshold` → `end` ("released"). A `begin` always
|
|
81
|
+
* gets one `stay` frame so one-frame gestures still surface both edges.
|
|
82
|
+
*/
|
|
83
|
+
export declare const stepGestureDetector: (state: GestureDetectorState, sample: GestureSample, nowMs: number, options: GestureDetectorOptions) => GestureDetectorState;
|
|
84
|
+
/** Copy the public fields of a detector state (for publishing to React state). */
|
|
85
|
+
export declare const snapshotGestureState: (state: GestureDetectorState, target?: GestureState) => GestureState;
|
|
86
|
+
/** Change detection for publishing; `durationMs` is deliberately excluded so an active gesture does not publish every frame. */
|
|
87
|
+
export declare const gestureStatesEqual: (a: GestureState, b: GestureState) => boolean;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { DEFAULT_GESTURE_DETECTOR_OPTIONS, createGestureDetectorState, gestureStatesEqual, resolveGestureDetectorOptions, snapshotGestureState, stepGestureDetector, } from './detector';
|
|
2
|
+
export type { GestureDetectorOptions, GestureDetectorState, GestureEndReason, GesturePhase, GestureSample, GestureState, } from './detector';
|
|
3
|
+
export { GESTURES, GESTURE_NAMES, defineGesture, resolveGestureDefinition } from './definitions';
|
|
4
|
+
export type { AnyGestureDefinition, BuiltInGestureName, GestureDefinition, GestureInputOf, GestureKind, GestureRef, } from './definitions';
|
|
5
|
+
export { HAND_JOINTS, OscillationTracker, POSE_JOINTS, measureArmRaise, fingerExtensions, measureFingerPattern, measureGrab, measureHandHeight, measureOpenPalm, measurePinch, measureTPose, measureThumb, thumbDirection, thumbExtension, } from './measures';
|
|
6
|
+
export type { FingerPattern } from './measures';
|
|
7
|
+
export { DEFAULT_GESTURE_SETTINGS, GESTURE_SETTINGS_FIELDS, patchGestureSettings, resolveGestureSettings, } from './settings';
|
|
8
|
+
export type { GestureSettings } from './settings';
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { TrackerPoint } from '../types/common';
|
|
2
|
+
/** Clamp to 0..1. */
|
|
3
|
+
export declare const unit: (value: number) => number;
|
|
4
|
+
/** MediaPipe hand joints used by the measures. */
|
|
5
|
+
export declare const HAND_JOINTS: {
|
|
6
|
+
readonly wrist: 0;
|
|
7
|
+
readonly thumbTip: 4;
|
|
8
|
+
readonly indexBase: 5;
|
|
9
|
+
readonly indexTip: 8;
|
|
10
|
+
readonly middleBase: 9;
|
|
11
|
+
readonly middleTip: 12;
|
|
12
|
+
readonly ringBase: 13;
|
|
13
|
+
readonly ringTip: 16;
|
|
14
|
+
readonly pinkyBase: 17;
|
|
15
|
+
readonly pinkyTip: 20;
|
|
16
|
+
};
|
|
17
|
+
/** Palm size: wrist to middle-finger base, in tracker units. 0 without a hand. */
|
|
18
|
+
export declare const handSize: (hand: ReadonlyArray<TrackerPoint> | undefined) => number;
|
|
19
|
+
/**
|
|
20
|
+
* Pinch: 1 when the thumb and index tips touch, 0 when they are a palm
|
|
21
|
+
* length apart. Scale-free (divided by the palm size).
|
|
22
|
+
*/
|
|
23
|
+
export declare const measurePinch: (hand: ReadonlyArray<TrackerPoint> | undefined) => number;
|
|
24
|
+
/**
|
|
25
|
+
* Finger curl, 0 (extended) .. 1 (curled), from the tip-to-wrist distance
|
|
26
|
+
* relative to the base-to-wrist distance: extended ≈ 1.6×, curled ≈ 1.0×.
|
|
27
|
+
*/
|
|
28
|
+
export declare const fingerCurl: (hand: ReadonlyArray<TrackerPoint>, base: number, tip: number) => number;
|
|
29
|
+
/** Extension of index..pinky, 0 (curled) .. 1 (extended), in finger order. */
|
|
30
|
+
export declare const fingerExtensions: (hand: ReadonlyArray<TrackerPoint>, target?: [number, number, number, number]) => [number, number, number, number];
|
|
31
|
+
/**
|
|
32
|
+
* Thumb extension: how far the thumb tip sits from the index base, in palm
|
|
33
|
+
* sizes. Tucked across the palm ≈ 0.4, stretched out ≈ 1.0+.
|
|
34
|
+
*/
|
|
35
|
+
export declare const thumbExtension: (hand: ReadonlyArray<TrackerPoint>) => number;
|
|
36
|
+
/** Thumb direction: +1 pointing up (tracker Y up), −1 pointing down, in palm sizes of vertical rise. */
|
|
37
|
+
export declare const thumbDirection: (hand: ReadonlyArray<TrackerPoint>) => number;
|
|
38
|
+
export type FingerPattern = {
|
|
39
|
+
/** Required state of index, middle, ring, pinky: `true` extended, `false` curled, `null` either. */
|
|
40
|
+
fingers: readonly [boolean | null, boolean | null, boolean | null, boolean | null];
|
|
41
|
+
/** Required thumb state; `null` = either. */
|
|
42
|
+
thumb?: boolean | null;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Score a finger pattern: the weakest of each required finger's extension
|
|
46
|
+
* (or curl) and the thumb's. 1 only when every required finger agrees.
|
|
47
|
+
*/
|
|
48
|
+
export declare const measureFingerPattern: (hand: ReadonlyArray<TrackerPoint> | undefined, pattern: FingerPattern) => number;
|
|
49
|
+
/** Thumb up / down: thumb out and pointing the right way while the fingers curl. */
|
|
50
|
+
export declare const measureThumb: (hand: ReadonlyArray<TrackerPoint> | undefined, direction: "up" | "down") => number;
|
|
51
|
+
/** Grab (fist): mean curl of index..pinky. */
|
|
52
|
+
export declare const measureGrab: (hand: ReadonlyArray<TrackerPoint> | undefined) => number;
|
|
53
|
+
/** Open palm: mean extension of index..pinky (1 − curl). */
|
|
54
|
+
export declare const measureOpenPalm: (hand: ReadonlyArray<TrackerPoint> | undefined) => number;
|
|
55
|
+
/** Hand height on screen: 0 at the bottom edge, 0.5 at the centre, 1 at the top (tracker Y up). */
|
|
56
|
+
export declare const measureHandHeight: (hand: ReadonlyArray<TrackerPoint> | undefined) => number;
|
|
57
|
+
/** MediaPipe pose landmarks used by the body measures (person's perspective). */
|
|
58
|
+
export declare const POSE_JOINTS: {
|
|
59
|
+
readonly leftShoulder: 11;
|
|
60
|
+
readonly rightShoulder: 12;
|
|
61
|
+
readonly leftElbow: 13;
|
|
62
|
+
readonly rightElbow: 14;
|
|
63
|
+
readonly leftWrist: 15;
|
|
64
|
+
readonly rightWrist: 16;
|
|
65
|
+
readonly leftHip: 23;
|
|
66
|
+
readonly rightHip: 24;
|
|
67
|
+
};
|
|
68
|
+
/** Shoulder width in tracker units; the body's scale reference. */
|
|
69
|
+
export declare const shoulderWidth: (pose: ReadonlyArray<TrackerPoint>) => number;
|
|
70
|
+
/**
|
|
71
|
+
* How far a wrist is raised above its shoulder, in shoulder widths: 0 at
|
|
72
|
+
* shoulder level or below, 1 at one shoulder width above.
|
|
73
|
+
*/
|
|
74
|
+
export declare const measureArmRaise: (pose: ReadonlyArray<TrackerPoint> | undefined, side: "left" | "right") => number;
|
|
75
|
+
/**
|
|
76
|
+
* T-pose: both wrists level with the shoulders and stretched outward by at
|
|
77
|
+
* least a shoulder width. 1 when fully extended and level.
|
|
78
|
+
*/
|
|
79
|
+
export declare const measureTPose: (pose: ReadonlyArray<TrackerPoint> | undefined) => number;
|
|
80
|
+
/**
|
|
81
|
+
* Counts direction reversals of a scalar over a sliding window: the engine
|
|
82
|
+
* behind nod, head shake and wave. A reversal counts when the signal has
|
|
83
|
+
* moved at least `minAmplitude` from the last turning point. `measure`
|
|
84
|
+
* returns `min(1, reversals / requiredReversals)` within `windowMs`.
|
|
85
|
+
*/
|
|
86
|
+
export declare class OscillationTracker {
|
|
87
|
+
private readonly options;
|
|
88
|
+
private reversals;
|
|
89
|
+
private lastExtremum;
|
|
90
|
+
private lastValue;
|
|
91
|
+
private direction;
|
|
92
|
+
constructor(options: {
|
|
93
|
+
minAmplitude: number;
|
|
94
|
+
requiredReversals: number;
|
|
95
|
+
windowMs: number;
|
|
96
|
+
});
|
|
97
|
+
reset(): void;
|
|
98
|
+
/** Feed one sample; returns the oscillation progress 0..1. */
|
|
99
|
+
push(value: number, nowMs: number): number;
|
|
100
|
+
private progress;
|
|
101
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { GestureDetectorOptions } from './detector';
|
|
2
|
+
/** Flat, panel-friendly detector options. */
|
|
3
|
+
export type GestureSettings = GestureDetectorOptions;
|
|
4
|
+
export declare const DEFAULT_GESTURE_SETTINGS: GestureSettings;
|
|
5
|
+
export declare const GESTURE_SETTINGS_FIELDS: [{
|
|
6
|
+
readonly key: "enterThreshold";
|
|
7
|
+
readonly label: "Enter threshold";
|
|
8
|
+
readonly type: "number";
|
|
9
|
+
readonly min: 0;
|
|
10
|
+
readonly max: 1;
|
|
11
|
+
readonly step: 0.01;
|
|
12
|
+
}, {
|
|
13
|
+
readonly key: "exitThreshold";
|
|
14
|
+
readonly label: "Exit threshold";
|
|
15
|
+
readonly type: "number";
|
|
16
|
+
readonly min: 0;
|
|
17
|
+
readonly max: 1;
|
|
18
|
+
readonly step: 0.01;
|
|
19
|
+
}, {
|
|
20
|
+
readonly key: "holdMs";
|
|
21
|
+
readonly label: "Hold before begin (ms)";
|
|
22
|
+
readonly type: "number";
|
|
23
|
+
readonly min: 0;
|
|
24
|
+
readonly max: 1000;
|
|
25
|
+
readonly step: 10;
|
|
26
|
+
}, {
|
|
27
|
+
readonly key: "cooldownMs";
|
|
28
|
+
readonly label: "Cooldown after end (ms)";
|
|
29
|
+
readonly type: "number";
|
|
30
|
+
readonly min: 0;
|
|
31
|
+
readonly max: 3000;
|
|
32
|
+
readonly step: 50;
|
|
33
|
+
}, {
|
|
34
|
+
readonly key: "minConfidence";
|
|
35
|
+
readonly label: "Min confidence";
|
|
36
|
+
readonly type: "number";
|
|
37
|
+
readonly min: 0;
|
|
38
|
+
readonly max: 1;
|
|
39
|
+
readonly step: 0.05;
|
|
40
|
+
}, {
|
|
41
|
+
readonly key: "lostGraceMs";
|
|
42
|
+
readonly label: "Loss grace (ms)";
|
|
43
|
+
readonly type: "number";
|
|
44
|
+
readonly min: 0;
|
|
45
|
+
readonly max: 1000;
|
|
46
|
+
readonly step: 10;
|
|
47
|
+
}];
|
|
48
|
+
export declare const resolveGestureSettings: (value?: Partial<GestureSettings>, defaults?: GestureSettings) => GestureSettings;
|
|
49
|
+
export declare const patchGestureSettings: (current: GestureSettings, patch: Partial<GestureSettings>) => GestureSettings;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState as X, useEffect as Y } from "react";
|
|
2
|
-
import { F as A } from "./index-
|
|
2
|
+
import { F as A } from "./index-CsUdQ-pn.js";
|
|
3
3
|
const E = (e, t = {
|
|
4
4
|
minX: 0,
|
|
5
5
|
minY: 0,
|
|
@@ -107,10 +107,10 @@ const E = (e, t = {
|
|
|
107
107
|
export {
|
|
108
108
|
R as D,
|
|
109
109
|
C as a,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
q as b,
|
|
111
|
+
_ as c,
|
|
112
|
+
P as d,
|
|
113
|
+
E as e,
|
|
114
114
|
w as g,
|
|
115
115
|
T as h,
|
|
116
116
|
L as p,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const x=require("react"),b=require("./index-
|
|
1
|
+
"use strict";const x=require("react"),b=require("./index-OCPjOaeP.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;
|
|
@@ -1,8 +1,68 @@
|
|
|
1
1
|
import { CanvasTexture } from 'three';
|
|
2
2
|
import { XRModel } from '../constants';
|
|
3
|
-
import {
|
|
3
|
+
import { sessionReasonToFallback } from '../capabilities/detect';
|
|
4
|
+
import { XRFallbackReason } from '../capabilities/types';
|
|
5
|
+
import { XRCameraPermissionState } from '../camera/permission';
|
|
6
|
+
import { XRCameraFacing, XROrientation } from '../types/compositor';
|
|
7
|
+
import { XRQualityConfig, XRQualityState } from '../quality/types';
|
|
8
|
+
import { FeedCrop } from '../coordinates/feed';
|
|
9
|
+
import { SessionLifecycleState, XRModelError, XRSessionError } from './useXRSession/store';
|
|
4
10
|
export declare const useXRReady: () => boolean;
|
|
5
11
|
export declare const useXRError: () => XRSessionError | undefined;
|
|
12
|
+
/** The session lifecycle state (`idle` → `media-bound` → `running` ⇄ `paused` → `stopped`). */
|
|
13
|
+
export declare const useXRLifecycle: () => SessionLifecycleState;
|
|
14
|
+
/** Models whose last initialize failed, keyed by `XRModel`. Empty map while healthy. */
|
|
15
|
+
export declare const useXRModelErrors: () => ReadonlyMap<XRModel, XRModelError>;
|
|
16
|
+
export { sessionReasonToFallback };
|
|
17
|
+
export type XRCameraPermission = {
|
|
18
|
+
state: XRCameraPermissionState;
|
|
19
|
+
/** Structured cause for `denied` / `blocked` / `unavailable`; `null` otherwise. */
|
|
20
|
+
reason: XRFallbackReason | null;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Whether the session mirrors its feed. One answer for preview AND tracking:
|
|
24
|
+
* both read the same mirrored (front camera) or straight (rear camera, image,
|
|
25
|
+
* video) feed, so a point computed from landmarks lands where the preview
|
|
26
|
+
* shows it. Use it only for *direction* signs (left/right semantics), never
|
|
27
|
+
* to flip positions.
|
|
28
|
+
*/
|
|
29
|
+
export declare const useXRMirrored: () => boolean;
|
|
30
|
+
/** Device orientation (`portrait` / `landscape`, rotation angle) as the session tracks it. */
|
|
31
|
+
export declare const useXROrientation: () => XROrientation;
|
|
32
|
+
/** Device id of the live camera (`null` for stream / canvas sources or when the browser hides it). */
|
|
33
|
+
export declare const useXRCameraDeviceId: () => string | null;
|
|
34
|
+
/** The mounted quality controller's resolved config (`null` when none is mounted). */
|
|
35
|
+
export declare const useXRQualityConfig: () => XRQualityConfig | null;
|
|
36
|
+
/** Adaptive-quality state as published by the controller (`null` when none is mounted). */
|
|
37
|
+
export declare const useXRQualityState: () => XRQualityState | null;
|
|
38
|
+
/** Facing of the live camera the session bound (`null` for stream / canvas sources). */
|
|
39
|
+
export declare const useXRCameraFacing: () => XRCameraFacing | null;
|
|
40
|
+
/**
|
|
41
|
+
* The SESSION's live camera permission: `requesting` while its webcam
|
|
42
|
+
* `getUserMedia` prompt is open, `granted` once bound, `denied` / `blocked` /
|
|
43
|
+
* `unavailable` after a failure or a mid-session revoke, `unknown` before
|
|
44
|
+
* the first webcam bind. This is not the pre-session gate: for a landing
|
|
45
|
+
* screen without a provider use `useCameraPermission` from the core door.
|
|
46
|
+
*/
|
|
47
|
+
export declare const useXRSessionCameraPermission: () => XRCameraPermission;
|
|
48
|
+
export type XRTrackerStatus = {
|
|
49
|
+
/**
|
|
50
|
+
* `unavailable`: nobody acquired the model. `loading`: acquired, not yet
|
|
51
|
+
* initialized. `ready`: initialized, whatever the session lifecycle (a
|
|
52
|
+
* paused or stopped session keeps it initialized; `useXRDiagnostics`
|
|
53
|
+
* reports that as `paused`). `blocked`: the camera failed, so the model
|
|
54
|
+
* cannot see frames. `error`: the model itself failed to initialize.
|
|
55
|
+
*/
|
|
56
|
+
status: "unavailable" | "loading" | "ready" | "blocked" | "error";
|
|
57
|
+
/** Structured cause for `blocked` / `error`; `null` otherwise. */
|
|
58
|
+
fallback: XRFallbackReason | null;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Actionable status for one tracker, readable by components that do not own
|
|
62
|
+
* it (a "tracking unavailable" banner, a fallback 2D mode). Combines the
|
|
63
|
+
* session's camera error with the model's registration and init error.
|
|
64
|
+
*/
|
|
65
|
+
export declare const useXRTrackerStatus: (modelName: XRModel) => XRTrackerStatus;
|
|
6
66
|
export declare const useXRCameraTexture: () => CanvasTexture | undefined;
|
|
7
67
|
export declare const useXRRenderSize: () => {
|
|
8
68
|
width: number;
|
|
@@ -21,6 +81,13 @@ export declare const useXRRenderSize: () => {
|
|
|
21
81
|
* directly would warn about unstable snapshots because most model classes
|
|
22
82
|
* build their node object literal on every `getModelNode()` call.
|
|
23
83
|
*/
|
|
84
|
+
/**
|
|
85
|
+
* The session's source → feed transform (`FeedCrop`): cover crop at the
|
|
86
|
+
* render size, `perf.cameraZoom`, and the webcam mirror. `null` until media
|
|
87
|
+
* is bound. Feed it to `sourceToFeed` / `feedToSource` from `@vincentt-xr/sdk`
|
|
88
|
+
* to move points between raw media pixels and landmark space.
|
|
89
|
+
*/
|
|
90
|
+
export declare const useXRFeedCrop: () => FeedCrop | null;
|
|
24
91
|
export declare const useXRModelNode: <T extends Record<string, unknown>>(modelName: XRModel) => T | null;
|
|
25
92
|
/**
|
|
26
93
|
* Snapshot of which models are currently registered. Useful for debugger
|
|
@@ -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: "ready" | "error" | "idle" | "initializing";
|
|
22
22
|
error: string | null;
|
|
23
23
|
};
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { FaceInfo } from '../face-info';
|
|
2
|
+
import { XRSubjectPolicy } from '../subjects/types';
|
|
2
3
|
import { UseFaceInfosOptions } from './useFaceInfos';
|
|
3
4
|
export type UseFaceInfoOptions = UseFaceInfosOptions & {
|
|
5
|
+
/** Result-array position to read (not a persistent identity). Default 0. Ignored when `subject` is set. */
|
|
4
6
|
faceIndex?: number;
|
|
7
|
+
/**
|
|
8
|
+
* Multi-subject policy: pick the face by `largest`, `nearest-center`,
|
|
9
|
+
* `leftmost`, `rightmost`, or `sticky` (follows the previously selected
|
|
10
|
+
* face by proximity). With a policy and no `numFaces`, the model is asked
|
|
11
|
+
* for `DEFAULT_POLICY_NUM_FACES` (4) faces so the policy has candidates;
|
|
12
|
+
* pass `numFaces` to choose the count.
|
|
13
|
+
*/
|
|
14
|
+
subject?: XRSubjectPolicy;
|
|
5
15
|
};
|
|
16
|
+
/** Faces requested when a `subject` policy is set without `numFaces`. */
|
|
17
|
+
export declare const DEFAULT_POLICY_NUM_FACES = 4;
|
|
6
18
|
/** Single-face selector over `useFaceInfos`; it does not create another reader loop. */
|
|
7
|
-
export declare const useFaceInfo: ({ faceIndex, numFaces, ...options }?: UseFaceInfoOptions) => FaceInfo | null;
|
|
19
|
+
export declare const useFaceInfo: ({ faceIndex, numFaces, subject, ...options }?: UseFaceInfoOptions) => FaceInfo | null;
|
|
@@ -2,7 +2,7 @@ import { FaceInfo } from '../face-info';
|
|
|
2
2
|
export type UseFaceInfosOptions = {
|
|
3
3
|
/** Pauses this consumer's model interest when false. Default true. */
|
|
4
4
|
active?: boolean;
|
|
5
|
-
/** Maximum faces requested from the shared model. Default 1. */
|
|
5
|
+
/** Maximum faces requested from the shared model. Default 1, capped at 10 (`XR_MAX_SUBJECTS.face.max`). */
|
|
6
6
|
numFaces?: number;
|
|
7
7
|
/** Optional inference-rate cap. */
|
|
8
8
|
targetFps?: number;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GestureDetectorOptions, GestureState } from '../gestures/detector';
|
|
2
|
+
import { GestureRef } from '../gestures/definitions';
|
|
3
|
+
export type UseGestureOptions = Partial<GestureDetectorOptions> & {
|
|
4
|
+
/** Pause measuring (the tracker interest is released too). Default true. */
|
|
5
|
+
active?: boolean;
|
|
6
|
+
/** Face gestures: result-array index of the face. Default 0. */
|
|
7
|
+
faceIndex?: number;
|
|
8
|
+
/** Face gestures: faces to request from the shared model (first acquirer wins). */
|
|
9
|
+
numFaces?: number;
|
|
10
|
+
/** Hand gestures: prefer this hand when present. */
|
|
11
|
+
hand?: "left" | "right";
|
|
12
|
+
/** Hand gestures: positional fallback. Default 0. */
|
|
13
|
+
handIndex?: number;
|
|
14
|
+
/** Body gestures: pose index. Default 0. */
|
|
15
|
+
bodyIndex?: number;
|
|
16
|
+
/** Optional inference cap for the underlying model. */
|
|
17
|
+
targetFps?: number;
|
|
18
|
+
/** Lifecycle events; called from the frame loop with the state of that frame. */
|
|
19
|
+
onBegin?: (state: GestureState) => void;
|
|
20
|
+
onEnd?: (state: GestureState) => void;
|
|
21
|
+
onChange?: (state: GestureState) => void;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Detect one gesture from the tracker it needs. Acquires the shared face,
|
|
25
|
+
* hand or body model (no second detector), measures the definition every
|
|
26
|
+
* frame, and runs the gesture engine: enter/exit hysteresis, hold,
|
|
27
|
+
* cooldown, a confidence gate and a loss grace window. Returns React state
|
|
28
|
+
* that changes only when the gesture's state changes; `onBegin` / `onEnd` /
|
|
29
|
+
* `onChange` fire from the frame loop. Must run inside `XRProvider` and the
|
|
30
|
+
* R3F canvas.
|
|
31
|
+
*/
|
|
32
|
+
export declare const useGesture: (gesture: GestureRef, options?: UseGestureOptions) => GestureState;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { IrisResult } from '../iris/types';
|
|
2
|
+
export type IrisTrackingStatus = "loading" | "ready" | "error";
|
|
3
|
+
export type UseIrisTrackingOptions = {
|
|
4
|
+
/** Result-array index of the face to read. Default 0. */
|
|
5
|
+
faceIndex?: number;
|
|
6
|
+
/** Maximum faces requested from the shared face model (first acquirer wins). Default `faceIndex + 1`. */
|
|
7
|
+
numFaces?: number;
|
|
8
|
+
/** Pauses this consumer's model interest when false. Default true. */
|
|
9
|
+
active?: boolean;
|
|
10
|
+
/** Optional inference-rate cap for the shared face model. */
|
|
11
|
+
targetFps?: number;
|
|
12
|
+
/** Keep the last iris data for this long (ms) after the face drops. Default 250. */
|
|
13
|
+
holdMs?: number;
|
|
14
|
+
/** While held, extrapolate along the last velocity for up to this long (ms). Default 0. */
|
|
15
|
+
predictMs?: number;
|
|
16
|
+
/**
|
|
17
|
+
* One Euro smoothing of the iris centers and radius, same scale as
|
|
18
|
+
* `TrackingAnchor`'s `smoothing` (~15 is a good default; 0 = raw). Resets on
|
|
19
|
+
* re-acquire so the iris never slides in from a stale position.
|
|
20
|
+
*/
|
|
21
|
+
smoothing?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Inference runs below the render rate (24 fps by default against 60+
|
|
24
|
+
* rendered), so the iris would hold then jump on each sample. Between
|
|
25
|
+
* samples the centers are advanced along their last velocity for at most
|
|
26
|
+
* this long (ms), which keeps fast head motion continuous. Default 80;
|
|
27
|
+
* 0 disables.
|
|
28
|
+
*/
|
|
29
|
+
leadMs?: number;
|
|
30
|
+
};
|
|
31
|
+
export type IrisTrackingHandle = {
|
|
32
|
+
/** Stable object, updated in place every frame. Read it inside `useFrame`. */
|
|
33
|
+
result: IrisResult;
|
|
34
|
+
/** True once the shared face model is registered without error. */
|
|
35
|
+
ready: boolean;
|
|
36
|
+
status: IrisTrackingStatus;
|
|
37
|
+
error: Error | null;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Per-frame iris reader over the shared face tracker: no second detector,
|
|
41
|
+
* the same `faceIndex` / `numFaces` selection as `useFaceInfo`, the SDK's
|
|
42
|
+
* one dropout bridge (`FaceTrackMemory`, hold 250 / predict 0) and optional
|
|
43
|
+
* One Euro smoothing. Must run inside `XRProvider` and the R3F canvas.
|
|
44
|
+
*/
|
|
45
|
+
export declare const useIrisTracking: ({ faceIndex, numFaces, active, targetFps, holdMs, predictMs, smoothing, leadMs, }?: UseIrisTrackingOptions) => IrisTrackingHandle;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { XRModel, XRMediaSource } from '../constants';
|
|
2
|
+
import { XRModelDiagnostics } from '../models/Base';
|
|
3
|
+
import { XRSessionSourceKind } from '../types/compositor';
|
|
4
|
+
import { SessionFacade } from './useXRSession';
|
|
5
|
+
import { SessionLifecycleState, XRSessionError } from './useXRSession/store';
|
|
6
|
+
/** One tracker's health, merged from the registry and the model instance. */
|
|
7
|
+
export type XRModelDiagnosticsEntry = XRModelDiagnostics & {
|
|
8
|
+
model: XRModel;
|
|
9
|
+
/** Short human label (`face`, `hand`, …). */
|
|
10
|
+
label: string;
|
|
11
|
+
/**
|
|
12
|
+
* `unavailable`: nothing acquired it. `loading`: acquired, initializing.
|
|
13
|
+
* `ready`: running. `paused`: initialized but no active owner (or the
|
|
14
|
+
* session is stopped / paused). `error`: initialize or inference failed.
|
|
15
|
+
*/
|
|
16
|
+
state: "unavailable" | "loading" | "ready" | "paused" | "error";
|
|
17
|
+
/** Inference-rate cap requested for this model (`null` = uncapped / unknown). */
|
|
18
|
+
targetFps: number | null;
|
|
19
|
+
/** Owners holding the model and those that want it running. */
|
|
20
|
+
owners: {
|
|
21
|
+
refs: string[];
|
|
22
|
+
active: string[];
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export type XRSessionDiagnostics = {
|
|
26
|
+
lifecycle: SessionLifecycleState;
|
|
27
|
+
ready: boolean;
|
|
28
|
+
error: XRSessionError | undefined;
|
|
29
|
+
source: XRMediaSource | undefined;
|
|
30
|
+
sourceKind: XRSessionSourceKind | undefined;
|
|
31
|
+
/** Native media size. */
|
|
32
|
+
sourceWidth: number;
|
|
33
|
+
sourceHeight: number;
|
|
34
|
+
/** Tracker feed / render size. */
|
|
35
|
+
renderWidth: number;
|
|
36
|
+
renderHeight: number;
|
|
37
|
+
/** Frames the session blitted into the tracker feed per second (0 while paused). */
|
|
38
|
+
feedFps: number;
|
|
39
|
+
/** Total feed frames since the provider mounted. */
|
|
40
|
+
feedFrames: number;
|
|
41
|
+
};
|
|
42
|
+
export type XRDiagnostics = {
|
|
43
|
+
session: XRSessionDiagnostics;
|
|
44
|
+
/** Adaptive-quality tier (`null` when no controller is mounted). */
|
|
45
|
+
quality: {
|
|
46
|
+
tier: string;
|
|
47
|
+
index: number;
|
|
48
|
+
locked: boolean;
|
|
49
|
+
reason: string;
|
|
50
|
+
} | null;
|
|
51
|
+
models: XRModelDiagnosticsEntry[];
|
|
52
|
+
/** Sum of the last inference time of every running model (ms). */
|
|
53
|
+
inferenceMsTotal: number;
|
|
54
|
+
/** `performance.now()` when this sample was taken. */
|
|
55
|
+
sampledAt: number;
|
|
56
|
+
};
|
|
57
|
+
export type UseXRDiagnosticsOptions = {
|
|
58
|
+
/** Sampling period in ms (default 250). Diagnostics never sample per frame. */
|
|
59
|
+
intervalMs?: number;
|
|
60
|
+
/** Models to report; default every `XRModel`, so unacquired ones show as `unavailable`. */
|
|
61
|
+
models?: XRModel[];
|
|
62
|
+
/** `false` stops sampling (the last sample stays). Default `true`. */
|
|
63
|
+
enabled?: boolean;
|
|
64
|
+
};
|
|
65
|
+
export declare const XR_MODEL_LABELS: Record<XRModel, string>;
|
|
66
|
+
/**
|
|
67
|
+
* Take one diagnostics sample from a session. Pure over the session's current
|
|
68
|
+
* state; `previous` supplies the frame baseline for the feed fps.
|
|
69
|
+
*/
|
|
70
|
+
export declare const sampleXRDiagnostics: (session: SessionFacade, models: XRModel[], previous: {
|
|
71
|
+
feedFrames: number;
|
|
72
|
+
sampledAt: number;
|
|
73
|
+
} | null, now?: number) => XRDiagnostics;
|
|
74
|
+
/**
|
|
75
|
+
* Opt-in tracking diagnostics: session lifecycle, source and feed size, feed
|
|
76
|
+
* frame rate, and per-model readiness, inference time and rate, skipped
|
|
77
|
+
* frames, detections, confidence and errors. Sampled on an interval (never per
|
|
78
|
+
* frame) only while a consumer is mounted, so it costs nothing in production
|
|
79
|
+
* until you render it. Requires an `<XRProvider>`.
|
|
80
|
+
*/
|
|
81
|
+
export declare const useXRDiagnostics: (options?: UseXRDiagnosticsOptions) => XRDiagnostics;
|