three-mediapipe-rig 0.1.1 → 0.1.2

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 (38) hide show
  1. package/README.md +3 -1
  2. package/dist/face-tracker-utils-xt9__vBF.js +16 -0
  3. package/dist/meshcap/atlas-builder.d.ts +10 -0
  4. package/dist/meshcap/atlas-builder.d.ts.map +1 -0
  5. package/dist/meshcap/constants.d.ts +3 -0
  6. package/dist/meshcap/constants.d.ts.map +1 -0
  7. package/dist/meshcap/material.d.ts +53 -0
  8. package/dist/meshcap/material.d.ts.map +1 -0
  9. package/dist/meshcap/meshcap.d.ts +5 -0
  10. package/dist/meshcap/meshcap.d.ts.map +1 -0
  11. package/dist/meshcap/parse-mcap-file.d.ts +8 -0
  12. package/dist/meshcap/parse-mcap-file.d.ts.map +1 -0
  13. package/dist/meshcap/types.d.ts +53 -0
  14. package/dist/meshcap/types.d.ts.map +1 -0
  15. package/dist/meshcap/write-mcap-file.d.ts +3 -0
  16. package/dist/meshcap/write-mcap-file.d.ts.map +1 -0
  17. package/dist/meshcap.d.ts +2 -0
  18. package/dist/meshcap.js +316 -0
  19. package/dist/module.d.ts +1 -0
  20. package/dist/module.d.ts.map +1 -1
  21. package/dist/rigger.d.ts +2 -0
  22. package/dist/rigger.js +853 -0
  23. package/dist/tracking/BoneMapping.d.ts.map +1 -1
  24. package/dist/tracking/FaceTracker.d.ts +12 -2
  25. package/dist/tracking/FaceTracker.d.ts.map +1 -1
  26. package/dist/tracking/HandTracker.d.ts +3 -3
  27. package/dist/tracking/HandTracker.d.ts.map +1 -1
  28. package/dist/tracking/PoseTracker.d.ts +1 -1
  29. package/dist/tracking/PoseTracker.d.ts.map +1 -1
  30. package/dist/tracking/TrackerManager.d.ts +118 -0
  31. package/dist/tracking/TrackerManager.d.ts.map +1 -0
  32. package/dist/tracking/recoding/recorder.d.ts +10 -8
  33. package/dist/tracking/recoding/recorder.d.ts.map +1 -1
  34. package/dist/tracking/util/face-tracker-utils.d.ts +9 -0
  35. package/dist/tracking/util/face-tracker-utils.d.ts.map +1 -0
  36. package/package.json +17 -12
  37. package/dist/three-mediapipe-rig.js +0 -839
  38. package/dist/three-mediapipe-rig.js.map +0 -1
