@vincentt-xr/sdk 2.0.0-alpha.0
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 +537 -0
- package/LICENSE +7 -0
- package/README.md +85 -0
- package/dist/DebuggerUI-CEfdddkZ.cjs +1 -0
- package/dist/DebuggerUI-Dgop6Q6o.js +269 -0
- package/dist/audio/AudioEngine.d.ts +98 -0
- package/dist/audio/index.d.ts +34 -0
- package/dist/components/AspectRatioContainer/index.d.ts +10 -0
- package/dist/components/BodyTracker/index.d.ts +15 -0
- package/dist/components/Debugger/DebuggerProvider.d.ts +22 -0
- package/dist/components/Debugger/DebuggerUI.d.ts +13 -0
- package/dist/components/Debugger/index.d.ts +38 -0
- package/dist/components/Debugger/styles.d.ts +19 -0
- package/dist/components/FaceMesh/FaceMesh.d.ts +26 -0
- package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +34 -0
- package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +16 -0
- package/dist/components/FaceMesh/canonical/useCanonicalFaceMesh.d.ts +15 -0
- package/dist/components/FaceMesh/deform.d.ts +36 -0
- package/dist/components/FaceMesh/index.d.ts +6 -0
- package/dist/components/FaceMesh/indices.d.ts +1 -0
- package/dist/components/FaceMesh/material/blendModes.d.ts +2 -0
- package/dist/components/FaceMesh/material/defaults.d.ts +3 -0
- package/dist/components/FaceMesh/material/index.d.ts +5 -0
- package/dist/components/FaceMesh/material/options.d.ts +25 -0
- package/dist/components/FaceMesh/material/support.d.ts +3 -0
- package/dist/components/FaceMesh/material/types.d.ts +23 -0
- package/dist/components/FaceMesh/uv.d.ts +1 -0
- package/dist/components/FaceRetouch/Background.d.ts +16 -0
- package/dist/components/FaceRetouch/index.d.ts +6 -0
- package/dist/components/FaceRetouch/landmarkMask.d.ts +23 -0
- package/dist/components/FaceRetouch/retouchRegions.d.ts +23 -0
- package/dist/components/FaceRetouch/useFaceRetouchMask.d.ts +14 -0
- package/dist/components/FaceRetouch/useFaceRetouchRegions.d.ts +12 -0
- package/dist/components/FaceTracker/BoundingBoxOverlay.d.ts +20 -0
- package/dist/components/FaceTracker/index.d.ts +54 -0
- package/dist/components/GestureTracker/index.d.ts +31 -0
- package/dist/components/GestureTrigger/index.d.ts +3 -0
- package/dist/components/HandTracker/index.d.ts +24 -0
- package/dist/components/HeadBinding/index.d.ts +31 -0
- package/dist/components/HeadBindingOccluder/index.d.ts +36 -0
- package/dist/components/HeadOccluder/index.d.ts +13 -0
- package/dist/components/Panel/index.d.ts +71 -0
- package/dist/components/PerspectiveCamera/index.d.ts +14 -0
- package/dist/components/ScreenSpaceUI/ScreenTransform.d.ts +54 -0
- package/dist/components/ScreenSpaceUI/context.d.ts +29 -0
- package/dist/components/ScreenSpaceUI/index.d.ts +40 -0
- package/dist/components/Segmentation/index.d.ts +44 -0
- package/dist/components/SpriteAnimation/index.d.ts +52 -0
- package/dist/components/TextLabel/index.d.ts +62 -0
- package/dist/components/TrackingAnchor/index.d.ts +74 -0
- package/dist/components/VideoBackground/index.d.ts +38 -0
- package/dist/components/XRCompositor/index.d.ts +5 -0
- package/dist/components/XRDebugView/index.d.ts +6 -0
- package/dist/components/XRLayer/index.d.ts +6 -0
- package/dist/components/XRMediaSurface/index.d.ts +27 -0
- package/dist/components/XRProvider/index.d.ts +13 -0
- package/dist/components/XRScene/defaults.d.ts +4 -0
- package/dist/components/XRScene/index.d.ts +15 -0
- package/dist/components/XRViewport/index.d.ts +101 -0
- package/dist/components/index.d.ts +26 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/constants/index.d.ts +25 -0
- package/dist/constants/renderLayers.d.ts +25 -0
- package/dist/entries/all.d.ts +15 -0
- package/dist/entries/core.d.ts +21 -0
- package/dist/entries/face-effects.d.ts +19 -0
- package/dist/entries/internal.d.ts +16 -0
- package/dist/entries/low-level.d.ts +30 -0
- package/dist/entries/tracking.d.ts +15 -0
- package/dist/face-effects.cjs +252 -0
- package/dist/face-effects.js +3542 -0
- package/dist/hasFullUnitUVBounds-BGvcFsQM.js +26 -0
- package/dist/hasFullUnitUVBounds-p1Dl0ejX.cjs +1 -0
- package/dist/hooks/faceResults.d.ts +39 -0
- package/dist/hooks/selectors.d.ts +33 -0
- package/dist/hooks/useCalibrationFaceTracker.d.ts +23 -0
- package/dist/hooks/useDebugger/index.d.ts +25 -0
- package/dist/hooks/useDebugger/types.d.ts +20 -0
- package/dist/hooks/useFaceBoundingBox.d.ts +11 -0
- package/dist/hooks/useFaceResults.d.ts +31 -0
- package/dist/hooks/useGestureEdge.d.ts +53 -0
- package/dist/hooks/useMediaRecorder.d.ts +40 -0
- package/dist/hooks/useTrackerContext.d.ts +35 -0
- package/dist/hooks/useXRModel.d.ts +15 -0
- package/dist/hooks/useXRSession/constants.d.ts +4 -0
- package/dist/hooks/useXRSession/facade.d.ts +39 -0
- package/dist/hooks/useXRSession/fns.d.ts +5 -0
- package/dist/hooks/useXRSession/index.d.ts +4 -0
- package/dist/hooks/useXRSession/registry.d.ts +52 -0
- package/dist/hooks/useXRSession/store.d.ts +40 -0
- package/dist/index-B5J4gzn2.cjs +1 -0
- package/dist/index-BD-JWMjE.js +1991 -0
- package/dist/index-BVBVg96G.cjs +1 -0
- package/dist/index-CYMj26Ej.js +1331 -0
- package/dist/index-DtwHElmG.js +157 -0
- package/dist/index-PtFmD6B8.cjs +1 -0
- package/dist/internal-DH5d1Xnq.cjs +1 -0
- package/dist/internal-KOKJDxCG.js +519 -0
- package/dist/internal.cjs +1 -0
- package/dist/internal.js +14 -0
- package/dist/low-level.cjs +1 -0
- package/dist/low-level.js +941 -0
- package/dist/main.cjs +1 -0
- package/dist/main.js +612 -0
- package/dist/models/Base/index.d.ts +25 -0
- package/dist/models/Body/index.d.ts +22 -0
- package/dist/models/Face/constants.d.ts +2 -0
- package/dist/models/Face/index.d.ts +45 -0
- package/dist/models/Face/landmarksData.d.ts +2 -0
- package/dist/models/Hand/GestureTracking.d.ts +21 -0
- package/dist/models/Hand/HandTracking.d.ts +21 -0
- package/dist/models/Segmentation/index.d.ts +75 -0
- package/dist/models/index.d.ts +5 -0
- package/dist/modules/XRClient/index.d.ts +9 -0
- package/dist/modules/index.d.ts +1 -0
- package/dist/selectors-BHO6TnoC.js +59 -0
- package/dist/selectors-Bub0o3qy.cjs +1 -0
- package/dist/services/ApiService.d.ts +12 -0
- package/dist/services/MetricsCollector/CameraFPSTracker.d.ts +25 -0
- package/dist/services/MetricsCollector/MemoryTracker.d.ts +43 -0
- package/dist/services/MetricsCollector/RenderTimeTracker.d.ts +10 -0
- package/dist/services/MetricsCollector/ResolutionTracker.d.ts +26 -0
- package/dist/services/MetricsCollector/index.d.ts +59 -0
- package/dist/services/MetricsCollector/types.d.ts +47 -0
- package/dist/services/MetricsCollector/utils.d.ts +65 -0
- package/dist/texture/computeContainScale.d.ts +25 -0
- package/dist/texture/hasFullUnitUVBounds.d.ts +37 -0
- package/dist/texture/types.d.ts +20 -0
- package/dist/tracking.cjs +1 -0
- package/dist/tracking.js +344 -0
- package/dist/types/body.d.ts +3 -0
- package/dist/types/client.d.ts +3 -0
- package/dist/types/common.d.ts +9 -0
- package/dist/types/compositor.d.ts +23 -0
- package/dist/types/debugger.d.ts +83 -0
- package/dist/types/face.d.ts +67 -0
- package/dist/types/gesture-tracking.d.ts +15 -0
- package/dist/types/hand-tracking.d.ts +5 -0
- package/dist/types/headBinding.d.ts +67 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/logger.d.ts +4 -0
- package/dist/types/model.d.ts +46 -0
- package/dist/types/nodes.d.ts +35 -0
- package/dist/types/segmentation.d.ts +31 -0
- package/dist/types/session.d.ts +102 -0
- package/dist/types/tracking.d.ts +30 -0
- package/dist/types/util-types.d.ts +1 -0
- package/dist/useFaceResults-cpsSmKKc.js +81 -0
- package/dist/useFaceResults-hVUJYSEY.cjs +1 -0
- package/dist/utils/calibrationDebug.d.ts +9 -0
- package/dist/utils/dataURL.d.ts +6 -0
- package/dist/utils/drawMediaCover.d.ts +18 -0
- package/dist/utils/errors.d.ts +3 -0
- package/dist/utils/fns.d.ts +48 -0
- package/dist/utils/headBinding.d.ts +85 -0
- package/dist/utils/integrity.d.ts +43 -0
- package/dist/utils/landmarkBounds.d.ts +11 -0
- package/dist/utils/logger.d.ts +7 -0
- package/package.json +113 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { NormalizedLandmark } from '@mediapipe/tasks-vision';
|
|
2
|
+
import { XRModelNodeFaceTracking } from '../../types/nodes';
|
|
3
|
+
import { RunModelParams } from '../../types';
|
|
4
|
+
import { PerformanceData } from '../../types/common';
|
|
5
|
+
import { FaceModelOptions } from '../../types/face';
|
|
6
|
+
import { BaseXRModel } from '../Base';
|
|
7
|
+
export declare class FaceTrackingModel extends BaseXRModel {
|
|
8
|
+
private landmarker;
|
|
9
|
+
private processingTime;
|
|
10
|
+
private sourceCanvas;
|
|
11
|
+
private analysisCanvas;
|
|
12
|
+
private getSource;
|
|
13
|
+
private detectionResults;
|
|
14
|
+
private numFaces;
|
|
15
|
+
private cameras;
|
|
16
|
+
private faces;
|
|
17
|
+
private leftCheekScratch;
|
|
18
|
+
private rightCheekScratch;
|
|
19
|
+
private landmarkScratch;
|
|
20
|
+
private rotMatrixScratch;
|
|
21
|
+
private rotQuatScratch;
|
|
22
|
+
private rotEulerScratch;
|
|
23
|
+
constructor();
|
|
24
|
+
private landmarkForSource;
|
|
25
|
+
private extractAndUpdateFaceData;
|
|
26
|
+
private processFaceTracking;
|
|
27
|
+
resume(): void;
|
|
28
|
+
private getFace;
|
|
29
|
+
private getDetectionResults;
|
|
30
|
+
private getRawFaceTrackingData;
|
|
31
|
+
initialize(options?: FaceModelOptions): Promise<void>;
|
|
32
|
+
run({ sourceCanvas, getSource, targetFps }: RunModelParams): Promise<void>;
|
|
33
|
+
getModelNode(): XRModelNodeFaceTracking;
|
|
34
|
+
getPerformanceData(): Promise<PerformanceData>;
|
|
35
|
+
}
|
|
36
|
+
export declare const resolveFaceYawRotation: (yawDegrees: number) => number;
|
|
37
|
+
export declare const resolveFaceAnalysisDimension: (numFaces: number) => 1024 | 512;
|
|
38
|
+
/**
|
|
39
|
+
* Reference (allocating) source-aware landmark normalization. Non-webcam
|
|
40
|
+
* sources (image/video) read mirrored from MediaPipe, so x is flipped to
|
|
41
|
+
* display space. The per-frame extraction path uses an in-place scratch
|
|
42
|
+
* variant (`landmarkForSource`) to avoid allocating; this pure form exists
|
|
43
|
+
* for callers/tests that need a plain array transform.
|
|
44
|
+
*/
|
|
45
|
+
export declare const normalizeFaceLandmarksForSource: (landmarks: NormalizedLandmark[], sourceKind?: "webcam" | "image" | "video") => NormalizedLandmark[];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { XRModelNodeGestureTracking } from '../../types/nodes';
|
|
2
|
+
import { RunModelParams } from '../../types';
|
|
3
|
+
import { PerformanceData } from '../../types/common';
|
|
4
|
+
import { BaseXRModel } from '../Base';
|
|
5
|
+
export declare class GestureTrackingModel extends BaseXRModel {
|
|
6
|
+
private landmarker;
|
|
7
|
+
private processingTime;
|
|
8
|
+
private coordinates;
|
|
9
|
+
private gesture;
|
|
10
|
+
private sourceCanvas;
|
|
11
|
+
private readonly downscaler;
|
|
12
|
+
constructor();
|
|
13
|
+
private getGestureData;
|
|
14
|
+
private processGestureTracking;
|
|
15
|
+
resume(): void;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
initialize(): Promise<void>;
|
|
18
|
+
run({ sourceCanvas, targetFps }: RunModelParams): Promise<void>;
|
|
19
|
+
getModelNode(): XRModelNodeGestureTracking;
|
|
20
|
+
getPerformanceData(): Promise<PerformanceData>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { XRModelNodeHandTracking } from '../../types/nodes';
|
|
2
|
+
import { RunModelParams } from '../../types';
|
|
3
|
+
import { PerformanceData } from '../../types/common';
|
|
4
|
+
import { BaseXRModel } from '../Base';
|
|
5
|
+
export declare class HandTrackingModel extends BaseXRModel {
|
|
6
|
+
private landmarker;
|
|
7
|
+
private processingTime;
|
|
8
|
+
private coordinates;
|
|
9
|
+
private gesture;
|
|
10
|
+
private sourceCanvas;
|
|
11
|
+
private readonly downscaler;
|
|
12
|
+
constructor();
|
|
13
|
+
private getHandData;
|
|
14
|
+
private processHandTracking;
|
|
15
|
+
resume(): void;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
initialize(): Promise<void>;
|
|
18
|
+
run({ sourceCanvas, targetFps }: RunModelParams): Promise<void>;
|
|
19
|
+
getModelNode(): XRModelNodeHandTracking;
|
|
20
|
+
getPerformanceData(): Promise<PerformanceData>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { PerformanceData, RunModelParams, SegmentationModelOptions } from '../../types';
|
|
2
|
+
import { XRModelNodeSegmentation } from '../../types/nodes';
|
|
3
|
+
import { BaseXRModel } from '../Base';
|
|
4
|
+
export declare class BackgroundSegmentationModel extends BaseXRModel {
|
|
5
|
+
private segmenter;
|
|
6
|
+
private processingTime;
|
|
7
|
+
private sourceCanvas;
|
|
8
|
+
private processCanvas;
|
|
9
|
+
private filterCanvas;
|
|
10
|
+
private inputSource;
|
|
11
|
+
private inputSourceSize;
|
|
12
|
+
private glCanvas;
|
|
13
|
+
private drawingUtils;
|
|
14
|
+
private useGpuMaskPath;
|
|
15
|
+
private maskImageData;
|
|
16
|
+
private maskCanvas;
|
|
17
|
+
private segmentationMaskTexture;
|
|
18
|
+
private isMaskSetup;
|
|
19
|
+
private isProcessing;
|
|
20
|
+
private latestMask;
|
|
21
|
+
private rawCache;
|
|
22
|
+
private quality;
|
|
23
|
+
constructor();
|
|
24
|
+
private getQualityScaleFactor;
|
|
25
|
+
/**
|
|
26
|
+
* Set (or clear) a high-resolution input override. Pass the raw <video>/<img>
|
|
27
|
+
* (or any CanvasImageSource with intrinsic dimensions) to run segmentation on
|
|
28
|
+
* native-resolution, uncropped frames instead of the small display-fit session
|
|
29
|
+
* feed. Pass `undefined` to revert to the shared feed canvas.
|
|
30
|
+
*/
|
|
31
|
+
setInputSource(source: CanvasImageSource | undefined): void;
|
|
32
|
+
private readIntrinsicSize;
|
|
33
|
+
/**
|
|
34
|
+
* Size the process canvas to the override input's aspect ratio, bounded by
|
|
35
|
+
* PROCESS_MAX_DIM on the long edge, and keep the GL canvas in sync so the GPU
|
|
36
|
+
* mask renders at the same resolution. No-op when there is no override, or when
|
|
37
|
+
* the intrinsic size hasn't changed since the last frame.
|
|
38
|
+
*/
|
|
39
|
+
private ensureProcessCanvasForInput;
|
|
40
|
+
private processSegmentation;
|
|
41
|
+
/**
|
|
42
|
+
* Blit the GPU-rendered mask (already RGBA-inverted by drawCategoryMask)
|
|
43
|
+
* straight from the GL canvas into the mask canvas, cover-fitted through the
|
|
44
|
+
* soft-edge blur. `drawImage(glCanvas)` is a GPU→GPU transfer — no readPixels,
|
|
45
|
+
* no CPU array, no ImageData, no row flip (the 2D canvas presents the WebGL
|
|
46
|
+
* canvas right-side-up). This is the zero-readback path.
|
|
47
|
+
*/
|
|
48
|
+
private blitGlToMask;
|
|
49
|
+
/**
|
|
50
|
+
* CPU-fallback inverted-alpha ImageData build (only when the GPU path is off).
|
|
51
|
+
* The single-channel mask is expanded to RGBA with the person→transparent,
|
|
52
|
+
* background→opaque convention (green carries the signal for the alphaMap).
|
|
53
|
+
*/
|
|
54
|
+
private readMaskToImageData;
|
|
55
|
+
/**
|
|
56
|
+
* CPU-fallback blit: put the inverted-alpha mask ImageData into maskCanvas
|
|
57
|
+
* with a soft-edge blur, cover-fitted to the render target. Only used when the
|
|
58
|
+
* GPU path is off; the GPU path blits the GL canvas directly (blitGlToMask).
|
|
59
|
+
*/
|
|
60
|
+
private blitImageDataToMask;
|
|
61
|
+
private stagingCanvas;
|
|
62
|
+
private getStagingCanvas;
|
|
63
|
+
resume(): void;
|
|
64
|
+
dispose(): void;
|
|
65
|
+
initialize(options?: SegmentationModelOptions): Promise<void>;
|
|
66
|
+
run({ sourceCanvas, renderWidth, renderHeight, targetFps, }: RunModelParams): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Lazily read the single-channel mask back to a Uint8Array. Only invoked when
|
|
69
|
+
* a consumer calls getRawSegmentationData(); the default texture path never
|
|
70
|
+
* touches it, so apps that only use <VideoBackground> pay no extra readback.
|
|
71
|
+
*/
|
|
72
|
+
private getRawSegmentationData;
|
|
73
|
+
getModelNode(): XRModelNodeSegmentation;
|
|
74
|
+
getPerformanceData(): Promise<PerformanceData>;
|
|
75
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { BodyTrackingModel } from './Body';
|
|
2
|
+
export { FaceTrackingModel } from './Face';
|
|
3
|
+
export { GestureTrackingModel } from './Hand/GestureTracking';
|
|
4
|
+
export { HandTrackingModel } from './Hand/HandTracking';
|
|
5
|
+
export { BackgroundSegmentationModel } from './Segmentation';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { XRClientConfig } from '../../types';
|
|
2
|
+
export declare class XRClient {
|
|
3
|
+
private static instance;
|
|
4
|
+
private logger;
|
|
5
|
+
private session?;
|
|
6
|
+
static initialize(config: XRClientConfig): Promise<XRClient>;
|
|
7
|
+
private constructor();
|
|
8
|
+
createSession(): Promise<XRSession>;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './XRClient';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useSyncExternalStore as s, useMemo as a } from "react";
|
|
2
|
+
import { u } from "./index-CYMj26Ej.js";
|
|
3
|
+
const r = () => u().session.store, o = (e) => (t) => e.subscribe(t), p = () => {
|
|
4
|
+
const e = r();
|
|
5
|
+
return s(
|
|
6
|
+
o(e),
|
|
7
|
+
() => e.getSnapshot().ready,
|
|
8
|
+
() => !1
|
|
9
|
+
);
|
|
10
|
+
}, l = () => {
|
|
11
|
+
const e = r();
|
|
12
|
+
return s(
|
|
13
|
+
o(e),
|
|
14
|
+
() => e.getSnapshot().error,
|
|
15
|
+
() => {
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
}, d = () => {
|
|
19
|
+
const e = r();
|
|
20
|
+
return s(
|
|
21
|
+
o(e),
|
|
22
|
+
() => e.getSnapshot().cameraTexture,
|
|
23
|
+
() => {
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
}, h = () => {
|
|
27
|
+
const e = r(), t = s(
|
|
28
|
+
o(e),
|
|
29
|
+
() => e.getSnapshot().renderWidth,
|
|
30
|
+
() => 0
|
|
31
|
+
), n = s(
|
|
32
|
+
o(e),
|
|
33
|
+
() => e.getSnapshot().renderHeight,
|
|
34
|
+
() => 0
|
|
35
|
+
);
|
|
36
|
+
return a(() => ({ width: t, height: n }), [t, n]);
|
|
37
|
+
}, S = (e) => {
|
|
38
|
+
const t = r(), n = s(
|
|
39
|
+
o(t),
|
|
40
|
+
() => t.getSnapshot().pipeline.get(e) ?? null,
|
|
41
|
+
() => null
|
|
42
|
+
);
|
|
43
|
+
return a(() => n ? n.getModelNode() : null, [n]);
|
|
44
|
+
}, g = () => {
|
|
45
|
+
const e = r(), t = s(
|
|
46
|
+
o(e),
|
|
47
|
+
() => e.getSnapshot().pipeline,
|
|
48
|
+
() => e.getSnapshot().pipeline
|
|
49
|
+
);
|
|
50
|
+
return a(() => Array.from(t.keys()), [t]);
|
|
51
|
+
};
|
|
52
|
+
export {
|
|
53
|
+
S as a,
|
|
54
|
+
p as b,
|
|
55
|
+
l as c,
|
|
56
|
+
h as d,
|
|
57
|
+
g as e,
|
|
58
|
+
d as u
|
|
59
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const s=require("react"),u=require("./index-PtFmD6B8.cjs"),o=()=>u.useXRContext().session.store,n=e=>t=>e.subscribe(t),c=()=>{const e=o();return s.useSyncExternalStore(n(e),()=>e.getSnapshot().ready,()=>!1)},a=()=>{const e=o();return s.useSyncExternalStore(n(e),()=>e.getSnapshot().error,()=>{})},i=()=>{const e=o();return s.useSyncExternalStore(n(e),()=>e.getSnapshot().cameraTexture,()=>{})},S=()=>{const e=o(),t=s.useSyncExternalStore(n(e),()=>e.getSnapshot().renderWidth,()=>0),r=s.useSyncExternalStore(n(e),()=>e.getSnapshot().renderHeight,()=>0);return s.useMemo(()=>({width:t,height:r}),[t,r])},l=e=>{const t=o(),r=s.useSyncExternalStore(n(t),()=>t.getSnapshot().pipeline.get(e)??null,()=>null);return s.useMemo(()=>r?r.getModelNode():null,[r])},p=()=>{const e=o(),t=s.useSyncExternalStore(n(e),()=>e.getSnapshot().pipeline,()=>e.getSnapshot().pipeline);return s.useMemo(()=>Array.from(t.keys()),[t])};exports.useXRCameraTexture=i;exports.useXRError=a;exports.useXRModelNode=l;exports.useXRPipelineSnapshot=p;exports.useXRReady=c;exports.useXRRenderSize=S;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrapper class for making API requests.
|
|
3
|
+
*/
|
|
4
|
+
export declare class ApiService {
|
|
5
|
+
private baseUrl;
|
|
6
|
+
private apiKey;
|
|
7
|
+
constructor(params: {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
apiKey: string;
|
|
10
|
+
});
|
|
11
|
+
fetch<T = unknown>(url: string, options?: RequestInit): Promise<T>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camera FPS Tracker
|
|
3
|
+
* Tracks frames per second from the camera/video processing loop
|
|
4
|
+
* Updates every 500ms as specified in PRD
|
|
5
|
+
*/
|
|
6
|
+
export declare class CameraFPSTracker {
|
|
7
|
+
private frameTimestamps;
|
|
8
|
+
private lastUpdateTime;
|
|
9
|
+
private currentFPS;
|
|
10
|
+
private readonly updateInterval;
|
|
11
|
+
constructor();
|
|
12
|
+
/**
|
|
13
|
+
* Track a new frame
|
|
14
|
+
* Should be called on each camera frame from renderVideo loop
|
|
15
|
+
*/
|
|
16
|
+
trackFrame(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Get current FPS value
|
|
19
|
+
*/
|
|
20
|
+
getFPS(): number;
|
|
21
|
+
/**
|
|
22
|
+
* Reset tracker state
|
|
23
|
+
*/
|
|
24
|
+
reset(): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Tracker
|
|
3
|
+
* Tracks JavaScript heap memory usage via performance.memory API
|
|
4
|
+
* Updates every 1 second as specified in PRD
|
|
5
|
+
* Gracefully handles browsers that don't support performance.memory (non-Chrome)
|
|
6
|
+
*/
|
|
7
|
+
export interface MemoryUsage {
|
|
8
|
+
used: number;
|
|
9
|
+
total: number;
|
|
10
|
+
percentage: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class MemoryTracker {
|
|
13
|
+
private intervalId;
|
|
14
|
+
private memoryUsage;
|
|
15
|
+
private readonly updateInterval;
|
|
16
|
+
private isSupported;
|
|
17
|
+
constructor(updateInterval?: number);
|
|
18
|
+
/**
|
|
19
|
+
* Check if performance.memory is supported
|
|
20
|
+
*/
|
|
21
|
+
private checkSupport;
|
|
22
|
+
/**
|
|
23
|
+
* Start tracking memory usage
|
|
24
|
+
*/
|
|
25
|
+
start(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Stop tracking memory usage
|
|
28
|
+
*/
|
|
29
|
+
stop(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Update memory measurements
|
|
32
|
+
*/
|
|
33
|
+
private updateMemory;
|
|
34
|
+
/**
|
|
35
|
+
* Get current memory usage
|
|
36
|
+
* Returns null if performance.memory is not supported
|
|
37
|
+
*/
|
|
38
|
+
getMemoryUsage(): MemoryUsage | null;
|
|
39
|
+
/**
|
|
40
|
+
* Check if memory tracking is supported
|
|
41
|
+
*/
|
|
42
|
+
isMemorySupported(): boolean;
|
|
43
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RenderTimeCallback } from './types';
|
|
2
|
+
export interface RenderTimeTrackerProps {
|
|
3
|
+
/** Callback function to receive render time measurements */
|
|
4
|
+
onUpdate: RenderTimeCallback;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Hidden component that tracks rendering performance
|
|
8
|
+
* Place this inside your XRScene to enable render time tracking
|
|
9
|
+
*/
|
|
10
|
+
export declare function RenderTimeTracker({ onUpdate }: RenderTimeTrackerProps): null;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolution Tracker
|
|
3
|
+
* Tracks the active camera stream resolution from the video element
|
|
4
|
+
* Updates when video metadata is loaded or dimensions change
|
|
5
|
+
*/
|
|
6
|
+
export declare class ResolutionTracker {
|
|
7
|
+
private resolution;
|
|
8
|
+
private videoElement;
|
|
9
|
+
private metadataListener;
|
|
10
|
+
/**
|
|
11
|
+
* Start tracking resolution from a video element
|
|
12
|
+
*/
|
|
13
|
+
start(videoElement: HTMLVideoElement | null): void;
|
|
14
|
+
/**
|
|
15
|
+
* Stop tracking and clean up listeners
|
|
16
|
+
*/
|
|
17
|
+
stop(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Update resolution from video element
|
|
20
|
+
*/
|
|
21
|
+
private updateResolution;
|
|
22
|
+
/**
|
|
23
|
+
* Get current resolution string (e.g., "1280x720")
|
|
24
|
+
*/
|
|
25
|
+
getResolution(): string;
|
|
26
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { DebuggerMetrics } from '../../types/debugger';
|
|
2
|
+
import { MetricsCollectorOptions } from './types';
|
|
3
|
+
export declare class MetricsCollector {
|
|
4
|
+
private options;
|
|
5
|
+
private isRunning;
|
|
6
|
+
private metrics;
|
|
7
|
+
private cameraFPSTracker;
|
|
8
|
+
private memoryTracker;
|
|
9
|
+
private resolutionTracker;
|
|
10
|
+
private frameTimes;
|
|
11
|
+
private lastEffectiveFPSUpdate;
|
|
12
|
+
constructor(options?: MetricsCollectorOptions);
|
|
13
|
+
/**
|
|
14
|
+
* Start collecting metrics
|
|
15
|
+
* @param videoElement Optional video element for resolution tracking
|
|
16
|
+
*/
|
|
17
|
+
start(videoElement?: HTMLVideoElement | null): void;
|
|
18
|
+
/**
|
|
19
|
+
* Stop collecting metrics and clean up
|
|
20
|
+
*/
|
|
21
|
+
stop(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Setup global hook for camera FPS tracking
|
|
24
|
+
* This allows useXRSession to call trackFrame() without tight coupling
|
|
25
|
+
*/
|
|
26
|
+
private setupCameraFPSHook;
|
|
27
|
+
/**
|
|
28
|
+
* Cleanup global hook
|
|
29
|
+
*/
|
|
30
|
+
private cleanupCameraFPSHook;
|
|
31
|
+
/**
|
|
32
|
+
* Get current metrics snapshot
|
|
33
|
+
* Updates metrics from all trackers before returning
|
|
34
|
+
*/
|
|
35
|
+
getMetrics(): DebuggerMetrics;
|
|
36
|
+
/**
|
|
37
|
+
* Update metrics from all trackers
|
|
38
|
+
*/
|
|
39
|
+
private updateMetricsFromTrackers;
|
|
40
|
+
/**
|
|
41
|
+
* Update render time (called from RenderTimeTracker component)
|
|
42
|
+
*/
|
|
43
|
+
updateRenderTime(renderTime: number): void;
|
|
44
|
+
/**
|
|
45
|
+
* Update detection time from models
|
|
46
|
+
* Aggregates processing time from all active models in the XR pipeline
|
|
47
|
+
*/
|
|
48
|
+
updateDetectionTime(pipeline?: Partial<Record<string, any>>): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Update effective FPS calculation
|
|
51
|
+
* (will be implemented in Phase 6)
|
|
52
|
+
*/
|
|
53
|
+
private updateEffectiveFPS;
|
|
54
|
+
/**
|
|
55
|
+
* Check if collector is running
|
|
56
|
+
*/
|
|
57
|
+
isActive(): boolean;
|
|
58
|
+
}
|
|
59
|
+
export default MetricsCollector;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { DebuggerMetrics } from '../../types/debugger';
|
|
2
|
+
/**
|
|
3
|
+
* Memory information from performance.memory API (Chrome-specific)
|
|
4
|
+
*/
|
|
5
|
+
export interface PerformanceMemory {
|
|
6
|
+
/** Used JavaScript heap size in bytes */
|
|
7
|
+
usedJSHeapSize: number;
|
|
8
|
+
/** Total allocated heap size in bytes */
|
|
9
|
+
totalJSHeapSize: number;
|
|
10
|
+
/** JavaScript heap size limit in bytes */
|
|
11
|
+
jsHeapSizeLimit: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Extended Performance interface with memory property
|
|
15
|
+
*/
|
|
16
|
+
export interface PerformanceWithMemory extends Performance {
|
|
17
|
+
memory?: PerformanceMemory;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Callback type for render time tracking
|
|
21
|
+
*/
|
|
22
|
+
export type RenderTimeCallback = (renderTime: number) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Callback type for camera frame tracking
|
|
25
|
+
*/
|
|
26
|
+
export type CameraFrameCallback = () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Global window interface extension for debugger hooks
|
|
29
|
+
*/
|
|
30
|
+
export interface WindowWithDebuggerHooks extends Window {
|
|
31
|
+
__xr_debugger_metrics?: {
|
|
32
|
+
trackCameraFrame: CameraFrameCallback;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Options for MetricsCollector initialization
|
|
37
|
+
*/
|
|
38
|
+
export interface MetricsCollectorOptions {
|
|
39
|
+
/** Whether to enable memory tracking (default: true) */
|
|
40
|
+
enableMemoryTracking?: boolean;
|
|
41
|
+
/** Update interval for memory polling in ms (default: 1000) */
|
|
42
|
+
memoryUpdateInterval?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Partial metrics for incremental updates
|
|
46
|
+
*/
|
|
47
|
+
export type PartialMetrics = Partial<DebuggerMetrics>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for metrics collection
|
|
3
|
+
* Provides efficient data structures and helpers for performance tracking
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Efficient circular buffer for rolling averages
|
|
7
|
+
* Uses typed array for better performance
|
|
8
|
+
*/
|
|
9
|
+
export declare class CircularBuffer {
|
|
10
|
+
private buffer;
|
|
11
|
+
private index;
|
|
12
|
+
private filled;
|
|
13
|
+
private size;
|
|
14
|
+
constructor(size: number);
|
|
15
|
+
/**
|
|
16
|
+
* Add a value to the buffer
|
|
17
|
+
*/
|
|
18
|
+
add(value: number): void;
|
|
19
|
+
/**
|
|
20
|
+
* Get average of all values in buffer
|
|
21
|
+
*/
|
|
22
|
+
getAverage(): number;
|
|
23
|
+
/**
|
|
24
|
+
* Get the most recent value
|
|
25
|
+
*/
|
|
26
|
+
getLast(): number;
|
|
27
|
+
/**
|
|
28
|
+
* Get number of values currently in buffer
|
|
29
|
+
*/
|
|
30
|
+
getCount(): number;
|
|
31
|
+
/**
|
|
32
|
+
* Clear all values from buffer
|
|
33
|
+
*/
|
|
34
|
+
clear(): void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Exponential moving average for smooth value transitions
|
|
38
|
+
* @param currentValue Current smoothed value
|
|
39
|
+
* @param newValue New raw value
|
|
40
|
+
* @param smoothing Smoothing factor (0-1), higher = more smoothing
|
|
41
|
+
*/
|
|
42
|
+
export declare function smoothValue(currentValue: number, newValue: number, smoothing?: number): number;
|
|
43
|
+
/**
|
|
44
|
+
* Throttle function to limit execution frequency
|
|
45
|
+
* @param func Function to throttle
|
|
46
|
+
* @param wait Minimum time between executions in milliseconds
|
|
47
|
+
*/
|
|
48
|
+
export declare function throttle<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Format number to fixed decimal places
|
|
51
|
+
* @param value Number to format
|
|
52
|
+
* @param decimals Number of decimal places (default: 1)
|
|
53
|
+
*/
|
|
54
|
+
export declare function formatNumber(value: number, decimals?: number): string;
|
|
55
|
+
/**
|
|
56
|
+
* Format bytes to megabytes
|
|
57
|
+
* @param bytes Bytes value
|
|
58
|
+
*/
|
|
59
|
+
export declare function bytesToMB(bytes: number): number;
|
|
60
|
+
/**
|
|
61
|
+
* Calculate percentage
|
|
62
|
+
* @param value Numerator
|
|
63
|
+
* @param total Denominator
|
|
64
|
+
*/
|
|
65
|
+
export declare function percentage(value: number, total: number): number;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computes the `[sx, sy, sz]` scale factors that, when multiplied into a
|
|
3
|
+
* mesh's scale inside a rect of `rectAspect`, produce a mesh whose rendered
|
|
4
|
+
* aspect equals `textureAspect`. This is the core of `mapFit: "contain"` —
|
|
5
|
+
* instead of transforming the texture's UV matrix (which produces zoom/crop
|
|
6
|
+
* under three.js's default wrap mode), the mesh itself is shrunk on one axis
|
|
7
|
+
* so the texture fills a correctly-shaped plane and the remaining rect area
|
|
8
|
+
* is genuinely empty.
|
|
9
|
+
*
|
|
10
|
+
* Rule:
|
|
11
|
+
* - `rectAspect > textureAspect` → rect is wider than texture →
|
|
12
|
+
* `[textureAspect / rectAspect, 1, 1]` (shrink X, letterbox L/R).
|
|
13
|
+
* - `rectAspect < textureAspect` → rect is taller than texture →
|
|
14
|
+
* `[1, rectAspect / textureAspect, 1]` (shrink Y, letterbox T/B).
|
|
15
|
+
* - `rectAspect === textureAspect` (within 1e-6) → `[1, 1, 1]` (no-op).
|
|
16
|
+
*
|
|
17
|
+
* Pure math — no three.js imports. Safe to call every render.
|
|
18
|
+
*
|
|
19
|
+
* @param rectAspect Aspect (width / height) of the enclosing rect.
|
|
20
|
+
* @param textureAspect Aspect (width / height) of the texture.
|
|
21
|
+
* @returns `[sx, sy, sz]`. `sz` is always `1`; we fit 2D textures to 2D rects.
|
|
22
|
+
* Returns `[1, 1, 1]` for non-positive / non-finite inputs so the
|
|
23
|
+
* caller doesn't have to pre-guard on asset-load state.
|
|
24
|
+
*/
|
|
25
|
+
export declare function computeContainScale(rectAspect: number, textureAspect: number): [number, number, number];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
/**
|
|
3
|
+
* Returns `true` if the `uv` attribute of `geometry` covers exactly the full
|
|
4
|
+
* 0..1 unit square within `tolerance` on each axis.
|
|
5
|
+
*
|
|
6
|
+
* Primitive geometries (`PlaneGeometry`, `BoxGeometry`, etc.) always return
|
|
7
|
+
* `true`. Imported GLTF meshes may return `false` when their UVs have been
|
|
8
|
+
* baked to a sub-region or use tiling coordinates outside [0, 1].
|
|
9
|
+
*
|
|
10
|
+
* This is the fit-eligibility guard used by `mapFit: "contain"` in the
|
|
11
|
+
* xr-client renderer. The v2 mesh-scale fit mechanism assumes the whole
|
|
12
|
+
* plane shows the whole texture — only true when UVs cover the unit square.
|
|
13
|
+
* When this returns `false`, the caller should skip the fit and emit a
|
|
14
|
+
* warning via `logUVBoundsWarningOnce`.
|
|
15
|
+
*
|
|
16
|
+
* @param geometry The geometry to inspect.
|
|
17
|
+
* @param tolerance Epsilon for comparing UV min/max to 0 and 1.
|
|
18
|
+
* Defaults to `0.001`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function hasFullUnitUVBounds(geometry: THREE.BufferGeometry, tolerance?: number): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Emits a deduplicated console warning for a mesh whose UV bounds are not
|
|
23
|
+
* full-unit, so `textureFit` had to fall back to `uvAspect = 1`.
|
|
24
|
+
*
|
|
25
|
+
* Only fires once per `meshId` per session (de-duplicated via module-level
|
|
26
|
+
* Set). Subsequent calls with the same `meshId` are silently ignored.
|
|
27
|
+
*
|
|
28
|
+
* @param meshId A stable identifier for the mesh (e.g. the three.js Object3D `uuid`).
|
|
29
|
+
* @param meshLabel A human-readable label (e.g. the mesh's `name` or `_label`).
|
|
30
|
+
* Falls back to `meshId` if not provided.
|
|
31
|
+
*/
|
|
32
|
+
export declare function logUVBoundsWarningOnce(meshId: string, meshLabel?: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Test helper — resets the deduplicated warning set.
|
|
35
|
+
* Not intended for production use.
|
|
36
|
+
*/
|
|
37
|
+
export declare function _resetUVBoundsWarnings(): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported texture fit modes.
|
|
3
|
+
*
|
|
4
|
+
* - `"fill"` — three.js default; texture is stretched to fill the mesh's UV
|
|
5
|
+
* rectangle. No mesh-scale adjustment is performed.
|
|
6
|
+
* - `"contain"` — the enclosing mesh's rendered scale is adjusted inside its
|
|
7
|
+
* parent rect so the mesh's aspect matches the texture's aspect. The texture
|
|
8
|
+
* then fills a correctly-shaped plane naturally; the remainder of the rect
|
|
9
|
+
* is genuinely empty (nothing drawn). See `computeContainScale`.
|
|
10
|
+
*
|
|
11
|
+
* Implementation note: v2 implements `"contain"` by adjusting the mesh, not
|
|
12
|
+
* by transforming the texture's UV matrix. v1 tried the latter and produced
|
|
13
|
+
* zoom/crop under three.js's default `ClampToEdgeWrapping`.
|
|
14
|
+
*/
|
|
15
|
+
export type TextureFit = "fill" | "contain";
|
|
16
|
+
/**
|
|
17
|
+
* Runtime array of all valid TextureFit values.
|
|
18
|
+
* Consumed by editor-ui's type picker and the design agent's approved-types validator.
|
|
19
|
+
*/
|
|
20
|
+
export declare const TEXTURE_FITS: readonly TextureFit[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("./useFaceResults-hVUJYSEY.cjs"),b=require("./index-B5J4gzn2.cjs"),E=require("react/jsx-runtime"),S=require("@react-three/fiber"),i=require("react"),z=require("three"),m=require("./index-PtFmD6B8.cjs");function O(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:()=>e[t]})}}return r.default=e,Object.freeze(r)}const g=O(z),j={"body.head":0,"body.leftShoulder":11,"body.rightShoulder":12,"body.leftElbow":13,"body.rightElbow":14,"body.leftWrist":15,"body.rightWrist":16,"body.leftHip":23,"body.rightHip":24,"body.leftKnee":25,"body.rightKnee":26,"body.leftAnkle":27,"body.rightAnkle":28},B=({bodyIndex:e=0,active:r=!0,children:t})=>{const n=i.useRef(null),{ready:o,node:d}=b.useXRModel(m.XRModel.BODY_TRACKER,void 0,r),{camera:u}=S.useThree(),l=i.useRef(u);l.current!==u&&(l.current=u);const c=i.useRef(null);S.useFrame(()=>{if(!o||!d||!n.current)return;const p=d;c.current=p;const s=p.getLandmarks2D(e),a=s==null?void 0:s[0];if(!a){n.current.visible=!1;return}const h=x(a,l.current);n.current.visible=!0,n.current.position.copy(h)});const f=i.useCallback(p=>{const s=c.current;if(!s)return null;const a=s.getLandmarks2D(e);if(!a)return null;if(p==="body.neck"){const R=a[11],A=a[12];if(!R||!A)return null;const k={x:(R.x+A.x)/2,y:(R.y+A.y)/2,z:(R.z+A.z)/2};return{position:x(k,l.current)}}const h=j[p];if(h===void 0)return null;const T=a[h];return T?{position:x(T,l.current)}:null},[e]),y=i.useMemo(()=>({type:"body",resolveLandmark:f}),[f]);return E.jsx(b.TrackerContext.Provider,{value:y,children:E.jsx("group",{ref:n,renderOrder:m.RENDER_LAYERS.TRACKED,children:t})})},x=(e,r)=>{const t=new g.Vector3(e.x,e.y,e.z);t.unproject(r);const n=t.sub(r.position).normalize(),o=-r.position.z/n.z;return r.position.clone().add(n.multiplyScalar(o))},H={"hand.wrist":0,"hand.thumbTip":4,"hand.indexTip":8,"hand.middleTip":12,"hand.ringTip":16,"hand.pinkyTip":20,"hand.indexBase":5,"hand.middleBase":9,"hand.ringBase":13,"hand.pinkyBase":17},G=({children:e,targetFps:r,active:t=!0})=>{const n=i.useRef(null),o=i.useMemo(()=>r===void 0?void 0:{targetFps:r},[r]),{ready:d,node:u}=b.useXRModel(m.XRModel.GESTURE_TRACKER,o,t),{camera:l}=S.useThree(),c=i.useRef(l);c.current!==l&&(c.current=l);const f=i.useRef(null);S.useFrame(()=>{var h;if(!d||!u||!n.current)return;f.current=u;const s=(h=u==null?void 0:u.coordinates)==null?void 0:h[0];if(!s){n.current.visible=!1;return}const a=D(s,c.current);n.current.visible=!0,n.current.position.copy(a)});const y=i.useCallback(s=>{var T,R;const a=H[s];if(a===void 0)return null;const h=(R=(T=f.current)==null?void 0:T.coordinates)==null?void 0:R[a];return h?{position:D(h,c.current)}:null},[]),p=i.useMemo(()=>({type:"hand",resolveLandmark:y}),[y]);return E.jsx(b.TrackerContext.Provider,{value:p,children:E.jsx("group",{ref:n,renderOrder:m.RENDER_LAYERS.TRACKED,children:e})})},D=(e,r)=>{const t=new g.Vector3(e.x,e.y,e.z);t.unproject(r);const n=t.sub(r.position).normalize(),o=-r.position.z/n.z;return r.position.clone().add(n.multiplyScalar(o))},K=800,L=200,F=()=>({armed:!1,armStart:null,holdStart:null,fired:!1}),P=(e,{isTrigger:r,gesture:t,now:n,mode:o,debounceMs:d,holdMs:u})=>{if(e.fired)return null;if(o==="hold"){if(r&&t){if(e.holdStart===null&&(e.holdStart=n),n-e.holdStart>=u)return e.fired=!0,t}else e.holdStart=null;return null}return e.armed?r&&t?(e.fired=!0,t):null:(r?e.armStart=null:(e.armStart===null&&(e.armStart=n),n-e.armStart>=d&&(e.armed=!0)),null)};function q({gestures:e,mode:r="arm",debounceMs:t=K,holdMs:n=L,onTrigger:o,enabled:d=!0}){const{ready:u,node:l}=b.useXRModel(m.XRModel.GESTURE_TRACKER),c=i.useRef(o);i.useEffect(()=>{c.current=o},[o]);const f=i.useRef(new Set);i.useEffect(()=>{f.current=new Set(Array.isArray(e)?e:[e])},[e]);const y=i.useRef(F());S.useFrame(()=>{if(!d||!u||!l)return;const p=l.gesture,s=!!(p&&f.current.has(p)),a=P(y.current,{isTrigger:s,gesture:p,now:performance.now(),mode:r,debounceMs:t,holdMs:n});a&&c.current(a)})}const X=e=>(q(e),null),W={"hand.wrist":0,"hand.thumbTip":4,"hand.indexTip":8,"hand.middleTip":12,"hand.ringTip":16,"hand.pinkyTip":20,"hand.indexBase":5,"hand.middleBase":9,"hand.ringBase":13,"hand.pinkyBase":17},V=({children:e,targetFps:r,active:t=!0})=>{const n=i.useRef(null),o=i.useMemo(()=>r===void 0?void 0:{targetFps:r},[r]),{ready:d,node:u}=b.useXRModel(m.XRModel.HAND_TRACKER,o,t),{camera:l}=S.useThree(),c=i.useRef(l);c.current!==l&&(c.current=l);const f=i.useRef(null);S.useFrame(()=>{var T;if(!d||!u||!n.current)return;const s=u;f.current=s;const a=(T=s==null?void 0:s.coordinates)==null?void 0:T[0];if(!a){n.current.visible=!1;return}const h=M(a,c.current);n.current.visible=!0,n.current.position.copy(h)});const y=i.useCallback(s=>{var T,R;const a=W[s];if(a===void 0)return null;const h=(R=(T=f.current)==null?void 0:T.coordinates)==null?void 0:R[a];return h?{position:M(h,c.current)}:null},[]),p=i.useMemo(()=>({type:"hand",resolveLandmark:y}),[y]);return E.jsx(b.TrackerContext.Provider,{value:p,children:E.jsx("group",{ref:n,renderOrder:m.RENDER_LAYERS.TRACKED,children:e})})},M=(e,r)=>{const t=new g.Vector3(e.x,e.y,e.z);t.unproject(r);const n=t.sub(r.position).normalize(),o=-r.position.z/n.z;return r.position.clone().add(n.multiplyScalar(o))},v=["portrait"],Y=({type:e,active:r=!0,children:t})=>(b.useXRModel(m.XRModel.BACKGROUND_SEGMENTATION,{type:e},r),i.useEffect(()=>{v.includes(e)||console.warn(`[Segmentation] unsupported type "${e}"; valid values: ${v.join(", ")}`)},[e]),E.jsx(E.Fragment,{children:t})),$=["face.forehead","face.noseTip","face.chin","face.leftEyeOuter","face.rightEyeOuter","face.leftCheek","face.rightCheek","face.mouthCenter"],U=["hand.wrist","hand.thumbTip","hand.indexTip","hand.middleTip","hand.ringTip","hand.pinkyTip","hand.indexBase","hand.middleBase","hand.ringBase","hand.pinkyBase"],I=["body.head","body.neck","body.leftShoulder","body.rightShoulder","body.leftElbow","body.rightElbow","body.leftWrist","body.rightWrist","body.leftHip","body.rightHip","body.leftKnee","body.rightKnee","body.leftAnkle","body.rightAnkle"],_=e=>e.startsWith("face.")?"face":e.startsWith("hand.")?"hand":e.startsWith("body.")?"body":null,N=(e,r,t)=>r+t*(e-r),w=(e,r)=>1/(1+1/(2*Math.PI*e)/r),J=(e,r,t,n,o,d)=>{if(!e.initialized||t<=0)return e.pos.copy(r),e.prevRaw.copy(r),e.dxHat.set(0,0,0),e.initialized=!0,e;const u=w(d,t),l=["x","y","z"];for(const c of l){const f=(r[c]-e.prevRaw[c])/t,y=N(f,e.dxHat[c],u);e.dxHat[c]=y;const p=n+o*Math.abs(y),s=w(p,t);e.pos[c]=N(r[c],e.pos[c],s),e.prevRaw[c]=r[c]}return e},Q=({target:e,offset:r,smoothing:t=0,children:n})=>{const o=b.useTrackerContext(),d=i.useRef(null),u=i.useRef(!1),l=i.useRef(new g.Vector3),c=i.useRef({pos:new g.Vector3,prevRaw:new g.Vector3,dxHat:new g.Vector3,initialized:!1}),f=_(e),y=o!==null&&f!==null&&o.type!==f,p=o===null,s=p||y||f===null;return i.useEffect(()=>{p?console.warn(`[TrackingAnchor] target "${e}" requires a FaceTracker / HandTracker / BodyTracker ancestor; rendering null.`):y?console.warn(`[TrackingAnchor] target "${e}" namespace does not match parent tracker type "${o==null?void 0:o.type}"; rendering null.`):f===null&&console.warn(`[TrackingAnchor] target "${e}" is not a recognized face/hand/body landmark; rendering null.`)},[e,f,p,y,o==null?void 0:o.type]),S.useFrame((a,h)=>{if(s||!d.current||!o)return;const T=o.resolveLandmark(e);if(!T){d.current.visible=!1,u.current=!1,c.current.initialized=!1;return}d.current.visible=!0;const R=l.current.copy(T.position),A=d.current.parent;if(A){A.updateMatrixWorld();const k=new g.Matrix4().copy(A.matrixWorld).invert();R.applyMatrix4(k)}if(r&&(R.x+=r[0],R.y+=r[1],R.z+=r[2]),t>0){const k=t*.1;J(c.current,R,u.current?h:0,k,.5,1),d.current.position.copy(c.current.pos)}else d.current.position.copy(R);u.current=!0,T.quaternion&&d.current.quaternion.copy(T.quaternion)}),s?null:E.jsx("group",{ref:d,renderOrder:m.RENDER_LAYERS.TRACKED,children:n})};exports.useFaceResults=C.useFaceResults;exports.FaceMesh=b.FaceMesh;exports.FaceTracker=b.FaceTracker;exports.BODY_TARGETS=I;exports.BodyTracker=B;exports.FACE_TARGETS=$;exports.GestureTracker=G;exports.GestureTrigger=X;exports.HAND_TARGETS=U;exports.HandTracker=V;exports.SEGMENTATION_TYPES=v;exports.Segmentation=Y;exports.TrackingAnchor=Q;exports.getTargetNamespace=_;
|