three-mediapipe-rig 0.1.1 → 0.1.3
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/README.md +8 -4
- package/dist/face-tracker-utils-xt9__vBF.js +16 -0
- package/dist/meshcap/atlas-builder.d.ts +10 -0
- package/dist/meshcap/atlas-builder.d.ts.map +1 -0
- package/dist/meshcap/audio.d.ts +27 -0
- package/dist/meshcap/audio.d.ts.map +1 -0
- package/dist/meshcap/constants.d.ts +3 -0
- package/dist/meshcap/constants.d.ts.map +1 -0
- package/dist/meshcap/material.d.ts +75 -0
- package/dist/meshcap/material.d.ts.map +1 -0
- package/dist/meshcap/meshcap.d.ts +6 -0
- package/dist/meshcap/meshcap.d.ts.map +1 -0
- package/dist/meshcap/parse-mcap-file.d.ts +8 -0
- package/dist/meshcap/parse-mcap-file.d.ts.map +1 -0
- package/dist/meshcap/types.d.ts +88 -0
- package/dist/meshcap/types.d.ts.map +1 -0
- package/dist/meshcap/write-mcap-file.d.ts +3 -0
- package/dist/meshcap/write-mcap-file.d.ts.map +1 -0
- package/dist/meshcap.d.ts +2 -0
- package/dist/meshcap.js +468 -0
- package/dist/module.d.ts +1 -0
- package/dist/module.d.ts.map +1 -1
- package/dist/rigger.d.ts +2 -0
- package/dist/rigger.js +864 -0
- package/dist/tracking/BoneMapping.d.ts.map +1 -1
- package/dist/tracking/FaceTracker.d.ts +12 -2
- package/dist/tracking/FaceTracker.d.ts.map +1 -1
- package/dist/tracking/HandTracker.d.ts +3 -3
- package/dist/tracking/HandTracker.d.ts.map +1 -1
- package/dist/tracking/PoseTracker.d.ts +1 -1
- package/dist/tracking/PoseTracker.d.ts.map +1 -1
- package/dist/tracking/TrackerManager.d.ts +126 -0
- package/dist/tracking/TrackerManager.d.ts.map +1 -0
- package/dist/tracking/recoding/recorder.d.ts +10 -8
- package/dist/tracking/recoding/recorder.d.ts.map +1 -1
- package/dist/tracking/util/face-tracker-utils.d.ts +9 -0
- package/dist/tracking/util/face-tracker-utils.d.ts.map +1 -0
- package/package.json +16 -10
- package/dist/three-mediapipe-rig.js +0 -839
- package/dist/three-mediapipe-rig.js.map +0 -1
package/dist/meshcap.js
ADDED
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import { inflate as xt, deflate as Mt } from "fflate";
|
|
2
|
+
import { c as At, F as X } from "./face-tracker-utils-xt9__vBF.js";
|
|
3
|
+
import { MeshPhysicalNodeMaterial as Ct, Vector3 as et } from "three/webgpu";
|
|
4
|
+
import { instancedArray as H, texture as it, uniform as K, attribute as bt, varying as St, vec3 as It, float as kt } from "three/tsl";
|
|
5
|
+
const dt = 1296253264, Rt = 2;
|
|
6
|
+
async function Vt(a) {
|
|
7
|
+
if (a instanceof ArrayBuffer)
|
|
8
|
+
return a;
|
|
9
|
+
if (a instanceof File || a instanceof Blob)
|
|
10
|
+
return a.arrayBuffer();
|
|
11
|
+
if (typeof a == "string")
|
|
12
|
+
return (await fetch(a)).arrayBuffer();
|
|
13
|
+
throw new Error(`Unsupported audio source type: ${typeof a}`);
|
|
14
|
+
}
|
|
15
|
+
async function Lt(a, d) {
|
|
16
|
+
const i = new AudioContext(), o = await Vt(a), e = await i.decodeAudioData(o);
|
|
17
|
+
for (const l of d) {
|
|
18
|
+
if (!l.audioSprite)
|
|
19
|
+
continue;
|
|
20
|
+
const v = Math.floor(l.audioSprite.start * e.sampleRate), x = Math.floor(l.duration * e.sampleRate), f = i.createBuffer(
|
|
21
|
+
e.numberOfChannels,
|
|
22
|
+
x,
|
|
23
|
+
e.sampleRate
|
|
24
|
+
);
|
|
25
|
+
for (let r = 0; r < e.numberOfChannels; r++) {
|
|
26
|
+
const p = e.getChannelData(r).subarray(v, v + x);
|
|
27
|
+
f.getChannelData(r).set(p);
|
|
28
|
+
}
|
|
29
|
+
const s = Tt(f), t = new Blob([s], { type: "audio/wav" }), n = URL.createObjectURL(t), c = new Audio(n);
|
|
30
|
+
l.audioSprite.domElement = c, console.log("Assigned audio to clip: ", l.name, " at ", l.audioSprite.start, " for ", l.duration, " seconds");
|
|
31
|
+
}
|
|
32
|
+
return i.close(), {
|
|
33
|
+
blob: new Blob([o], { type: "audio/wav" }),
|
|
34
|
+
sprites: d.map((l) => l.audioSprite ? [l.audioSprite.start, l.duration] : void 0)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function Tt(a) {
|
|
38
|
+
const d = a.numberOfChannels, i = a.sampleRate, o = a.length * d * 2, e = new ArrayBuffer(44 + o), l = new DataView(e), v = (f, s) => [...s].forEach((t, n) => l.setUint8(f + n, t.charCodeAt(0)));
|
|
39
|
+
v(0, "RIFF"), l.setUint32(4, 36 + o, !0), v(8, "WAVE"), v(12, "fmt "), l.setUint32(16, 16, !0), l.setUint16(20, 1, !0), l.setUint16(22, d, !0), l.setUint32(24, i, !0), l.setUint32(28, i * d * 2, !0), l.setUint16(32, d * 2, !0), l.setUint16(34, 16, !0), v(36, "data"), l.setUint32(40, o, !0);
|
|
40
|
+
let x = 44;
|
|
41
|
+
for (let f = 0; f < a.length; f++)
|
|
42
|
+
for (let s = 0; s < d; s++) {
|
|
43
|
+
const t = Math.max(-1, Math.min(1, a.getChannelData(s)[f]));
|
|
44
|
+
l.setInt16(x, t * 32767, !0), x += 2;
|
|
45
|
+
}
|
|
46
|
+
return e;
|
|
47
|
+
}
|
|
48
|
+
const ct = /* @__PURE__ */ new WeakMap();
|
|
49
|
+
function zt(a, d) {
|
|
50
|
+
const i = ct.get(a) || new AudioContext();
|
|
51
|
+
ct.set(a, i);
|
|
52
|
+
const o = i.createGain();
|
|
53
|
+
o.connect(i.destination), o.gain.value = 1;
|
|
54
|
+
let e;
|
|
55
|
+
return {
|
|
56
|
+
stopCurrent() {
|
|
57
|
+
e && (e.stop(), e = void 0);
|
|
58
|
+
},
|
|
59
|
+
setVolume(l) {
|
|
60
|
+
o.gain.value = l;
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* @param clipIndex Index of the clip to play
|
|
64
|
+
* @returns The audio buffer source node that is playing the audio.
|
|
65
|
+
*/
|
|
66
|
+
playSprite(l) {
|
|
67
|
+
this.stopCurrent();
|
|
68
|
+
const v = d[l];
|
|
69
|
+
if (!v.audioSprite) return;
|
|
70
|
+
const x = i.createBufferSource();
|
|
71
|
+
return x.buffer = a, x.connect(o), x.start(0, v.audioSprite.start, v.duration), e = x, console.log("PLAYING SOUNC", v.name), x;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function Bt(a, d, i, o, e) {
|
|
76
|
+
const l = !o;
|
|
77
|
+
o ?? (o = new Ct()), l && (i.material = o), i.geometry.hasAttribute("landmarkIndex") || At(i);
|
|
78
|
+
const v = [], x = [], f = [];
|
|
79
|
+
let s = 0, t = 0;
|
|
80
|
+
for (let U = 0; U < d.length; U++) {
|
|
81
|
+
const w = d[U];
|
|
82
|
+
v.push(s, t, w.frames.length, w.fps), s += w.frames.length, t += w.frames.length * X, x.push(w.aspectRatio), f.push(U == 0 ? 0 : f[U - 1] + d[U - 1].frames.length);
|
|
83
|
+
}
|
|
84
|
+
const n = H(new Float32Array(x), "float"), c = H(new Uint32Array(v), "uvec4"), r = new Float32Array(d.flatMap((U) => U.frames).reduce((U, w) => (U.push(w.frameUV.u, w.frameUV.v, w.frameUV.w, w.frameUV.h), U), [])), p = H(r, "vec4"), M = new Float32Array(d.flatMap((U) => U.frames.flatMap((w) => [w.cropUV.u, w.cropUV.v, w.cropUV.w, w.cropUV.h]))), m = H(M, "vec4"), u = new Float32Array(d.flatMap((U) => U.landmarks.flatMap((w) => w.flatMap((I) => [I.x, I.y, I.z])))), h = H(u, "vec3"), g = it(a), y = K(0), A = K(0), C = K(!0), k = n.element(y), j = H(new Uint32Array(f), "uint"), R = A, D = j.element(y).add(R), z = p.element(c.element(y).x.add(R)), b = c.element(y).y.add(R.mul(X)), J = bt("landmarkIndex", "uint").toUint(), Q = b.add(J), B = h.element(Q), V = m.element(D), Y = B.xy.sub(V.xy).div(V.zw), q = St(z.xy.add(Y.mul(z.zw))), _ = it(g, q);
|
|
85
|
+
o.colorNode = _;
|
|
86
|
+
const ft = h.element(b.add(234)).xy, nt = h.element(b.add(93)).xy, ut = h.element(b.add(454)).xy, ot = h.element(b.add(323)).xy, at = ft.sub(nt).div(2).add(nt), ht = ut.sub(ot).div(2).add(ot).sub(at).div(2).add(at), E = i.geometry.attributes.position, Z = 116, $ = 346, pt = new et().subVectors(
|
|
87
|
+
new et(E.getX(Z), E.getY(Z), E.getZ(Z)),
|
|
88
|
+
new et(E.getX($), E.getY($), E.getZ($))
|
|
89
|
+
).lengthSq(), mt = K(pt), gt = h.element(b.add($)).sub(h.element(b.add(Z))).lengthSq(), Ut = mt.div(gt).sqrt().mul(2), wt = B.sub(ht).xzy.mul(It(1, -1, kt(1).div(k))).mul(Ut);
|
|
90
|
+
o.positionNode = wt;
|
|
91
|
+
let G = 0, L = 0, N, P, st = d[0].frames, tt = !1, O = e ? zt(e, d) : void 0;
|
|
92
|
+
const S = {
|
|
93
|
+
muted: !1,
|
|
94
|
+
clips: d,
|
|
95
|
+
atlasTexture: a,
|
|
96
|
+
material: o,
|
|
97
|
+
goto(U, w = !0, I, yt = !0) {
|
|
98
|
+
var rt;
|
|
99
|
+
let T = -1;
|
|
100
|
+
if (typeof U == "number")
|
|
101
|
+
T = U;
|
|
102
|
+
else if (T = d.findIndex((vt) => vt.name === U), T === -1)
|
|
103
|
+
throw new Error(`Clip ${U.toString()} not found`);
|
|
104
|
+
C.value = w, A.value = 0, y.value = T;
|
|
105
|
+
const W = d[T];
|
|
106
|
+
N = W, st = W.frames, G = W.duration, L = 0, P = I, tt = !0, O && (O.stopCurrent(), yt && !S.muted && W.audioSprite && (O.playSprite(T), (rt = S.playClipAudioHook) == null || rt.call(S, T, W.audioSprite.start, W.duration)));
|
|
107
|
+
},
|
|
108
|
+
update(U) {
|
|
109
|
+
var w;
|
|
110
|
+
if (tt) {
|
|
111
|
+
if (L += U, A.value = Ft(st, L, A.value), C.value)
|
|
112
|
+
L >= G && (L -= G, A.value = 0, S.muted || (O == null || O.playSprite(y.value), N != null && N.audioSprite && ((w = S.playClipAudioHook) == null || w.call(S, y.value, N.audioSprite.start, N.duration))), P == null || P(L));
|
|
113
|
+
else if (L >= G) {
|
|
114
|
+
const I = P;
|
|
115
|
+
P = void 0, I == null || I(G);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
dispose() {
|
|
120
|
+
a.dispose(), o.dispose();
|
|
121
|
+
},
|
|
122
|
+
gotoAndLoop(U, w) {
|
|
123
|
+
this.goto(U, !0, w);
|
|
124
|
+
},
|
|
125
|
+
gotoAndPlay(U, w) {
|
|
126
|
+
this.goto(U, !1, w);
|
|
127
|
+
},
|
|
128
|
+
gotoAndStop(U, w = 0) {
|
|
129
|
+
this.goto(U, !1, void 0, !1), A.value = w, tt = !1;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
return S;
|
|
133
|
+
}
|
|
134
|
+
function Ft(a, d, i) {
|
|
135
|
+
for (; i < a.length - 1 && a[i + 1].startTime <= d; )
|
|
136
|
+
i++;
|
|
137
|
+
return i;
|
|
138
|
+
}
|
|
139
|
+
async function _t(a) {
|
|
140
|
+
if (typeof a == "string") {
|
|
141
|
+
const i = await (await fetch(a)).arrayBuffer();
|
|
142
|
+
return lt(i);
|
|
143
|
+
} else
|
|
144
|
+
return new Promise((d, i) => {
|
|
145
|
+
const o = new FileReader();
|
|
146
|
+
o.onload = (e) => {
|
|
147
|
+
const l = e.target.result;
|
|
148
|
+
d(lt(l));
|
|
149
|
+
}, o.onerror = (e) => {
|
|
150
|
+
i(e);
|
|
151
|
+
}, o.readAsArrayBuffer(a);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
async function lt(a) {
|
|
155
|
+
let d = !1;
|
|
156
|
+
const i = await new Promise((n, c) => {
|
|
157
|
+
xt(new Uint8Array(a), (r, p) => {
|
|
158
|
+
r ? c(r) : n(p);
|
|
159
|
+
});
|
|
160
|
+
}), o = new DataView(i.buffer);
|
|
161
|
+
let e = 0;
|
|
162
|
+
const l = o.getUint32(e);
|
|
163
|
+
if (e += 4, l !== dt) throw new Error("Invalid file: not a MCAP file");
|
|
164
|
+
const v = o.getUint8(e);
|
|
165
|
+
e += 1;
|
|
166
|
+
const x = o.getUint8(e);
|
|
167
|
+
e += 1;
|
|
168
|
+
const f = o.getUint16(e);
|
|
169
|
+
e += 2;
|
|
170
|
+
const s = o.getUint8(e);
|
|
171
|
+
e += 1;
|
|
172
|
+
const t = [];
|
|
173
|
+
for (let n = 0; n < x; n++) {
|
|
174
|
+
const c = o.getUint8(e);
|
|
175
|
+
e += 1;
|
|
176
|
+
const r = new Uint8Array(i.buffer, e, c), p = new TextDecoder().decode(r);
|
|
177
|
+
e += c;
|
|
178
|
+
const M = o.getUint8(e);
|
|
179
|
+
e += 1;
|
|
180
|
+
const m = o.getUint8(e);
|
|
181
|
+
e += 1;
|
|
182
|
+
const u = o.getUint8(e) / 100;
|
|
183
|
+
e += 1;
|
|
184
|
+
const h = o.getUint8(e) / 100;
|
|
185
|
+
e += 1;
|
|
186
|
+
const g = [], y = [], A = [];
|
|
187
|
+
for (let C = 0; C < M; C++) {
|
|
188
|
+
const k = o.getUint16(e) / 1e3;
|
|
189
|
+
e += 2;
|
|
190
|
+
const j = o.getUint16(e) / 1e3;
|
|
191
|
+
e += 2;
|
|
192
|
+
const R = o.getUint16(e) / 1e3;
|
|
193
|
+
e += 2;
|
|
194
|
+
const D = o.getUint16(e) / 1e3;
|
|
195
|
+
e += 2, g.push({ u: k, v: j, w: R, h: D });
|
|
196
|
+
const z = o.getUint16(e) / 1e3;
|
|
197
|
+
e += 2;
|
|
198
|
+
const b = o.getUint16(e) / 1e3;
|
|
199
|
+
e += 2;
|
|
200
|
+
const J = o.getUint16(e) / 1e3;
|
|
201
|
+
e += 2;
|
|
202
|
+
const Q = o.getUint16(e) / 1e3;
|
|
203
|
+
e += 2, A.push({ u: z, v: b, w: J, h: Q });
|
|
204
|
+
const B = [], V = C > 0 ? y[C - 1] : null;
|
|
205
|
+
for (let F = 0; F < X; F++)
|
|
206
|
+
if (V === null) {
|
|
207
|
+
const Y = o.getUint16(e) / 1e3;
|
|
208
|
+
e += 2;
|
|
209
|
+
const q = o.getUint16(e) / 1e3;
|
|
210
|
+
e += 2;
|
|
211
|
+
const _ = o.getInt16(e) / 1e3;
|
|
212
|
+
e += 2, B.push({ x: Y, y: q, z: _ });
|
|
213
|
+
} else {
|
|
214
|
+
const Y = o.getInt8(e) / 1e3;
|
|
215
|
+
e += 1;
|
|
216
|
+
const q = o.getInt8(e) / 1e3;
|
|
217
|
+
e += 1;
|
|
218
|
+
const _ = o.getInt8(e) / 1e3;
|
|
219
|
+
e += 1, B.push({
|
|
220
|
+
x: V[F].x + Y,
|
|
221
|
+
y: V[F].y + q,
|
|
222
|
+
z: V[F].z + _
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
y.push(B);
|
|
226
|
+
}
|
|
227
|
+
t.push({
|
|
228
|
+
name: p,
|
|
229
|
+
fps: m,
|
|
230
|
+
scale: u,
|
|
231
|
+
aspectRatio: h,
|
|
232
|
+
frames: A.map((C, k) => ({
|
|
233
|
+
cropUV: C,
|
|
234
|
+
frameUV: g[k],
|
|
235
|
+
startTime: k / m
|
|
236
|
+
//<-- default for versions sub 2...
|
|
237
|
+
})),
|
|
238
|
+
landmarks: y,
|
|
239
|
+
duration: M / m
|
|
240
|
+
// default for versions sub 2...
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (v >= 2) {
|
|
244
|
+
for (let n = 0; n < t.length; n++) {
|
|
245
|
+
let c = o.getUint16(e);
|
|
246
|
+
e += 2, t[n].duration = c / 1e3;
|
|
247
|
+
let r = o.getUint16(e);
|
|
248
|
+
e += 2, r === 1 ? console.log("Clip " + n + " has no audio") : (r /= 1e3, t[n].audioSprite = { start: r }, d = !0);
|
|
249
|
+
}
|
|
250
|
+
for (let n = 0; n < t.length; n++) {
|
|
251
|
+
const c = t[n];
|
|
252
|
+
let r = 0;
|
|
253
|
+
for (let p = 0; p < c.frames.length; p++) {
|
|
254
|
+
const M = o.getUint8(e);
|
|
255
|
+
e += 1;
|
|
256
|
+
const m = r + M / 1e3;
|
|
257
|
+
c.frames[p].startTime = m, r = m;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
clips: t,
|
|
263
|
+
version: v,
|
|
264
|
+
atlasSize: f,
|
|
265
|
+
atlasPadding: s,
|
|
266
|
+
unpackClips: async (n, c) => {
|
|
267
|
+
let r, p = !0, M;
|
|
268
|
+
if (n instanceof HTMLCanvasElement)
|
|
269
|
+
p = !1, r = n;
|
|
270
|
+
else {
|
|
271
|
+
let u = new Image();
|
|
272
|
+
if (typeof n == "string")
|
|
273
|
+
u.src = n;
|
|
274
|
+
else if (n instanceof File || n instanceof Blob) {
|
|
275
|
+
const g = URL.createObjectURL(n);
|
|
276
|
+
u.src = g, await new Promise((y, A) => {
|
|
277
|
+
u.onload = () => {
|
|
278
|
+
URL.revokeObjectURL(g), y();
|
|
279
|
+
}, u.onerror = A;
|
|
280
|
+
});
|
|
281
|
+
} else n instanceof HTMLImageElement && (u = n);
|
|
282
|
+
(!u.complete || !u.naturalWidth) && await new Promise((g, y) => {
|
|
283
|
+
u.onload = () => g(), u.onerror = y;
|
|
284
|
+
}), r = document.createElement("canvas"), r.width = u.width, r.height = u.height, r.getContext("2d").drawImage(u, 0, 0);
|
|
285
|
+
}
|
|
286
|
+
const m = t.map((u) => ({
|
|
287
|
+
...u,
|
|
288
|
+
frames: u.frames.map((h) => {
|
|
289
|
+
const g = document.createElement("canvas");
|
|
290
|
+
return g.width = h.frameUV.w * r.width, g.height = h.frameUV.h * r.height, g.getContext("2d").drawImage(
|
|
291
|
+
r,
|
|
292
|
+
h.frameUV.u * r.width,
|
|
293
|
+
h.frameUV.v * r.height,
|
|
294
|
+
h.frameUV.w * r.width,
|
|
295
|
+
h.frameUV.h * r.height,
|
|
296
|
+
0,
|
|
297
|
+
0,
|
|
298
|
+
g.width,
|
|
299
|
+
g.height
|
|
300
|
+
), {
|
|
301
|
+
canvas: g,
|
|
302
|
+
cropUV: h.cropUV,
|
|
303
|
+
startTime: h.startTime
|
|
304
|
+
};
|
|
305
|
+
})
|
|
306
|
+
}));
|
|
307
|
+
return p && r.remove(), d && (c ? M = await Lt(c, m) : console.warn("This mcap file uses an audio atlas, but no audio atlas file was provided.")), {
|
|
308
|
+
clips: m,
|
|
309
|
+
audioAtlas: M
|
|
310
|
+
};
|
|
311
|
+
},
|
|
312
|
+
createMaterialHandlerOnMesh: (n, c, r, p) => Bt(c, t, n, r, p)
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
async function Et(a, d = !0) {
|
|
316
|
+
const i = new TextEncoder(), o = a.clips.map((n) => i.encode(n.name)), e = 9, l = o.reduce((n, c, r) => {
|
|
317
|
+
const p = a.clips[r].frames.length, M = 1 + c.byteLength, m = 1, u = 1, h = 1, g = 1, y = 16;
|
|
318
|
+
let A = X * 6;
|
|
319
|
+
return n + M + m + u + h + g + (d ? y + A + (y + X * 3) * (p - 1) : (y + A) * p);
|
|
320
|
+
}, 0), v = a.clips.reduce((n, c) => n + 2 + 2, 0), x = a.clips.reduce((n, c) => n + c.frames.length * 1, 0), f = new ArrayBuffer(e + l + v + x), s = new DataView(f);
|
|
321
|
+
let t = 0;
|
|
322
|
+
s.setUint32(t, dt), t += 4, s.setUint8(t, Rt), t += 1, s.setUint8(t, a.clips.length), t += 1, s.setUint16(t, a.atlasSize), t += 2, s.setUint8(t, a.padding), t += 1;
|
|
323
|
+
for (let n = 0; n < a.clips.length; n++) {
|
|
324
|
+
s.setUint8(t, o[n].byteLength), t += 1, new Uint8Array(f, t, o[n].byteLength).set(o[n]), t += o[n].byteLength, s.setUint8(t, a.clips[n].frames.length), t += 1, s.setUint8(t, a.clips[n].fps), t += 1, s.setUint8(t, Math.round(a.clips[n].scale * 100)), t += 1, s.setUint8(t, Math.round(a.clips[n].aspectRatio * 100)), t += 1;
|
|
325
|
+
const c = a.clips[n];
|
|
326
|
+
for (let r = 0; r < c.frames.length; r++) {
|
|
327
|
+
const p = c.frames[r].cropUV, M = c.frames[r].frameUV;
|
|
328
|
+
s.setUint16(t, Math.round(M.u * 1e3)), t += 2, s.setUint16(t, Math.round(M.v * 1e3)), t += 2, s.setUint16(t, Math.round(M.w * 1e3)), t += 2, s.setUint16(t, Math.round(M.h * 1e3)), t += 2, s.setUint16(t, Math.round(p.u * 1e3)), t += 2, s.setUint16(t, Math.round(p.v * 1e3)), t += 2, s.setUint16(t, Math.round(p.w * 1e3)), t += 2, s.setUint16(t, Math.round(p.h * 1e3)), t += 2;
|
|
329
|
+
const m = c.landmarks[r], u = r > 0 ? c.landmarks[r - 1] : null;
|
|
330
|
+
m.reduce((h, g) => Math.max(h, Math.abs(g.z)), 0);
|
|
331
|
+
for (let h = 0; h < X; h++) {
|
|
332
|
+
const g = Math.round(m[h].x * 1e3), y = Math.round(m[h].y * 1e3), A = Math.round(m[h].z * 1e3);
|
|
333
|
+
if (d)
|
|
334
|
+
if (u === null)
|
|
335
|
+
s.setUint16(t, g), t += 2, s.setUint16(t, y), t += 2, s.setInt16(t, A), t += 2;
|
|
336
|
+
else {
|
|
337
|
+
const C = Math.round(u[h].x * 1e3), k = Math.round(u[h].y * 1e3), j = Math.round(u[h].z * 1e3), R = g - C, D = y - k, z = A - j;
|
|
338
|
+
s.setInt8(t, R), t += 1, s.setInt8(t, D), t += 1, s.setInt8(t, z), t += 1;
|
|
339
|
+
}
|
|
340
|
+
else
|
|
341
|
+
s.setUint16(t, g), t += 2, s.setUint16(t, y), t += 2, s.setInt16(t, A), t += 2;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
for (let n = 0; n < a.clips.length; n++) {
|
|
346
|
+
const c = a.clips[n];
|
|
347
|
+
s.setUint16(t, Math.round(c.duration * 1e3)), t += 2, c.audioSprite ? s.setUint16(t, Math.round(c.audioSprite.start * 1e3)) : s.setUint16(t, 1), t += 2;
|
|
348
|
+
}
|
|
349
|
+
for (let n = 0; n < a.clips.length; n++) {
|
|
350
|
+
const c = a.clips[n];
|
|
351
|
+
let r = 0;
|
|
352
|
+
for (const p of c.frames) {
|
|
353
|
+
const M = Math.floor((p.startTime - r) * 1e3);
|
|
354
|
+
s.setUint8(t, M), t += 1, r = p.startTime;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return new Promise((n, c) => {
|
|
358
|
+
Mt(new Uint8Array(f), { level: 9 }, (r, p) => {
|
|
359
|
+
if (r) return c(r);
|
|
360
|
+
const M = new Blob([p], { type: "application/octet-stream" });
|
|
361
|
+
n(M);
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
function Nt(a) {
|
|
366
|
+
const d = Pt(a), i = [], o = [];
|
|
367
|
+
let e = 0;
|
|
368
|
+
const l = [...a].sort((f, s) => s.height - f.height);
|
|
369
|
+
for (const f of l) {
|
|
370
|
+
let s = !1;
|
|
371
|
+
for (const t of i)
|
|
372
|
+
if (f.width <= d - t.currentX && f.height <= t.height) {
|
|
373
|
+
o.push({
|
|
374
|
+
...f,
|
|
375
|
+
x: t.currentX,
|
|
376
|
+
y: t.y
|
|
377
|
+
}), t.currentX += f.width, s = !0;
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
if (!s) {
|
|
381
|
+
const t = {
|
|
382
|
+
y: e,
|
|
383
|
+
height: f.height,
|
|
384
|
+
currentX: f.width
|
|
385
|
+
};
|
|
386
|
+
i.push(t), o.push({
|
|
387
|
+
...f,
|
|
388
|
+
x: 0,
|
|
389
|
+
y: e
|
|
390
|
+
}), e += f.height;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
const v = i.length > 0 ? Math.max(...i.map((f) => f.currentX)) : 0, x = e;
|
|
394
|
+
return {
|
|
395
|
+
packed: o,
|
|
396
|
+
width: Math.max(v, d),
|
|
397
|
+
height: x
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
function Pt(a) {
|
|
401
|
+
if (a.length === 0) return 1;
|
|
402
|
+
const d = a.reduce((e, l) => e + l.width * l.height, 0);
|
|
403
|
+
let i = Math.ceil(Math.sqrt(d));
|
|
404
|
+
const o = Math.max(...a.map((e) => e.width));
|
|
405
|
+
return i = Math.max(i, o), i = Ot(i), i;
|
|
406
|
+
}
|
|
407
|
+
function Ot(a) {
|
|
408
|
+
return Math.pow(2, Math.ceil(Math.log2(a)));
|
|
409
|
+
}
|
|
410
|
+
const Wt = 20;
|
|
411
|
+
function Gt(a, d, i = 0) {
|
|
412
|
+
const o = a.flatMap((m) => m.frames.map((u) => u.canvas)), e = Array.from(o.entries()).map(([m, u]) => ({
|
|
413
|
+
id: m,
|
|
414
|
+
// index of the frame after all the frames from all the clips have been flattened
|
|
415
|
+
width: u.width + i * 2,
|
|
416
|
+
height: u.height + i * 2
|
|
417
|
+
})), l = Nt(e), v = l.height, x = l.width, f = Math.min(1, d / x, d / v), s = Math.floor(x * f), t = Math.floor(v * f) + Wt, n = document.createElement("canvas");
|
|
418
|
+
n.width = s, n.height = t;
|
|
419
|
+
const c = n.getContext("2d");
|
|
420
|
+
c.fillStyle = "#000000", c.fillRect(0, 0, n.width, n.height);
|
|
421
|
+
const r = [];
|
|
422
|
+
for (const m of l.packed) {
|
|
423
|
+
const u = o[m.id], h = m.x + i, g = m.y + i, y = u.width, A = u.height;
|
|
424
|
+
c.drawImage(u, h * f, g * f, y * f, A * f), r[m.id] = {
|
|
425
|
+
u: h * f / s,
|
|
426
|
+
v: g * f / t,
|
|
427
|
+
w: y * f / s,
|
|
428
|
+
h: A * f / t
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
const p = [];
|
|
432
|
+
let M = 0;
|
|
433
|
+
for (const m of a) {
|
|
434
|
+
const u = {
|
|
435
|
+
...m,
|
|
436
|
+
frames: []
|
|
437
|
+
};
|
|
438
|
+
for (const h of m.frames)
|
|
439
|
+
u.frames.push({
|
|
440
|
+
frameUV: r[M++],
|
|
441
|
+
cropUV: h.cropUV,
|
|
442
|
+
startTime: h.startTime
|
|
443
|
+
});
|
|
444
|
+
p.push(u);
|
|
445
|
+
}
|
|
446
|
+
return c.font = `${Math.max(6, Math.floor(12))}px monospace`, c.fillStyle = "#ff0000", c.fillText("Created with MeshCap : https://bandinopla.github.io/three-mediapipe-rig/?editor=meshcap", 0, t - 4), {
|
|
447
|
+
canvas: n,
|
|
448
|
+
clips: p,
|
|
449
|
+
padding: i,
|
|
450
|
+
atlasSize: d,
|
|
451
|
+
async save(m) {
|
|
452
|
+
const u = await Et(this);
|
|
453
|
+
if (m) {
|
|
454
|
+
const h = URL.createObjectURL(u), g = document.createElement("a");
|
|
455
|
+
g.href = h, g.download = "atlas.mcap", g.click(), URL.revokeObjectURL(h), g.remove();
|
|
456
|
+
}
|
|
457
|
+
return u;
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
export {
|
|
462
|
+
Tt as audioBufferToWav,
|
|
463
|
+
Gt as buildMeshCapAtlas,
|
|
464
|
+
zt as createAudioAtlasPlayer,
|
|
465
|
+
Bt as createMeshCapMaterial,
|
|
466
|
+
Lt as extractAudioSprites,
|
|
467
|
+
_t as loadMeshCapFile
|
|
468
|
+
};
|
package/dist/module.d.ts
CHANGED
package/dist/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AACA,cAAc,2BAA2B,CAAA"}
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AACA,cAAc,2BAA2B,CAAA;AACzC,cAAc,oCAAoC,CAAA"}
|
package/dist/rigger.d.ts
ADDED