@@ -1,839 +0,0 @@
1
- var Re = Object.defineProperty;
2
- var Pe = (c, s, e) => s in c ? Re(c, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[s] = e;
3
- var P = (c, s, e) => Pe(c, typeof s != "symbol" ? s + "" : s, e);
4
- import { PoseLandmarker as fe, HandLandmarker as U, FaceLandmarker as G, FilesetResolver as ve, DrawingUtils as ge } from "@mediapipe/tasks-vision";
5
- import * as u from "three/webgpu";
6
- import { Vector3 as b, Quaternion as we, BufferAttribute as Ee, VideoTexture as We, SRGBColorSpace as Fe, MeshPhysicalNodeMaterial as Ae } from "three/webgpu";
7
- import * as T from "three";
8
- import { Bone as Se } from "three";
9
- import { uniform as _, attribute as Me, instancedArray as Ve, varying as Ne, vec3 as Oe, texture as Te, vec2 as _e } from "three/tsl";
10
- import { GLTFExporter as Ce } from "three/examples/jsm/Addons.js";
11
- const z = new b(), Y = new b(), De = new b(1, 0, 0), ze = new b(-1, 0, 0), Be = new b(0, 1, 0), Ie = new b(0, -1, 0), Z = new b(0, 0, 1);
12
- new b(0, 0, -1);
13
- const J = new b(), Ue = new b(), Ge = new b(), ee = new we(), B = new we();
14
- function M(c, s, e, t = "+x") {
15
- c.lookAt(s);
16
- const o = t == "+x" ? De : t == "-x" ? ze : t == "+y" ? Be : Ie;
17
- c.getWorldPosition(Y), c.getWorldQuaternion(B), z.subVectors(e, Y).normalize(), J.copy(o).applyQuaternion(B);
18
- const n = J, a = Ue.copy(Z).applyQuaternion(B), i = z.clone().addScaledVector(a, -z.dot(a)).normalize(), r = Ge.crossVectors(n, i), l = Math.atan2(r.dot(a), n.dot(i));
19
- ee.setFromAxisAngle(Z, l), c.quaternion.multiply(ee);
20
- }
21
- const C = new u.Vector3(), V = new u.Vector3(), I = new u.Vector3();
22
- new u.Vector3();
23
- class H {
24
- constructor(s, e) {
25
- P(this, "objectGhost");
26
- P(this, "root");
27
- /**
28
- * per landmark index, it points to it's object3D equivalent.
29
- */
30
- P(this, "marks", {});
31
- this.points = s, this.debugConnections = e, this.root = new u.Object3D(), this.objectGhost = /* @__PURE__ */ new Map();
32
- for (let t in this.points)
33
- this.marks[t] = new He(), this.root.add(this.marks[t]);
34
- }
35
- updateLandmarks(s, e, t) {
36
- for (let o in this.points) {
37
- const n = this.points[o], a = this.marks[o];
38
- a && (n instanceof Array ? (C.copy(s[n[0]]), a.position.copy(s[n[1]]).sub(C).divideScalar(2).add(s[n[0]]), n.length == 4 && (C.subVectors(
39
- s[n[3]],
40
- s[n[2]]
41
- ).divideScalar(2).add(s[n[2]]).sub(a.position).divideScalar(2), a.position.add(C))) : a.position.copy(s[n]));
42
- }
43
- t && e && t.drawConnectors(
44
- e,
45
- this.debugConnections,
46
- {
47
- lineWidth: 1
48
- }
49
- );
50
- }
51
- getGhost(s) {
52
- var e;
53
- if (!this.objectGhost.has(s)) {
54
- const t = new $e();
55
- t.position.copy(s.position), t.quaternion.copy(s.quaternion), (e = s.parent) == null || e.add(t), this.objectGhost.set(s, t);
56
- }
57
- return this.objectGhost.get(s);
58
- }
59
- predict(s, e) {
60
- throw new Error("Method 'predict' must be implemented.");
61
- }
62
- sync(s, e) {
63
- throw new Error("Method 'sync' must be implemented.");
64
- }
65
- test(s) {
66
- this.marks[s].position.set(1, 2, 3);
67
- }
68
- syncObjects(s, e, t) {
69
- for (const [o, n, a, i] of s) {
70
- this.marks[a].getWorldPosition(I), this.marks[n].getWorldPosition(V);
71
- const r = I.sub(V);
72
- o.getWorldPosition(V), V.add(r);
73
- const l = V, h = o.getWorldPosition(I).sub(t), f = this.getGhost(o);
74
- M(f, l, h, i), f.rotateX(Math.PI / 2), o.position.lerp(f.position, e * 4), o.quaternion.slerp(f.quaternion, e * 4);
75
- }
76
- }
77
- getBone(s, e) {
78
- return s.getObjectByName(e.replace(/[\.\:]/g, ""));
79
- }
80
- }
81
- class He extends u.Mesh {
82
- constructor() {
83
- super(new u.SphereGeometry(0.01, 3, 3), new u.MeshStandardMaterial({ color: 16711680, wireframe: !0 }));
84
- P(this, "_worldPosition", new u.Vector3());
85
- this.add(new u.AxesHelper(1e-3));
86
- }
87
- get worldPosition() {
88
- return this.getWorldPosition(this._worldPosition), this._worldPosition;
89
- }
90
- }
91
- class $e extends u.Object3D {
92
- lerp(s, e, t = 8) {
93
- s.position.lerp(this.position, e * t), s.quaternion.slerp(this.quaternion, e * t);
94
- }
95
- }
96
- function S(c, s, e) {
97
- return e.worldToLocal(s.getWorldPosition(c)), c;
98
- }
99
- function qe(c) {
100
- return c.replace(/[\.\:]/g, "");
101
- }
102
- function g(c, s) {
103
- let e;
104
- return s = qe(s), c.traverse((t) => {
105
- t.name.indexOf(s) === 0 && t instanceof Se && (e = t);
106
- }), e || console.log("Bone not found: ", s, c.name), e;
107
- }
108
- async function je(c, s) {
109
- const e = await fe.createFromOptions(c, {
110
- baseOptions: {
111
- modelAssetPath: (s == null ? void 0 : s.modelPath) ?? "pose_landmarker_lite.task",
112
- //modelAssetPath: `https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task`,
113
- //modelAssetPath: "https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_heavy/float16/latest/pose_landmarker_heavy.task",
114
- delegate: "GPU"
115
- },
116
- runningMode: "VIDEO",
117
- numPoses: 1
118
- });
119
- return new Je(e, s);
120
- }
121
- const Ke = {
122
- hips: [24, 23],
123
- neck: [12, 11],
124
- leftLeg: 23,
125
- leftKnee: 25,
126
- leftFoot: 27,
127
- leftToes: 31,
128
- leftArm: 11,
129
- leftElbow: 13,
130
- leftWrist: 15,
131
- rightLeg: 24,
132
- rightKnee: 26,
133
- rightFoot: 28,
134
- rightToes: 32,
135
- rightArm: 12,
136
- rightElbow: 14,
137
- rightWrist: 16,
138
- head: [8, 7],
139
- mouth: [10, 9],
140
- torso: [24, 23, 12, 11],
141
- leftEar: 7,
142
- rightEar: 8
143
- }, Xe = new u.Vector3(), te = new u.Vector3(), Qe = new u.Vector3(), Ye = new u.Vector3(), Ze = new u.Vector3(), oe = new u.Vector3(), se = new u.Vector3();
144
- class Je extends H {
145
- constructor(e, t) {
146
- super(Ke, fe.POSE_CONNECTIONS);
147
- P(this, "_leftWristNormalizedPosition");
148
- P(this, "_rightWristNormalizedPosition");
149
- this.poseLandmarker = e, this.config = t, this.root.scale.y *= -2, this.root.scale.z *= -2, this.root.scale.x *= 2;
150
- }
151
- /**
152
- * Position of the left wrist in normalized coordinates (0..1)
153
- */
154
- get leftWristNormalizedPosition() {
155
- return this._leftWristNormalizedPosition;
156
- }
157
- /**
158
- * Position of the right wrist in normalized coordinates (0..1)
159
- */
160
- get rightWristNormalizedPosition() {
161
- return this._rightWristNormalizedPosition;
162
- }
163
- predict(e, t) {
164
- this.poseLandmarker.detectForVideo(e, performance.now(), (o) => {
165
- var n;
166
- o.landmarks.length != 0 && (this.updateLandmarks(o.worldLandmarks[0], ((n = this.config) == null ? void 0 : n.drawLandmarks) === !1 ? void 0 : o.landmarks[0], t), this._leftWristNormalizedPosition = o.landmarks[0][this.points.leftWrist], this._rightWristNormalizedPosition = o.landmarks[0][this.points.rightWrist]);
167
- });
168
- }
169
- // override sync ( delta:number, objects: BoneBinding[] ) {
170
- // const hipsPos = this.marks.hips.getWorldPosition(C);
171
- // this.marks.rightArm.getWorldPosition(A).sub(hipsPos);
172
- // this.marks.leftArm.getWorldPosition(B).sub(hipsPos);
173
- // const torsoNormal = C.crossVectors(A,B);
174
- // this.syncObjects(objects, delta, torsoNormal);
175
- // }
176
- bind(e, t) {
177
- var r;
178
- const o = {
179
- hips: g(e, t.hips),
180
- neck: g(e, t.neck),
181
- leftArm: g(e, t.armL),
182
- leftElbow: g(e, t.forearmL),
183
- leftWrist: g(e, t.handL),
184
- rightArm: g(e, t.armR),
185
- rightElbow: g(e, t.forearmR),
186
- rightWrist: g(e, t.handR),
187
- head: g(e, t.head),
188
- torso: g(e, t.torso),
189
- leftLeg: g(e, t.thighL),
190
- leftKnee: g(e, t.shinL),
191
- leftFoot: g(e, t.footL),
192
- rightLeg: g(e, t.thighR),
193
- rightKnee: g(e, t.shinR),
194
- rightFoot: g(e, t.footR)
195
- };
196
- (r = this.config) != null && r.ignoreLegs && (delete o.leftLeg, delete o.leftKnee, delete o.leftFoot, delete o.leftToes, delete o.rightLeg, delete o.rightKnee, delete o.rightFoot, delete o.rightToes);
197
- const n = new u.Vector3(), a = new u.Vector3(), i = (l, h, f, x, d, m) => {
198
- if (!h) return;
199
- const y = this.marks[x].getWorldPosition(n).sub(this.marks[f].getWorldPosition(a)).normalize();
200
- S(oe, h, e).add(y).applyMatrix4(e.matrixWorld), S(se, h, e).add(d).applyMatrix4(e.matrixWorld);
201
- const p = this.getGhost(h);
202
- M(p, oe, se, m), p.rotateX(Math.PI / 2), p.lerp(h, l);
203
- };
204
- return {
205
- update: (l) => {
206
- const h = this.marks.leftLeg.getWorldPosition(Xe).sub(this.marks.rightLeg.getWorldPosition(te)).normalize(), f = this.marks.leftArm.getWorldPosition(te).sub(this.marks.rightArm.getWorldPosition(Qe)).normalize(), x = this.marks.leftEar.getWorldPosition(Ye).sub(this.marks.rightEar.getWorldPosition(Ze)).normalize();
207
- i(l, o.hips, "hips", "torso", h, "+x"), i(l, o.torso, "torso", "neck", f, "+x"), i(l, o.neck, "neck", "head", x, "+x"), i(l, o.head, "neck", "head", x, "+x"), i(l, o.leftArm, "leftArm", "leftElbow", f, "-x"), i(l, o.leftElbow, "leftElbow", "leftWrist", f, "-x"), i(l, o.leftLeg, "leftLeg", "leftKnee", h, "+x"), i(l, o.leftKnee, "leftKnee", "leftFoot", h, "+x"), i(l, o.leftFoot, "leftFoot", "leftToes", h, "+x"), i(l, o.rightArm, "rightArm", "rightElbow", f, "-x"), i(l, o.rightElbow, "rightElbow", "rightWrist", f, "-x"), i(l, o.rightLeg, "rightLeg", "rightKnee", h, "+x"), i(l, o.rightKnee, "rightKnee", "rightFoot", h, "+x"), i(l, o.rightFoot, "rightFoot", "rightToes", h, "+x");
208
- }
209
- };
210
- }
211
- }
212
- const ne = new u.Vector2(), ie = new u.Vector2();
213
- async function et(c, s) {
214
- const e = await U.createFromOptions(c, {
215
- baseOptions: {
216
- modelAssetPath: s.modelPath ?? "hand_landmarker.task",
217
- //modelAssetPath: `https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task`,
218
- delegate: "GPU"
219
- },
220
- runningMode: "VIDEO",
221
- numHands: 2
222
- }), t = (o, n, a) => {
223
- try {
224
- ne.copy(o()), ie.copy(n());
225
- } catch (i) {
226
- return console.warn("No pose data... will just be optimitic and say yes to everything.", i), !0;
227
- }
228
- return ne.distanceTo(a) < ie.distanceTo(a);
229
- };
230
- return {
231
- left: new me(e, "Left", t.bind(null, s.leftWrist, s.rightWrist), s.drawLandmarks),
232
- right: new me(e, "Right", t.bind(null, s.rightWrist, s.leftWrist), s.drawLandmarks)
233
- };
234
- }
235
- const tt = {
236
- wrist: 0,
237
- palm: [9, 13],
238
- thumb1: 1,
239
- thumb2: 2,
240
- thumb3: 3,
241
- thumb4: 4,
242
- index1: 5,
243
- index2: 6,
244
- index3: 7,
245
- index4: 8,
246
- middle1: 9,
247
- middle2: 10,
248
- middle3: 11,
249
- middle4: 12,
250
- ring1: 13,
251
- ring2: 14,
252
- ring3: 15,
253
- ring4: 16,
254
- pinky1: 17,
255
- pinky2: 18,
256
- pinky3: 19,
257
- pinky4: 20
258
- }, N = {
259
- thumb: ["thumb1", "thumb2", "thumb3", "thumb4"],
260
- index: ["index1", "index2", "index3", "index4"],
261
- middle: ["middle1", "middle2", "middle3", "middle4"],
262
- ring: ["ring1", "ring2", "ring3", "ring4"],
263
- pinky: ["pinky1", "pinky2", "pinky3", "pinky4"]
264
- }, ot = new u.Vector3(), re = new u.Vector3(), ae = new u.Vector3(), de = new u.Vector3(), ce = new u.Vector3(), le = new u.Vector3();
265
- new u.Vector3();
266
- new u.Vector3();
267
- new u.Vector3();
268
- const he = new u.Vector3(), pe = Math.PI / 2, st = new u.Vector3(0, -1, 0);
269
- class me extends H {
270
- constructor(e, t, o, n = !0) {
271
- super(tt, U.HAND_CONNECTIONS);
272
- P(this, "sign");
273
- P(this, "isLeft");
274
- /**
275
- * the axis used to look at the pole
276
- */
277
- P(this, "lookAtPoleAxis");
278
- this.handLandmarker = e, this.side = t, this.isMyWrist = o, this.drawLandmarks = n, this.sign = this.side == "Left" ? -1 : 1, this.isLeft = this.side == "Left", this.lookAtPoleAxis = this.sign < 0 ? "+x" : "-x", this.root.scale.setScalar(7), this.root.scale.y *= -1, this.root.scale.z *= -1;
279
- }
280
- predict(e, t) {
281
- const o = this.handLandmarker.detectForVideo(e, performance.now());
282
- if (o.landmarks.length)
283
- for (let n = 0; n < o.landmarks.length; n++) {
284
- const a = o.landmarks[n], i = a[this.points.wrist];
285
- if (this.isMyWrist(i)) {
286
- this.updateLandmarks(o.worldLandmarks[n]), this.drawLandmarks && (t.drawConnectors(a, U.HAND_CONNECTIONS, {
287
- color: this.side == "Left" ? "#00FF00" : "#0000FF",
288
- lineWidth: 4
289
- }), t.drawLandmarks(a, { color: this.side == "Left" ? "#00FF00" : "#0000FF", lineWidth: 3, radius: 1 }));
290
- break;
291
- }
292
- }
293
- }
294
- sync(e, t) {
295
- throw new Error("Not used. Use syncHandBones instead");
296
- }
297
- /**
298
- *
299
- * @param delta time since last frame
300
- * @param landmark2bones Array the same size as the umber of hand landmarks, and on each positionthe bone that belongs to that point.
301
- * @see https://ai.google.dev/edge/mediapipe/solutions/vision/hand_landmarker
302
- */
303
- syncHandBones(e, t, o) {
304
- const n = ot.crossVectors(
305
- re.copy(this.marks.index1.worldPosition).sub(this.marks.wrist.worldPosition),
306
- ae.copy(this.marks.pinky1.worldPosition).sub(this.marks.wrist.worldPosition)
307
- ).normalize(), a = re.copy(this.marks.palm.worldPosition).sub(this.marks.wrist.worldPosition).normalize(), i = ae.copy(this.marks.pinky1.worldPosition).sub(this.marks.index1.worldPosition).normalize();
308
- if (!(a.dot(st) > 0.8)) {
309
- if (t.wrist) {
310
- const r = S(de, t.wrist, o).add(a).applyMatrix4(o.matrixWorld), l = S(ce, t.wrist, o).sub(i).applyMatrix4(o.matrixWorld), h = this.getGhost(t.wrist);
311
- M(h, r, l, "-y"), h.rotateX(pe), h.lerp(t.wrist, e);
312
- }
313
- this.syncFinger(e, o, n, a, i, t, N.index, "middle1"), this.syncFinger(e, o, n, a, i, t, N.middle, "ring1"), this.syncFinger(e, o, n, a, i, t, N.ring, "pinky1"), this.syncFinger(e, o, n, a, i, t, N.pinky, "ring1", !0), this.syncFinger(e, o, n, a, i, t, N.thumb, "index1");
314
- }
315
- }
316
- syncFinger(e, t, o, n, a, i, r, l, h = !1) {
317
- for (let f = 0; f < r.length - 1; f++) {
318
- const x = i[r[f]];
319
- if (!x) continue;
320
- const d = this.getGhost(x), m = de.copy(this.marks[r[f + 1]].worldPosition).sub(this.marks[r[f]].worldPosition).normalize(), y = S(ce, x, t);
321
- if (f == 0) {
322
- const p = le.copy(this.marks[l].worldPosition).sub(this.marks[r[0]].worldPosition).normalize();
323
- h && p.negate(), he.copy(p), M(
324
- d,
325
- m.add(y).applyMatrix4(t.matrixWorld),
326
- p.add(y).applyMatrix4(t.matrixWorld),
327
- this.lookAtPoleAxis
328
- );
329
- } else
330
- M(
331
- d,
332
- m.add(y).applyMatrix4(t.matrixWorld),
333
- le.copy(he).add(y).applyMatrix4(t.matrixWorld),
334
- this.lookAtPoleAxis
335
- );
336
- d.rotateX(pe), d.lerp(x, e);
337
- }
338
- }
339
- bind(e, t) {
340
- const o = {}, n = (a, i) => {
341
- const r = g(e, a);
342
- if (r)
343
- return o[i] = r, i;
344
- };
345
- return n(this.isLeft ? t.handL : t.handR, "wrist"), n(this.isLeft ? t.index1L : t.index1R, "index1"), n(this.isLeft ? t.index2L : t.index2R, "index2"), n(this.isLeft ? t.index3L : t.index3R, "index3"), n(this.isLeft ? t.middle1L : t.middle1R, "middle1"), n(this.isLeft ? t.middle2L : t.middle2R, "middle2"), n(this.isLeft ? t.middle3L : t.middle3R, "middle3"), n(this.isLeft ? t.ring1L : t.ring1R, "ring1"), n(this.isLeft ? t.ring2L : t.ring2R, "ring2"), n(this.isLeft ? t.ring3L : t.ring3R, "ring3"), n(this.isLeft ? t.pinky1L : t.pinky1R, "pinky1"), n(this.isLeft ? t.pinky2L : t.pinky2R, "pinky2"), n(this.isLeft ? t.pinky3L : t.pinky3R, "pinky3"), n(this.isLeft ? t.thumb1L : t.thumb1R, "thumb1"), n(this.isLeft ? t.thumb2L : t.thumb2R, "thumb2"), n(this.isLeft ? t.thumb3L : t.thumb3R, "thumb3"), {
346
- update: (a) => {
347
- this.syncHandBones(a, o, e);
348
- }
349
- };
350
- }
351
- }
352
- async function nt(c, s) {
353
- const e = await G.createFromOptions(c, {
354
- baseOptions: {
355
- modelAssetPath: (s == null ? void 0 : s.modelPath) ?? "face_landmarker.task",
356
- delegate: "GPU"
357
- },
358
- outputFaceBlendshapes: !0,
359
- runningMode: "VIDEO",
360
- numFaces: 1
361
- });
362
- return new lt(e, { ...s });
363
- }
364
- const it = {
365
- eyeL: 473,
366
- eyeR: 468,
367
- eyeStartL: 463,
368
- eyeStartR: 243,
369
- eyeEndL: 263,
370
- eyeEndR: 33,
371
- earL: 454,
372
- earR: 234,
373
- noseTip: 4,
374
- noseBone: 6,
375
- chin: 152,
376
- forehead: 10
377
- }, rt = new b(), at = new b(), ye = new b(), dt = new b(), ct = new b();
378
- new b();
379
- class lt extends H {
380
- constructor(e, t) {
381
- super(it, G.FACE_LANDMARKS_TESSELATION);
382
- P(this, "blendshapeCategories");
383
- P(this, "blendshapeMap", /* @__PURE__ */ new Map());
384
- P(this, "smoothed", {});
385
- P(this, "smoothing", 3e-4);
386
- // lower = smoother but more lag, higher = more responsive
387
- P(this, "_faceLandmarks", []);
388
- this.faceLandmarker = e, this.cfg = t, this.root.scale.y *= -1, this.root.scale.z *= -1, this.root.scale.multiplyScalar(3);
389
- }
390
- predict(e, t) {
391
- var n, a, i;
392
- const o = this.faceLandmarker.detectForVideo(e, performance.now());
393
- o.faceLandmarks[0] && (this.cfg.drawLandmarks && (t.drawConnectors(o.faceLandmarks[0], G.FACE_LANDMARKS_TESSELATION, { color: "#00fff2ff", lineWidth: 0.1 }), t.drawLandmarks(o.faceLandmarks[0], { color: "#00ff00", lineWidth: 0.1, radius: 0.4 })), this.updateLandmarks(o.faceLandmarks[0], o.faceLandmarks[0])), this._faceLandmarks = o.faceLandmarks[0], this.blendshapeCategories = (a = (n = o.faceBlendshapes) == null ? void 0 : n[0]) == null ? void 0 : a.categories, (i = this.blendshapeCategories) == null || i.forEach((r) => {
394
- this.blendshapeMap.set(r.categoryName, r.score);
395
- });
396
- }
397
- get lastKnownLandmarks() {
398
- return this._faceLandmarks;
399
- }
400
- bindShapeKeys(e) {
401
- const t = e.morphTargetDictionary;
402
- return {
403
- update: (o) => {
404
- var n;
405
- (n = this.blendshapeCategories) == null || n.forEach((a) => {
406
- const { categoryName: i, score: r } = a;
407
- if (!(t != null && t.hasOwnProperty(i))) return;
408
- this.smoothed[i] === void 0 && (this.smoothed[i] = r);
409
- const l = 1 - Math.pow(this.smoothing, o);
410
- this.smoothed[i] += (r - this.smoothed[i]) * l, e.morphTargetInfluences[t[i]] = this.smoothed[i];
411
- });
412
- }
413
- };
414
- }
415
- bind(e) {
416
- const t = new ue(e, "L"), o = new ue(e, "R"), n = g(e, "head");
417
- return {
418
- update: (a) => {
419
- if (t.update(a, this.blendshapeMap), o.update(a, this.blendshapeMap), !n) return;
420
- const i = rt.copy(this.marks.earL.worldPosition), r = at.copy(this.marks.earR.worldPosition), l = ye.subVectors(i, r).multiplyScalar(0.5).add(r), h = dt.subVectors(this.marks.noseTip.worldPosition, l), f = i.sub(r), x = S(ct, n, e), d = f.add(x).applyMatrix4(e.matrixWorld), m = h.add(x).applyMatrix4(e.matrixWorld);
421
- M(n, m, d, "+x");
422
- }
423
- };
424
- }
425
- /**
426
- * The mesh is assumed to be a canonical_face_model because we will be manipulating it's vertices.
427
- *
428
- * @see https://github.com/google-ai-edge/mediapipe/tree/master/mediapipe/modules/face_geometry
429
- * @param mesh basically either the original or a clone of the canonical_face_model
430
- */
431
- bindGeometry(e, t) {
432
- const o = new b(), n = new b(), a = new b();
433
- new b();
434
- const i = e.geometry, r = i.attributes.position, l = [], h = /* @__PURE__ */ new Map(), f = [];
435
- for (let F = 0; F < r.count; F++) {
436
- const v = `${r.getX(F).toFixed(6)},${r.getY(F).toFixed(6)},${r.getZ(F).toFixed(6)}`;
437
- h.has(v) || (h.set(v, l.length), l.push(F)), f.push(h.get(v));
438
- }
439
- const x = _(new b(0.5, 0.5, 0.5));
440
- i.setAttribute("landmarkIndex", new Ee(new Uint16Array(f), 1));
441
- const d = Me("landmarkIndex", "uint"), m = Ve(468, "vec3"), y = Ne(m.element(d)).xy;
442
- let p;
443
- const R = 116, k = 346, E = a.subVectors(
444
- new b(r.getX(R), r.getY(R), r.getZ(R)),
445
- new b(r.getX(k), r.getY(k), r.getZ(k))
446
- ).lengthSq(), L = _(E), w = _(1), A = _(1);
447
- return {
448
- update: (F) => {
449
- var O, j;
450
- if (!p) {
451
- const W = (j = (O = this.cfg) == null ? void 0 : O.videoElementRef) == null ? void 0 : j.call(O);
452
- if (!W || !W.videoWidth || !W.videoHeight) return;
453
- p = W;
454
- const K = new We(p);
455
- K.colorSpace = Fe;
456
- const xe = p.videoWidth / p.videoHeight, X = m.element(d).sub(x).xzy.mul(Oe(1, -1, 1 / xe)).mul(A), Q = Te(K, _e(y.x, y.y.oneMinus()));
457
- t ? t(X, Q) : e.material = new Ae({
458
- positionNode: X,
459
- colorNode: Q,
460
- roughness: 0.93
461
- });
462
- }
463
- const v = this.lastKnownLandmarks;
464
- if (!(v != null && v.length)) return;
465
- w.value = a.subVectors(v[k], v[R]).lengthSq(), w.needsUpdate = !0;
466
- const D = m.value.array;
467
- for (let W = 0; W < v.length; W++)
468
- D[W * 3] = v[W].x, D[W * 3 + 1] = v[W].y, D[W * 3 + 2] = v[W].z;
469
- m.value.needsUpdate = !0;
470
- const ke = v[234], $ = v[93], be = v[454], q = v[323];
471
- o.copy(ke).sub($).divideScalar(2).add($), n.copy(be).sub(q).divideScalar(2).add(q), x.value.subVectors(n, o).divideScalar(2).add(o), x.needsUpdate = !0, A.value = Math.sqrt(L.value / w.value), A.needsUpdate = !0;
472
- }
473
- };
474
- }
475
- }
476
- class ue {
477
- constructor(s, e) {
478
- P(this, "eyeBone");
479
- P(this, "eyeLookOut");
480
- P(this, "eyeLookIn");
481
- P(this, "eyeLookUp");
482
- P(this, "eyeLookDown");
483
- P(this, "sign", 1);
484
- this.rig = s, this.side = e, this.eyeBone = s.getObjectByName(`eye${e}`);
485
- const t = e == "L" ? "Left" : "Right";
486
- this.eyeLookOut = `eyeLookOut${t}`, this.eyeLookIn = `eyeLookIn${t}`, this.eyeLookUp = `eyeLookUp${t}`, this.eyeLookDown = `eyeLookDown${t}`, this.sign = e == "L" ? -1 : 1;
487
- }
488
- update(s, e) {
489
- if (!this.eyeBone) return;
490
- S(ye, this.eyeBone, this.rig);
491
- const t = e.get(this.eyeLookOut) ?? 0, o = e.get(this.eyeLookIn) ?? 0, n = e.get(this.eyeLookUp) ?? 0, a = e.get(this.eyeLookDown) ?? 0, i = o - t, r = a - n;
492
- this.eyeBone.rotation.y = i * this.sign / 2, this.eyeBone.rotation.x = r / 2;
493
- }
494
- }
495
- const Le = {
496
- faceMesh: "face",
497
- head: "head",
498
- hips: "hips",
499
- neck: "neck",
500
- torso: "torso",
501
- armL: "upper_armL",
502
- forearmL: "forearmL",
503
- armR: "upper_armR",
504
- forearmR: "forearmR",
505
- thighL: "thighL",
506
- shinL: "shinL",
507
- footL: "footL",
508
- thighR: "thighR",
509
- shinR: "shinR",
510
- footR: "footR",
511
- handL: "handL",
512
- index1L: "index1L",
513
- index2L: "index2L",
514
- index3L: "index3L",
515
- middle1L: "middle1L",
516
- middle2L: "middle2L",
517
- middle3L: "middle3L",
518
- ring1L: "ring1L",
519
- ring2L: "ring2L",
520
- ring3L: "ring3L",
521
- pinky1L: "pinky1L",
522
- pinky2L: "pinky2L",
523
- pinky3L: "pinky3L",
524
- thumb1L: "thumb1L",
525
- thumb2L: "thumb2L",
526
- thumb3L: "thumb3L",
527
- handR: "handR",
528
- index1R: "index1R",
529
- index2R: "index2R",
530
- index3R: "index3R",
531
- middle1R: "middle1R",
532
- middle2R: "middle2R",
533
- middle3R: "middle3R",
534
- ring1R: "ring1R",
535
- ring2R: "ring2R",
536
- ring3R: "ring3R",
537
- pinky1R: "pinky1R",
538
- pinky2R: "pinky2R",
539
- pinky3R: "pinky3R",
540
- thumb1R: "thumb1R",
541
- thumb2R: "thumb2R",
542
- thumb3R: "thumb3R"
543
- }, ht = [
544
- "eyeBlinkLeft",
545
- "eyeBlinkRight",
546
- "eyeLookDownLeft",
547
- "eyeLookDownRight",
548
- "eyeLookInLeft",
549
- "eyeLookInRight",
550
- "eyeLookOutLeft",
551
- "eyeLookOutRight",
552
- "eyeLookUpLeft",
553
- "eyeLookUpRight",
554
- "eyeSquintLeft",
555
- "eyeSquintRight",
556
- "eyeWideLeft",
557
- "eyeWideRight",
558
- "browDownLeft",
559
- "browDownRight",
560
- "browInnerUp",
561
- "browOuterUpLeft",
562
- "browOuterUpRight",
563
- "noseSneerLeft",
564
- "noseSneerRight",
565
- "cheekPuff",
566
- "cheekSquintLeft",
567
- "cheekSquintRight",
568
- "jawForward",
569
- "jawLeft",
570
- "jawOpen",
571
- "jawRight",
572
- "mouthClose",
573
- "mouthDimpleLeft",
574
- "mouthDimpleRight",
575
- "mouthFrownLeft",
576
- "mouthFrownRight",
577
- "mouthFunnel",
578
- "mouthLeft",
579
- "mouthLowerDownLeft",
580
- "mouthLowerDownRight",
581
- "mouthPressLeft",
582
- "mouthPressRight",
583
- "mouthPucker",
584
- "mouthRight",
585
- "mouthRollLower",
586
- "mouthRollUpper",
587
- "mouthShrugLower",
588
- "mouthShrugUpper",
589
- "mouthSmileLeft",
590
- "mouthSmileRight",
591
- "mouthStretchLeft",
592
- "mouthStretchRight",
593
- "mouthUpperUpLeft",
594
- "mouthUpperUpRight",
595
- "tongueOut"
596
- ];
597
- function pt(c, s, e = 30) {
598
- const t = [], o = c.getObjectByName(
599
- s.faceMesh
600
- ), n = /* @__PURE__ */ new Set();
601
- if (o != null && o.morphTargetDictionary)
602
- for (const y in o.morphTargetDictionary)
603
- ht.includes(y) && n.add(y);
604
- const a = Object.keys(s);
605
- c.traverse((y) => {
606
- if (y instanceof T.Bone) {
607
- const p = a.find((R) => y.name.indexOf(s[R]) === 0);
608
- p && t.push({
609
- ref: y,
610
- name: y.name,
611
- normalizedName: p
612
- });
613
- }
614
- });
615
- const i = [], r = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map();
616
- let h = !1, f = 0;
617
- function x() {
618
- r.clear(), l.clear(), i.length = 0, f = performance.now() / 1e3, h = !0;
619
- }
620
- function d() {
621
- if (!h) return;
622
- const y = performance.now() / 1e3 - f;
623
- i.push(y);
624
- for (const p of t) {
625
- r.has(p.name) || r.set(p.name, []);
626
- const R = r.get(p.name), k = p.ref.quaternion;
627
- R.push(k.x, k.y, k.z, k.w);
628
- }
629
- for (const p of n) {
630
- l.has(p) || l.set(p, []);
631
- const R = l.get(p), k = o.morphTargetDictionary[p], E = o.morphTargetInfluences[k];
632
- R.push(E);
633
- }
634
- }
635
- function m(y = "RecordedClip") {
636
- h = !1;
637
- const p = [];
638
- for (const [k, E] of r)
639
- p.push(
640
- new T.QuaternionKeyframeTrack(
641
- `${k}.quaternion`,
642
- i,
643
- E
644
- )
645
- );
646
- for (const [k, E] of l)
647
- p.push(
648
- new T.NumberKeyframeTrack(
649
- `${Le.faceMesh}.morphTargetInfluences[${k}]`,
650
- i,
651
- E
652
- )
653
- );
654
- const R = new T.AnimationClip(y, -1, p);
655
- return {
656
- clip: R,
657
- saveToFile: () => {
658
- new Ce().parse(
659
- c,
660
- (E) => {
661
- const L = new Blob([E], {
662
- type: "model/gltf-binary"
663
- }), w = URL.createObjectURL(L), A = document.createElement("a");
664
- A.href = w, A.download = y + ".glb", A.click();
665
- },
666
- (E) => {
667
- console.error(E);
668
- },
669
- {
670
- binary: !0,
671
- animations: [R]
672
- }
673
- );
674
- }
675
- };
676
- }
677
- return { start: x, captureFrame: d, stop: m, isRecording: () => h };
678
- }
679
- const mt = () => {
680
- var c;
681
- return !!((c = navigator.mediaDevices) != null && c.getUserMedia);
682
- };
683
- async function bt(c) {
684
- const s = {
685
- debugFrame: void 0,
686
- displayScale: 1,
687
- ignoreLegs: !1,
688
- debugVideo: void 0,
689
- ignoreFace: !1,
690
- onlyFace: !1,
691
- drawLandmarksOverlay: !0,
692
- modelPaths: {
693
- vision: "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.3/wasm",
694
- pose: "https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task",
695
- hand: "https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task",
696
- face: "https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task"
697
- },
698
- ...c
699
- };
700
- let e;
701
- const t = await ve.forVisionTasks(s.modelPaths.vision ?? "/wasm"), o = s.onlyFace ? void 0 : await je(t, {
702
- ignoreLegs: s.ignoreLegs,
703
- modelPath: s.modelPaths.pose,
704
- drawLandmarks: s.drawLandmarksOverlay
705
- }), n = s.onlyFace ? void 0 : await et(t, {
706
- leftWrist: () => o.leftWristNormalizedPosition,
707
- rightWrist: () => o.rightWristNormalizedPosition,
708
- modelPath: s.modelPaths.hand,
709
- drawLandmarks: s.drawLandmarksOverlay,
710
- ...c == null ? void 0 : c.handsTrackerOptions
711
- }), a = s.ignoreFace ? void 0 : await nt(t, { modelPath: s.modelPaths.face, videoElementRef: () => e, drawLandmarks: s.drawLandmarksOverlay }), i = document.createElement("div");
712
- i.style.position = "absolute", i.style.top = "0px", i.style.left = "0px", i.style.zIndex = "21", i.classList.add("three-mediapipe-rig"), document.body.appendChild(i);
713
- const r = document.createElement("canvas"), l = r.getContext("2d"), h = new ge(l);
714
- r.style.zIndex = "22", r.style.position = "absolute", r.style.top = "0px", r.style.left = "0px", r.style.pointerEvents = "none", i.appendChild(r);
715
- function f(d) {
716
- l.save(), l.clearRect(0, 0, r.width, r.height), o == null || o.predict(d, h), n == null || n.left.predict(d, h), n == null || n.right.predict(d, h), a == null || a.predict(d, h), l.restore();
717
- }
718
- function x() {
719
- e = document.createElement("video"), i.appendChild(e);
720
- let d = -1;
721
- e.style.zIndex = "21", e.style.position = "absolute", e.style.top = "0px", e.style.left = "0px", s.debugVideo && (e.src = s.debugVideo, e.controls = !0, e.loop = !0, e.muted = !0, e.controls = !0, e.play());
722
- function m() {
723
- d !== e.currentTime && (f(e), d = e.currentTime), window.requestAnimationFrame(m);
724
- }
725
- e.addEventListener("loadeddata", () => {
726
- e.width = e.videoWidth * s.displayScale, e.height = e.videoHeight * s.displayScale, r.width = e.videoWidth, r.height = e.videoHeight, r.style.height = e.height + "px", r.style.width = e.width + "px", window.requestAnimationFrame(m);
727
- });
728
- }
729
- if (s.debugFrame) {
730
- const d = document.createElement("img");
731
- d.src = s.debugFrame, d.style.zIndex = "21", d.style.position = "absolute", d.style.top = "0px", d.style.left = "0px", i.appendChild(d), d.addEventListener("load", () => {
732
- d.width = d.naturalWidth * s.displayScale, d.height = d.naturalHeight * s.displayScale, r.width = d.naturalWidth, r.height = d.naturalWidth, r.style.width = d.width + "px", r.style.height = d.height + "px";
733
- function m() {
734
- f(d);
735
- }
736
- window.requestAnimationFrame(m);
737
- });
738
- } else s.debugVideo && x();
739
- return {
740
- poseTracker: o,
741
- handsTracker: n,
742
- faceTracker: a,
743
- video: e,
744
- canvas: r,
745
- /**
746
- * A div that contains the video and canvas used to display the landmarks stacked on top of each other.
747
- */
748
- domElement: i,
749
- /**
750
- * Start the webcam feed. This must be initiated by a user triggered event ( a click on a button ) due to security reasons.
751
- */
752
- start: async () => {
753
- let d = !1;
754
- if (!mt())
755
- throw new Error("Webcam not supported");
756
- e || x();
757
- let m;
758
- function y(L) {
759
- console.warn("Camera track ended, attempting recovery..."), p(L), R(L);
760
- }
761
- function p(L) {
762
- m == null || m.getTracks().forEach((w) => w.stop()), m = void 0, L.srcObject = null;
763
- }
764
- async function R(L, w = 0) {
765
- const F = Math.min(1e3 * 2 ** w, 16e3);
766
- if (w >= 5)
767
- throw new Error("Camera recovery failed after max attempts");
768
- if (await new Promise((v) => setTimeout(v, F)), !d)
769
- try {
770
- await k(L), console.log("Camera recovered successfully");
771
- } catch {
772
- R(L, w + 1);
773
- }
774
- }
775
- async function k(L) {
776
- try {
777
- m = await navigator.mediaDevices.getUserMedia({ video: !0 }), L.srcObject = m, await L.play(), m.getVideoTracks().forEach((w) => {
778
- w.addEventListener("ended", () => y(L));
779
- });
780
- } catch (w) {
781
- E(w, L);
782
- }
783
- }
784
- function E(L, w) {
785
- if (L instanceof DOMException)
786
- switch (L.name) {
787
- case "NotAllowedError":
788
- throw new Error("Permission denied — prompt user to allow camera");
789
- case "NotFoundError":
790
- console.error("No camera found — retry when device is connected"), R(w);
791
- break;
792
- case "NotReadableError":
793
- console.error("Camera in use by another app"), R(w);
794
- break;
795
- default:
796
- console.error("Camera error:", L.message), R(w);
797
- }
798
- }
799
- return await k(e), {
800
- stop: () => {
801
- d = !0, p(e);
802
- }
803
- };
804
- },
805
- /**
806
- * Binds the bones of the rig to the landmarks provided by media pipe.
807
- * @param rig The rig that contains all the bones and skinned meshes of your character.
808
- * @param magging The bone mapping to use for the rig.
809
- */
810
- bind: (d, m) => {
811
- if (m = m || Le, !o) throw new Error("Pose tracker not initialized");
812
- if (!n) throw new Error("Hands tracker not initialized");
813
- if (!a) throw new Error("Face tracker not initialized");
814
- const y = o.bind(d, m), p = n.left.bind(d, m), R = n.right.bind(d, m);
815
- let k;
816
- const E = a == null ? void 0 : a.bind(d);
817
- d.traverse((w) => {
818
- w instanceof u.Mesh && w.name.indexOf(m.faceMesh) === 0 && (w.frustumCulled = !1, k = a == null ? void 0 : a.bindShapeKeys(w));
819
- });
820
- const L = pt(d, m);
821
- return {
822
- /**
823
- * Will save the tracked movement of the rig to an animation clip.
824
- * Only the bones moved by the bone mapping will be recorded.
825
- */
826
- startRecording: L.start,
827
- stopRecording: L.stop,
828
- isRecording: () => L.isRecording(),
829
- update: (w) => {
830
- y.update(w), p.update(w), R.update(w), k == null || k.update(w), E == null || E.update(w), L.isRecording() && L.captureFrame();
831
- }
832
- };
833
- }
834
- };
835
- }
836
- export {
837
- bt as setupTracker
838
- };
839
- //# sourceMappingURL=three-mediapipe-rig.js.map