@vincentt-xr/sdk 2.0.0-alpha.6 → 2.0.0-alpha.7

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.
Files changed (77) hide show
  1. package/GROUNDING.md +81 -3
  2. package/dist/{DebuggerUI-DYT_dk1E.cjs → DebuggerUI-B6bP6P9r.cjs} +1 -1
  3. package/dist/{DebuggerUI-C_rbLdkh.js → DebuggerUI-BjOMr8q_.js} +1 -1
  4. package/dist/{FaceMeshRenderer-D1WsrTLA.cjs → FaceMeshRenderer-C5l6VLdO.cjs} +6 -6
  5. package/dist/{FaceMeshRenderer-DSCd1H55.js → FaceMeshRenderer-wjAHrJzP.js} +102 -96
  6. package/dist/{FaceRetouch-DsE0Dbw-.cjs → FaceRetouch-BkJzoA79.cjs} +1 -1
  7. package/dist/{FaceRetouch-CMJbGThL.js → FaceRetouch-DwbKQJAN.js} +4 -4
  8. package/dist/components/FaceMesh/FaceMeshRenderer.d.ts +11 -3
  9. package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +10 -4
  10. package/dist/components/FaceMesh/index.d.ts +2 -2
  11. package/dist/components/SceneObjectRenderer/index.d.ts +9 -2
  12. package/dist/components/XRMediaSurface/index.d.ts +2 -1
  13. package/dist/{contexts-DvQI4PqI.js → contexts-ByhzppYl.js} +3 -3
  14. package/dist/{contexts-h-9TRH0r.cjs → contexts-Dr62It_K.cjs} +1 -1
  15. package/dist/debug-ui/media-source.cjs +1 -1
  16. package/dist/debug-ui/media-source.js +1 -1
  17. package/dist/debug-ui.cjs +1 -1
  18. package/dist/debug-ui.js +10 -10
  19. package/dist/entries/core.d.ts +3 -2
  20. package/dist/entries/face-effects.d.ts +2 -2
  21. package/dist/entries/tracking.d.ts +2 -0
  22. package/dist/face-effects.cjs +1 -1
  23. package/dist/face-effects.js +25 -24
  24. package/dist/{getFaceInfo-B43Cwq4n.js → getFaceInfo-C4QpCQIY.js} +1 -1
  25. package/dist/{getFaceInfo-DEzcL_Ub.cjs → getFaceInfo-fA1bFBub.cjs} +1 -1
  26. package/dist/hooks/useXRSession/facade.d.ts +2 -0
  27. package/dist/{index-I4eF5TKT.js → index-9dlAQAhy.js} +405 -400
  28. package/dist/{index-CY7Z8cHV.cjs → index-BjmTe9eM.cjs} +1 -1
  29. package/dist/{index-D67hHm44.cjs → index-BpEf2BBb.cjs} +1 -1
  30. package/dist/{index-B-s4YbWu.js → index-ByoNj0QP.js} +1 -1
  31. package/dist/{index-CxMEeCRP.cjs → index-CyUUurQT.cjs} +1 -1
  32. package/dist/index-DCiMbxC3.cjs +1 -0
  33. package/dist/{index-G_5h_FJQ.js → index-DXT3WccE.js} +808 -787
  34. package/dist/index-DpI-qo5X.cjs +17 -0
  35. package/dist/{index-DYfY9ljy.js → index-DyVF4vEW.js} +1 -1
  36. package/dist/{index-uE3sKczj.js → index-VJ0SJwmG.js} +1 -1
  37. package/dist/{internal-MvKrz0Nt.cjs → internal-Cq-TEQ5Y.cjs} +1 -1
  38. package/dist/{internal-ldPYiUF0.js → internal-Dmk1cTXq.js} +3 -3
  39. package/dist/internal.cjs +1 -1
  40. package/dist/internal.js +1 -1
  41. package/dist/low-level.cjs +1 -1
  42. package/dist/low-level.js +344 -330
  43. package/dist/main.cjs +1 -1
  44. package/dist/main.js +94 -91
  45. package/dist/{renderGroups-BJsx32q5.cjs → renderGroups-80H3DpTl.cjs} +1 -1
  46. package/dist/{renderGroups-CFt1yYLB.js → renderGroups-KZk6eRiY.js} +1 -1
  47. package/dist/{renderPasses-D-Krl6D0.cjs → renderPasses-BOoBSr8z.cjs} +1 -1
  48. package/dist/{renderPasses-C72MbZ-a.js → renderPasses-BcquyVtu.js} +4 -4
  49. package/dist/scene-object.cjs +1 -1
  50. package/dist/scene-object.js +2 -2
  51. package/dist/screen2d/coordinates.d.ts +20 -0
  52. package/dist/{selectors-ByKNTXeA.js → selectors-B8H97CKA.js} +1 -1
  53. package/dist/{selectors-CAwmL9VW.cjs → selectors-CZLKT2Iv.cjs} +1 -1
  54. package/dist/{session-CANvoLD6.cjs → session-CpkiK5YA.cjs} +1 -1
  55. package/dist/{session-Dhi0OqZo.js → session-DLFN_VII.js} +1 -1
  56. package/dist/tracking/coordinates.d.ts +5 -0
  57. package/dist/tracking.cjs +1 -1
  58. package/dist/tracking.js +69 -66
  59. package/dist/types/common.d.ts +11 -1
  60. package/dist/types/gesture-tracking.d.ts +2 -2
  61. package/dist/types/hand-tracking.d.ts +3 -3
  62. package/dist/types/nodes.d.ts +2 -2
  63. package/dist/types/session.d.ts +7 -1
  64. package/dist/{useFaceInfo-BSZq7AO1.cjs → useFaceInfo-BJ8-_MOs.cjs} +1 -1
  65. package/dist/{useFaceInfo-FVQBBNdY.js → useFaceInfo-Dk426LTu.js} +3 -3
  66. package/dist/{useFaceResults-D62STzT1.js → useFaceResults-CtetsO9M.js} +1 -1
  67. package/dist/{useFaceResults-C3oZkn2Z.cjs → useFaceResults-wBJF3zyp.cjs} +1 -1
  68. package/docs/SDK_DOCUMENTATION.md +3 -0
  69. package/docs/api/capture-recording.mdx +9 -1
  70. package/docs/api/face-mesh.mdx +33 -0
  71. package/docs/api/runtime-3d.mdx +5 -0
  72. package/docs/api/screen-image.mdx +3 -1
  73. package/docs/api/screen-space-coordinates.mdx +31 -0
  74. package/docs/api/trackers.mdx +13 -0
  75. package/package.json +4 -1
  76. package/dist/index-C0-fg1Hk.cjs +0 -1
  77. package/dist/index-DPPpU5By.cjs +0 -17
@@ -1,6 +1,7 @@
1
1
  import { Camera, Ray, Vector3Like } from 'three';
2
2
  import { ScreenTransformRoot } from './screenTransform';
3
3
  import { XRMediaLayout } from '../types/compositor';
