@vincentt-xr/sdk 2.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GROUNDING.md +537 -0
- package/LICENSE +7 -0
- package/README.md +85 -0
- package/dist/DebuggerUI-CEfdddkZ.cjs +1 -0
- package/dist/DebuggerUI-Dgop6Q6o.js +269 -0
- package/dist/audio/AudioEngine.d.ts +98 -0
- package/dist/audio/index.d.ts +34 -0
- package/dist/components/AspectRatioContainer/index.d.ts +10 -0
- package/dist/components/BodyTracker/index.d.ts +15 -0
- package/dist/components/Debugger/DebuggerProvider.d.ts +22 -0
- package/dist/components/Debugger/DebuggerUI.d.ts +13 -0
- package/dist/components/Debugger/index.d.ts +38 -0
- package/dist/components/Debugger/styles.d.ts +19 -0
- package/dist/components/FaceMesh/FaceMesh.d.ts +26 -0
- package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +34 -0
- package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +16 -0
- package/dist/components/FaceMesh/canonical/useCanonicalFaceMesh.d.ts +15 -0
- package/dist/components/FaceMesh/deform.d.ts +36 -0
- package/dist/components/FaceMesh/index.d.ts +6 -0
- package/dist/components/FaceMesh/indices.d.ts +1 -0
- package/dist/components/FaceMesh/material/blendModes.d.ts +2 -0
- package/dist/components/FaceMesh/material/defaults.d.ts +3 -0
- package/dist/components/FaceMesh/material/index.d.ts +5 -0
- package/dist/components/FaceMesh/material/options.d.ts +25 -0
- package/dist/components/FaceMesh/material/support.d.ts +3 -0
- package/dist/components/FaceMesh/material/types.d.ts +23 -0
- package/dist/components/FaceMesh/uv.d.ts +1 -0
- package/dist/components/FaceRetouch/Background.d.ts +16 -0
- package/dist/components/FaceRetouch/index.d.ts +6 -0
- package/dist/components/FaceRetouch/landmarkMask.d.ts +23 -0
- package/dist/components/FaceRetouch/retouchRegions.d.ts +23 -0
- package/dist/components/FaceRetouch/useFaceRetouchMask.d.ts +14 -0
- package/dist/components/FaceRetouch/useFaceRetouchRegions.d.ts +12 -0
- package/dist/components/FaceTracker/BoundingBoxOverlay.d.ts +20 -0
- package/dist/components/FaceTracker/index.d.ts +54 -0
- package/dist/components/GestureTracker/index.d.ts +31 -0
- package/dist/components/GestureTrigger/index.d.ts +3 -0
- package/dist/components/HandTracker/index.d.ts +24 -0
- package/dist/components/HeadBinding/index.d.ts +31 -0
- package/dist/components/HeadBindingOccluder/index.d.ts +36 -0
- package/dist/components/HeadOccluder/index.d.ts +13 -0
- package/dist/components/Panel/index.d.ts +71 -0
- package/dist/components/PerspectiveCamera/index.d.ts +14 -0
- package/dist/components/ScreenSpaceUI/ScreenTransform.d.ts +54 -0
- package/dist/components/ScreenSpaceUI/context.d.ts +29 -0
- package/dist/components/ScreenSpaceUI/index.d.ts +40 -0
- package/dist/components/Segmentation/index.d.ts +44 -0
- package/dist/components/SpriteAnimation/index.d.ts +52 -0
- package/dist/components/TextLabel/index.d.ts +62 -0
- package/dist/components/TrackingAnchor/index.d.ts +74 -0
- package/dist/components/VideoBackground/index.d.ts +38 -0
- package/dist/components/XRCompositor/index.d.ts +5 -0
- package/dist/components/XRDebugView/index.d.ts +6 -0
- package/dist/components/XRLayer/index.d.ts +6 -0
- package/dist/components/XRMediaSurface/index.d.ts +27 -0
- package/dist/components/XRProvider/index.d.ts +13 -0
- package/dist/components/XRScene/defaults.d.ts +4 -0
- package/dist/components/XRScene/index.d.ts +15 -0
- package/dist/components/XRViewport/index.d.ts +101 -0
- package/dist/components/index.d.ts +26 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/constants/index.d.ts +25 -0
- package/dist/constants/renderLayers.d.ts +25 -0
- package/dist/entries/all.d.ts +15 -0
- package/dist/entries/core.d.ts +21 -0
- package/dist/entries/face-effects.d.ts +19 -0
- package/dist/entries/internal.d.ts +16 -0
- package/dist/entries/low-level.d.ts +30 -0
- package/dist/entries/tracking.d.ts +15 -0
- package/dist/face-effects.cjs +252 -0
- package/dist/face-effects.js +3542 -0
- package/dist/hasFullUnitUVBounds-BGvcFsQM.js +26 -0
- package/dist/hasFullUnitUVBounds-p1Dl0ejX.cjs +1 -0
- package/dist/hooks/faceResults.d.ts +39 -0
- package/dist/hooks/selectors.d.ts +33 -0
- package/dist/hooks/useCalibrationFaceTracker.d.ts +23 -0
- package/dist/hooks/useDebugger/index.d.ts +25 -0
- package/dist/hooks/useDebugger/types.d.ts +20 -0
- package/dist/hooks/useFaceBoundingBox.d.ts +11 -0
- package/dist/hooks/useFaceResults.d.ts +31 -0
- package/dist/hooks/useGestureEdge.d.ts +53 -0
- package/dist/hooks/useMediaRecorder.d.ts +40 -0
- package/dist/hooks/useTrackerContext.d.ts +35 -0
- package/dist/hooks/useXRModel.d.ts +15 -0
- package/dist/hooks/useXRSession/constants.d.ts +4 -0
- package/dist/hooks/useXRSession/facade.d.ts +39 -0
- package/dist/hooks/useXRSession/fns.d.ts +5 -0
- package/dist/hooks/useXRSession/index.d.ts +4 -0
- package/dist/hooks/useXRSession/registry.d.ts +52 -0
- package/dist/hooks/useXRSession/store.d.ts +40 -0
- package/dist/index-B5J4gzn2.cjs +1 -0
- package/dist/index-BD-JWMjE.js +1991 -0
- package/dist/index-BVBVg96G.cjs +1 -0
- package/dist/index-CYMj26Ej.js +1331 -0
- package/dist/index-DtwHElmG.js +157 -0
- package/dist/index-PtFmD6B8.cjs +1 -0
- package/dist/internal-DH5d1Xnq.cjs +1 -0
- package/dist/internal-KOKJDxCG.js +519 -0
- package/dist/internal.cjs +1 -0
- package/dist/internal.js +14 -0
- package/dist/low-level.cjs +1 -0
- package/dist/low-level.js +941 -0
- package/dist/main.cjs +1 -0
- package/dist/main.js +612 -0
- package/dist/models/Base/index.d.ts +25 -0
- package/dist/models/Body/index.d.ts +22 -0
- package/dist/models/Face/constants.d.ts +2 -0
- package/dist/models/Face/index.d.ts +45 -0
- package/dist/models/Face/landmarksData.d.ts +2 -0
- package/dist/models/Hand/GestureTracking.d.ts +21 -0
- package/dist/models/Hand/HandTracking.d.ts +21 -0
- package/dist/models/Segmentation/index.d.ts +75 -0
- package/dist/models/index.d.ts +5 -0
- package/dist/modules/XRClient/index.d.ts +9 -0
- package/dist/modules/index.d.ts +1 -0
- package/dist/selectors-BHO6TnoC.js +59 -0
- package/dist/selectors-Bub0o3qy.cjs +1 -0
- package/dist/services/ApiService.d.ts +12 -0
- package/dist/services/MetricsCollector/CameraFPSTracker.d.ts +25 -0
- package/dist/services/MetricsCollector/MemoryTracker.d.ts +43 -0
- package/dist/services/MetricsCollector/RenderTimeTracker.d.ts +10 -0
- package/dist/services/MetricsCollector/ResolutionTracker.d.ts +26 -0
- package/dist/services/MetricsCollector/index.d.ts +59 -0
- package/dist/services/MetricsCollector/types.d.ts +47 -0
- package/dist/services/MetricsCollector/utils.d.ts +65 -0
- package/dist/texture/computeContainScale.d.ts +25 -0
- package/dist/texture/hasFullUnitUVBounds.d.ts +37 -0
- package/dist/texture/types.d.ts +20 -0
- package/dist/tracking.cjs +1 -0
- package/dist/tracking.js +344 -0
- package/dist/types/body.d.ts +3 -0
- package/dist/types/client.d.ts +3 -0
- package/dist/types/common.d.ts +9 -0
- package/dist/types/compositor.d.ts +23 -0
- package/dist/types/debugger.d.ts +83 -0
- package/dist/types/face.d.ts +67 -0
- package/dist/types/gesture-tracking.d.ts +15 -0
- package/dist/types/hand-tracking.d.ts +5 -0
- package/dist/types/headBinding.d.ts +67 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/logger.d.ts +4 -0
- package/dist/types/model.d.ts +46 -0
- package/dist/types/nodes.d.ts +35 -0
- package/dist/types/segmentation.d.ts +31 -0
- package/dist/types/session.d.ts +102 -0
- package/dist/types/tracking.d.ts +30 -0
- package/dist/types/util-types.d.ts +1 -0
- package/dist/useFaceResults-cpsSmKKc.js +81 -0
- package/dist/useFaceResults-hVUJYSEY.cjs +1 -0
- package/dist/utils/calibrationDebug.d.ts +9 -0
- package/dist/utils/dataURL.d.ts +6 -0
- package/dist/utils/drawMediaCover.d.ts +18 -0
- package/dist/utils/errors.d.ts +3 -0
- package/dist/utils/fns.d.ts +48 -0
- package/dist/utils/headBinding.d.ts +85 -0
- package/dist/utils/integrity.d.ts +43 -0
- package/dist/utils/landmarkBounds.d.ts +11 -0
- package/dist/utils/logger.d.ts +7 -0
- package/package.json +113 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { jsx as e, jsxs as r, Fragment as f } from "react/jsx-runtime";
|
|
2
|
+
import { useState as P, useEffect as M } from "react";
|
|
3
|
+
import { createPortal as F } from "react-dom";
|
|
4
|
+
import { f as i } from "./internal-KOKJDxCG.js";
|
|
5
|
+
const z = {
|
|
6
|
+
position: "fixed",
|
|
7
|
+
top: "10px",
|
|
8
|
+
left: "10px",
|
|
9
|
+
zIndex: 9999,
|
|
10
|
+
fontFamily: "'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace",
|
|
11
|
+
fontSize: "12px",
|
|
12
|
+
color: "#fff",
|
|
13
|
+
pointerEvents: "auto",
|
|
14
|
+
userSelect: "none"
|
|
15
|
+
}, x = {
|
|
16
|
+
background: "rgba(0, 0, 0, 0.85)",
|
|
17
|
+
borderRadius: "6px",
|
|
18
|
+
padding: "12px 16px",
|
|
19
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.5)",
|
|
20
|
+
backdropFilter: "blur(10px)",
|
|
21
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
22
|
+
minWidth: "240px"
|
|
23
|
+
}, w = {
|
|
24
|
+
...x,
|
|
25
|
+
padding: "8px 12px",
|
|
26
|
+
minWidth: "auto"
|
|
27
|
+
}, R = {
|
|
28
|
+
display: "flex",
|
|
29
|
+
justifyContent: "space-between",
|
|
30
|
+
alignItems: "center",
|
|
31
|
+
marginBottom: "12px",
|
|
32
|
+
paddingBottom: "8px",
|
|
33
|
+
borderBottom: "1px solid rgba(255, 255, 255, 0.2)"
|
|
34
|
+
}, B = {
|
|
35
|
+
fontSize: "13px",
|
|
36
|
+
fontWeight: "bold",
|
|
37
|
+
color: "#00ff9f",
|
|
38
|
+
letterSpacing: "0.5px",
|
|
39
|
+
textTransform: "uppercase"
|
|
40
|
+
}, E = {
|
|
41
|
+
display: "flex",
|
|
42
|
+
gap: "6px"
|
|
43
|
+
}, h = {
|
|
44
|
+
background: "rgba(255, 255, 255, 0.1)",
|
|
45
|
+
border: "1px solid rgba(255, 255, 255, 0.2)",
|
|
46
|
+
borderRadius: "4px",
|
|
47
|
+
color: "#fff",
|
|
48
|
+
padding: "4px 8px",
|
|
49
|
+
fontSize: "11px",
|
|
50
|
+
cursor: "pointer",
|
|
51
|
+
transition: "all 0.2s"
|
|
52
|
+
}, D = {
|
|
53
|
+
display: "grid",
|
|
54
|
+
gridTemplateColumns: "1fr 1fr",
|
|
55
|
+
gap: "10px"
|
|
56
|
+
}, d = {
|
|
57
|
+
display: "flex",
|
|
58
|
+
flexDirection: "column",
|
|
59
|
+
gap: "4px"
|
|
60
|
+
}, l = {
|
|
61
|
+
fontSize: "10px",
|
|
62
|
+
color: "rgba(255, 255, 255, 0.6)",
|
|
63
|
+
textTransform: "uppercase",
|
|
64
|
+
letterSpacing: "0.5px"
|
|
65
|
+
}, s = {
|
|
66
|
+
fontSize: "16px",
|
|
67
|
+
fontWeight: "bold",
|
|
68
|
+
color: "#fff"
|
|
69
|
+
}, u = {
|
|
70
|
+
...s,
|
|
71
|
+
color: "#00ff9f"
|
|
72
|
+
}, m = {
|
|
73
|
+
...s,
|
|
74
|
+
color: "#ffaa00"
|
|
75
|
+
}, y = {
|
|
76
|
+
...s,
|
|
77
|
+
color: "#ff4444"
|
|
78
|
+
}, a = {
|
|
79
|
+
fontSize: "11px",
|
|
80
|
+
color: "rgba(255, 255, 255, 0.5)",
|
|
81
|
+
marginLeft: "4px"
|
|
82
|
+
}, I = {
|
|
83
|
+
width: "100%",
|
|
84
|
+
height: "4px",
|
|
85
|
+
background: "rgba(255, 255, 255, 0.2)",
|
|
86
|
+
borderRadius: "2px",
|
|
87
|
+
overflow: "hidden",
|
|
88
|
+
marginTop: "4px"
|
|
89
|
+
}, V = (t) => ({
|
|
90
|
+
width: `${t}%`,
|
|
91
|
+
height: "100%",
|
|
92
|
+
background: t > 90 ? "#ff4444" : t > 70 ? "#ffaa00" : "#00ff9f",
|
|
93
|
+
transition: "width 0.3s ease, background 0.3s ease"
|
|
94
|
+
}), W = {
|
|
95
|
+
fontSize: "9px",
|
|
96
|
+
color: "rgba(255, 255, 255, 0.4)",
|
|
97
|
+
marginTop: "8px",
|
|
98
|
+
textAlign: "center",
|
|
99
|
+
fontStyle: "italic"
|
|
100
|
+
};
|
|
101
|
+
function c(t, o) {
|
|
102
|
+
return o === "fps" ? t >= 30 ? u : t >= 20 ? m : y : t <= 40 ? u : t <= 60 ? m : y;
|
|
103
|
+
}
|
|
104
|
+
function G({
|
|
105
|
+
metrics: t,
|
|
106
|
+
collapsed: o,
|
|
107
|
+
onCollapse: b,
|
|
108
|
+
onClose: v,
|
|
109
|
+
position: p = "top-left",
|
|
110
|
+
keyboardShortcut: S = "ctrl+shift+d"
|
|
111
|
+
}) {
|
|
112
|
+
const [g, T] = P(null);
|
|
113
|
+
if (M(() => {
|
|
114
|
+
const n = document.createElement("div");
|
|
115
|
+
return n.id = "xr-debugger-overlay", document.body.appendChild(n), T(n), () => {
|
|
116
|
+
document.body.removeChild(n);
|
|
117
|
+
};
|
|
118
|
+
}, []), !g) return null;
|
|
119
|
+
const C = {
|
|
120
|
+
...z,
|
|
121
|
+
...p === "top-right" && { left: "auto", right: "10px" },
|
|
122
|
+
...p === "bottom-left" && { top: "auto", bottom: "10px" },
|
|
123
|
+
...p === "bottom-right" && {
|
|
124
|
+
top: "auto",
|
|
125
|
+
bottom: "10px",
|
|
126
|
+
left: "auto",
|
|
127
|
+
right: "10px"
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
return F(
|
|
131
|
+
/* @__PURE__ */ e("div", { style: C, children: /* @__PURE__ */ r("div", { style: o ? w : x, children: [
|
|
132
|
+
/* @__PURE__ */ r("div", { style: R, children: [
|
|
133
|
+
/* @__PURE__ */ e("div", { style: B, children: o ? "AR Debugger" : "AR Performance" }),
|
|
134
|
+
/* @__PURE__ */ r("div", { style: E, children: [
|
|
135
|
+
/* @__PURE__ */ e(
|
|
136
|
+
"button",
|
|
137
|
+
{
|
|
138
|
+
style: h,
|
|
139
|
+
onClick: () => b(!o),
|
|
140
|
+
onMouseEnter: (n) => {
|
|
141
|
+
n.currentTarget.style.background = "rgba(255, 255, 255, 0.2)";
|
|
142
|
+
},
|
|
143
|
+
onMouseLeave: (n) => {
|
|
144
|
+
n.currentTarget.style.background = "rgba(255, 255, 255, 0.1)";
|
|
145
|
+
},
|
|
146
|
+
children: o ? "+" : "−"
|
|
147
|
+
}
|
|
148
|
+
),
|
|
149
|
+
/* @__PURE__ */ e(
|
|
150
|
+
"button",
|
|
151
|
+
{
|
|
152
|
+
style: h,
|
|
153
|
+
onClick: v,
|
|
154
|
+
onMouseEnter: (n) => {
|
|
155
|
+
n.currentTarget.style.background = "rgba(255, 255, 255, 0.2)";
|
|
156
|
+
},
|
|
157
|
+
onMouseLeave: (n) => {
|
|
158
|
+
n.currentTarget.style.background = "rgba(255, 255, 255, 0.1)";
|
|
159
|
+
},
|
|
160
|
+
children: "✕"
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
] })
|
|
164
|
+
] }),
|
|
165
|
+
!o && /* @__PURE__ */ r(f, { children: [
|
|
166
|
+
/* @__PURE__ */ r("div", { style: D, children: [
|
|
167
|
+
/* @__PURE__ */ r("div", { style: d, children: [
|
|
168
|
+
/* @__PURE__ */ e("div", { style: l, children: "Camera FPS" }),
|
|
169
|
+
/* @__PURE__ */ r("div", { children: [
|
|
170
|
+
/* @__PURE__ */ e("span", { style: c(t.cameraFPS, "fps"), children: i(t.cameraFPS, 0) }),
|
|
171
|
+
/* @__PURE__ */ e("span", { style: a, children: "fps" })
|
|
172
|
+
] })
|
|
173
|
+
] }),
|
|
174
|
+
/* @__PURE__ */ r("div", { style: d, children: [
|
|
175
|
+
/* @__PURE__ */ e("div", { style: l, children: "Resolution" }),
|
|
176
|
+
/* @__PURE__ */ e("span", { style: s, children: t.resolution })
|
|
177
|
+
] }),
|
|
178
|
+
/* @__PURE__ */ r("div", { style: d, children: [
|
|
179
|
+
/* @__PURE__ */ e("div", { style: l, children: "Detection" }),
|
|
180
|
+
/* @__PURE__ */ r("div", { children: [
|
|
181
|
+
/* @__PURE__ */ e("span", { style: c(t.detectionTime, "time"), children: i(t.detectionTime, 1) }),
|
|
182
|
+
/* @__PURE__ */ e("span", { style: a, children: "ms" })
|
|
183
|
+
] })
|
|
184
|
+
] }),
|
|
185
|
+
/* @__PURE__ */ r("div", { style: d, children: [
|
|
186
|
+
/* @__PURE__ */ e("div", { style: l, children: "Rendering" }),
|
|
187
|
+
/* @__PURE__ */ r("div", { children: [
|
|
188
|
+
/* @__PURE__ */ e("span", { style: c(t.renderTime, "time"), children: i(t.renderTime, 1) }),
|
|
189
|
+
/* @__PURE__ */ e("span", { style: a, children: "ms" })
|
|
190
|
+
] })
|
|
191
|
+
] }),
|
|
192
|
+
/* @__PURE__ */ r("div", { style: d, children: [
|
|
193
|
+
/* @__PURE__ */ e("div", { style: l, children: "Effective FPS" }),
|
|
194
|
+
/* @__PURE__ */ r("div", { children: [
|
|
195
|
+
/* @__PURE__ */ e("span", { style: c(t.effectiveFPS, "fps"), children: i(t.effectiveFPS, 0) }),
|
|
196
|
+
/* @__PURE__ */ e("span", { style: a, children: "fps" })
|
|
197
|
+
] })
|
|
198
|
+
] }),
|
|
199
|
+
/* @__PURE__ */ r("div", { style: d, children: [
|
|
200
|
+
/* @__PURE__ */ e("div", { style: l, children: "Memory" }),
|
|
201
|
+
t.memory ? /* @__PURE__ */ r(f, { children: [
|
|
202
|
+
/* @__PURE__ */ r("div", { children: [
|
|
203
|
+
/* @__PURE__ */ e("span", { style: s, children: i(t.memory.used, 0) }),
|
|
204
|
+
/* @__PURE__ */ r("span", { style: a, children: [
|
|
205
|
+
"/ ",
|
|
206
|
+
i(t.memory.total, 0),
|
|
207
|
+
" MB"
|
|
208
|
+
] })
|
|
209
|
+
] }),
|
|
210
|
+
/* @__PURE__ */ e("div", { style: I, children: /* @__PURE__ */ e("div", { style: V(t.memory.percentage) }) })
|
|
211
|
+
] }) : /* @__PURE__ */ e("span", { style: s, children: "N/A" })
|
|
212
|
+
] })
|
|
213
|
+
] }),
|
|
214
|
+
t.modelPerformance.length > 0 && /* @__PURE__ */ e(f, { children: /* @__PURE__ */ r(
|
|
215
|
+
"div",
|
|
216
|
+
{
|
|
217
|
+
style: {
|
|
218
|
+
borderTop: "1px solid rgba(255, 255, 255, 0.15)",
|
|
219
|
+
marginTop: "12px",
|
|
220
|
+
paddingTop: "12px"
|
|
221
|
+
},
|
|
222
|
+
children: [
|
|
223
|
+
/* @__PURE__ */ e("div", { style: l, children: "Model Performance" }),
|
|
224
|
+
/* @__PURE__ */ e(
|
|
225
|
+
"div",
|
|
226
|
+
{
|
|
227
|
+
style: {
|
|
228
|
+
marginTop: "8px",
|
|
229
|
+
display: "flex",
|
|
230
|
+
flexDirection: "column",
|
|
231
|
+
gap: "6px"
|
|
232
|
+
},
|
|
233
|
+
children: t.modelPerformance.map((n, k) => /* @__PURE__ */ r(
|
|
234
|
+
"div",
|
|
235
|
+
{
|
|
236
|
+
style: {
|
|
237
|
+
display: "flex",
|
|
238
|
+
justifyContent: "space-between",
|
|
239
|
+
alignItems: "center",
|
|
240
|
+
fontSize: "11px"
|
|
241
|
+
},
|
|
242
|
+
children: [
|
|
243
|
+
/* @__PURE__ */ e("span", { style: { color: "rgba(255, 255, 255, 0.7)" }, children: n.name }),
|
|
244
|
+
/* @__PURE__ */ r("div", { children: [
|
|
245
|
+
/* @__PURE__ */ e("span", { style: c(n.processingTime, "time"), children: i(n.processingTime, 1) }),
|
|
246
|
+
/* @__PURE__ */ e("span", { style: a, children: "ms" })
|
|
247
|
+
] })
|
|
248
|
+
]
|
|
249
|
+
},
|
|
250
|
+
k
|
|
251
|
+
))
|
|
252
|
+
}
|
|
253
|
+
)
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
) }),
|
|
257
|
+
/* @__PURE__ */ r("div", { style: W, children: [
|
|
258
|
+
"Press ",
|
|
259
|
+
S.toUpperCase(),
|
|
260
|
+
" to toggle"
|
|
261
|
+
] })
|
|
262
|
+
] })
|
|
263
|
+
] }) }),
|
|
264
|
+
g
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
export {
|
|
268
|
+
G as DebuggerUI
|
|
269
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTMLAudioElement sound engine for AR filters. Three iOS traps this solves,
|
|
3
|
+
* all verified on-device (they recur in every AR app, so they belong here):
|
|
4
|
+
*
|
|
5
|
+
* 1. Gesture-started audio is BLOCKED. Audio kicked off from a camera-detected
|
|
6
|
+
* gesture (a peace sign to start) is not a user-input event, so iOS autoplay
|
|
7
|
+
* policy blocks it. The fix is IG/Snap-style: run muted by default (muted
|
|
8
|
+
* autoplay is allowed un-gestured) and let the tap that unmutes be the real
|
|
9
|
+
* gesture that unlocks the pipeline (prime each element with a muted
|
|
10
|
+
* play->pause on that tap).
|
|
11
|
+
* 2. Pure Web Audio is SILENCED by the hardware ring/silent switch. iOS routes
|
|
12
|
+
* Web Audio through the "ambient" session category, which the switch mutes;
|
|
13
|
+
* HTMLMediaElements use the switch-immune "playback" category. So this engine
|
|
14
|
+
* is built on <audio> elements, NOT Web Audio.
|
|
15
|
+
* 3. HTMLAudio's rewind seek janks a frame. `el.currentTime = 0` before replay
|
|
16
|
+
* is a synchronous media seek that hitches Safari; fired on every collision
|
|
17
|
+
* SFX it lagged the game. So pooled elements rewind on their `ended` event
|
|
18
|
+
* (off the hot path) and the play call does no synchronous seek on a ready
|
|
19
|
+
* element.
|
|
20
|
+
*
|
|
21
|
+
* Two audio paths, deliberately separate (this shape generalizes across apps):
|
|
22
|
+
* - BACKGROUND MUSIC: one long-running looping element. Plays/pauses on mute;
|
|
23
|
+
* never pooled, coalesced, or capped.
|
|
24
|
+
* - INTERACTION SFX: short one-shots via a per-sound voice pool (a concurrency
|
|
25
|
+
* cap bounds decode load on low-end phones) plus a per-URL coalesce window
|
|
26
|
+
* (the same sound fired twice in a frame plays once, so identical SFX don't
|
|
27
|
+
* stack to ~2x loudness; two DIFFERENT sounds at once both play).
|
|
28
|
+
*
|
|
29
|
+
* To keep unmute INSTANT (no fetch/decode stall on the tap), every element is
|
|
30
|
+
* created + `.load()`ed up front and the loading gate awaits `canplaythrough`
|
|
31
|
+
* (via `whenReady`); the unmute tap then just `.play()`s already-buffered,
|
|
32
|
+
* iOS-unlocked elements.
|
|
33
|
+
*/
|
|
34
|
+
export interface AudioEngineOptions {
|
|
35
|
+
/**
|
|
36
|
+
* Per-sound voice cap: the max simultaneous copies of ONE effect. A rapid
|
|
37
|
+
* burst beyond this reuses the oldest element rather than piling up decodes,
|
|
38
|
+
* bounding audio load on low-end phones. Default 4.
|
|
39
|
+
*/
|
|
40
|
+
sfxPoolSize?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Coalesce window (ms) for a rapid repeat of the SAME sound. Two objects
|
|
43
|
+
* caught in this window fire one play, not two stacked. Per-URL only, so a
|
|
44
|
+
* catch and a hit at the same instant are different sounds and both play.
|
|
45
|
+
* Default 50.
|
|
46
|
+
*/
|
|
47
|
+
coalesceMs?: number;
|
|
48
|
+
}
|
|
49
|
+
export declare class AudioEngine {
|
|
50
|
+
private readonly sfxPoolSize;
|
|
51
|
+
private readonly coalesceMs;
|
|
52
|
+
private muted;
|
|
53
|
+
private readonly listeners;
|
|
54
|
+
private music;
|
|
55
|
+
private musicWanted;
|
|
56
|
+
private readonly pools;
|
|
57
|
+
/** Last play time per SFX URL, for the coalesce window. */
|
|
58
|
+
private readonly lastPlayed;
|
|
59
|
+
/** Readiness promises so a loading gate can await decode/buffer. */
|
|
60
|
+
private readonly ready;
|
|
61
|
+
constructor(options?: AudioEngineOptions);
|
|
62
|
+
/**
|
|
63
|
+
* Create + buffer the looping music element. Await in the loading gate so the
|
|
64
|
+
* unmute tap is instant. Idempotent per URL (re-requesting the same track is
|
|
65
|
+
* a no-op that returns the in-flight promise).
|
|
66
|
+
*/
|
|
67
|
+
prefetchMusic(url: string, volume?: number): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Create + buffer an SFX voice pool (round-robin so overlapping plays don't
|
|
70
|
+
* cut each other off). Returns a promise that resolves when the first element
|
|
71
|
+
* buffers. Idempotent per URL.
|
|
72
|
+
*/
|
|
73
|
+
registerSound(url: string, volume?: number): Promise<void>;
|
|
74
|
+
/** Subscribe to mute-state changes (for a toggle UI). Fires immediately with
|
|
75
|
+
* the current state. Returns an unsubscribe. */
|
|
76
|
+
onMuteChange(fn: (muted: boolean) => void): () => void;
|
|
77
|
+
isMuted(): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Toggle sound. The first unmute is a real user gesture that unlocks every
|
|
80
|
+
* preloaded element (iOS gates media playback on a gesture): touch each SFX
|
|
81
|
+
* element with a muted play/pause so later `playOneShot` calls are allowed,
|
|
82
|
+
* then start the music. All elements are already buffered, so this is instant.
|
|
83
|
+
*/
|
|
84
|
+
setMuted(next: boolean): void;
|
|
85
|
+
toggleMuted(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Play a preloaded SFX; no-op while muted. Cycles the voice pool so
|
|
88
|
+
* overlapping plays don't cut each other off, coalesces a rapid repeat of the
|
|
89
|
+
* same sound into one play, and does NO synchronous `currentTime` seek on a
|
|
90
|
+
* ready element (the pool rewinds on `ended`, off the hot path).
|
|
91
|
+
*/
|
|
92
|
+
playOneShot(url: string, volume?: number): void;
|
|
93
|
+
/** Request the looping background track (buffer it with prefetchMusic, which
|
|
94
|
+
* a loading gate awaits). Remembered while muted; starts on unmute. */
|
|
95
|
+
startMusic(url: string, volume?: number): void;
|
|
96
|
+
stopMusic(): void;
|
|
97
|
+
private applyMusic;
|
|
98
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AudioEngine } from './AudioEngine';
|
|
2
|
+
export { AudioEngine } from './AudioEngine';
|
|
3
|
+
export type { AudioEngineOptions } from './AudioEngine';
|
|
4
|
+
/** The process-wide default engine the free functions target. */
|
|
5
|
+
export declare const audio: AudioEngine;
|
|
6
|
+
/** Create + buffer the looping music element. Await in the loading gate so the
|
|
7
|
+
* unmute tap is instant. Idempotent per URL. */
|
|
8
|
+
export declare const prefetchMusic: (url: string, volume?: number) => Promise<void>;
|
|
9
|
+
/** Create + buffer an SFX voice pool. Returns a promise that resolves when the
|
|
10
|
+
* first element buffers. Idempotent per URL. */
|
|
11
|
+
export declare const registerSound: (url: string, volume?: number) => Promise<void>;
|
|
12
|
+
/** Request the looping background track. Remembered while muted; starts on
|
|
13
|
+
* unmute. */
|
|
14
|
+
export declare const startMusic: (url: string, volume?: number) => void;
|
|
15
|
+
/** Stop + rewind the background track. */
|
|
16
|
+
export declare const stopMusic: () => void;
|
|
17
|
+
/** Play a preloaded SFX; no-op while muted. Pool-cycled, coalesced per URL,
|
|
18
|
+
* no synchronous seek on the hot path. */
|
|
19
|
+
export declare const playOneShot: (url: string, volume?: number) => void;
|
|
20
|
+
/** Set mute state. The first unmute must be a real user gesture — it unlocks
|
|
21
|
+
* every preloaded element for iOS and starts any wanted music. */
|
|
22
|
+
export declare const setMuted: (next: boolean) => void;
|
|
23
|
+
/** Toggle mute. Call from the tap handler of the sound toggle. */
|
|
24
|
+
export declare const toggleMuted: () => void;
|
|
25
|
+
export declare const isMuted: () => boolean;
|
|
26
|
+
/** Subscribe to mute-state changes; fires immediately with the current state.
|
|
27
|
+
* Returns an unsubscribe. Prefer `useMuted()` inside components. */
|
|
28
|
+
export declare const onMuteChange: (fn: (muted: boolean) => void) => (() => void);
|
|
29
|
+
/**
|
|
30
|
+
* React binding for the default engine's mute state — the toggle UI reads this
|
|
31
|
+
* and calls `toggleMuted()`. Subscribes on mount, unsubscribes on unmount, and
|
|
32
|
+
* seeds with the current state so the first render is correct.
|
|
33
|
+
*/
|
|
34
|
+
export declare const useMuted: () => boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Letterbox the app into a fixed 9:16 portrait frame, centered on a dark
|
|
4
|
+
* ground. On landscape or wider viewports it pillarboxes to keep the portrait
|
|
5
|
+
* ratio; on portrait it fills the width. Keeps the AR composition framed the
|
|
6
|
+
* same across phones and desktop.
|
|
7
|
+
*/
|
|
8
|
+
export declare const AspectRatioContainer: ({ children }: {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
type BodyTrackerProps = PropsWithChildren & {
|
|
3
|
+
bodyIndex?: number;
|
|
4
|
+
/**
|
|
5
|
+
* Whether this tracker should run. `false` pauses the shared model's
|
|
6
|
+
* per-frame inference (and its expensive GPU→CPU readback) while keeping it
|
|
7
|
+
* mounted and initialized, so gating it off-scene costs nothing yet flipping
|
|
8
|
+
* back to `true` resumes instantly — no unmount, no registry re-acquire race.
|
|
9
|
+
* When several trackers share the model, it runs while any is active.
|
|
10
|
+
* Defaults to `true`.
|
|
11
|
+
*/
|
|
12
|
+
active?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare const BodyTracker: ({ bodyIndex, active, children }: BodyTrackerProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { DebuggerContextValue } from '../../types/debugger';
|
|
3
|
+
export interface DebuggerProviderProps {
|
|
4
|
+
/** Child components */
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
/** Keyboard shortcut (default: "ctrl+shift+d") */
|
|
7
|
+
keyboardShortcut?: string;
|
|
8
|
+
/** Initial enabled state (default: false - hidden) */
|
|
9
|
+
initialEnabled?: boolean;
|
|
10
|
+
/** Position of the overlay (default: "top-left") */
|
|
11
|
+
position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Provider component that manages debugger state
|
|
15
|
+
* Wrap your app with this to enable debugger functionality
|
|
16
|
+
*/
|
|
17
|
+
export declare function DebuggerProvider({ children, keyboardShortcut, initialEnabled, position, }: DebuggerProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
/**
|
|
19
|
+
* Access the debugger context
|
|
20
|
+
* Must be used within a DebuggerProvider
|
|
21
|
+
*/
|
|
22
|
+
export declare function useDebuggerContext(): DebuggerContextValue;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DebuggerMetrics } from '../../types/debugger';
|
|
2
|
+
export interface DebuggerUIProps {
|
|
3
|
+
metrics: DebuggerMetrics;
|
|
4
|
+
collapsed: boolean;
|
|
5
|
+
onCollapse: (collapsed: boolean) => void;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
8
|
+
keyboardShortcut?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Debugger UI component
|
|
12
|
+
*/
|
|
13
|
+
export declare function DebuggerUI({ metrics, collapsed, onCollapse, onClose, position, keyboardShortcut, }: DebuggerUIProps): import('react').ReactPortal | null;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debugger Overlay
|
|
3
|
+
* Component for tracking render time inside the Canvas
|
|
4
|
+
* The DOM overlay is rendered by DebuggerProvider (outside Canvas)
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Debugger Overlay Component
|
|
8
|
+
*
|
|
9
|
+
* Place this component inside your XRScene to enable render time tracking.
|
|
10
|
+
* The debugger UI is rendered by DebuggerProvider (outside the Canvas).
|
|
11
|
+
* Toggle the debugger with Ctrl+Shift+D (or custom keyboard shortcut).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* import { XRProvider, XRScene, DebuggerProvider, DebuggerOverlay } from '@vincentt-xr/sdk';
|
|
16
|
+
*
|
|
17
|
+
* function App() {
|
|
18
|
+
* return (
|
|
19
|
+
* <XRProvider>
|
|
20
|
+
* <DebuggerProvider>
|
|
21
|
+
* <Content />
|
|
22
|
+
* </DebuggerProvider>
|
|
23
|
+
* </XRProvider>
|
|
24
|
+
* );
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* function Content() {
|
|
28
|
+
* return (
|
|
29
|
+
* <XRScene>
|
|
30
|
+
* <DebuggerOverlay />
|
|
31
|
+
* {/* Your AR content *\/}
|
|
32
|
+
* </XRScene>
|
|
33
|
+
* );
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function DebuggerOverlay(): import("react/jsx-runtime").JSX.Element | null;
|
|
38
|
+
export default DebuggerOverlay;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
export declare const overlayContainer: CSSProperties;
|
|
3
|
+
export declare const panel: CSSProperties;
|
|
4
|
+
export declare const panelCollapsed: CSSProperties;
|
|
5
|
+
export declare const header: CSSProperties;
|
|
6
|
+
export declare const title: CSSProperties;
|
|
7
|
+
export declare const buttonGroup: CSSProperties;
|
|
8
|
+
export declare const button: CSSProperties;
|
|
9
|
+
export declare const metricsGrid: CSSProperties;
|
|
10
|
+
export declare const metricItem: CSSProperties;
|
|
11
|
+
export declare const metricLabel: CSSProperties;
|
|
12
|
+
export declare const metricValue: CSSProperties;
|
|
13
|
+
export declare const metricValueGood: CSSProperties;
|
|
14
|
+
export declare const metricValueWarning: CSSProperties;
|
|
15
|
+
export declare const metricValueCritical: CSSProperties;
|
|
16
|
+
export declare const metricUnit: CSSProperties;
|
|
17
|
+
export declare const memoryBar: CSSProperties;
|
|
18
|
+
export declare const memoryBarFill: (percentage: number) => CSSProperties;
|
|
19
|
+
export declare const shortcutHint: CSSProperties;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
export declare const FACE_LANDMARK_Z_SCALE_FACTOR = 2;
|
|
4
|
+
type FaceMeshProps = PropsWithChildren & {
|
|
5
|
+
/**
|
|
6
|
+
* Imperative material instance. If set, takes precedence over any JSX
|
|
7
|
+
* material child. Leave unset and pass a `<meshStandardMaterial />` (or
|
|
8
|
+
* similar) as a child to customize the face mesh declaratively — this is
|
|
9
|
+
* how the in-editor preview iframe wires up material edits from the
|
|
10
|
+
* creator's scene tree.
|
|
11
|
+
*/
|
|
12
|
+
material?: THREE.Material;
|
|
13
|
+
faceIndex?: number;
|
|
14
|
+
numFaces?: number;
|
|
15
|
+
visible?: boolean;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Internal: deforming face mesh implementation. No longer a public
|
|
19
|
+
* export — consumers must use `<FaceTracker.Mesh>` instead, which
|
|
20
|
+
* delegates here.
|
|
21
|
+
*/
|
|
22
|
+
export declare const FaceMesh: {
|
|
23
|
+
({ material, faceIndex, numFaces, visible, children, }: FaceMeshProps): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
displayName: string;
|
|
25
|
+
};
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { FaceMeshAlphaMap, FaceMeshBlendMode, FaceMeshMaskTextureSource, FaceMeshMaterialType, FaceMeshShaderPreset, FaceMeshSide, FaceMeshTextureMap } from '../material/types';
|
|
2
|
+
import { ParsedCanonicalMesh } from './parseCanonicalFaceModel';
|
|
3
|
+
export type CanonicalFaceMeshRendererProps = {
|
|
4
|
+
faceIndex?: number;
|
|
5
|
+
color?: string;
|
|
6
|
+
opacity?: number;
|
|
7
|
+
materialType?: FaceMeshMaterialType;
|
|
8
|
+
shaderPreset?: FaceMeshShaderPreset;
|
|
9
|
+
textureMap?: FaceMeshTextureMap;
|
|
10
|
+
alphaMap?: FaceMeshAlphaMap;
|
|
11
|
+
alphaOpacity?: number;
|
|
12
|
+
side?: FaceMeshSide;
|
|
13
|
+
blendMode?: FaceMeshBlendMode;
|
|
14
|
+
showMouthMask?: boolean;
|
|
15
|
+
showEyeMask?: boolean;
|
|
16
|
+
showNoseMask?: boolean;
|
|
17
|
+
maskTextureSource?: FaceMeshMaskTextureSource;
|
|
18
|
+
maskColor?: string;
|
|
19
|
+
maskOpacity?: number;
|
|
20
|
+
faceTextureUrl?: string;
|
|
21
|
+
faceTextureStyle2Url?: string;
|
|
22
|
+
faceAlphaMaskUrl?: string;
|
|
23
|
+
compositeShading?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Pre-parsed canonical mesh. If omitted, the renderer lazily fetches
|
|
26
|
+
* the default OBJ from `libConfig.sdkAssetsBaseUrl` and parses it.
|
|
27
|
+
*/
|
|
28
|
+
mesh?: ParsedCanonicalMesh;
|
|
29
|
+
/**
|
|
30
|
+
* Override the canonical OBJ URL. Ignored if `mesh` is provided.
|
|
31
|
+
*/
|
|
32
|
+
meshUrl?: string;
|
|
33
|
+
};
|
|
34
|
+
export declare const CanonicalFaceMeshRenderer: ({ faceIndex, color, opacity, materialType, shaderPreset, textureMap, alphaMap, alphaOpacity, side, blendMode, showMouthMask, showEyeMask, showNoseMask, maskTextureSource, maskColor, maskOpacity, faceTextureUrl, faceTextureStyle2Url, faceAlphaMaskUrl, compositeShading, mesh, meshUrl, }: CanonicalFaceMeshRendererProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ParsedCanonicalMesh = {
|
|
2
|
+
baseIndices: Uint16Array;
|
|
3
|
+
mouthIndices: Uint16Array;
|
|
4
|
+
eyeIndices: Uint16Array;
|
|
5
|
+
noseIndices: Uint16Array;
|
|
6
|
+
uvs: Float32Array;
|
|
7
|
+
vertexCount: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Parse the MediaPipe canonical face OBJ into vertex/UV/index buffers
|
|
11
|
+
* grouped by anatomical region (base / mouth / eye / nose).
|
|
12
|
+
*
|
|
13
|
+
* Indices are emitted as Uint16Array — the canonical model has 468
|
|
14
|
+
* vertices and ~900 faces, well within range.
|
|
15
|
+
*/
|
|
16
|
+
export declare const parseCanonicalFaceModel: (source: string) => ParsedCanonicalMesh;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ParsedCanonicalMesh } from './parseCanonicalFaceModel';
|
|
2
|
+
/**
|
|
3
|
+
* Load and parse the MediaPipe canonical face model.
|
|
4
|
+
*
|
|
5
|
+
* By default this fetches `${libConfig.sdkAssetsBaseUrl}/canonical_face_model.obj`.
|
|
6
|
+
* Override `url` to point at a self-hosted copy. Pass a pre-parsed mesh
|
|
7
|
+
* via the `mesh` argument to skip the fetch entirely.
|
|
8
|
+
*
|
|
9
|
+
* The fetched OBJ is cached in-memory per URL — subsequent callers
|
|
10
|
+
* reuse the parsed buffers.
|
|
11
|
+
*/
|
|
12
|
+
export declare const useCanonicalFaceMesh: (options?: {
|
|
13
|
+
url?: string;
|
|
14
|
+
mesh?: ParsedCanonicalMesh;
|
|
15
|
+
}) => ParsedCanonicalMesh | null;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { NormalizedLandmark } from '@mediapipe/tasks-vision';
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
/** Minimal landmark shape the deform reads (x/y/z in normalized space). */
|
|
4
|
+
type LandmarkXYZ = {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
z: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Shared, allocation-free landmark deform for the face-mesh renderers.
|
|
11
|
+
*
|
|
12
|
+
* Both `FaceMesh` (single mesh, ray-to-z0 projection) and
|
|
13
|
+
* `CanonicalFaceMeshRenderer` (multi-submesh, depth-preserving projection)
|
|
14
|
+
* write MediaPipe landmarks straight into a position Float32Array each frame.
|
|
15
|
+
* The only real difference is the projection, so that is the one callback;
|
|
16
|
+
* the loop and buffer writes are shared here. The projector MUST write into
|
|
17
|
+
* the provided `out` vector and not allocate (called ~468× per frame).
|
|
18
|
+
*/
|
|
19
|
+
export type LandmarkProjector = (landmark: LandmarkXYZ, camera: THREE.Camera, out: THREE.Vector3) => THREE.Vector3;
|
|
20
|
+
/**
|
|
21
|
+
* Project to the z=0 plane (drops landmark depth). Used by the lightweight
|
|
22
|
+
* `FaceMesh`. Wraps the shared `unprojectToZZeroInto`, which reads only x/y/z.
|
|
23
|
+
*/
|
|
24
|
+
export declare const projectLandmarkToZPlane: LandmarkProjector;
|
|
25
|
+
/**
|
|
26
|
+
* Depth-preserving projection: unproject NDC with a clamped landmark z.
|
|
27
|
+
* Used by `CanonicalFaceMeshRenderer`. Allocation-free — writes into `out`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const projectLandmarkWithDepth: LandmarkProjector;
|
|
30
|
+
/**
|
|
31
|
+
* Write up to `count` projected landmark positions into `positions`
|
|
32
|
+
* (a 3-per-vertex Float32Array), reusing `work` for each projection. No
|
|
33
|
+
* per-landmark allocation. Returns the number of vertices written.
|
|
34
|
+
*/
|
|
35
|
+
export declare const writeLandmarkPositions: (landmarks: NormalizedLandmark[], count: number, positions: Float32Array, camera: THREE.Camera, project: LandmarkProjector, work: THREE.Vector3) => number;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { FaceMesh, FACE_LANDMARK_Z_SCALE_FACTOR } from './FaceMesh';
|
|
2
|
+
export { CanonicalFaceMeshRenderer } from './canonical/CanonicalFaceMeshRenderer';
|
|
3
|
+
export type { CanonicalFaceMeshRendererProps } from './canonical/CanonicalFaceMeshRenderer';
|
|
4
|
+
export { useCanonicalFaceMesh } from './canonical/useCanonicalFaceMesh';
|
|
5
|
+
export { parseCanonicalFaceModel, type ParsedCanonicalMesh, } from './canonical/parseCanonicalFaceModel';
|
|
6
|
+
export * from './material';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FACE_MESH_INDICES: number[];
|