@vincentt-xr/sdk 2.0.0-alpha.6 → 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 +1188 -14
- package/dist/{DebuggerUI-C_rbLdkh.js → DebuggerUI-C-ldiozL.js} +1 -1
- package/dist/{DebuggerUI-DYT_dk1E.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/FaceMeshRenderer.d.ts +11 -3
- package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +41 -5
- 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 +2 -2
- 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/SceneObjectRenderer/index.d.ts +9 -2
- 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/XRMediaSurface/index.d.ts +2 -1
- 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-DvQI4PqI.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 +21 -3
- package/dist/entries/face-effects.d.ts +12 -4
- package/dist/entries/low-level.d.ts +22 -3
- package/dist/entries/product.d.ts +11 -0
- package/dist/entries/tracking.d.ts +26 -1
- package/dist/face-effects.cjs +155 -1
- package/dist/face-effects.js +1134 -2196
- 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-B43Cwq4n.js → getFaceInfo-BkZfaQs-.js} +5 -5
- package/dist/{getFaceInfo-DEzcL_Ub.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 +44 -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-uE3sKczj.js → index-CHVbH0hz.js} +4 -4
- package/dist/index-CeVkgsag.cjs +1 -0
- package/dist/index-CnGox6Xr.js +3054 -0
- package/dist/{index-B-s4YbWu.js → index-CsUdQ-pn.js} +113 -111
- package/dist/{index-CY7Z8cHV.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-G_5h_FJQ.js → index-s9pF4zkG.js} +999 -1014
- package/dist/internal-BYza1h8_.cjs +1 -0
- package/dist/{internal-ldPYiUF0.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 +1104 -639
- package/dist/main.cjs +1 -1
- package/dist/main.js +1519 -462
- 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-CFt1yYLB.js → renderGroups-CN1cGFUo.js} +1 -1
- package/dist/{renderGroups-BJsx32q5.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/screen2d/coordinates.d.ts +20 -0
- 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-CANvoLD6.cjs → session-BBr0yN8h.cjs} +7 -7
- package/dist/{session-Dhi0OqZo.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/coordinates.d.ts +5 -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 -380
- package/dist/types/common.d.ts +11 -1
- package/dist/types/compositor.d.ts +21 -0
- package/dist/types/gesture-tracking.d.ts +2 -2
- package/dist/types/hand-tracking.d.ts +3 -3
- 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 +29 -4
- package/dist/types/segmentation.d.ts +19 -0
- package/dist/types/session.d.ts +48 -4
- 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/SDK_DOCUMENTATION.md +3 -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/capture-recording.mdx +9 -1
- 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 +35 -0
- 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/runtime-3d.mdx +5 -0
- package/docs/api/screen-image.mdx +3 -1
- package/docs/api/screen-space-coordinates.mdx +35 -1
- package/docs/api/segmentation-overlay.mdx +301 -0
- package/docs/api/session-lifecycle.mdx +136 -0
- package/docs/api/trackers.mdx +18 -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 +16 -1
- package/dist/FaceMeshRenderer-D1WsrTLA.cjs +0 -155
- package/dist/FaceMeshRenderer-DSCd1H55.js +0 -1264
- package/dist/FaceRetouch-CMJbGThL.js +0 -551
- package/dist/FaceRetouch-DsE0Dbw-.cjs +0 -134
- package/dist/contexts-h-9TRH0r.cjs +0 -1
- package/dist/index-C0-fg1Hk.cjs +0 -1
- package/dist/index-CxMEeCRP.cjs +0 -1
- package/dist/index-D67hHm44.cjs +0 -1
- package/dist/index-DPPpU5By.cjs +0 -17
- package/dist/index-DYfY9ljy.js +0 -111
- package/dist/index-I4eF5TKT.js +0 -1457
- package/dist/internal-MvKrz0Nt.cjs +0 -1
- package/dist/renderLayers-lDtL0_43.cjs +0 -1
- package/dist/renderLayers-zrK2pv5O.js +0 -13
- package/dist/renderPasses-C72MbZ-a.js +0 -1500
- package/dist/renderPasses-D-Krl6D0.cjs +0 -21
- package/dist/selectors-ByKNTXeA.js +0 -59
- package/dist/selectors-CAwmL9VW.cjs +0 -1
- package/dist/useFaceInfo-BSZq7AO1.cjs +0 -1
- package/dist/useFaceInfo-FVQBBNdY.js +0 -62
- package/dist/useFaceResults-C3oZkn2Z.cjs +0 -1
- package/dist/useFaceResults-D62STzT1.js +0 -19
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { useMemo as I, useEffect as N, useCallback as k, useRef as U } from "react";
|
|
2
|
+
import { Vector2 as X, Raycaster as S, Ray as Y, Vector3 as L } from "three";
|
|
3
|
+
import { D as d, a as y } from "./screenTransform-BenfCtZt.js";
|
|
4
|
+
import { n as j, t as A, X as p } from "./index-CnGox6Xr.js";
|
|
5
|
+
import { useThree as D } from "@react-three/fiber";
|
|
6
|
+
import { g as B, u as J } from "./getFaceInfo-BkZfaQs-.js";
|
|
7
|
+
import { u as V } from "./index-CsUdQ-pn.js";
|
|
8
|
+
const a = (e, n) => {
|
|
9
|
+
if (!Number.isFinite(e) || e <= 0) throw new RangeError(`${n} must be positive`);
|
|
10
|
+
return e;
|
|
11
|
+
}, q = (e, n) => {
|
|
12
|
+
const t = a(n.width, "root.width"), s = a(n.height, "root.height");
|
|
13
|
+
return !Number.isFinite(e.width) || !Number.isFinite(e.height) || e.width <= 0 || e.height <= 0 ? 0 : Math.min(e.width / t, e.height / s);
|
|
14
|
+
}, b = (e, n, t, s) => n.width <= 0 || n.height <= 0 ? Object.assign(s, { x: 0, y: 0 }) : (a(t.width, "root.width"), a(t.height, "root.height"), s.x = (e.x / n.width - 0.5) * t.width, s.y = (0.5 - e.y / n.height) * t.height, s), P = (e, n, t, s) => n.width <= 0 || n.height <= 0 ? Object.assign(s, { x: 0, y: 0 }) : (a(t.width, "root.width"), a(t.height, "root.height"), s.x = (e.x / t.width + 0.5) * n.width, s.y = (0.5 - e.y / t.height) * n.height, s), O = ({
|
|
15
|
+
parentSize: e,
|
|
16
|
+
referencePixelsPerUnit: n = y,
|
|
17
|
+
root: t = d
|
|
18
|
+
}) => q(e, t) * (y / a(n, "referencePixelsPerUnit")), re = (e, n) => e * O(n), ce = (e, n) => {
|
|
19
|
+
const t = O(n);
|
|
20
|
+
return t === 0 ? 0 : e / t;
|
|
21
|
+
}, oe = ({
|
|
22
|
+
point: e,
|
|
23
|
+
parentSize: n,
|
|
24
|
+
referencePixelsPerUnit: t = y,
|
|
25
|
+
root: s = d,
|
|
26
|
+
target: i = { x: 0, y: 0 }
|
|
27
|
+
}) => {
|
|
28
|
+
if (n.width <= 0 || n.height <= 0) return Object.assign(i, { x: 0, y: 0 });
|
|
29
|
+
const r = y / a(t, "referencePixelsPerUnit");
|
|
30
|
+
return i.x = e.x * (n.width / a(s.width, "root.width")) * r, i.y = e.y * (n.height / a(s.height, "root.height")) * r, i;
|
|
31
|
+
}, he = ({
|
|
32
|
+
point: e,
|
|
33
|
+
parentSize: n,
|
|
34
|
+
referencePixelsPerUnit: t = y,
|
|
35
|
+
root: s = d,
|
|
36
|
+
target: i = { x: 0, y: 0 }
|
|
37
|
+
}) => {
|
|
38
|
+
if (n.width <= 0 || n.height <= 0) return Object.assign(i, { x: 0, y: 0 });
|
|
39
|
+
const r = y / a(t, "referencePixelsPerUnit");
|
|
40
|
+
return i.x = e.x / (n.width / a(s.width, "root.width") * r), i.y = e.y / (n.height / a(s.height, "root.height") * r), i;
|
|
41
|
+
}, xe = ({
|
|
42
|
+
point: e,
|
|
43
|
+
rect: n,
|
|
44
|
+
root: t = d,
|
|
45
|
+
target: s = { x: 0, y: 0 }
|
|
46
|
+
}) => b({ x: e.x - n.left, y: e.y - n.top }, n, t, s), ae = ({
|
|
47
|
+
point: e,
|
|
48
|
+
rect: n,
|
|
49
|
+
root: t = d,
|
|
50
|
+
target: s = { x: 0, y: 0 }
|
|
51
|
+
}) => (P(e, n, t, s), s.x += n.left, s.y += n.top, s), _ = ({
|
|
52
|
+
point: e,
|
|
53
|
+
root: n = d,
|
|
54
|
+
target: t = { x: 0, y: 0 },
|
|
55
|
+
viewportSize: s
|
|
56
|
+
}) => b(
|
|
57
|
+
{ x: e.x * s.width, y: e.y * s.height },
|
|
58
|
+
s,
|
|
59
|
+
n,
|
|
60
|
+
t
|
|
61
|
+
), K = ({
|
|
62
|
+
point: e,
|
|
63
|
+
root: n = d,
|
|
64
|
+
target: t = { x: 0, y: 0 },
|
|
65
|
+
viewportSize: s
|
|
66
|
+
}) => s.width <= 0 || s.height <= 0 ? Object.assign(t, { x: 0, y: 0 }) : (P(e, s, n, t), t.x /= s.width, t.y /= s.height, t), de = ({
|
|
67
|
+
point: e,
|
|
68
|
+
root: n = d,
|
|
69
|
+
target: t = { x: 0, y: 0 },
|
|
70
|
+
viewportSize: s
|
|
71
|
+
}) => _({
|
|
72
|
+
point: { x: (e.x + 1) / 2, y: (1 - e.y) / 2 },
|
|
73
|
+
viewportSize: s,
|
|
74
|
+
root: n,
|
|
75
|
+
target: t
|
|
76
|
+
}), le = ({
|
|
77
|
+
layout: e,
|
|
78
|
+
mirrored: n = !1,
|
|
79
|
+
point: t,
|
|
80
|
+
root: s = d,
|
|
81
|
+
target: i = { x: 0, y: 0 }
|
|
82
|
+
}) => {
|
|
83
|
+
if (e.scale <= 0) return Object.assign(i, { x: 0, y: 0 });
|
|
84
|
+
const r = e.offsetX + t.x * e.scale;
|
|
85
|
+
return b(
|
|
86
|
+
{
|
|
87
|
+
x: n ? e.destination.width - r : r,
|
|
88
|
+
y: e.offsetY + t.y * e.scale
|
|
89
|
+
},
|
|
90
|
+
e.destination,
|
|
91
|
+
s,
|
|
92
|
+
i
|
|
93
|
+
);
|
|
94
|
+
}, ue = ({
|
|
95
|
+
layout: e,
|
|
96
|
+
mirrored: n = !1,
|
|
97
|
+
point: t,
|
|
98
|
+
root: s = d,
|
|
99
|
+
target: i = { x: 0, y: 0 }
|
|
100
|
+
}) => {
|
|
101
|
+
if (e.scale <= 0) return Object.assign(i, { x: 0, y: 0 });
|
|
102
|
+
P(t, e.destination, s, i);
|
|
103
|
+
const r = n ? e.destination.width - i.x : i.x;
|
|
104
|
+
return i.x = (r - e.offsetX) / e.scale, i.y = (i.y - e.offsetY) / e.scale, i;
|
|
105
|
+
}, w = new L(), g = new X(), R = new S(), fe = ({
|
|
106
|
+
camera: e,
|
|
107
|
+
point: n,
|
|
108
|
+
root: t = d,
|
|
109
|
+
target: s = { x: 0, y: 0, depth: 0 },
|
|
110
|
+
viewportSize: i
|
|
111
|
+
}) => (a(t.width, "root.width"), a(t.height, "root.height"), w.set(n.x, n.y, n.z).project(e), s.x = w.x * t.width / 2, s.y = w.y * t.height / 2, s.depth = w.z, s), ye = ({
|
|
112
|
+
camera: e,
|
|
113
|
+
point: n,
|
|
114
|
+
root: t = d,
|
|
115
|
+
target: s = new Y(),
|
|
116
|
+
viewportSize: i
|
|
117
|
+
}) => (a(t.width, "root.width"), a(t.height, "root.height"), g.set(n.x * 2 / t.width, n.y * 2 / t.height), R.setFromCamera(g, e), s.copy(R.ray)), me = (e, n) => j({ x: e.x, y: e.y, z: e.z ?? 0 }, n), H = (e, n = { x: 0, y: 0 }) => {
|
|
118
|
+
const t = A(e);
|
|
119
|
+
return n.x = t.x, n.y = t.y, n.z = t.z, n;
|
|
120
|
+
}, we = (e, n, t = { x: 0, y: 0 }) => (t.x = e.x * n.width, t.y = e.y * n.height, t), Te = (e, n, t = { x: 0, y: 0 }) => n.width <= 0 || n.height <= 0 ? Object.assign(t, { x: 0, y: 0 }) : (t.x = e.x / n.width, t.y = e.y / n.height, t), be = (e, n, t = {}) => _({
|
|
121
|
+
point: e,
|
|
122
|
+
viewportSize: n,
|
|
123
|
+
root: t.root,
|
|
124
|
+
target: t.target
|
|
125
|
+
}), Pe = (e, n, t = {}) => {
|
|
126
|
+
const s = t.target ?? { x: 0, y: 0 };
|
|
127
|
+
return K({ point: e, viewportSize: n, root: t.root, target: s }), s;
|
|
128
|
+
}, W = { selection: "index", index: 0 }, $ = Object.freeze({
|
|
129
|
+
face: { max: 10, default: 1, option: "numFaces" },
|
|
130
|
+
hand: { max: 2, default: 2, option: null },
|
|
131
|
+
gesture: { max: 1, default: 1, option: null },
|
|
132
|
+
body: { max: 1, default: 1, option: null },
|
|
133
|
+
holistic: { max: 1, default: 1, option: null }
|
|
134
|
+
}), C = { center: null }, f = (e, n) => Math.hypot(e.x - n.x, e.y - n.y), M = (e, n, t) => {
|
|
135
|
+
if (!e.length) return null;
|
|
136
|
+
switch (n) {
|
|
137
|
+
case "largest":
|
|
138
|
+
return e.reduce((s, i) => i.size > s.size ? i : s);
|
|
139
|
+
case "nearest-center":
|
|
140
|
+
return e.reduce(
|
|
141
|
+
(s, i) => f(i.center, { x: 0.5, y: 0.5 }) < f(s.center, { x: 0.5, y: 0.5 }) ? i : s
|
|
142
|
+
);
|
|
143
|
+
case "leftmost":
|
|
144
|
+
return e.reduce((s, i) => i.center.x < s.center.x ? i : s);
|
|
145
|
+
case "rightmost":
|
|
146
|
+
return e.reduce((s, i) => i.center.x > s.center.x ? i : s);
|
|
147
|
+
default:
|
|
148
|
+
return e.find((s) => s.index === t) ?? null;
|
|
149
|
+
}
|
|
150
|
+
}, G = (e, n = W, t = C) => {
|
|
151
|
+
const s = n.index ?? 0;
|
|
152
|
+
if (n.selection !== "sticky") {
|
|
153
|
+
const c = M(e, n.selection, s);
|
|
154
|
+
return {
|
|
155
|
+
index: (c == null ? void 0 : c.index) ?? null,
|
|
156
|
+
reason: c ? n.selection : "none",
|
|
157
|
+
memory: c ? { center: { ...c.center }, label: c.label } : t
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const i = n.stickyRadius ?? 0.2;
|
|
161
|
+
if (t.center) {
|
|
162
|
+
const c = t.center, x = e.filter((l) => f(l.center, c) <= i).sort((l, m) => f(l.center, c) - f(m.center, c)), h = (t.label ? x.find((l) => l.label === t.label) : void 0) ?? x[0];
|
|
163
|
+
if (h)
|
|
164
|
+
return {
|
|
165
|
+
index: h.index,
|
|
166
|
+
reason: "sticky",
|
|
167
|
+
memory: { center: { ...h.center }, label: h.label }
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
const r = M(e, n.fallback ?? "largest", s);
|
|
171
|
+
return {
|
|
172
|
+
index: (r == null ? void 0 : r.index) ?? null,
|
|
173
|
+
reason: r ? "sticky-fallback" : "none",
|
|
174
|
+
// Keep the old memory on a miss so a brief dropout does not forget the subject.
|
|
175
|
+
memory: r ? { center: { ...r.center }, label: r.label } : t
|
|
176
|
+
};
|
|
177
|
+
}, Fe = (e) => e.map((n, t) => {
|
|
178
|
+
let s = 1 / 0, i = -1 / 0, r = 1 / 0, c = -1 / 0;
|
|
179
|
+
for (const o of n)
|
|
180
|
+
o.x < s && (s = o.x), o.x > i && (i = o.x), o.y < r && (r = o.y), o.y > c && (c = o.y);
|
|
181
|
+
const x = n.length > 0 && Number.isFinite(s);
|
|
182
|
+
return {
|
|
183
|
+
index: t,
|
|
184
|
+
center: x ? { x: (s + i) / 2, y: (r + c) / 2 } : { x: 0.5, y: 0.5 },
|
|
185
|
+
size: x ? i - s : 0
|
|
186
|
+
};
|
|
187
|
+
}), Ee = (e) => e.map((n, t) => {
|
|
188
|
+
const s = (n.coordinates ?? []).map((h) => H(h));
|
|
189
|
+
let i = 1 / 0, r = -1 / 0, c = 1 / 0, x = -1 / 0;
|
|
190
|
+
for (const h of s)
|
|
191
|
+
h.x < i && (i = h.x), h.x > r && (r = h.x), h.y < c && (c = h.y), h.y > x && (x = h.y);
|
|
192
|
+
const o = s.length > 0;
|
|
193
|
+
return {
|
|
194
|
+
index: t,
|
|
195
|
+
center: o ? { x: (i + r) / 2, y: (c + x) / 2 } : { x: 0.5, y: 0.5 },
|
|
196
|
+
size: o ? Math.max(r - i, x - c) : 0,
|
|
197
|
+
...n.label ? { label: n.label } : {}
|
|
198
|
+
};
|
|
199
|
+
}), ge = (e, n, t = 0.35) => {
|
|
200
|
+
const s = [];
|
|
201
|
+
for (const c of e)
|
|
202
|
+
for (const x of n) {
|
|
203
|
+
const o = f(c.center, x.center);
|
|
204
|
+
o <= t && s.push({ primaryIndex: c.index, secondaryIndex: x.index, distance: o });
|
|
205
|
+
}
|
|
206
|
+
s.sort((c, x) => c.distance - x.distance);
|
|
207
|
+
const i = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set();
|
|
208
|
+
return s.filter((c) => i.has(c.primaryIndex) || r.has(c.secondaryIndex) ? !1 : (i.add(c.primaryIndex), r.add(c.secondaryIndex), !0));
|
|
209
|
+
}, Q = ({
|
|
210
|
+
active: e = !0,
|
|
211
|
+
holdMs: n = 250,
|
|
212
|
+
numFaces: t = 1,
|
|
213
|
+
targetFps: s,
|
|
214
|
+
throttleMs: i = 16
|
|
215
|
+
} = {}) => {
|
|
216
|
+
const { camera: r } = D(), c = Number.isFinite(t) ? Math.min($.face.max, Math.max(1, Math.round(t))) : 1, x = s !== void 0 && Number.isFinite(s) && s > 0 ? s : void 0, o = I(
|
|
217
|
+
() => ({
|
|
218
|
+
numFaces: c,
|
|
219
|
+
...x ? { targetFps: x } : {}
|
|
220
|
+
}),
|
|
221
|
+
[c, x]
|
|
222
|
+
), { node: h, ready: l } = V(
|
|
223
|
+
p.FACE_TRACKER,
|
|
224
|
+
o,
|
|
225
|
+
e
|
|
226
|
+
);
|
|
227
|
+
N(() => {
|
|
228
|
+
if (h)
|
|
229
|
+
for (let u = 0; u < o.numFaces; u += 1)
|
|
230
|
+
h.setCamera(r, u);
|
|
231
|
+
}, [o.numFaces, r, h]);
|
|
232
|
+
const m = k(
|
|
233
|
+
(u) => {
|
|
234
|
+
if (!h) return [];
|
|
235
|
+
const F = [];
|
|
236
|
+
for (let T = 0; T < u.faceLandmarks.length; T += 1) {
|
|
237
|
+
const E = B(h, u, T);
|
|
238
|
+
E && F.push(E);
|
|
239
|
+
}
|
|
240
|
+
return F;
|
|
241
|
+
},
|
|
242
|
+
[h]
|
|
243
|
+
);
|
|
244
|
+
return J({
|
|
245
|
+
enabled: e && l,
|
|
246
|
+
holdMs: Number.isFinite(n) ? Math.max(0, n) : 250,
|
|
247
|
+
node: h,
|
|
248
|
+
prepare: m,
|
|
249
|
+
throttleMs: Number.isFinite(i) ? Math.max(0, i) : 16
|
|
250
|
+
});
|
|
251
|
+
}, Z = 4, Re = ({
|
|
252
|
+
faceIndex: e = 0,
|
|
253
|
+
numFaces: n,
|
|
254
|
+
subject: t,
|
|
255
|
+
...s
|
|
256
|
+
} = {}) => {
|
|
257
|
+
const i = Number.isFinite(e) ? Math.max(0, Math.round(e)) : 0, r = Q({
|
|
258
|
+
...s,
|
|
259
|
+
numFaces: Math.max(n ?? (t ? Z : i + 1), i + 1)
|
|
260
|
+
}), c = U(C), x = JSON.stringify(t ?? null), o = I(() => {
|
|
261
|
+
if (!t) return null;
|
|
262
|
+
const h = r.map((l, m) => ({
|
|
263
|
+
index: m,
|
|
264
|
+
center: { x: l.bounds.centerX, y: l.bounds.centerY },
|
|
265
|
+
size: l.bounds.width
|
|
266
|
+
}));
|
|
267
|
+
return G(h, t, c.current);
|
|
268
|
+
}, [r, x]);
|
|
269
|
+
return N(() => {
|
|
270
|
+
o && (c.current = o.memory);
|
|
271
|
+
}, [o]), t ? o && o.index !== null ? r[o.index] ?? null : null : r[i] ?? null;
|
|
272
|
+
};
|
|
273
|
+
export {
|
|
274
|
+
W as D,
|
|
275
|
+
C as E,
|
|
276
|
+
$ as X,
|
|
277
|
+
ge as a,
|
|
278
|
+
Z as b,
|
|
279
|
+
Re as c,
|
|
280
|
+
xe as d,
|
|
281
|
+
re as e,
|
|
282
|
+
Fe as f,
|
|
283
|
+
ae as g,
|
|
284
|
+
ue as h,
|
|
285
|
+
K as i,
|
|
286
|
+
Ee as j,
|
|
287
|
+
oe as k,
|
|
288
|
+
ye as l,
|
|
289
|
+
le as m,
|
|
290
|
+
_ as n,
|
|
291
|
+
he as o,
|
|
292
|
+
ce as p,
|
|
293
|
+
be as q,
|
|
294
|
+
me as r,
|
|
295
|
+
G as s,
|
|
296
|
+
de as t,
|
|
297
|
+
Q as u,
|
|
298
|
+
we as v,
|
|
299
|
+
fe as w,
|
|
300
|
+
Pe as x,
|
|
301
|
+
H as y,
|
|
302
|
+
Te as z
|
|
303
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const T=require("react"),R=require("three"),l=require("./screenTransform-BiXdpVf0.cjs"),F=require("./index-CeVkgsag.cjs"),j=require("@react-three/fiber"),w=require("./getFaceInfo-ahPxQFGu.cjs"),q=require("./index-OCPjOaeP.cjs"),h=(e,n)=>{if(!Number.isFinite(e)||e<=0)throw new RangeError(`${n} must be positive`);return e},B=(e,n)=>{const t=h(n.width,"root.width"),i=h(n.height,"root.height");return!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0?0:Math.min(e.width/t,e.height/i)},m=(e,n,t,i)=>n.width<=0||n.height<=0?Object.assign(i,{x:0,y:0}):(h(t.width,"root.width"),h(t.height,"root.height"),i.x=(e.x/n.width-.5)*t.width,i.y=(.5-e.y/n.height)*t.height,i),P=(e,n,t,i)=>n.width<=0||n.height<=0?Object.assign(i,{x:0,y:0}):(h(t.width,"root.width"),h(t.height,"root.height"),i.x=(e.x/t.width+.5)*n.width,i.y=(.5-e.y/t.height)*n.height,i),I=({parentSize:e,referencePixelsPerUnit:n=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT})=>B(e,t)*(l.DEFAULT_REFERENCE_PIXELS_PER_UNIT/h(n,"referencePixelsPerUnit")),J=(e,n)=>e*I(n),V=(e,n)=>{const t=I(n);return t===0?0:e/t},p=({point:e,parentSize:n,referencePixelsPerUnit:t=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT,root:i=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:s={x:0,y:0}})=>{if(n.width<=0||n.height<=0)return Object.assign(s,{x:0,y:0});const r=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT/h(t,"referencePixelsPerUnit");return s.x=e.x*(n.width/h(i.width,"root.width"))*r,s.y=e.y*(n.height/h(i.height,"root.height"))*r,s},H=({point:e,parentSize:n,referencePixelsPerUnit:t=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT,root:i=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:s={x:0,y:0}})=>{if(n.width<=0||n.height<=0)return Object.assign(s,{x:0,y:0});const r=l.DEFAULT_REFERENCE_PIXELS_PER_UNIT/h(t,"referencePixelsPerUnit");return s.x=e.x/(n.width/h(i.width,"root.width")*r),s.y=e.y/(n.height/h(i.height,"root.height")*r),s},K=({point:e,rect:n,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:i={x:0,y:0}})=>m({x:e.x-n.left,y:e.y-n.top},n,t,i),$=({point:e,rect:n,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:i={x:0,y:0}})=>(P(e,n,t,i),i.x+=n.left,i.y+=n.top,i),S=({point:e,root:n=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:t={x:0,y:0},viewportSize:i})=>m({x:e.x*i.width,y:e.y*i.height},i,n,t),L=({point:e,root:n=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:t={x:0,y:0},viewportSize:i})=>i.width<=0||i.height<=0?Object.assign(t,{x:0,y:0}):(P(e,i,n,t),t.x/=i.width,t.y/=i.height,t),W=({point:e,root:n=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:t={x:0,y:0},viewportSize:i})=>S({point:{x:(e.x+1)/2,y:(1-e.y)/2},viewportSize:i,root:n,target:t}),z=({layout:e,mirrored:n=!1,point:t,root:i=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:s={x:0,y:0}})=>{if(e.scale<=0)return Object.assign(s,{x:0,y:0});const r=e.offsetX+t.x*e.scale;return m({x:n?e.destination.width-r:r,y:e.offsetY+t.y*e.scale},e.destination,i,s)},G=({layout:e,mirrored:n=!1,point:t,root:i=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:s={x:0,y:0}})=>{if(e.scale<=0)return Object.assign(s,{x:0,y:0});P(t,e.destination,i,s);const r=n?e.destination.width-s.x:s.x;return s.x=(r-e.offsetX)/e.scale,s.y=(s.y-e.offsetY)/e.scale,s},y=new R.Vector3,C=new R.Vector2,A=new R.Raycaster,Q=({camera:e,point:n,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:i={x:0,y:0,depth:0},viewportSize:s})=>(h(t.width,"root.width"),h(t.height,"root.height"),y.set(n.x,n.y,n.z).project(e),i.x=y.x*t.width/2,i.y=y.y*t.height/2,i.depth=y.z,i),Z=({camera:e,point:n,root:t=l.DEFAULT_SCREEN_TRANSFORM_ROOT,target:i=new R.Ray,viewportSize:s})=>(h(t.width,"root.width"),h(t.height,"root.height"),C.set(n.x*2/t.width,n.y*2/t.height),A.setFromCamera(C,e),i.copy(A.ray)),v=(e,n)=>F.normalizedTrackerPointToTrackerPoint({x:e.x,y:e.y,z:e.z??0},n),b=(e,n={x:0,y:0})=>{const t=F.trackerPointToNormalizedTrackerPoint(e);return n.x=t.x,n.y=t.y,n.z=t.z,n},ee=(e,n,t={x:0,y:0})=>(t.x=e.x*n.width,t.y=e.y*n.height,t),ne=(e,n,t={x:0,y:0})=>n.width<=0||n.height<=0?Object.assign(t,{x:0,y:0}):(t.x=e.x/n.width,t.y=e.y/n.height,t),te=(e,n,t={})=>S({point:e,viewportSize:n,root:t.root,target:t.target}),ie=(e,n,t={})=>{const i=t.target??{x:0,y:0};return L({point:e,viewportSize:n,root:t.root,target:i}),i},D={selection:"index",index:0},g=Object.freeze({face:{max:10,default:1,option:"numFaces"},hand:{max:2,default:2,option:null},gesture:{max:1,default:1,option:null},body:{max:1,default:1,option:null},holistic:{max:1,default:1,option:null}}),O={center:null},f=(e,n)=>Math.hypot(e.x-n.x,e.y-n.y),M=(e,n,t)=>{if(!e.length)return null;switch(n){case"largest":return e.reduce((i,s)=>s.size>i.size?s:i);case"nearest-center":return e.reduce((i,s)=>f(s.center,{x:.5,y:.5})<f(i.center,{x:.5,y:.5})?s:i);case"leftmost":return e.reduce((i,s)=>s.center.x<i.center.x?s:i);case"rightmost":return e.reduce((i,s)=>s.center.x>i.center.x?s:i);default:return e.find(i=>i.index===t)??null}},X=(e,n=D,t=O)=>{const i=n.index??0;if(n.selection!=="sticky"){const c=M(e,n.selection,i);return{index:(c==null?void 0:c.index)??null,reason:c?n.selection:"none",memory:c?{center:{...c.center},label:c.label}:t}}const s=n.stickyRadius??.2;if(t.center){const c=t.center,d=e.filter(a=>f(a.center,c)<=s).sort((a,E)=>f(a.center,c)-f(E.center,c)),x=(t.label?d.find(a=>a.label===t.label):void 0)??d[0];if(x)return{index:x.index,reason:"sticky",memory:{center:{...x.center},label:x.label}}}const r=M(e,n.fallback??"largest",i);return{index:(r==null?void 0:r.index)??null,reason:r?"sticky-fallback":"none",memory:r?{center:{...r.center},label:r.label}:t}},se=e=>e.map((n,t)=>{let i=1/0,s=-1/0,r=1/0,c=-1/0;for(const o of n)o.x<i&&(i=o.x),o.x>s&&(s=o.x),o.y<r&&(r=o.y),o.y>c&&(c=o.y);const d=n.length>0&&Number.isFinite(i);return{index:t,center:d?{x:(i+s)/2,y:(r+c)/2}:{x:.5,y:.5},size:d?s-i:0}}),re=e=>e.map((n,t)=>{const i=(n.coordinates??[]).map(x=>b(x));let s=1/0,r=-1/0,c=1/0,d=-1/0;for(const x of i)x.x<s&&(s=x.x),x.x>r&&(r=x.x),x.y<c&&(c=x.y),x.y>d&&(d=x.y);const o=i.length>0;return{index:t,center:o?{x:(s+r)/2,y:(c+d)/2}:{x:.5,y:.5},size:o?Math.max(r-s,d-c):0,...n.label?{label:n.label}:{}}}),ce=(e,n,t=.35)=>{const i=[];for(const c of e)for(const d of n){const o=f(c.center,d.center);o<=t&&i.push({primaryIndex:c.index,secondaryIndex:d.index,distance:o})}i.sort((c,d)=>c.distance-d.distance);const s=new Set,r=new Set;return i.filter(c=>s.has(c.primaryIndex)||r.has(c.secondaryIndex)?!1:(s.add(c.primaryIndex),r.add(c.secondaryIndex),!0))},k=({active:e=!0,holdMs:n=250,numFaces:t=1,targetFps:i,throttleMs:s=16}={})=>{const{camera:r}=j.useThree(),c=Number.isFinite(t)?Math.min(g.face.max,Math.max(1,Math.round(t))):1,d=i!==void 0&&Number.isFinite(i)&&i>0?i:void 0,o=T.useMemo(()=>({numFaces:c,...d?{targetFps:d}:{}}),[c,d]),{node:x,ready:a}=q.useXRModel(F.XRModel.FACE_TRACKER,o,e);T.useEffect(()=>{if(x)for(let u=0;u<o.numFaces;u+=1)x.setCamera(r,u)},[o.numFaces,r,x]);const E=T.useCallback(u=>{if(!x)return[];const N=[];for(let _=0;_<u.faceLandmarks.length;_+=1){const U=w.getFaceInfoFromResults(x,u,_);U&&N.push(U)}return N},[x]);return w.useFaceResultReader({enabled:e&&a,holdMs:Number.isFinite(n)?Math.max(0,n):250,node:x,prepare:E,throttleMs:Number.isFinite(s)?Math.max(0,s):16})},Y=4,oe=({faceIndex:e=0,numFaces:n,subject:t,...i}={})=>{const s=Number.isFinite(e)?Math.max(0,Math.round(e)):0,r=k({...i,numFaces:Math.max(n??(t?Y:s+1),s+1)}),c=T.useRef(O),d=JSON.stringify(t??null),o=T.useMemo(()=>{if(!t)return null;const x=r.map((a,E)=>({index:E,center:{x:a.bounds.centerX,y:a.bounds.centerY},size:a.bounds.width}));return X(x,t,c.current)},[r,d]);return T.useEffect(()=>{o&&(c.current=o.memory)},[o]),t?o&&o.index!==null?r[o.index]??null:null:r[s]??null};exports.DEFAULT_POLICY_NUM_FACES=Y;exports.DEFAULT_SUBJECT_POLICY=D;exports.EMPTY_SUBJECT_MEMORY=O;exports.XR_MAX_SUBJECTS=g;exports.associateSubjects=ce;exports.clientToScreenPixels=K;exports.faceCandidates=se;exports.feedToScreenPixels=te;exports.feedToTracker=v;exports.feedToViewport=ee;exports.jointCandidates=re;exports.mediaToScreenPixels=z;exports.normalizedToScreenPixels=S;exports.screenPixelsToClient=$;exports.screenPixelsToFeed=ie;exports.screenPixelsToMedia=G;exports.screenPixelsToNormalized=L;exports.screenPixelsToScreenSpace=p;exports.screenPixelsToUnits=J;exports.screenPointToRay=Z;exports.screenSpaceToScreenPixels=H;exports.screenUnitsToPixels=V;exports.selectSubject=X;exports.trackerPointToScreenPixels=W;exports.trackerToFeed=b;exports.useFaceInfo=oe;exports.useFaceInfos=k;exports.viewportToFeed=ne;exports.worldToScreenPixels=Q;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const e=require("react"),C=require("./index-CeVkgsag.cjs"),S=(s={})=>{const{enabled:c=!0,timeoutMs:i,queryPermission:l}=s,f=(s.models??[]).join("|"),a=e.useRef(s.models);a.current=s.models;const[m,b]=e.useState(null),[R,n]=e.useState("idle"),[y,o]=e.useState(null),t=e.useRef(0),u=e.useCallback(async()=>{t.current+=1;const d=t.current;n("checking");try{const r=await C.detectXRCapabilities({models:a.current,timeoutMs:i,queryPermission:l});return d!==t.current?null:(b(r),o(null),n("ready"),r)}catch(r){return d!==t.current||(o(r instanceof Error?r:new Error(String(r))),n("error")),null}},[i,l]);return e.useEffect(()=>{if(c)return u(),()=>{t.current+=1}},[c,u,f]),{capabilities:m,status:R,error:y,refresh:u}};exports.useXRCapabilities=S;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useRef as m, useState as u, useCallback as E, useEffect as R } from "react";
|
|
2
|
+
import { d as g } from "./index-CnGox6Xr.js";
|
|
3
|
+
const k = (t = {}) => {
|
|
4
|
+
const { enabled: c = !0, timeoutMs: o, queryPermission: l } = t, f = (t.models ?? []).join("|"), i = m(t.models);
|
|
5
|
+
i.current = t.models;
|
|
6
|
+
const [b, p] = u(null), [y, n] = u("idle"), [C, a] = u(null), e = m(0), s = E(async () => {
|
|
7
|
+
e.current += 1;
|
|
8
|
+
const d = e.current;
|
|
9
|
+
n("checking");
|
|
10
|
+
try {
|
|
11
|
+
const r = await g({
|
|
12
|
+
models: i.current,
|
|
13
|
+
timeoutMs: o,
|
|
14
|
+
queryPermission: l
|
|
15
|
+
});
|
|
16
|
+
return d !== e.current ? null : (p(r), a(null), n("ready"), r);
|
|
17
|
+
} catch (r) {
|
|
18
|
+
return d !== e.current || (a(r instanceof Error ? r : new Error(String(r))), n("error")), null;
|
|
19
|
+
}
|
|
20
|
+
}, [o, l]);
|
|
21
|
+
return R(() => {
|
|
22
|
+
if (c)
|
|
23
|
+
return s(), () => {
|
|
24
|
+
e.current += 1;
|
|
25
|
+
};
|
|
26
|
+
}, [c, s, f]), { capabilities: b, status: y, error: C, refresh: s };
|
|
27
|
+
};
|
|
28
|
+
export {
|
|
29
|
+
k as u
|
|
30
|
+
};
|
package/dist/utils/fns.d.ts
CHANGED
|
@@ -14,11 +14,11 @@ export declare const drawImageDataCover: (canvas: HTMLCanvasElement, input: Imag
|
|
|
14
14
|
* trackers call this once per landmark per frame (~468× for face), so the
|
|
15
15
|
* allocating variant below shows up as a real GC pressure source.
|
|
16
16
|
*/
|
|
17
|
-
export declare const unprojectToZZeroInto: (
|
|
17
|
+
export declare const unprojectToZZeroInto: (landmark: NormalizedLandmark, camera: THREE.Camera, out: THREE.Vector3) => THREE.Vector3;
|
|
18
18
|
/**
|
|
19
19
|
* Allocating wrapper kept for backwards compatibility with any
|
|
20
|
-
* consumer-facing API surface. New call sites
|
|
21
|
-
* unprojectToZZeroInto with a pre-allocated out
|
|
20
|
+
* consumer-facing API surface. New call sites use `feedToWorld` from
|
|
21
|
+
* `lib/coordinates` (or `unprojectToZZeroInto` with a pre-allocated out).
|
|
22
22
|
*/
|
|
23
23
|
export declare const unprojectToZZero: (landmark: NormalizedLandmark, camera: THREE.Camera) => THREE.Vector3;
|
|
24
24
|
export declare const smoothScale: (originalScale: number, newScale: number, alpha?: number) => number;
|
|
@@ -37,7 +37,10 @@ export declare const smoothScale: (originalScale: number, newScale: number, alph
|
|
|
37
37
|
export declare class AnalysisDownscaler {
|
|
38
38
|
private readonly maxDimension;
|
|
39
39
|
private canvas;
|
|
40
|
+
private scale;
|
|
40
41
|
constructor(maxDimension: number);
|
|
42
|
+
/** Multiply the cap (0.25..1); the adaptive-quality tier sets it. */
|
|
43
|
+
setScale(scale: number): void;
|
|
41
44
|
/**
|
|
42
45
|
* Returns a downscaled copy of `source` capped to `maxDimension` on its
|
|
43
46
|
* longest side (or `source` unchanged if it's already within the cap, or if a
|
|
@@ -14,7 +14,10 @@ export declare const INTEGRITY_MANIFEST: Record<string, IntegrityHash>;
|
|
|
14
14
|
* Consumer-owned URLs with no manifest entry pass through with a warning.
|
|
15
15
|
* SDK-owned CDN URLs with no entry fail closed.
|
|
16
16
|
*/
|
|
17
|
-
export declare function fetchAndVerify(url: string
|
|
17
|
+
export declare function fetchAndVerify(url: string, init?: {
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}): Promise<ArrayBuffer>;
|
|
20
|
+
export declare function isSdkOwnedUrl(url: string): boolean;
|
|
18
21
|
/**
|
|
19
22
|
* fetchAndVerify variant that returns a Uint8Array view — what MediaPipe's
|
|
20
23
|
* `modelAssetBuffer` expects.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type StableUniforms<T extends Record<string, unknown>> = {
|
|
2
|
+
[K in keyof T]: {
|
|
3
|
+
value: T[K];
|
|
4
|
+
};
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Build a `ShaderMaterial` uniforms object whose entries never change identity.
|
|
8
|
+
*
|
|
9
|
+
* three.js captures `material.uniforms` once, when the program is compiled,
|
|
10
|
+
* and keeps reading that object on every draw. A uniforms object re-created
|
|
11
|
+
* on a React render (a plain literal, or a `useMemo` with dependencies) is
|
|
12
|
+
* therefore silently ignored after the first frame unless the material is
|
|
13
|
+
* re-mounted. This hook allocates each `{ value }` entry once and copies the
|
|
14
|
+
* latest values into them on every render, so prop changes reach the shader.
|
|
15
|
+
*
|
|
16
|
+
* The set of keys must be the same on every render.
|
|
17
|
+
*/
|
|
18
|
+
export declare const useStableUniforms: <T extends Record<string, unknown>>(values: T) => StableUniforms<T>;
|
|
@@ -341,6 +341,7 @@ import { XRScene } from "@vincentt-xr/sdk";
|
|
|
341
341
|
- media source selection
|
|
342
342
|
- cover/contain fitting
|
|
343
343
|
- mirror state
|
|
344
|
+
- a shared media composition canvas for display, tracker input, and DOM capture
|
|
344
345
|
- DOM overlay composition
|
|
345
346
|
- optional scene adapter mounting
|
|
346
347
|
|
|
@@ -360,6 +361,8 @@ Modes:
|
|
|
360
361
|
Media strategies:
|
|
361
362
|
|
|
362
363
|
- `internal` — viewport owns webcam/image/video and tracking preview lifecycle
|
|
364
|
+
- `internal` media reuses its composed canvas for session tracker input and
|
|
365
|
+
`session.captureFrame()` / `session.captureStream()` when no XRScene is mounted
|
|
363
366
|
- `external` — legacy session/media owner stays in control while viewport provides responsive scene/overlay composition
|
|
364
367
|
|
|
365
368
|
Core props:
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Adaptive Quality & Performance Budget"
|
|
3
|
+
description: "An opt-out performance budget that measures frame time, inference time, memory and device signals, then steps tracker fps, analysis resolution, render pixel ratio and camera resolution between declared tiers; bounded, observable, reversible."
|
|
4
|
+
sidebarTitle: "Adaptive Quality"
|
|
5
|
+
icon: "gauge"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Phones differ by an order of magnitude and heat up over a session. Instead
|
|
9
|
+
of hand-tuning `perf.targetFps`, declare quality tiers and a budget; the
|
|
10
|
+
controller moves between the tiers and tells you why.
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { XRProvider, useXRQuality } from "@vincentt-xr/sdk";
|
|
14
|
+
|
|
15
|
+
// On by default. Customise, pin, or turn it off:
|
|
16
|
+
<XRProvider quality={{ budget: { maxFrameMs: 33 }, minTier: "medium" }}>…</XRProvider>;
|
|
17
|
+
<XRProvider quality={{ adaptive: false, initialTier: "medium" }}>…</XRProvider>;
|
|
18
|
+
<XRProvider quality={false}>…</XRProvider>;
|
|
19
|
+
|
|
20
|
+
const { tier, decision, signals, setTier, lock, unlock, reset } = useXRQuality();
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Tiers and budget (serializable)
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
const DEFAULT_QUALITY_TIERS = [
|
|
27
|
+
{ name: "high", targetFps: 30, renderScale: 1, analysisScale: 1, camRes: 960 },
|
|
28
|
+
{ name: "medium", targetFps: 24, renderScale: 0.8, analysisScale: 0.85, camRes: 720 },
|
|
29
|
+
{ name: "low", targetFps: 15, renderScale: 0.6, analysisScale: 0.7, camRes: 640 },
|
|
30
|
+
];
|
|
31
|
+
const DEFAULT_PERFORMANCE_BUDGET = {
|
|
32
|
+
maxFrameMs: 1000 / 24,
|
|
33
|
+
maxInferenceMs: 24,
|
|
34
|
+
maxMemoryMb: null,
|
|
35
|
+
sampleMs: 1000,
|
|
36
|
+
downgradeAfter: 2,
|
|
37
|
+
upgradeAfter: 6,
|
|
38
|
+
upgradeHeadroom: 0.75,
|
|
39
|
+
cooldownMs: 4000,
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Tiers are ordered best → worst; every knob is optional. `resolveQualityConfig`
|
|
44
|
+
validates a partial config (clamps scales to 0.25..1, drops invalid knobs,
|
|
45
|
+
resolves `initialTier` / `minTier` / `maxTier` by index or name), and the
|
|
46
|
+
result is plain JSON you can persist.
|
|
47
|
+
|
|
48
|
+
## Knobs and ownership
|
|
49
|
+
|
|
50
|
+
| Knob | Owner | Applied how |
|
|
51
|
+
| --------------- | ------------------------------------------------------------------- | -------------------------------------------------------------- |
|
|
52
|
+
| `targetFps` | session perf config → every tracker without its own `targetFps` | `_setPerf` re-runs the models; immediate |
|
|
53
|
+
| `analysisScale` | session perf config → every model's analysis downscaler | immediate (next inference) |
|
|
54
|
+
| `renderScale` | `<XRScene>` pixel ratio: `min(devicePixelRatio, cap) × renderScale` | immediate; `cap` is the `dpr` ceiling (3 or `canvasProps.dpr`) |
|
|
55
|
+
| `camRes` | session perf config, **only with `rebindCamera: true`** | re-opens the webcam once when the tier changes |
|
|
56
|
+
|
|
57
|
+
A per-tracker `targetFps` prop still beats the tier. The app's own `perf`
|
|
58
|
+
is the base the tiers are merged over, and it is restored when the
|
|
59
|
+
controller unmounts.
|
|
60
|
+
|
|
61
|
+
## Behaviour
|
|
62
|
+
|
|
63
|
+
- **Sample** every `sampleMs`: mean main-thread frame time (window RAF),
|
|
64
|
+
fps, total tracker inference (`inferenceMsTotal` from diagnostics), feed
|
|
65
|
+
fps, JS heap (`performance.memory` where it exists), `deviceMemory`,
|
|
66
|
+
`hardwareConcurrency`, thermal. Hidden tabs are never judged.
|
|
67
|
+
- **Judge** most severe first: thermal `critical` → memory over
|
|
68
|
+
`maxMemoryMb` → inference over `maxInferenceMs` → frame time over
|
|
69
|
+
`maxFrameMs`.
|
|
70
|
+
- **Step down** after `downgradeAfter` consecutive bad samples, at most once
|
|
71
|
+
per `cooldownMs`, never below `minTier`. At the floor and still over
|
|
72
|
+
budget on frame time, `signals.thermal` becomes `"suspected"` so the app
|
|
73
|
+
can shed content; nothing else changes.
|
|
74
|
+
- **Step up** after `upgradeAfter` consecutive good samples (frame time and
|
|
75
|
+
inference under `budget × upgradeHeadroom`), never above `maxTier`.
|
|
76
|
+
- **Initial tier**: `initialTier` if set, else one step down from the top on
|
|
77
|
+
devices with ≤ 4 GB or ≤ 4 cores.
|
|
78
|
+
- **Manual**: `setTier()` (controller may move again after the cooldown),
|
|
79
|
+
`lock()` / `unlock()`, `reset()`. Every change is a decision with a
|
|
80
|
+
`reason` (`init`, `frame-time`, `inference`, `memory`, `thermal`,
|
|
81
|
+
`recovered`, `manual`, `locked`, `reset`) kept in `history`.
|
|
82
|
+
- **Unsupported signals degrade gracefully**: no `performance.memory` →
|
|
83
|
+
`memoryMb: null` and memory is ignored; no thermal API in browsers →
|
|
84
|
+
`thermal: "unknown"` unless the host passes one to
|
|
85
|
+
`<XRQualityController thermal=…>`.
|
|
86
|
+
|
|
87
|
+
The state is published to the session store (`useXRQualityState()` in
|
|
88
|
+
low-level) and shows in `useXRDiagnostics().quality` and the
|
|
89
|
+
`XRDiagnosticsPanel`. The pure stepping functions (`stepQualityController`,
|
|
90
|
+
`judgeSample`, …) are exported from `/low-level` for tests and custom
|
|
91
|
+
controllers.
|
|
92
|
+
|
|
93
|
+
## Manual validation
|
|
94
|
+
|
|
95
|
+
Run `/adaptive-quality` (budget tightened: 2 bad samples, 3 s cooldown):
|
|
96
|
+
|
|
97
|
+
| Case | Steps | Expect |
|
|
98
|
+
| ----------- | --------------------------- | ----------------------------------------------------------------- |
|
|
99
|
+
| Baseline | load with a video source | tier `high` (or `medium` on a weak device), `init` |
|
|
100
|
+
| Load | simulated load 60 ms | within ~3 s `medium` (`frame-time`), then `low` |
|
|
101
|
+
| Recover | load 0 | after ~4 good samples back to `medium`, then `high` (`recovered`) |
|
|
102
|
+
| Lock | lock, load 60 | stays put |
|
|
103
|
+
| Manual | pick `low` | tier `low` (`manual`), diagnostics panel shows it |
|
|
104
|
+
| Pixel ratio | pick `low` on a DPR-3 phone | scene renders softer (0.6×) |
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Asset Lifecycle & GPU Memory"
|
|
3
|
+
description: "Preload, cache, reference-count, de-duplicate, dispose and budget textures, GLB models and video with the SDK's own three.js loaders; observe usage and eviction."
|
|
4
|
+
sidebarTitle: "Asset Lifecycle"
|
|
5
|
+
icon: "memory"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
GPU memory grows when the same texture is loaded twice, when a route change
|
|
9
|
+
leaves a model behind, or when nobody owns disposal. The asset cache gives
|
|
10
|
+
every asset one identity, one load, one owner list and one disposal.
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import {
|
|
14
|
+
XRAssetCacheProvider,
|
|
15
|
+
defineGltfAsset,
|
|
16
|
+
defineTextureAsset,
|
|
17
|
+
useXRAsset,
|
|
18
|
+
useXRAssetStats,
|
|
19
|
+
} from "@vincentt-xr/sdk";
|
|
20
|
+
|
|
21
|
+
const HAT = defineGltfAsset("https://cdn.example.com/hat.glb");
|
|
22
|
+
const LOGO = defineTextureAsset("https://cdn.example.com/logo.png");
|
|
23
|
+
|
|
24
|
+
const Hat = () => {
|
|
25
|
+
const { value, status } = useXRAsset(HAT); // shared with every other <Hat>
|
|
26
|
+
return value ? <primitive object={value.scene} /> : null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
<XRAssetCacheProvider>
|
|
30
|
+
{" "}
|
|
31
|
+
{/* optional: scopes a cache; releases unreferenced assets on unmount */}
|
|
32
|
+
<Hat />
|
|
33
|
+
<Hat /> {/* second mount: cache hit, same scene object */}
|
|
34
|
+
</XRAssetCacheProvider>;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Model
|
|
38
|
+
|
|
39
|
+
- **Definition** `XRAssetDefinition<T> = { key, load(signal), dispose?(value), bytes?(value) }`. `key` is the identity; `defineTextureAsset`, `defineGltfAsset` and `defineVideoAsset` build one over three's loaders (no drei); SDK-CDN URLs go through the verifying fetch (fail closed without a pinned hash), consumer URLs are fetched plainly. Loads honour the abort signal, and a decode or parse that finishes after a release is disposed, not leaked. Write your own for anything else (audio buffers, JSON, fonts).
|
|
40
|
+
- **Acquire / release** `cache.acquire(asset, ownerId)` returns the shared value (in-flight loads are shared too); `cache.release(key, ownerId)` drops that owner. Owners are ids, so a re-render or a StrictMode double mount never double-counts. `useXRAsset` does both for a component.
|
|
41
|
+
- **Unreferenced values stay cached** until the budget needs room, `disposeUnreferenced()` or `disposeAll()`. A value nobody wanted by the time its load finished is disposed at once; releasing during a load aborts it.
|
|
42
|
+
- **Budget** `createAssetCache({ budgetBytes })` (default 256 MiB, `Infinity` disables). Above it, unreferenced values are disposed least-recently-used first; referenced values are never evicted, so `overBudget` can stay true while everything is in use. `setBudget` applies immediately; `evict(bytes)` forces room.
|
|
43
|
+
- **Bytes** come from `bytes(value)`: `estimateTextureBytes` (RGBA × mip chain), `estimateGeometryBytes`, `estimateObjectBytes` (geometries and textures reachable from a scene, each once). They are estimates of resident GPU memory; the browser exposes no exact figure.
|
|
44
|
+
- **Disposal is exactly once**: `dispose(value)` runs once per loaded value, on eviction, `disposeUnreferenced`, `disposeAll` or a too-late load. `disposeObject3D` releases every geometry, material and texture under an object.
|
|
45
|
+
- **Errors** are recorded on the entry (`status: "error"`); the next acquire retries.
|
|
46
|
+
|
|
47
|
+
## Observability
|
|
48
|
+
|
|
49
|
+
`useXRAssetStats()` (or `cache.getStats()`) reports `assets`,
|
|
50
|
+
`referencedAssets`, `loadingAssets`, `erroredAssets`, `usageBytes`,
|
|
51
|
+
`reclaimableBytes`, `budgetBytes`, `overBudget`, `evictions`, `hits` and
|
|
52
|
+
`misses`; `cache.list()` gives every entry with its status, bytes and owner
|
|
53
|
+
count; `cache.subscribe(listener)` fires on every change.
|
|
54
|
+
|
|
55
|
+
## Route changes and session shutdown
|
|
56
|
+
|
|
57
|
+
Owners release on unmount, so navigating away drops every reference held by
|
|
58
|
+
the page. `<XRAssetCacheProvider>` then calls `disposeUnreferenced()` as it
|
|
59
|
+
unmounts (`disposeUnreferencedOnUnmount`, default `true`), so a page-scoped
|
|
60
|
+
cache leaves nothing behind; the app-wide default cache (no provider) keeps
|
|
61
|
+
unreferenced values for the next page until the budget says otherwise. For
|
|
62
|
+
a hard shutdown call `cache.disposeAll()`. Tracker-owned resources (the
|
|
63
|
+
MediaPipe models, the camera texture, segmentation masks) are managed by the
|
|
64
|
+
session registry, released once when the provider unmounts; the asset cache
|
|
65
|
+
covers everything the app loads on top.
|
|
66
|
+
|
|
67
|
+
## Manual validation
|
|
68
|
+
|
|
69
|
+
Run `/asset-lifecycle` (a 24 MB page-scoped cache):
|
|
70
|
+
|
|
71
|
+
| Case | Steps | Expect |
|
|
72
|
+
| ------------ | ----------------------------------- | ------------------------------------------------------------------ |
|
|
73
|
+
| Dedupe | mount texture 1 twice (remount) | `hits` rises, one entry |
|
|
74
|
+
| Release | unmount a texture | entry stays with 0 owners, `reclaimable` grows |
|
|
75
|
+
| Budget | lower the budget slider | unreferenced entries disappear oldest first, `evictions` counts up |
|
|
76
|
+
| Referenced | budget below usage with all mounted | `OVER` shown, nothing evicted |
|
|
77
|
+
| Preload | "preload texture 4" | entry `ready` with 0 owners; mounting it is a hit |
|
|
78
|
+
| Route change | navigate away and back | entries empty on return (provider disposed the unreferenced ones) |
|