4
+ import { TrackerPoint } from '../types/common';
4
5
  export type ScreenViewportSize = {
5
6
  width: number;
6
7
  height: number;
@@ -21,10 +22,22 @@ export type ScreenUnitConversionOptions = {
21
22
  referencePixelsPerUnit?: number;
22
23
  root?: ScreenTransformRoot;
23
24
  };
25
+ export type ScreenPointUnitConversionOptions = ScreenUnitConversionOptions & {
26
+ point: ScreenPixelPoint;
27
+ target?: ScreenPixelPoint;
28
+ };
24
29
  /** Converts SDK design-canvas pixels to Three.js ScreenSpaceUI plane units. */
25
30
  export declare const screenPixelsToUnits: (pixels: number, options: ScreenUnitConversionOptions) => number;
26
31
  /** Converts Three.js ScreenSpaceUI plane units to SDK design-canvas pixels. */
27
32
  export declare const screenUnitsToPixels: (units: number, options: ScreenUnitConversionOptions) => number;
33
+ /**
34
+ * Converts SDK design pixels into a ScreenSpaceUI parent's world units.
35
+ * X and Y deliberately use their own scale so the design canvas stays aligned
36
+ * with canvas-positioned screen primitives on every viewport aspect ratio.
37
+ */
38
+ export declare const screenPixelsToScreenSpace: ({ point, parentSize, referencePixelsPerUnit, root, target, }: ScreenPointUnitConversionOptions) => ScreenPixelPoint;
39
+ /** Converts ScreenSpaceUI parent world units back to SDK design pixels. */
40
+ export declare const screenSpaceToScreenPixels: ({ point, parentSize, referencePixelsPerUnit, root, target, }: ScreenPointUnitConversionOptions) => ScreenPixelPoint;
28
41
  /** Converts DOM client coordinates to center-origin, +Y-up SDK design pixels. */
29
42
  export declare const clientToScreenPixels: ({ point, rect, root, target, }: {
30
43
  point: ScreenPixelPoint;
@@ -53,6 +66,13 @@ export declare const screenPixelsToNormalized: ({ point, root, target, viewportS
53
66
  root?: ScreenTransformRoot;
54
67
  target?: ScreenPixelPoint;
55
68
  }) => ScreenPixelPoint;
69
+ /** Converts center-origin, Y-up tracker coordinates to SDK design pixels. */
70
+ export declare const trackerPointToScreenPixels: ({ point, root, target, viewportSize, }: {
71
+ point: TrackerPoint;
72
+ viewportSize: ScreenViewportSize;
73
+ root?: ScreenTransformRoot;
74
+ target?: ScreenPixelPoint;
75
+ }) => ScreenPixelPoint;
56
76
  /** Maps source-media pixel coordinates through viewport fit/crop and optional mirroring. */
57
77
  export declare const mediaToScreenPixels: ({ layout, mirrored, point, root, target, }: {
58
78
  point: ScreenPixelPoint;
@@ -1,5 +1,5 @@
1
1
  import { useSyncExternalStore as s, useMemo as a } from "react";
2
- import { u } from "./index-I4eF5TKT.js";
2
+ import { u } from "./index-9dlAQAhy.js";
3
3
  const r = () => u().session.store, o = (e) => (t) => e.subscribe(t), p = () => {
4
4
  const e = r();
5
5
  return s(
@@ -1 +1 @@
1
- "use strict";const s=require("react"),u=require("./index-C0-fg1Hk.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;
1
+ "use strict";const s=require("react"),u=require("./index-DCiMbxC3.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;
@@ -1,4 +1,4 @@
1
- "use strict";const p=require("./index-C0-fg1Hk.cjs"),n=require("react/jsx-runtime"),L=require("react-dom"),c=require("react"),d=require("./x-KC8E4Gaj.cjs"),v=(t,e)=>new URL(`/assets/sdk/debug-ui/v1/${t}/${e}`,p.libConfig.assetStorageEndpoint).href,j=t=>t.replace(/\.[^.]+$/,"").replace(/[_-]+/g," ").replace(/\s+/g," ").trim().replace(/\b\w/g,e=>e.toUpperCase()),$=["person_fullbody.mp4","person_looking.mp4","person_shaking_head.mp4","person_thumbUp.mp4","two_people_smiling.mp4"],z=["person_fist_sign.jpg","person_fullbody.jpg","person_peace_sign.jpg","person_portrait.jpg","person_side_portrait.jpg","three_people_smiling.jpg","two_people_smiling.jpg"],W=(t,e)=>({id:`sdk-video-${e+1}`,kind:"video",label:j(t),url:v("videos",t)}),F=(t,e)=>({id:`sdk-image-${e+1}`,kind:"image",label:j(t),url:v("images",t)}),M=$.map(W),_=z.map(F),V=[{id:"webcam",kind:"webcam",label:"Webcam"},...M,..._];/**
1
+ "use strict";const p=require("./index-DCiMbxC3.cjs"),n=require("react/jsx-runtime"),L=require("react-dom"),c=require("react"),d=require("./x-KC8E4Gaj.cjs"),v=(t,e)=>new URL(`/assets/sdk/debug-ui/v1/${t}/${e}`,p.libConfig.assetStorageEndpoint).href,j=t=>t.replace(/\.[^.]+$/,"").replace(/[_-]+/g," ").replace(/\s+/g," ").trim().replace(/\b\w/g,e=>e.toUpperCase()),$=["person_fullbody.mp4","person_looking.mp4","person_shaking_head.mp4","person_thumbUp.mp4","two_people_smiling.mp4"],z=["person_fist_sign.jpg","person_fullbody.jpg","person_peace_sign.jpg","person_portrait.jpg","person_side_portrait.jpg","three_people_smiling.jpg","two_people_smiling.jpg"],W=(t,e)=>({id:`sdk-video-${e+1}`,kind:"video",label:j(t),url:v("videos",t)}),F=(t,e)=>({id:`sdk-image-${e+1}`,kind:"image",label:j(t),url:v("images",t)}),M=$.map(W),_=z.map(F),V=[{id:"webcam",kind:"webcam",label:"Webcam"},...M,..._];/**
2
2
  * @license lucide-react v1.17.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import { l as j, u as z, c as v, X as L } from "./index-I4eF5TKT.js";
1
+ import { l as j, u as z, c as v, X as L } from "./index-9dlAQAhy.js";
2
2
  import { jsx as n, jsxs as u } from "react/jsx-runtime";
3
3
  import { createPortal as W } from "react-dom";
4
4
  import { useState as y, useRef as $, useMemo as F, useEffect as f } from "react";
@@ -0,0 +1,5 @@
1
+ import { NormalizedTrackerPoint, TrackerPoint } from '../types/common';
2
+ /** Converts MediaPipe image coordinates to SDK center-origin, Y-up tracker coordinates. */
3
+ export declare const normalizedTrackerPointToTrackerPoint: (point: NormalizedTrackerPoint, target?: TrackerPoint) => TrackerPoint;
4
+ /** Converts SDK tracker coordinates back to normalized, top-left image coordinates. */
5
+ export declare const trackerPointToNormalizedTrackerPoint: (point: TrackerPoint, target?: NormalizedTrackerPoint) => NormalizedTrackerPoint;
package/dist/tracking.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var Q=Object.create;var U=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var ne=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty;var se=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of te(t))!re.call(e,s)&&s!==r&&U(e,s,{get:()=>t[s],enumerable:!(n=ee(t,s))||n.enumerable});return e};var z=(e,t,r)=>(r=e!=null?Q(ne(e)):{},se(t||!e||!e.__esModule?U(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("./index-CxMEeCRP.cjs"),F=require("react/jsx-runtime"),y=require("@react-three/fiber"),o=require("react"),oe=require("three"),_=require("./index-C0-fg1Hk.cjs"),j=require("./renderLayers-lDtL0_43.cjs"),N=require("./index-D67hHm44.cjs"),ue=require("./useFaceResults-C3oZkn2Z.cjs"),I=require("./useFaceInfo-BSZq7AO1.cjs"),S=require("./getFaceInfo-DEzcL_Ub.cjs"),ce=require("./drawNormalizedCrop-B-7zU-Xw.cjs");function ae(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const P=ae(oe),ie={"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};function le(e,t,r=0){var s;const n=(s=e==null?void 0:e.hands)!=null&&s.length?e.hands:e!=null&&e.coordinates?[{coordinates:e.coordinates,gesture:e.gesture,handedness:e.handedness}]:[];if(n.length){if(t){const c=n.find(a=>a.handedness===t);if(c)return c}return n[r]??n[0]}}const de=({children:e,hand:t,handIndex:r=0,targetFps:n,active:s=!0})=>{const c=o.useRef(null),a=o.useMemo(()=>n===void 0?void 0:{targetFps:n},[n]),{ready:l,node:m}=A.useXRModel(_.XRModel.HAND_TRACKER,a,s),{camera:u}=y.useThree(),i=o.useRef(u);i.current!==u&&(i.current=u);const d=o.useRef(null);y.useFrame(()=>{var E;if(!l||!m||!c.current)return;const g=le(m,t,r);d.current=g??null;const h=(E=g==null?void 0:g.coordinates)==null?void 0:E[0];if(!h){c.current.visible=!1;return}const R=G(h,i.current);c.current.visible=!0,c.current.position.copy(R)});const p=o.useCallback(g=>{var E,T;const h=ie[g];if(h===void 0)return null;const R=(T=(E=d.current)==null?void 0:E.coordinates)==null?void 0:T[h];return R?{position:G(R,i.current)}:null},[]),f=o.useMemo(()=>({type:"hand",resolveLandmark:p}),[p]);return F.jsx(A.TrackerContext.Provider,{value:f,children:F.jsx("group",{ref:c,renderOrder:j.RENDER_LAYERS.TRACKED,children:e})})},G=(e,t)=>{const r=new P.Vector3(e.x,e.y,e.z);r.unproject(t);const n=r.sub(t.position).normalize(),s=-t.position.z/n.z;return t.position.clone().add(n.multiplyScalar(s))},he={"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},fe=({children:e,targetFps:t,active:r=!0})=>{const n=o.useRef(null),s=o.useMemo(()=>t===void 0?void 0:{targetFps:t},[t]),{ready:c,node:a}=A.useXRModel(_.XRModel.GESTURE_TRACKER,s,r),{camera:l}=y.useThree(),m=o.useRef(l);m.current!==l&&(m.current=l);const u=o.useRef(null);y.useFrame(()=>{var g;if(!c||!a||!n.current)return;u.current=a;const p=(g=a==null?void 0:a.coordinates)==null?void 0:g[0];if(!p){n.current.visible=!1;return}const f=H(p,m.current);n.current.visible=!0,n.current.position.copy(f)});const i=o.useCallback(p=>{var h,R;const f=he[p];if(f===void 0)return null;const g=(R=(h=u.current)==null?void 0:h.coordinates)==null?void 0:R[f];return g?{position:H(g,m.current)}:null},[]),d=o.useMemo(()=>({type:"hand",resolveLandmark:i}),[i]);return F.jsx(A.TrackerContext.Provider,{value:d,children:F.jsx("group",{ref:n,renderOrder:j.RENDER_LAYERS.TRACKED,children:e})})},H=(e,t)=>{const r=new P.Vector3(e.x,e.y,e.z);r.unproject(t);const n=r.sub(t.position).normalize(),s=-t.position.z/n.z;return t.position.clone().add(n.multiplyScalar(s))},pe={"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},Re=({bodyIndex:e=0,active:t=!0,children:r})=>{const n=o.useRef(null),{ready:s,node:c}=A.useXRModel(_.XRModel.BODY_TRACKER,void 0,t),{camera:a}=y.useThree(),l=o.useRef(a);l.current!==a&&(l.current=a);const m=o.useRef(null);y.useFrame(()=>{if(!s||!c||!n.current)return;const d=c;m.current=d;const p=d.getLandmarks2D(e),f=p==null?void 0:p[0];if(!f){n.current.visible=!1;return}const g=B(f,l.current);n.current.visible=!0,n.current.position.copy(g)});const u=o.useCallback(d=>{const p=m.current;if(!p)return null;const f=p.getLandmarks2D(e);if(!f)return null;if(d==="body.neck"){const R=f[11],E=f[12];if(!R||!E)return null;const T={x:(R.x+E.x)/2,y:(R.y+E.y)/2,z:(R.z+E.z)/2};return{position:B(T,l.current)}}const g=pe[d];if(g===void 0)return null;const h=f[g];return h?{position:B(h,l.current)}:null},[e]),i=o.useMemo(()=>({type:"body",resolveLandmark:u}),[u]);return F.jsx(A.TrackerContext.Provider,{value:i,children:F.jsx("group",{ref:n,renderOrder:j.RENDER_LAYERS.TRACKED,children:r})})},B=(e,t)=>{const r=new P.Vector3(e.x,e.y,e.z);r.unproject(t);const n=r.sub(t.position).normalize(),s=-t.position.z/n.z;return t.position.clone().add(n.multiplyScalar(s))},O=["portrait"],Ee=({type:e,active:t=!0,children:r})=>(A.useXRModel(_.XRModel.BACKGROUND_SEGMENTATION,{type:e},t),o.useEffect(()=>{O.includes(e)||console.warn(`[Segmentation] unsupported type "${e}"; valid values: ${O.join(", ")}`)},[e]),F.jsx(F.Fragment,{children:r})),me=800,ge=200,Te=()=>({armed:!1,armStart:null,holdStart:null,fired:!1}),Se=(e,{isTrigger:t,gesture:r,now:n,mode:s,debounceMs:c,holdMs:a})=>{if(e.fired)return null;if(s==="hold"){if(t&&r){if(e.holdStart===null&&(e.holdStart=n),n-e.holdStart>=a)return e.fired=!0,r}else e.holdStart=null;return null}return e.armed?t&&r?(e.fired=!0,r):null:(t?e.armStart=null:(e.armStart===null&&(e.armStart=n),n-e.armStart>=c&&(e.armed=!0)),null)};function Ae({gestures:e,mode:t="arm",debounceMs:r=me,holdMs:n=ge,onTrigger:s,enabled:c=!0}){const{ready:a,node:l}=A.useXRModel(_.XRModel.GESTURE_TRACKER),m=o.useRef(s);o.useEffect(()=>{m.current=s},[s]);const u=o.useRef(new Set);o.useEffect(()=>{u.current=new Set(Array.isArray(e)?e:[e])},[e]);const i=o.useRef(Te());y.useFrame(()=>{if(!c||!a||!l)return;const d=l.gesture,p=!!(d&&u.current.has(d)),f=Se(i.current,{isTrigger:p,gesture:d,now:performance.now(),mode:t,debounceMs:r,holdMs:n});f&&m.current(f)})}const ye=e=>(Ae(e),null),Fe=(e,t)=>t&&!e?"begin":!t&&e?"end":t?"stay":"none",Le={face:null,faces:[],faceCount:0,detected:!1,justDetected:!1,justLost:!1,phase:"none"},_e=({faceIndex:e=0,numFaces:t,...r}={})=>{const n=Number.isFinite(e)?Math.max(0,Math.round(e)):0,s=I.useFaceInfos({...r,numFaces:Math.max(t??n+1,n+1)}),c=o.useRef([]),a=o.useRef(n),l=o.useRef({detected:!1,faceIndex:n}),[m,u]=o.useState(Le),i=o.useRef(m);return o.useEffect(()=>{c.current=s,a.current=n},[s,n]),y.useFrame(()=>{const d=c.current,p=a.current,f=d[p]??null,g=!!f,h=l.current.faceIndex===p&&l.current.detected,R=Fe(h,g);l.current={detected:g,faceIndex:p};const E={face:f,faces:d,faceCount:d.length,detected:g,justDetected:R==="begin",justLost:R==="end",phase:R},T=i.current;T.face===E.face&&T.faces===E.faces&&T.faceCount===E.faceCount&&T.detected===E.detected&&T.justDetected===E.justDetected&&T.justLost===E.justLost&&T.phase===E.phase||(i.current=E,u(E))}),m},be=["_neutral","browDownLeft","browDownRight","browInnerUp","browOuterUpLeft","browOuterUpRight","cheekPuff","cheekSquintLeft","cheekSquintRight","eyeBlinkLeft","eyeBlinkRight","eyeLookDownLeft","eyeLookDownRight","eyeLookInLeft","eyeLookInRight","eyeLookOutLeft","eyeLookOutRight","eyeLookUpLeft","eyeLookUpRight","eyeSquintLeft","eyeSquintRight","eyeWideLeft","eyeWideRight","jawForward","jawLeft","jawOpen","jawRight","mouthClose","mouthDimpleLeft","mouthDimpleRight","mouthFrownLeft","mouthFrownRight","mouthFunnel","mouthLeft","mouthLowerDownLeft","mouthLowerDownRight","mouthPressLeft","mouthPressRight","mouthPucker","mouthRight","mouthRollLower","mouthRollUpper","mouthShrugLower","mouthShrugUpper","mouthSmileLeft","mouthSmileRight","mouthStretchLeft","mouthStretchRight","mouthUpperUpLeft","mouthUpperUpRight","noseSneerLeft","noseSneerRight"],K=({source:e,face:t,canvas:r,outputSize:n,padding:s=.2})=>ce.drawNormalizedCrop({source:e,bounds:t.bounds,canvas:r,outputSize:n,padding:s}),De=["browRaise","eyeBlink","eyeBlinkLeft","eyeBlinkRight","eyeBlinkEither","headUp","headDown","headTurnLeft","headTurnRight","mouthOpen","mouthPout","headTiltLeft","headTiltRight"],L=(e=.5)=>({threshold:e,releaseThreshold:Math.max(0,e-.15),holdMs:50}),b={threshold:Math.PI/18,releaseThreshold:Math.PI/30,holdMs:80},Y={browRaise:L(.45),eyeBlink:L(.55),eyeBlinkLeft:L(.55),eyeBlinkRight:L(.55),eyeBlinkEither:L(.55),headUp:b,headDown:b,headTurnLeft:b,headTurnRight:b,mouthOpen:L(.45),mouthPout:L(.5),headTiltLeft:b,headTiltRight:b},D=e=>Math.max(0,e),x=(e,t)=>e!==void 0&&Number.isFinite(e)?e:t,V=(e,t={})=>{const r=Y[e],n=Math.max(0,x(t.threshold,r.threshold));return{threshold:n,releaseThreshold:Math.min(n,Math.max(0,x(t.releaseThreshold,r.releaseThreshold))),holdMs:Math.max(0,x(t.holdMs,r.holdMs))}},M=(e,t,{neutralRotation:r={x:0,y:0,z:0}}={})=>{const n=x(r.x,0),s=x(r.y,0),c=x(r.z,0);switch(t){case"browRaise":return Math.max(S.getFaceBlendshape(e,"browInnerUp"),S.getFaceBlendshape(e,"browOuterUpLeft"),S.getFaceBlendshape(e,"browOuterUpRight"));case"eyeBlink":return Math.min(S.getFaceBlendshape(e,"eyeBlinkLeft"),S.getFaceBlendshape(e,"eyeBlinkRight"));case"eyeBlinkLeft":return S.getFaceBlendshape(e,"eyeBlinkRight");case"eyeBlinkRight":return S.getFaceBlendshape(e,"eyeBlinkLeft");case"eyeBlinkEither":return Math.max(S.getFaceBlendshape(e,"eyeBlinkLeft"),S.getFaceBlendshape(e,"eyeBlinkRight"));case"mouthOpen":return S.getFaceBlendshape(e,"jawOpen");case"mouthPout":return S.getFaceBlendshape(e,"mouthPucker");case"headUp":return D(e.pose.rotation.x-n);case"headDown":return D(n-e.pose.rotation.x);case"headTurnLeft":return D(e.pose.rotation.y-s);case"headTurnRight":return D(s-e.pose.rotation.y);case"headTiltLeft":return D(e.pose.rotation.z-c);case"headTiltRight":return D(c-e.pose.rotation.z)}},we=(e,t,r={})=>M(e,t,r)>=V(t,r).threshold,xe=(e,t,r={})=>{let n=null,s=0;for(const c of e){const a=M(c,t,r);(!n||a>s)&&(n=c,s=a)}return{face:n,value:s}},X=e=>({action:e,active:!1,value:0,justStarted:!1,justEnded:!1,phase:"none",holdStartedAt:null}),Ne=(e,t,r,n,s)=>{const c=e.phase==="begin";if(e.value=t,e.justStarted=!1,e.justEnded=!1,e.phase=e.active?"stay":"none",!n)return e.holdStartedAt=null,e.active&&(e.active=!1,e.justEnded=!0,e.phase="end"),e;if(e.active){if(t<=s.releaseThreshold){if(c)return e;e.active=!1,e.justEnded=!0,e.phase="end"}return e}return t<s.threshold?(e.holdStartedAt=null,e):(e.holdStartedAt===null&&(e.holdStartedAt=r),r-e.holdStartedAt>=s.holdMs&&(e.active=!0,e.justStarted=!0,e.phase="begin",e.holdStartedAt=null),e)},q=e=>({action:e,active:!1,value:0,justStarted:!1,justEnded:!1,phase:"none"}),ke=(e,t,r={})=>{const n=o.useRef(X(t)),s=o.useRef(null),c=o.useRef(t),a=o.useRef({}),[l,m]=o.useState(()=>q(t)),u=o.useRef(l);return o.useEffect(()=>{s.current=e,a.current=r},[e,r]),o.useEffect(()=>{c.current=t,n.current=X(t);const i=q(t);u.current=i,m(i)},[t]),y.useFrame(({clock:i})=>{const d=s.current,p=c.current,f=a.current,g=d?M(d,p,f):0,h=Ne(n.current,g,i.elapsedTime*1e3,!!d,V(p,f)),R=u.current;if(R.action===h.action&&R.active===h.active&&R.value===h.value&&R.justStarted===h.justStarted&&R.justEnded===h.justEnded&&R.phase===h.phase)return;const E={action:h.action,active:h.active,value:h.value,justStarted:h.justStarted,justEnded:h.justEnded,phase:h.phase};u.current=E,m(E)}),l},Me=["angry","disgust","fear","happy","neutral","sad","surprise","unknown"],w=["angry","disgust","fear","happy","neutral","sad","surprise"],ve=(e,t=.55)=>{let r=-1/0;for(let u=0;u<w.length;u+=1)r=Math.max(r,Number(e[u])||0);const n=new Array(w.length);let s=0;for(let u=0;u<w.length;u+=1){const i=Math.exp((Number(e[u])||0)-r);n[u]=i,s+=i}const c=Object.fromEntries(w.map(u=>[u,0]));let a="unknown",l=0;for(let u=0;u<w.length;u+=1){const i=s?n[u]/s:0,d=w[u];c[d]=i,i>l&&(a=d,l=i)}const m=Number.isFinite(t)?Math.min(1,Math.max(0,t)):.55;return{expression:l>=m?a:"unknown",confidence:l,scores:c}},Be=e=>{const t=e.width*e.height,r=new Float32Array(t*3);for(let n=0,s=0;n<t;n+=1,s+=4)r[n]=e.data[s]/127.5-1,r[t+n]=e.data[s+1]/127.5-1,r[t*2+n]=e.data[s+2]/127.5-1;return r},W="https://huggingface.co/opencv/facial_expression_recognition/resolve/main/facial_expression_recognition_mobilefacenet_2022july_int8.onnx",Ce=e=>`https://cdn.jsdelivr.net/npm/onnxruntime-web@${e.env.versions.web}/dist/`,C=new Map,Oe=e=>{let t=C.get(e);return t||(t=Promise.all([import("onnxruntime-web/wasm"),_.fetchAndVerify(e)]).then(([r,n])=>(r.env.wasm.wasmPaths=Ce(r),r.InferenceSession.create(n,{executionProviders:["wasm"]}))).catch(r=>{throw C.delete(e),r}),C.set(e,t)),t},je=(e,{active:t=!0,targetFps:r=5,minConfidence:n=.55,modelUrl:s=W}={})=>{const{session:c}=_.useXRContext(),a=o.useRef(null),l=o.useRef(null),m=o.useRef(!1),u=o.useRef(-1/0),i=o.useRef(!0),[d,p]=o.useState({status:"idle",result:null,error:null});return o.useEffect(()=>{const f=document.createElement("canvas");return a.current=f,l.current=f.getContext("2d",{willReadFrequently:!0}),i.current=!0,()=>{i.current=!1,a.current=null,l.current=null}},[]),y.useFrame(({clock:f})=>{if(!t||!e||m.current||d.status==="error")return;const g=Number.isFinite(r)&&r>0?r:5,h=f.elapsedTime*1e3;if(h-u.current<1e3/g)return;const R=c.getInputFrame(),E=a.current,T=l.current;if(!R||!E||!T||!K({source:R,face:e,canvas:E,outputSize:{width:112,height:112}}))return;u.current=h,m.current=!0,d.status==="idle"&&p({status:"loading",result:null,error:null});const $=Be(T.getImageData(0,0,112,112));Promise.all([import("onnxruntime-web/wasm"),Oe(s)]).then(async([k,v])=>{const Z=await v.run({[v.inputNames[0]]:new k.Tensor("float32",$,[1,3,112,112])}),J=ve(Z[v.outputNames[0]].data,n);i.current&&p({status:"ready",result:J,error:null})}).catch(k=>{i.current&&p({status:"error",result:null,error:k instanceof Error?k:new Error(String(k))})}).finally(()=>{m.current=!1})}),d};exports.FACE_LANDMARK_INDICES=A.FACE_LANDMARK_INDICES;exports.FaceMesh=A.FaceMesh;exports.FaceTracker=A.FaceTracker;exports.BODY_TARGETS=N.BODY_TARGETS;exports.DEFAULT_TRACKING_ANCHOR=N.DEFAULT_TRACKING_ANCHOR;exports.FACE_TARGETS=N.FACE_TARGETS;exports.HAND_TARGETS=N.HAND_TARGETS;exports.TrackingAnchor=N.TrackingAnchor;exports.getTargetNamespace=N.getTargetNamespace;exports.useFaceResults=ue.useFaceResults;exports.useFaceInfo=I.useFaceInfo;exports.useFaceInfos=I.useFaceInfos;exports.DEFAULT_FACE_EXPRESSION_THRESHOLD=S.DEFAULT_FACE_EXPRESSION_THRESHOLD;exports.getFaceBlendshape=S.getFaceBlendshape;exports.getFaceEyeDistance=S.getFaceEyeDistance;exports.hasFaceExpression=S.hasFaceExpression;exports.BodyTracker=Re;exports.DEFAULT_FACE_ACTION_OPTIONS=Y;exports.DEFAULT_FACE_ATTRIBUTE_EXPRESSION_MODEL_URL=W;exports.FACE_ACTION_NAMES=De;exports.FACE_ATTRIBUTE_EXPRESSION_NAMES=Me;exports.FACE_BLENDSHAPE_NAMES=be;exports.GestureTracker=fe;exports.GestureTrigger=ye;exports.HandTracker=de;exports.SEGMENTATION_TYPES=O;exports.Segmentation=Ee;exports.drawFaceCrop=K;exports.getFaceActionValue=M;exports.getStrongestFaceAction=xe;exports.hasFaceAction=we;exports.useFaceAction=ke;exports.useFaceAttributeExpression=je;exports.useFaceDetection=_e;
1
+ "use strict";var Q=Object.create;var U=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var ne=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty;var oe=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of te(t))!re.call(e,o)&&o!==r&&U(e,o,{get:()=>t[o],enumerable:!(n=ee(t,o))||n.enumerable});return e};var z=(e,t,r)=>(r=e!=null?Q(ne(e)):{},oe(t||!e||!e.__esModule?U(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("./index-CyUUurQT.cjs"),L=require("react/jsx-runtime"),y=require("@react-three/fiber"),s=require("react"),se=require("three"),F=require("./index-DCiMbxC3.cjs"),j=require("./renderLayers-lDtL0_43.cjs"),w=require("./index-BpEf2BBb.cjs"),ue=require("./useFaceResults-wBJF3zyp.cjs"),I=require("./useFaceInfo-BJ8-_MOs.cjs"),S=require("./getFaceInfo-fA1bFBub.cjs"),ce=require("./drawNormalizedCrop-B-7zU-Xw.cjs");function ae(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const P=ae(se),ie={"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};function le(e,t,r=0){var o;const n=(o=e==null?void 0:e.hands)!=null&&o.length?e.hands:e!=null&&e.coordinates?[{coordinates:e.coordinates,gesture:e.gesture,handedness:e.handedness}]:[];if(n.length){if(t){const c=n.find(a=>a.handedness===t);if(c)return c}return n[r]??n[0]}}const de=({children:e,hand:t,handIndex:r=0,targetFps:n,active:o=!0})=>{const c=s.useRef(null),a=s.useMemo(()=>n===void 0?void 0:{targetFps:n},[n]),{ready:l,node:m}=A.useXRModel(F.XRModel.HAND_TRACKER,a,o),{camera:u}=y.useThree(),i=s.useRef(u);i.current!==u&&(i.current=u);const d=s.useRef(null);y.useFrame(()=>{var E;if(!l||!m||!c.current)return;const T=le(m,t,r);d.current=T??null;const h=(E=T==null?void 0:T.coordinates)==null?void 0:E[0];if(!h){c.current.visible=!1;return}const R=G(h,i.current);c.current.visible=!0,c.current.position.copy(R)});const p=s.useCallback(T=>{var E,g;const h=ie[T];if(h===void 0)return null;const R=(g=(E=d.current)==null?void 0:E.coordinates)==null?void 0:g[h];return R?{position:G(R,i.current)}:null},[]),f=s.useMemo(()=>({type:"hand",resolveLandmark:p}),[p]);return L.jsx(A.TrackerContext.Provider,{value:f,children:L.jsx("group",{ref:c,renderOrder:j.RENDER_LAYERS.TRACKED,children:e})})},G=(e,t)=>{const r=new P.Vector3(e.x,e.y,e.z);r.unproject(t);const n=r.sub(t.position).normalize(),o=-t.position.z/n.z;return t.position.clone().add(n.multiplyScalar(o))},he={"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},fe=({children:e,targetFps:t,active:r=!0})=>{const n=s.useRef(null),o=s.useMemo(()=>t===void 0?void 0:{targetFps:t},[t]),{ready:c,node:a}=A.useXRModel(F.XRModel.GESTURE_TRACKER,o,r),{camera:l}=y.useThree(),m=s.useRef(l);m.current!==l&&(m.current=l);const u=s.useRef(null);y.useFrame(()=>{var T;if(!c||!a||!n.current)return;u.current=a;const p=(T=a==null?void 0:a.coordinates)==null?void 0:T[0];if(!p){n.current.visible=!1;return}const f=H(p,m.current);n.current.visible=!0,n.current.position.copy(f)});const i=s.useCallback(p=>{var h,R;const f=he[p];if(f===void 0)return null;const T=(R=(h=u.current)==null?void 0:h.coordinates)==null?void 0:R[f];return T?{position:H(T,m.current)}:null},[]),d=s.useMemo(()=>({type:"hand",resolveLandmark:i}),[i]);return L.jsx(A.TrackerContext.Provider,{value:d,children:L.jsx("group",{ref:n,renderOrder:j.RENDER_LAYERS.TRACKED,children:e})})},H=(e,t)=>{const r=new P.Vector3(e.x,e.y,e.z);r.unproject(t);const n=r.sub(t.position).normalize(),o=-t.position.z/n.z;return t.position.clone().add(n.multiplyScalar(o))},pe={"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},Re=({bodyIndex:e=0,active:t=!0,children:r})=>{const n=s.useRef(null),{ready:o,node:c}=A.useXRModel(F.XRModel.BODY_TRACKER,void 0,t),{camera:a}=y.useThree(),l=s.useRef(a);l.current!==a&&(l.current=a);const m=s.useRef(null);y.useFrame(()=>{if(!o||!c||!n.current)return;const d=c;m.current=d;const p=d.getLandmarks2D(e),f=p==null?void 0:p[0];if(!f){n.current.visible=!1;return}const T=B(f,l.current);n.current.visible=!0,n.current.position.copy(T)});const u=s.useCallback(d=>{const p=m.current;if(!p)return null;const f=p.getLandmarks2D(e);if(!f)return null;if(d==="body.neck"){const R=f[11],E=f[12];if(!R||!E)return null;const g={x:(R.x+E.x)/2,y:(R.y+E.y)/2,z:(R.z+E.z)/2};return{position:B(g,l.current)}}const T=pe[d];if(T===void 0)return null;const h=f[T];return h?{position:B(h,l.current)}:null},[e]),i=s.useMemo(()=>({type:"body",resolveLandmark:u}),[u]);return L.jsx(A.TrackerContext.Provider,{value:i,children:L.jsx("group",{ref:n,renderOrder:j.RENDER_LAYERS.TRACKED,children:r})})},B=(e,t)=>{const r=new P.Vector3(e.x,e.y,e.z);r.unproject(t);const n=r.sub(t.position).normalize(),o=-t.position.z/n.z;return t.position.clone().add(n.multiplyScalar(o))},O=["portrait"],Ee=({type:e,active:t=!0,children:r})=>(A.useXRModel(F.XRModel.BACKGROUND_SEGMENTATION,{type:e},t),s.useEffect(()=>{O.includes(e)||console.warn(`[Segmentation] unsupported type "${e}"; valid values: ${O.join(", ")}`)},[e]),L.jsx(L.Fragment,{children:r})),me=800,Te=200,ge=()=>({armed:!1,armStart:null,holdStart:null,fired:!1}),Se=(e,{isTrigger:t,gesture:r,now:n,mode:o,debounceMs:c,holdMs:a})=>{if(e.fired)return null;if(o==="hold"){if(t&&r){if(e.holdStart===null&&(e.holdStart=n),n-e.holdStart>=a)return e.fired=!0,r}else e.holdStart=null;return null}return e.armed?t&&r?(e.fired=!0,r):null:(t?e.armStart=null:(e.armStart===null&&(e.armStart=n),n-e.armStart>=c&&(e.armed=!0)),null)};function Ae({gestures:e,mode:t="arm",debounceMs:r=me,holdMs:n=Te,onTrigger:o,enabled:c=!0}){const{ready:a,node:l}=A.useXRModel(F.XRModel.GESTURE_TRACKER),m=s.useRef(o);s.useEffect(()=>{m.current=o},[o]);const u=s.useRef(new Set);s.useEffect(()=>{u.current=new Set(Array.isArray(e)?e:[e])},[e]);const i=s.useRef(ge());y.useFrame(()=>{if(!c||!a||!l)return;const d=l.gesture,p=!!(d&&u.current.has(d)),f=Se(i.current,{isTrigger:p,gesture:d,now:performance.now(),mode:t,debounceMs:r,holdMs:n});f&&m.current(f)})}const ye=e=>(Ae(e),null),Fe=(e,t)=>t&&!e?"begin":!t&&e?"end":t?"stay":"none",Le={face:null,faces:[],faceCount:0,detected:!1,justDetected:!1,justLost:!1,phase:"none"},_e=({faceIndex:e=0,numFaces:t,...r}={})=>{const n=Number.isFinite(e)?Math.max(0,Math.round(e)):0,o=I.useFaceInfos({...r,numFaces:Math.max(t??n+1,n+1)}),c=s.useRef([]),a=s.useRef(n),l=s.useRef({detected:!1,faceIndex:n}),[m,u]=s.useState(Le),i=s.useRef(m);return s.useEffect(()=>{c.current=o,a.current=n},[o,n]),y.useFrame(()=>{const d=c.current,p=a.current,f=d[p]??null,T=!!f,h=l.current.faceIndex===p&&l.current.detected,R=Fe(h,T);l.current={detected:T,faceIndex:p};const E={face:f,faces:d,faceCount:d.length,detected:T,justDetected:R==="begin",justLost:R==="end",phase:R},g=i.current;g.face===E.face&&g.faces===E.faces&&g.faceCount===E.faceCount&&g.detected===E.detected&&g.justDetected===E.justDetected&&g.justLost===E.justLost&&g.phase===E.phase||(i.current=E,u(E))}),m},be=["_neutral","browDownLeft","browDownRight","browInnerUp","browOuterUpLeft","browOuterUpRight","cheekPuff","cheekSquintLeft","cheekSquintRight","eyeBlinkLeft","eyeBlinkRight","eyeLookDownLeft","eyeLookDownRight","eyeLookInLeft","eyeLookInRight","eyeLookOutLeft","eyeLookOutRight","eyeLookUpLeft","eyeLookUpRight","eyeSquintLeft","eyeSquintRight","eyeWideLeft","eyeWideRight","jawForward","jawLeft","jawOpen","jawRight","mouthClose","mouthDimpleLeft","mouthDimpleRight","mouthFrownLeft","mouthFrownRight","mouthFunnel","mouthLeft","mouthLowerDownLeft","mouthLowerDownRight","mouthPressLeft","mouthPressRight","mouthPucker","mouthRight","mouthRollLower","mouthRollUpper","mouthShrugLower","mouthShrugUpper","mouthSmileLeft","mouthSmileRight","mouthStretchLeft","mouthStretchRight","mouthUpperUpLeft","mouthUpperUpRight","noseSneerLeft","noseSneerRight"],K=({source:e,face:t,canvas:r,outputSize:n,padding:o=.2})=>ce.drawNormalizedCrop({source:e,bounds:t.bounds,canvas:r,outputSize:n,padding:o}),ke=["browRaise","eyeBlink","eyeBlinkLeft","eyeBlinkRight","eyeBlinkEither","headUp","headDown","headTurnLeft","headTurnRight","mouthOpen","mouthPout","headTiltLeft","headTiltRight"],_=(e=.5)=>({threshold:e,releaseThreshold:Math.max(0,e-.15),holdMs:50}),b={threshold:Math.PI/18,releaseThreshold:Math.PI/30,holdMs:80},Y={browRaise:_(.45),eyeBlink:_(.55),eyeBlinkLeft:_(.55),eyeBlinkRight:_(.55),eyeBlinkEither:_(.55),headUp:b,headDown:b,headTurnLeft:b,headTurnRight:b,mouthOpen:_(.45),mouthPout:_(.5),headTiltLeft:b,headTiltRight:b},k=e=>Math.max(0,e),N=(e,t)=>e!==void 0&&Number.isFinite(e)?e:t,V=(e,t={})=>{const r=Y[e],n=Math.max(0,N(t.threshold,r.threshold));return{threshold:n,releaseThreshold:Math.min(n,Math.max(0,N(t.releaseThreshold,r.releaseThreshold))),holdMs:Math.max(0,N(t.holdMs,r.holdMs))}},M=(e,t,{neutralRotation:r={x:0,y:0,z:0}}={})=>{const n=N(r.x,0),o=N(r.y,0),c=N(r.z,0);switch(t){case"browRaise":return Math.max(S.getFaceBlendshape(e,"browInnerUp"),S.getFaceBlendshape(e,"browOuterUpLeft"),S.getFaceBlendshape(e,"browOuterUpRight"));case"eyeBlink":return Math.min(S.getFaceBlendshape(e,"eyeBlinkLeft"),S.getFaceBlendshape(e,"eyeBlinkRight"));case"eyeBlinkLeft":return S.getFaceBlendshape(e,"eyeBlinkRight");case"eyeBlinkRight":return S.getFaceBlendshape(e,"eyeBlinkLeft");case"eyeBlinkEither":return Math.max(S.getFaceBlendshape(e,"eyeBlinkLeft"),S.getFaceBlendshape(e,"eyeBlinkRight"));case"mouthOpen":return S.getFaceBlendshape(e,"jawOpen");case"mouthPout":return S.getFaceBlendshape(e,"mouthPucker");case"headUp":return k(e.pose.rotation.x-n);case"headDown":return k(n-e.pose.rotation.x);case"headTurnLeft":return k(e.pose.rotation.y-o);case"headTurnRight":return k(o-e.pose.rotation.y);case"headTiltLeft":return k(e.pose.rotation.z-c);case"headTiltRight":return k(c-e.pose.rotation.z)}},De=(e,t,r={})=>M(e,t,r)>=V(t,r).threshold,Ne=(e,t,r={})=>{let n=null,o=0;for(const c of e){const a=M(c,t,r);(!n||a>o)&&(n=c,o=a)}return{face:n,value:o}},X=e=>({action:e,active:!1,value:0,justStarted:!1,justEnded:!1,phase:"none",holdStartedAt:null}),we=(e,t,r,n,o)=>{const c=e.phase==="begin";if(e.value=t,e.justStarted=!1,e.justEnded=!1,e.phase=e.active?"stay":"none",!n)return e.holdStartedAt=null,e.active&&(e.active=!1,e.justEnded=!0,e.phase="end"),e;if(e.active){if(t<=o.releaseThreshold){if(c)return e;e.active=!1,e.justEnded=!0,e.phase="end"}return e}return t<o.threshold?(e.holdStartedAt=null,e):(e.holdStartedAt===null&&(e.holdStartedAt=r),r-e.holdStartedAt>=o.holdMs&&(e.active=!0,e.justStarted=!0,e.phase="begin",e.holdStartedAt=null),e)},q=e=>({action:e,active:!1,value:0,justStarted:!1,justEnded:!1,phase:"none"}),xe=(e,t,r={})=>{const n=s.useRef(X(t)),o=s.useRef(null),c=s.useRef(t),a=s.useRef({}),[l,m]=s.useState(()=>q(t)),u=s.useRef(l);return s.useEffect(()=>{o.current=e,a.current=r},[e,r]),s.useEffect(()=>{c.current=t,n.current=X(t);const i=q(t);u.current=i,m(i)},[t]),y.useFrame(({clock:i})=>{const d=o.current,p=c.current,f=a.current,T=d?M(d,p,f):0,h=we(n.current,T,i.elapsedTime*1e3,!!d,V(p,f)),R=u.current;if(R.action===h.action&&R.active===h.active&&R.value===h.value&&R.justStarted===h.justStarted&&R.justEnded===h.justEnded&&R.phase===h.phase)return;const E={action:h.action,active:h.active,value:h.value,justStarted:h.justStarted,justEnded:h.justEnded,phase:h.phase};u.current=E,m(E)}),l},Me=["angry","disgust","fear","happy","neutral","sad","surprise","unknown"],D=["angry","disgust","fear","happy","neutral","sad","surprise"],ve=(e,t=.55)=>{let r=-1/0;for(let u=0;u<D.length;u+=1)r=Math.max(r,Number(e[u])||0);const n=new Array(D.length);let o=0;for(let u=0;u<D.length;u+=1){const i=Math.exp((Number(e[u])||0)-r);n[u]=i,o+=i}const c=Object.fromEntries(D.map(u=>[u,0]));let a="unknown",l=0;for(let u=0;u<D.length;u+=1){const i=o?n[u]/o:0,d=D[u];c[d]=i,i>l&&(a=d,l=i)}const m=Number.isFinite(t)?Math.min(1,Math.max(0,t)):.55;return{expression:l>=m?a:"unknown",confidence:l,scores:c}},Be=e=>{const t=e.width*e.height,r=new Float32Array(t*3);for(let n=0,o=0;n<t;n+=1,o+=4)r[n]=e.data[o]/127.5-1,r[t+n]=e.data[o+1]/127.5-1,r[t*2+n]=e.data[o+2]/127.5-1;return r},W="https://huggingface.co/opencv/facial_expression_recognition/resolve/main/facial_expression_recognition_mobilefacenet_2022july_int8.onnx",Ce=e=>`https://cdn.jsdelivr.net/npm/onnxruntime-web@${e.env.versions.web}/dist/`,C=new Map,Oe=e=>{let t=C.get(e);return t||(t=Promise.all([import("onnxruntime-web/wasm"),F.fetchAndVerify(e)]).then(([r,n])=>(r.env.wasm.wasmPaths=Ce(r),r.InferenceSession.create(n,{executionProviders:["wasm"]}))).catch(r=>{throw C.delete(e),r}),C.set(e,t)),t},je=(e,{active:t=!0,targetFps:r=5,minConfidence:n=.55,modelUrl:o=W}={})=>{const{session:c}=F.useXRContext(),a=s.useRef(null),l=s.useRef(null),m=s.useRef(!1),u=s.useRef(-1/0),i=s.useRef(!0),[d,p]=s.useState({status:"idle",result:null,error:null});return s.useEffect(()=>{const f=document.createElement("canvas");return a.current=f,l.current=f.getContext("2d",{willReadFrequently:!0}),i.current=!0,()=>{i.current=!1,a.current=null,l.current=null}},[]),y.useFrame(({clock:f})=>{if(!t||!e||m.current||d.status==="error")return;const T=Number.isFinite(r)&&r>0?r:5,h=f.elapsedTime*1e3;if(h-u.current<1e3/T)return;const R=c.getInputFrame(),E=a.current,g=l.current;if(!R||!E||!g||!K({source:R,face:e,canvas:E,outputSize:{width:112,height:112}}))return;u.current=h,m.current=!0,d.status==="idle"&&p({status:"loading",result:null,error:null});const $=Be(g.getImageData(0,0,112,112));Promise.all([import("onnxruntime-web/wasm"),Oe(o)]).then(async([x,v])=>{const Z=await v.run({[v.inputNames[0]]:new x.Tensor("float32",$,[1,3,112,112])}),J=ve(Z[v.outputNames[0]].data,n);i.current&&p({status:"ready",result:J,error:null})}).catch(x=>{i.current&&p({status:"error",result:null,error:x instanceof Error?x:new Error(String(x))})}).finally(()=>{m.current=!1})}),d};exports.FACE_LANDMARK_INDICES=A.FACE_LANDMARK_INDICES;exports.FaceMesh=A.FaceMesh;exports.FaceTracker=A.FaceTracker;exports.normalizedTrackerPointToTrackerPoint=F.normalizedTrackerPointToTrackerPoint;exports.trackerPointToNormalizedTrackerPoint=F.trackerPointToNormalizedTrackerPoint;exports.BODY_TARGETS=w.BODY_TARGETS;exports.DEFAULT_TRACKING_ANCHOR=w.DEFAULT_TRACKING_ANCHOR;exports.FACE_TARGETS=w.FACE_TARGETS;exports.HAND_TARGETS=w.HAND_TARGETS;exports.TrackingAnchor=w.TrackingAnchor;exports.getTargetNamespace=w.getTargetNamespace;exports.useFaceResults=ue.useFaceResults;exports.useFaceInfo=I.useFaceInfo;exports.useFaceInfos=I.useFaceInfos;exports.DEFAULT_FACE_EXPRESSION_THRESHOLD=S.DEFAULT_FACE_EXPRESSION_THRESHOLD;exports.getFaceBlendshape=S.getFaceBlendshape;exports.getFaceEyeDistance=S.getFaceEyeDistance;exports.hasFaceExpression=S.hasFaceExpression;exports.BodyTracker=Re;exports.DEFAULT_FACE_ACTION_OPTIONS=Y;exports.DEFAULT_FACE_ATTRIBUTE_EXPRESSION_MODEL_URL=W;exports.FACE_ACTION_NAMES=ke;exports.FACE_ATTRIBUTE_EXPRESSION_NAMES=Me;exports.FACE_BLENDSHAPE_NAMES=be;exports.GestureTracker=fe;exports.GestureTrigger=ye;exports.HandTracker=de;exports.SEGMENTATION_TYPES=O;exports.Segmentation=Ee;exports.drawFaceCrop=K;exports.getFaceActionValue=M;exports.getStrongestFaceAction=Ne;exports.hasFaceAction=De;exports.useFaceAction=xe;exports.useFaceAttributeExpression=je;exports.useFaceDetection=_e;
package/dist/tracking.js CHANGED
@@ -1,17 +1,18 @@
1
- import { u as N, T as O } from "./index-B-s4YbWu.js";
2
- import { d as Ve, c as We, b as qe } from "./index-B-s4YbWu.js";
1
+ import { u as N, T as O } from "./index-ByoNj0QP.js";
2
+ import { d as Ve, c as We, b as qe } from "./index-ByoNj0QP.js";
3
3
  import { jsx as A, Fragment as J } from "react/jsx-runtime";
4
4
  import { useThree as C, useFrame as b } from "@react-three/fiber";
5
- import { useRef as R, useMemo as _, useCallback as I, useEffect as L, useState as P } from "react";
5
+ import { useRef as R, useMemo as _, useCallback as P, useEffect as L, useState as I } from "react";
6
6
  import * as U from "three";
7
- import { X as F, u as Q, f as ee } from "./index-I4eF5TKT.js";
7
+ import { X as F, u as Q, f as ee } from "./index-9dlAQAhy.js";
8
+ import { n as $e, t as Ze } from "./index-9dlAQAhy.js";
8
9
  import { R as z } from "./renderLayers-zrK2pv5O.js";
9
- import { B as $e, D as Ze, F as Je, H as Qe, T as et, g as tt } from "./index-DYfY9ljy.js";
10
- import { u as rt } from "./useFaceResults-D62STzT1.js";
11
- import { u as te } from "./useFaceInfo-FVQBBNdY.js";
12
- import { a as st } from "./useFaceInfo-FVQBBNdY.js";
13
- import { a as S } from "./getFaceInfo-B43Cwq4n.js";
14
- import { D as it, b as ct, h as at } from "./getFaceInfo-B43Cwq4n.js";
10
+ import { B as Qe, D as et, F as tt, H as nt, T as rt, g as ot } from "./index-DyVF4vEW.js";
11
+ import { u as ut } from "./useFaceResults-CtetsO9M.js";
12
+ import { u as te } from "./useFaceInfo-Dk426LTu.js";
13
+ import { a as ct } from "./useFaceInfo-Dk426LTu.js";
14
+ import { a as T } from "./getFaceInfo-C4QpCQIY.js";
15
+ import { D as lt, b as dt, h as ht } from "./getFaceInfo-C4QpCQIY.js";
15
16
  import { d as ne } from "./drawNormalizedCrop-CRdIDyl1.js";
16
17
  const re = {
17
18
  "hand.wrist": 0,
@@ -72,7 +73,7 @@ const Ne = ({
72
73
  const p = K(d, c.current);
73
74
  u.current.visible = !0, u.current.position.copy(p);
74
75
  });
75
- const f = I((g) => {
76
+ const f = P((g) => {
76
77
  var m, E;
77
78
  const d = re[g];
78
79
  if (d === void 0) return null;
@@ -122,7 +123,7 @@ const Ne = ({
122
123
  const h = G(f, y.current);
123
124
  n.current.visible = !0, n.current.position.copy(h);
124
125
  });
125
- const c = I((f) => {
126
+ const c = P((f) => {
126
127
  var d, p;
127
128
  const h = se[f];
128
129
  if (h === void 0) return null;
@@ -172,7 +173,7 @@ const Ne = ({
172
173
  const g = B(h, a.current);
173
174
  n.current.visible = !0, n.current.position.copy(g);
174
175
  });
175
- const s = I(
176
+ const s = P(
176
177
  (l) => {
177
178
  const f = y.current;
178
179
  if (!f) return null;
@@ -278,7 +279,7 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
278
279
  const n = Number.isFinite(e) ? Math.max(0, Math.round(e)) : 0, o = te({
279
280
  ...r,
280
281
  numFaces: Math.max(t ?? n + 1, n + 1)
281
- }), u = R([]), i = R(n), a = R({ detected: !1, faceIndex: n }), [y, s] = P(fe), c = R(y);
282
+ }), u = R([]), i = R(n), a = R({ detected: !1, faceIndex: n }), [y, s] = I(fe), c = R(y);
282
283
  return L(() => {
283
284
  u.current = o, i.current = n;
284
285
  }, [o, n]), b(() => {
@@ -354,7 +355,7 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
354
355
  canvas: r,
355
356
  outputSize: n,
356
357
  padding: o = 0.2
357
- }) => ne({ source: e, bounds: t.bounds, canvas: r, outputSize: n, padding: o }), Ie = [
358
+ }) => ne({ source: e, bounds: t.bounds, canvas: r, outputSize: n, padding: o }), Pe = [
358
359
  "browRaise",
359
360
  "eyeBlink",
360
361
  "eyeBlinkLeft",
@@ -368,7 +369,7 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
368
369
  "mouthPout",
369
370
  "headTiltLeft",
370
371
  "headTiltRight"
371
- ], T = (e = 0.5) => ({
372
+ ], S = (e = 0.5) => ({
372
373
  threshold: e,
373
374
  releaseThreshold: Math.max(0, e - 0.15),
374
375
  holdMs: 50
@@ -377,56 +378,56 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
377
378
  releaseThreshold: Math.PI / 30,
378
379
  holdMs: 80
379
380
  }, me = {
380
- browRaise: T(0.45),
381
- eyeBlink: T(0.55),
382
- eyeBlinkLeft: T(0.55),
383
- eyeBlinkRight: T(0.55),
384
- eyeBlinkEither: T(0.55),
381
+ browRaise: S(0.45),
382
+ eyeBlink: S(0.55),
383
+ eyeBlinkLeft: S(0.55),
384
+ eyeBlinkRight: S(0.55),
385
+ eyeBlinkEither: S(0.55),
385
386
  headUp: w,
386
387
  headDown: w,
387
388
  headTurnLeft: w,
388
389
  headTurnRight: w,
389
- mouthOpen: T(0.45),
390
- mouthPout: T(0.5),
390
+ mouthOpen: S(0.45),
391
+ mouthPout: S(0.5),
391
392
  headTiltLeft: w,
392
393
  headTiltRight: w
393
- }, x = (e) => Math.max(0, e), k = (e, t) => e !== void 0 && Number.isFinite(e) ? e : t, q = (e, t = {}) => {
394
- const r = me[e], n = Math.max(0, k(t.threshold, r.threshold));
394
+ }, x = (e) => Math.max(0, e), v = (e, t) => e !== void 0 && Number.isFinite(e) ? e : t, q = (e, t = {}) => {
395
+ const r = me[e], n = Math.max(0, v(t.threshold, r.threshold));
395
396
  return {
396
397
  threshold: n,
397
398
  releaseThreshold: Math.min(
398
399
  n,
399
- Math.max(0, k(t.releaseThreshold, r.releaseThreshold))
400
+ Math.max(0, v(t.releaseThreshold, r.releaseThreshold))
400
401
  ),
401
- holdMs: Math.max(0, k(t.holdMs, r.holdMs))
402
+ holdMs: Math.max(0, v(t.holdMs, r.holdMs))
402
403
  };
403
404
  }, H = (e, t, { neutralRotation: r = { x: 0, y: 0, z: 0 } } = {}) => {
404
- const n = k(r.x, 0), o = k(r.y, 0), u = k(r.z, 0);
405
+ const n = v(r.x, 0), o = v(r.y, 0), u = v(r.z, 0);
405
406
  switch (t) {
406
407
  case "browRaise":
407
408
  return Math.max(
408
- S(e, "browInnerUp"),
409
- S(e, "browOuterUpLeft"),
410
- S(e, "browOuterUpRight")
409
+ T(e, "browInnerUp"),
410
+ T(e, "browOuterUpLeft"),
411
+ T(e, "browOuterUpRight")
411
412
  );
412
413
  case "eyeBlink":
413
414
  return Math.min(
414
- S(e, "eyeBlinkLeft"),
415
- S(e, "eyeBlinkRight")
415
+ T(e, "eyeBlinkLeft"),
416
+ T(e, "eyeBlinkRight")
416
417
  );
417
418
  case "eyeBlinkLeft":
418
- return S(e, "eyeBlinkRight");
419
+ return T(e, "eyeBlinkRight");
419
420
  case "eyeBlinkRight":
420
- return S(e, "eyeBlinkLeft");
421
+ return T(e, "eyeBlinkLeft");
421
422
  case "eyeBlinkEither":
422
423
  return Math.max(
423
- S(e, "eyeBlinkLeft"),
424
- S(e, "eyeBlinkRight")
424
+ T(e, "eyeBlinkLeft"),
425
+ T(e, "eyeBlinkRight")
425
426
  );
426
427
  case "mouthOpen":
427
- return S(e, "jawOpen");
428
+ return T(e, "jawOpen");
428
429
  case "mouthPout":
429
- return S(e, "mouthPucker");
430
+ return T(e, "mouthPucker");
430
431
  case "headUp":
431
432
  return x(e.pose.rotation.x - n);
432
433
  case "headDown":
@@ -440,7 +441,7 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
440
441
  case "headTiltRight":
441
442
  return x(u - e.pose.rotation.z);
442
443
  }
443
- }, Pe = (e, t, r = {}) => H(e, t, r) >= q(t, r).threshold, Ue = (e, t, r = {}) => {
444
+ }, Ie = (e, t, r = {}) => H(e, t, r) >= q(t, r).threshold, Ue = (e, t, r = {}) => {
444
445
  let n = null, o = 0;
445
446
  for (const u of e) {
446
447
  const i = H(u, t, r);
@@ -475,7 +476,7 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
475
476
  justEnded: !1,
476
477
  phase: "none"
477
478
  }), ze = (e, t, r = {}) => {
478
- const n = R(V(t)), o = R(null), u = R(t), i = R({}), [a, y] = P(() => W(t)), s = R(a);
479
+ const n = R(V(t)), o = R(null), u = R(t), i = R({}), [a, y] = I(() => W(t)), s = R(a);
479
480
  return L(() => {
480
481
  o.current = e, i.current = r;
481
482
  }, [e, r]), L(() => {
@@ -511,7 +512,7 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
511
512
  "sad",
512
513
  "surprise",
513
514
  "unknown"
514
- ], v = [
515
+ ], k = [
515
516
  "angry",
516
517
  "disgust",
517
518
  "fear",
@@ -521,18 +522,18 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
521
522
  "surprise"
522
523
  ], ye = (e, t = 0.55) => {
523
524
  let r = -1 / 0;
524
- for (let s = 0; s < v.length; s += 1)
525
+ for (let s = 0; s < k.length; s += 1)
525
526
  r = Math.max(r, Number(e[s]) || 0);
526
- const n = new Array(v.length);
527
+ const n = new Array(k.length);
527
528
  let o = 0;
528
- for (let s = 0; s < v.length; s += 1) {
529
+ for (let s = 0; s < k.length; s += 1) {
529
530
  const c = Math.exp((Number(e[s]) || 0) - r);
530
531
  n[s] = c, o += c;
531
532
  }
532
- const u = Object.fromEntries(v.map((s) => [s, 0]));
533
+ const u = Object.fromEntries(k.map((s) => [s, 0]));
533
534
  let i = "unknown", a = 0;
534
- for (let s = 0; s < v.length; s += 1) {
535
- const c = o ? n[s] / o : 0, l = v[s];
535
+ for (let s = 0; s < k.length; s += 1) {
536
+ const c = o ? n[s] / o : 0, l = k[s];
536
537
  u[l] = c, c > a && (i = l, a = c);
537
538
  }
538
539
  const y = Number.isFinite(t) ? Math.min(1, Math.max(0, t)) : 0.55;
@@ -542,9 +543,9 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
542
543
  for (let n = 0, o = 0; n < t; n += 1, o += 4)
543
544
  r[n] = e.data[o] / 127.5 - 1, r[t + n] = e.data[o + 1] / 127.5 - 1, r[t * 2 + n] = e.data[o + 2] / 127.5 - 1;
544
545
  return r;
545
- }, Ee = "https://huggingface.co/opencv/facial_expression_recognition/resolve/main/facial_expression_recognition_mobilefacenet_2022july_int8.onnx", Se = (e) => `https://cdn.jsdelivr.net/npm/onnxruntime-web@${e.env.versions.web}/dist/`, j = /* @__PURE__ */ new Map(), Te = (e) => {
546
+ }, Ee = "https://huggingface.co/opencv/facial_expression_recognition/resolve/main/facial_expression_recognition_mobilefacenet_2022july_int8.onnx", Te = (e) => `https://cdn.jsdelivr.net/npm/onnxruntime-web@${e.env.versions.web}/dist/`, j = /* @__PURE__ */ new Map(), Se = (e) => {
546
547
  let t = j.get(e);
547
- return t || (t = Promise.all([import("onnxruntime-web/wasm"), ee(e)]).then(([r, n]) => (r.env.wasm.wasmPaths = Se(r), r.InferenceSession.create(n, { executionProviders: ["wasm"] }))).catch((r) => {
548
+ return t || (t = Promise.all([import("onnxruntime-web/wasm"), ee(e)]).then(([r, n]) => (r.env.wasm.wasmPaths = Te(r), r.InferenceSession.create(n, { executionProviders: ["wasm"] }))).catch((r) => {
548
549
  throw j.delete(e), r;
549
550
  }), j.set(e, t)), t;
550
551
  }, Ke = (e, {
@@ -553,7 +554,7 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
553
554
  minConfidence: n = 0.55,
554
555
  modelUrl: o = Ee
555
556
  } = {}) => {
556
- const { session: u } = Q(), i = R(null), a = R(null), y = R(!1), s = R(-1 / 0), c = R(!0), [l, f] = P({
557
+ const { session: u } = Q(), i = R(null), a = R(null), y = R(!1), s = R(-1 / 0), c = R(!0), [l, f] = I({
557
558
  status: "idle",
558
559
  result: null,
559
560
  error: null
@@ -571,7 +572,7 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
571
572
  if (!p || !m || !E || !pe({ source: p, face: e, canvas: m, outputSize: { width: 112, height: 112 } })) return;
572
573
  s.current = d, y.current = !0, l.status === "idle" && f({ status: "loading", result: null, error: null });
573
574
  const Y = ge(E.getImageData(0, 0, 112, 112));
574
- Promise.all([import("onnxruntime-web/wasm"), Te(o)]).then(async ([D, M]) => {
575
+ Promise.all([import("onnxruntime-web/wasm"), Se(o)]).then(async ([D, M]) => {
575
576
  const $ = await M.run({
576
577
  [M.inputNames[0]]: new D.Tensor("float32", Y, [1, 3, 112, 112])
577
578
  }), Z = ye(
@@ -591,38 +592,40 @@ const je = (e) => (de(e), null), he = (e, t) => t && !e ? "begin" : !t && e ? "e
591
592
  }), l;
592
593
  };
593
594
  export {
594
- $e as BODY_TARGETS,
595
+ Qe as BODY_TARGETS,
595
596
  Me as BodyTracker,
596
597
  me as DEFAULT_FACE_ACTION_OPTIONS,
597
598
  Ee as DEFAULT_FACE_ATTRIBUTE_EXPRESSION_MODEL_URL,
598
- it as DEFAULT_FACE_EXPRESSION_THRESHOLD,
599
- Ze as DEFAULT_TRACKING_ANCHOR,
600
- Ie as FACE_ACTION_NAMES,
599
+ lt as DEFAULT_FACE_EXPRESSION_THRESHOLD,
600
+ et as DEFAULT_TRACKING_ANCHOR,
601
+ Pe as FACE_ACTION_NAMES,
601
602
  He as FACE_ATTRIBUTE_EXPRESSION_NAMES,
602
603
  Ce as FACE_BLENDSHAPE_NAMES,
603
604
  Ve as FACE_LANDMARK_INDICES,
604
- Je as FACE_TARGETS,
605
+ tt as FACE_TARGETS,
605
606
  We as FaceMesh,
606
607
  qe as FaceTracker,
607
608
  Fe as GestureTracker,
608
609
  je as GestureTrigger,
609
- Qe as HAND_TARGETS,
610
+ nt as HAND_TARGETS,
610
611
  Ne as HandTracker,
611
612
  X as SEGMENTATION_TYPES,
612
613
  Be as Segmentation,
613
- et as TrackingAnchor,
614
+ rt as TrackingAnchor,
614
615
  pe as drawFaceCrop,
615
616
  H as getFaceActionValue,
616
- S as getFaceBlendshape,
617
- ct as getFaceEyeDistance,
617
+ T as getFaceBlendshape,
618
+ dt as getFaceEyeDistance,
618
619
  Ue as getStrongestFaceAction,
619
- tt as getTargetNamespace,
620
- Pe as hasFaceAction,
621
- at as hasFaceExpression,
620
+ ot as getTargetNamespace,
621
+ Ie as hasFaceAction,
622
+ ht as hasFaceExpression,
623
+ $e as normalizedTrackerPointToTrackerPoint,
624
+ Ze as trackerPointToNormalizedTrackerPoint,
622
625
  ze as useFaceAction,
623
626
  Ke as useFaceAttributeExpression,
624
627
  Oe as useFaceDetection,
625
- st as useFaceInfo,
628
+ ct as useFaceInfo,
626
629
  te as useFaceInfos,
627
- rt as useFaceResults
630
+ ut as useFaceResults
628
631
  };
@@ -1,8 +1,18 @@
1
- export type Coordinate = {
1
+ /** MediaPipe tracker-input coordinates: normalized, top-left origin, Y down. */
2
+ export type NormalizedTrackerPoint = {
2
3
  x: number;
3
4
  y: number;
5
+ /** Tracker-relative depth. It is not a normalized screen axis. */
4
6
  z: number;
5
7
  };
8
+ /** SDK tracker coordinates: center origin, X right, Y up, Z toward the viewer. */
9
+ export type TrackerPoint = {
10
+ x: number;
11
+ y: number;
12
+ z: number;
13
+ };
14
+ /** @deprecated Use `TrackerPoint` to make the coordinate contract explicit. */
15
+ export type Coordinate = TrackerPoint;
6
16
  export type PerformanceData = {
7
17
  name: string;
8
18
  processingTime: number | null;
@@ -1,6 +1,6 @@
1
- import { Coordinate } from './common';
1
+ import { TrackerPoint } from './common';
2
2
  export type GestureData = {
3
- coordinates?: Coordinate[];
3
+ coordinates?: TrackerPoint[];
4
4
  gesture?: "closed_fist" | "open_palm" | "pointing_up" | "thumb_down" | "thumb_up" | "victory" | "i_love_you" | "none";
5
5
  };
6
6
  export declare enum Gestures {
@@ -1,13 +1,13 @@
1
- import { Coordinate } from './common';
1
+ import { TrackerPoint } from './common';
2
2
  export type Handedness = "left" | "right";
3
3
  export type HandData = {
4
- coordinates?: Coordinate[];
4
+ coordinates?: TrackerPoint[];
5
5
  gesture?: "closed_fist" | "open_palm";
6
6
  handedness?: Handedness;
7
7
  };
8
8
  export type HandTrackingData = {
9
9
  hands?: HandData[];
10
- coordinates?: Coordinate[];
10
+ coordinates?: TrackerPoint[];
11
11
  gesture?: HandData["gesture"];
12
12
  handedness?: Handedness;
13
13
  };
@@ -1,6 +1,6 @@
1
1
  import { FaceLandmarkerResult } from '@mediapipe/tasks-vision';
2
2
  import { Texture, Camera } from 'three';
3
- import { Coordinate } from './common';
3
+ import { TrackerPoint } from './common';
4
4
  import { Face, FaceRawTrackingData } from './face';
5
5
  import { GestureData } from './gesture-tracking';
6
6
  import { HandData } from './hand-tracking';
@@ -17,7 +17,7 @@ export type XRModelNodeSegmentation = {
17
17
  setInputSource: (source: CanvasImageSource | null | undefined) => void;
18
18
  };
19
19
  export type XRModelNodeBodyTracking = {
20
- getLandmarks2D: (bodyIndex?: number) => Coordinate[] | undefined;
20
+ getLandmarks2D: (bodyIndex?: number) => TrackerPoint[] | undefined;
21
21
  };
22
22
  export type XRModelNodeHandTracking = {
23
23
  hands?: HandData[];
@@ -95,9 +95,15 @@ export type XRSession = {
95
95
  * dataURL. Use from a gesture or state callback (e.g. on capture trigger)
96
96
  * to grab the visible frame as a photo. Returns the dataURL string.
97
97
  *
98
- * Throws `XRError` if called before `<XRScene>` has mounted.
98
+ * Throws `XRError` if no active `<XRScene>` or `<XRMediaSurface>` capture
99
+ * target has mounted.
99
100
  */
100
101
  captureFrame: () => string;
102
+ /**
103
+ * Captures the same active XRScene or XRMediaSurface composition as a
104
+ * MediaStream for use with `useMediaRecorder`.
105
+ */
106
+ captureStream: (fps?: number) => MediaStream;
101
107
  /** Current tracker-input frame. Read-only; reused and repainted by the session. */
102
108
  getInputFrame: () => OffscreenCanvas | HTMLCanvasElement | null;
103
109
  };
@@ -1 +1 @@
1
- "use strict";const R=require("@react-three/fiber"),m=require("react"),q=require("./index-C0-fg1Hk.cjs"),h=require("./getFaceInfo-DEzcL_Ub.cjs"),N=require("./index-CxMEeCRP.cjs"),x=({active:t=!0,holdMs:r=250,numFaces:o=1,targetFps:e,throttleMs:a=16}={})=>{const{camera:d}=R.useThree(),f=Number.isFinite(o)?Math.max(1,Math.round(o)):1,u=e!==void 0&&Number.isFinite(e)&&e>0?e:void 0,c=m.useMemo(()=>({numFaces:f,...u?{targetFps:u}:{}}),[f,u]),{node:n,ready:M}=N.useXRModel(q.XRModel.FACE_TRACKER,c,t);m.useEffect(()=>{if(n)for(let s=0;s<c.numFaces;s+=1)n.setCamera(d,s)},[c.numFaces,d,n]);const b=m.useCallback(s=>{if(!n)return[];const F=[];for(let i=0;i<s.faceLandmarks.length;i+=1){const l=h.getFaceInfoFromResults(n,s,i);l&&F.push(l)}return F},[n]);return h.useFaceResultReader({enabled:t&&M,holdMs:Number.isFinite(r)?Math.max(0,r):250,node:n,prepare:b,throttleMs:Number.isFinite(a)?Math.max(0,a):16})},I=({faceIndex:t=0,numFaces:r,...o}={})=>{const e=Number.isFinite(t)?Math.max(0,Math.round(t)):0;return x({...o,numFaces:Math.max(r??e+1,e+1)})[e]??null};exports.useFaceInfo=I;exports.useFaceInfos=x;
1
+ "use strict";const R=require("@react-three/fiber"),m=require("react"),q=require("./index-DCiMbxC3.cjs"),h=require("./getFaceInfo-fA1bFBub.cjs"),N=require("./index-CyUUurQT.cjs"),x=({active:t=!0,holdMs:r=250,numFaces:o=1,targetFps:e,throttleMs:a=16}={})=>{const{camera:d}=R.useThree(),f=Number.isFinite(o)?Math.max(1,Math.round(o)):1,u=e!==void 0&&Number.isFinite(e)&&e>0?e:void 0,c=m.useMemo(()=>({numFaces:f,...u?{targetFps:u}:{}}),[f,u]),{node:n,ready:M}=N.useXRModel(q.XRModel.FACE_TRACKER,c,t);m.useEffect(()=>{if(n)for(let s=0;s<c.numFaces;s+=1)n.setCamera(d,s)},[c.numFaces,d,n]);const b=m.useCallback(s=>{if(!n)return[];const F=[];for(let i=0;i<s.faceLandmarks.length;i+=1){const l=h.getFaceInfoFromResults(n,s,i);l&&F.push(l)}return F},[n]);return h.useFaceResultReader({enabled:t&&M,holdMs:Number.isFinite(r)?Math.max(0,r):250,node:n,prepare:b,throttleMs:Number.isFinite(a)?Math.max(0,a):16})},I=({faceIndex:t=0,numFaces:r,...o}={})=>{const e=Number.isFinite(t)?Math.max(0,Math.round(t)):0;return x({...o,numFaces:Math.max(r??e+1,e+1)})[e]??null};exports.useFaceInfo=I;exports.useFaceInfos=x;
@@ -1,8 +1,8 @@
1
1
  import { useThree as M } from "@react-three/fiber";
2
2
  import { useMemo as p, useEffect as x, useCallback as b } from "react";
3
- import { X as R } from "./index-I4eF5TKT.js";
4
- import { g as N, u as C } from "./getFaceInfo-B43Cwq4n.js";
5
- import { u as v } from "./index-B-s4YbWu.js";
3
+ import { X as R } from "./index-9dlAQAhy.js";
4
+ import { g as N, u as C } from "./getFaceInfo-C4QpCQIY.js";
5
+ import { u as v } from "./index-ByoNj0QP.js";
6
6
  const E = ({
7
7
  active: r = !0,
8
8
  holdMs: t = 250,
@@ -1,5 +1,5 @@
1
1
  import { useCallback as c } from "react";
2
- import { p as l, u as m } from "./getFaceInfo-B43Cwq4n.js";
2
+ import { p as l, u as m } from "./getFaceInfo-C4QpCQIY.js";
3
3
  const R = ({
4
4
  node: e,
5
5
  enabled: a,
@@ -1 +1 @@
1
- "use strict";const o=require("react"),e=require("./getFaceInfo-DEzcL_Ub.cjs"),R=({node:s,enabled:a,selectedSource:r,throttleMs:t=16,holdMs:c=250,onFrame:u})=>{const n=o.useCallback(l=>e.prepareCalibrationFaceResults(l.faceLandmarks??[]),[r]);return e.useFaceResultReader({enabled:a,holdMs:c,node:s,onFrame:u,prepare:n,throttleMs:t})};exports.useFaceResults=R;
1
+ "use strict";const o=require("react"),e=require("./getFaceInfo-fA1bFBub.cjs"),R=({node:s,enabled:a,selectedSource:r,throttleMs:t=16,holdMs:c=250,onFrame:u})=>{const n=o.useCallback(l=>e.prepareCalibrationFaceResults(l.faceLandmarks??[]),[r]);return e.useFaceResultReader({enabled:a,holdMs:c,node:s,onFrame:u,prepare:n,throttleMs:t})};exports.useFaceResults=R;
@@ -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: