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
package/README.md CHANGED
@@ -10,13 +10,15 @@ The motion from the webcam will be applied to a skeleton. Angle based so it work
10
10
  This will run 3 models: face, body, hands. So expect a FPS drop.
11
11
 
12
12
  Expolore the demos:
13
+ - New! [**MeshCap Editor**](https://github.com/bandinopla/three-mediapipe-rig/blob/main/MESHCAP.md)
13
14
  - [Characters](https://bandinopla.github.io/three-mediapipe-rig)
14
15
  - [Hands Demo](https://bandinopla.github.io/three-mediapipe-rig/?demo=hands)
15
16
  - [**Video to Face Geometry** !!](https://bandinopla.github.io/three-mediapipe-rig/?demo=face-uv)
17
+
16
18
  ---
17
19
 
18
20
  ## Table of Contents
19
-
21
+ - New! [**MeshCap Editor**](https://github.com/bandinopla/three-mediapipe-rig/blob/main/MESHCAP.md)
20
22
  - [Features](#features)
21
23
  - [Installation](#installation)
22
24
  - [Quick Start](#quick-start)
@@ -0,0 +1,16 @@
1
+ import { BufferAttribute as c } from "three";
2
+ const d = 478, g = (r) => {
3
+ if (r.geometry.hasAttribute("landmarkIndex")) return;
4
+ const s = r.geometry, e = s.attributes.position, a = [], n = /* @__PURE__ */ new Map(), i = [];
5
+ for (let t = 0; t < e.count; t++) {
6
+ const o = Math.round(e.getX(t) * 1e6) + "," + Math.round(e.getY(t) * 1e6) + "," + Math.round(e.getZ(t) * 1e6);
7
+ n.has(o) || (n.set(o, a.length), a.push(t));
8
+ const u = n.get(o);
9
+ i.push(u < d ? u : 65535);
10
+ }
11
+ s.setAttribute("landmarkIndex", new c(new Uint16Array(i), 1));
12
+ };
13
+ export {
14
+ d as F,
15
+ g as c
16
+ };
@@ -0,0 +1,10 @@
1
+ import { MeshCapAtlas, RecordedClip } from './types';
2
+ /**
3
+ * Builds a texture atlas from a list of recorded clips.
4
+ * @param clips The clips to build the atlas from
5
+ * @param atlasSize Max size of the atlas (width or height)
6
+ * @param padding The padding to add between frames
7
+ * @returns The atlas
8
+ */
9
+ export declare function buildMeshCapAtlas(clips: RecordedClip[], atlasSize: number, padding?: number): MeshCapAtlas;
10
+ //# sourceMappingURL=atlas-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atlas-builder.d.ts","sourceRoot":"","sources":["../../src/meshcap/atlas-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAY,YAAY,EAAW,MAAM,SAAS,CAAC;AA0DxE;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAE,KAAK,EAAC,YAAY,EAAE,EAAE,SAAS,EAAC,MAAM,EAAE,OAAO,GAAC,MAAQ,GAAG,YAAY,CAsGzG"}
@@ -0,0 +1,3 @@
1
+ export declare const MCAP_MAGIC = 1296253264;
2
+ export declare const MCAP_FILE_VERSION = 1;
3
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/meshcap/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,UAAU,aAAa,CAAC;AACrC,eAAO,MAAM,iBAAiB,IAAI,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { Mesh, Texture } from 'three';
2
+ import { MCapClip } from './types';
3
+ import { NodeMaterial } from 'three/webgpu';
4
+ export type MeshCapMaterialHandler = {
5
+ /**
6
+ * Moves to a particular clip
7
+ * @param clipIndex The index of the clip to move to
8
+ */
9
+ goto: (clipIndex: number | string, _loop?: boolean) => void;
10
+ /**
11
+ * Play a clip and when it reaches the end, it will loop back
12
+ * @param clipName Name of the clip
13
+ * @returns
14
+ */
15
+ gotoAndLoop: (clipIndex: number | string) => void;
16
+ /**
17
+ * Play a clip and when it reaches the end, it will not loop back
18
+ * @param clipName Name of the clip
19
+ * @returns
20
+ */
21
+ gotoAndPlay: (clipIndex: number | string) => void;
22
+ /**
23
+ * Updates the material with the given delta time
24
+ * @param delta The time to add to the current time
25
+ */
26
+ update: (delta: number) => void;
27
+ /**
28
+ * The clips available to play
29
+ */
30
+ clips: MCapClip[];
31
+ /**
32
+ * The texture atlas that contains the frames used by the clips
33
+ */
34
+ atlasTexture: Texture;
35
+ /**
36
+ * Disposes the material and the texture atlas
37
+ */
38
+ dispose: VoidFunction;
39
+ /**
40
+ * The material used
41
+ */
42
+ material: NodeMaterial;
43
+ };
44
+ /**
45
+ * Creates or setups a MeshCap material handler (not the material itself) for a given mesh.
46
+ * @param atlasTexture The texture atlas that contains the frames used by the clips
47
+ * @param clips The clips previously obtained by loading an .mcap file
48
+ * @param targetMesh The mesh to apply the material to. (It will be updated with a landmarkIndex attribute if it doesn't have one)
49
+ * @param host Optional: The material to use as a base. Defaults to a MeshPhysicalNodeMaterial.
50
+ * @returns A handler that allows you to control the material.
51
+ */
52
+ export declare function createMeshCapMaterial(atlasTexture: Texture, clips: MCapClip[], targetMesh: Mesh, host?: NodeMaterial): MeshCapMaterialHandler;
53
+ //# sourceMappingURL=material.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/meshcap/material.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAA4B,YAAY,EAAW,MAAM,cAAc,CAAC;AAM/E,MAAM,MAAM,sBAAsB,GAAG;IAEpC;;;OAGG;IACH,IAAI,EAAC,CAAE,SAAS,EAAC,MAAM,GAAC,MAAM,EAAE,KAAK,CAAC,EAAC,OAAO,KAAI,IAAI,CAAA;IAEtD;;;;OAIG;IACH,WAAW,EAAC,CAAE,SAAS,EAAC,MAAM,GAAC,MAAM,KAAI,IAAI,CAAA;IAE7C;;;;OAIG;IACH,WAAW,EAAC,CAAE,SAAS,EAAC,MAAM,GAAC,MAAM,KAAI,IAAI,CAAA;IAE7C;;;OAGG;IACH,MAAM,EAAC,CAAE,KAAK,EAAC,MAAM,KAAI,IAAI,CAAA;IAE7B;;OAEG;IACH,KAAK,EAAC,QAAQ,EAAE,CAAA;IAEhB;;OAEG;IACH,YAAY,EAAC,OAAO,CAAA;IAEpB;;OAEG;IACH,OAAO,EAAC,YAAY,CAAA;IAEpB;;OAEG;IACH,QAAQ,EAAC,YAAY,CAAA;CACrB,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAE,YAAY,EAAC,OAAO,EAAE,KAAK,EAAC,QAAQ,EAAE,EAAE,UAAU,EAAC,IAAI,EAAE,IAAI,CAAC,EAAC,YAAY,GAAG,sBAAsB,CAkN1I"}
@@ -0,0 +1,5 @@
1
+ export type * from './types';
2
+ export * from './parse-mcap-file';
3
+ export * from './atlas-builder';
4
+ export * from './material';
5
+ //# sourceMappingURL=meshcap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meshcap.d.ts","sourceRoot":"","sources":["../../src/meshcap/meshcap.ts"],"names":[],"mappings":"AAAA,mBAAmB,SAAS,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { MCapFile } from './types';
2
+ /**
3
+ * Loads a MeshCap (.mcap) file from a URL or File object. This is the file that contains the metadata for the clips.
4
+ * @param mcapFileSource URL or File object
5
+ * @returns
6
+ */
7
+ export declare function loadMeshCapFile(mcapFileSource: string | File): Promise<MCapFile>;
8
+ //# sourceMappingURL=parse-mcap-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-mcap-file.d.ts","sourceRoot":"","sources":["../../src/meshcap/parse-mcap-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,QAAQ,EAAyB,MAAM,SAAS,CAAC;AAOpE;;;;GAIG;AACH,wBAAsB,eAAe,CAAE,cAAc,EAAC,MAAM,GAAC,IAAI,GAAK,OAAO,CAAC,QAAQ,CAAC,CAmBtF"}
@@ -0,0 +1,53 @@
1
+ import { Vector3Like } from 'three';
2
+ export interface UVCoord {
3
+ u: number;
4
+ v: number;
5
+ w: number;
6
+ h: number;
7
+ }
8
+ export interface Clip {
9
+ fps: number;
10
+ name: string;
11
+ landmarks: Vector3Like[][];
12
+ scale: number;
13
+ aspectRatio: number;
14
+ }
15
+ export interface RecordedClip extends Clip {
16
+ frames: {
17
+ canvas: HTMLCanvasElement;
18
+ cropUV: UVCoord;
19
+ }[];
20
+ }
21
+ export interface MCapClip extends Clip {
22
+ frames: {
23
+ cropUV: UVCoord;
24
+ frameUV: UVCoord;
25
+ }[];
26
+ }
27
+ export interface MCapFile {
28
+ clips: MCapClip[];
29
+ version: number;
30
+ atlasSize: number;
31
+ atlasPadding: number;
32
+ /**
33
+ * Extract the clips from the atlas image using the metadata as a guide to know where the clips are.
34
+ * @param atlas
35
+ */
36
+ unpackClips: (atlas: File | string | HTMLImageElement | HTMLCanvasElement) => Promise<RecordedClip[]>;
37
+ }
38
+ export interface MeshCapAtlas {
39
+ canvas: HTMLCanvasElement;
40
+ /**
41
+ * the index of each will correspond to the provided recorded clip's frames array at the time of creation
42
+ */
43
+ clips: MCapClip[];
44
+ /**
45
+ * padding used in the creation of the atlas
46
+ */
47
+ padding: number;
48
+ /**
49
+ *
50
+ */
51
+ save(downloadFile: boolean): Promise<Blob>;
52
+ }
53
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/meshcap/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAInC,MAAM,WAAW,OAAO;IAAE,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC;AAE9D,MAAM,WAAW,IAAI;IACpB,GAAG,EAAC,MAAM,CAAC;IACX,IAAI,EAAC,MAAM,CAAC;IACZ,SAAS,EAAC,WAAW,EAAE,EAAE,CAAC;IAC1B,KAAK,EAAC,MAAM,CAAA;IACZ,WAAW,EAAC,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,YAAa,SAAQ,IAAI;IACzC,MAAM,EAAC;QAAE,MAAM,EAAC,iBAAiB,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,QAAS,SAAQ,IAAI;IACrC,MAAM,EAAE;QAAE,MAAM,EAAC,OAAO,CAAC;QAAC,OAAO,EAAC,OAAO,CAAA;KAAE,EAAE,CAAA;CAC7C;AAED,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAC,MAAM,CAAC;IACjB,YAAY,EAAC,MAAM,CAAC;IAEpB;;;OAGG;IACH,WAAW,EAAE,CAAC,KAAK,EAAC,IAAI,GAAC,MAAM,GAAC,gBAAgB,GAAC,iBAAiB,KAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC7F;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,iBAAiB,CAAC;IAE7B;;OAEG;IACA,KAAK,EAAE,QAAQ,EAAE,CAAC;IAErB;;OAEG;IACH,OAAO,EAAC,MAAM,CAAA;IAEd;;OAEG;IACH,IAAI,CAAE,YAAY,EAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1C"}
@@ -0,0 +1,3 @@
1
+ import { MeshCapAtlas } from './types';
2
+ export declare function atlasToMCap(atlas: MeshCapAtlas, useRelativeLandmarks?: boolean): Promise<Blob>;
3
+ //# sourceMappingURL=write-mcap-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-mcap-file.d.ts","sourceRoot":"","sources":["../../src/meshcap/write-mcap-file.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvC,wBAAsB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,oBAAoB,GAAC,OAAc,iBA2JzF"}
@@ -0,0 +1,2 @@
1
+ export * from './meshcap/meshcap'
2
+ export {}
@@ -0,0 +1,316 @@
1
+ import { inflate as ht, deflate as ft } from "fflate";
2
+ import { F as N, c as mt } from "./face-tracker-utils-xt9__vBF.js";
3
+ import { MeshPhysicalNodeMaterial as pt, Vector3 as W } from "three/webgpu";
4
+ import { instancedArray as B, texture as G, uniform as O, select as ut, attribute as gt, varying as Ut, vec3 as wt, float as yt } from "three/tsl";
5
+ const J = 1296253264, _ = 1;
6
+ async function Rt(m) {
7
+ if (typeof m == "string") {
8
+ const o = await (await fetch(m)).arrayBuffer();
9
+ return K(o);
10
+ } else
11
+ return new Promise((u, o) => {
12
+ const e = new FileReader();
13
+ e.onload = (v) => {
14
+ const x = v.target.result;
15
+ u(K(x));
16
+ }, e.onerror = (v) => {
17
+ o(v);
18
+ }, e.readAsArrayBuffer(m);
19
+ });
20
+ }
21
+ async function K(m) {
22
+ const u = await new Promise((a, r) => {
23
+ ht(new Uint8Array(m), (p, y) => {
24
+ p ? r(p) : a(y);
25
+ });
26
+ }), o = new DataView(u.buffer);
27
+ let e = 0;
28
+ const v = o.getUint32(e);
29
+ if (e += 4, v !== J) throw new Error("Invalid file: not a MCAP file");
30
+ const x = o.getUint8(e);
31
+ if (e += 1, x !== _) throw new Error(`Unsupported version: ${x} != ${_}`);
32
+ const h = o.getUint8(e);
33
+ e += 1;
34
+ const s = o.getUint16(e);
35
+ e += 2;
36
+ const t = o.getUint8(e);
37
+ e += 1;
38
+ const f = [];
39
+ for (let a = 0; a < h; a++) {
40
+ const r = o.getUint8(e);
41
+ e += 1;
42
+ const p = new Uint8Array(u.buffer, e, r), y = new TextDecoder().decode(p);
43
+ e += r;
44
+ const i = o.getUint8(e);
45
+ e += 1;
46
+ const U = o.getUint8(e);
47
+ e += 1;
48
+ const n = o.getUint8(e) / 100;
49
+ e += 1;
50
+ const c = o.getUint8(e) / 100;
51
+ e += 1;
52
+ const l = [], g = [], b = [];
53
+ for (let M = 0; M < i; M++) {
54
+ const k = o.getUint16(e) / 1e3;
55
+ e += 2;
56
+ const A = o.getUint16(e) / 1e3;
57
+ e += 2;
58
+ const R = o.getUint16(e) / 1e3;
59
+ e += 2;
60
+ const L = o.getUint16(e) / 1e3;
61
+ e += 2, l.push({ u: k, v: A, w: R, h: L });
62
+ const Y = o.getUint16(e) / 1e3;
63
+ e += 2;
64
+ const P = o.getUint16(e) / 1e3;
65
+ e += 2;
66
+ const q = o.getUint16(e) / 1e3;
67
+ e += 2;
68
+ const T = o.getUint16(e) / 1e3;
69
+ e += 2, b.push({ u: Y, v: P, w: q, h: T });
70
+ const C = [], z = M > 0 ? g[M - 1] : null;
71
+ for (let V = 0; V < N; V++)
72
+ if (z === null) {
73
+ const F = o.getUint16(e) / 1e3;
74
+ e += 2;
75
+ const E = o.getUint16(e) / 1e3;
76
+ e += 2;
77
+ const X = o.getInt16(e) / 1e3;
78
+ e += 2, C.push({ x: F, y: E, z: X });
79
+ } else {
80
+ const F = o.getInt8(e) / 1e3;
81
+ e += 1;
82
+ const E = o.getInt8(e) / 1e3;
83
+ e += 1;
84
+ const X = o.getInt8(e) / 1e3;
85
+ e += 1, C.push({
86
+ x: z[V].x + F,
87
+ y: z[V].y + E,
88
+ z: z[V].z + X
89
+ });
90
+ }
91
+ g.push(C);
92
+ }
93
+ f.push({
94
+ name: y,
95
+ fps: U,
96
+ scale: n,
97
+ aspectRatio: c,
98
+ frames: b.map((M, k) => ({
99
+ cropUV: M,
100
+ frameUV: l[k]
101
+ })),
102
+ landmarks: g
103
+ });
104
+ }
105
+ return {
106
+ clips: f,
107
+ version: x,
108
+ atlasSize: s,
109
+ atlasPadding: t,
110
+ unpackClips: async (a) => {
111
+ let r, p = !0;
112
+ if (a instanceof HTMLCanvasElement)
113
+ p = !1, r = a;
114
+ else {
115
+ let i = new Image();
116
+ if (typeof a == "string")
117
+ i.src = a;
118
+ else if (a instanceof File || a instanceof Blob) {
119
+ const n = URL.createObjectURL(a);
120
+ i.src = n, await new Promise((c, l) => {
121
+ i.onload = () => {
122
+ URL.revokeObjectURL(n), c();
123
+ }, i.onerror = l;
124
+ });
125
+ } else a instanceof HTMLImageElement && (i = a);
126
+ (!i.complete || !i.naturalWidth) && await new Promise((n, c) => {
127
+ i.onload = () => n(), i.onerror = c;
128
+ }), r = document.createElement("canvas"), r.width = i.width, r.height = i.height, r.getContext("2d").drawImage(i, 0, 0);
129
+ }
130
+ const y = f.map((i) => ({
131
+ ...i,
132
+ frames: i.frames.map((U) => {
133
+ const n = document.createElement("canvas");
134
+ return n.width = U.frameUV.w * r.width, n.height = U.frameUV.h * r.height, n.getContext("2d").drawImage(
135
+ r,
136
+ U.frameUV.u * r.width,
137
+ U.frameUV.v * r.height,
138
+ U.frameUV.w * r.width,
139
+ U.frameUV.h * r.height,
140
+ 0,
141
+ 0,
142
+ n.width,
143
+ n.height
144
+ ), {
145
+ canvas: n,
146
+ cropUV: U.cropUV
147
+ };
148
+ })
149
+ }));
150
+ return p && r.remove(), y;
151
+ }
152
+ };
153
+ }
154
+ async function vt(m, u = !0) {
155
+ const o = new TextEncoder(), e = m.clips.map((f) => o.encode(f.name)), v = 9, x = e.reduce((f, a, r) => {
156
+ const p = m.clips[r].frames.length, y = 1 + a.byteLength, i = 1, U = 1, n = 1, c = 1, l = 16;
157
+ let g = N * 6;
158
+ return f + y + i + U + n + c + (u ? l + g + (l + N * 3) * (p - 1) : (l + g) * p);
159
+ }, 0), h = new ArrayBuffer(v + x), s = new DataView(h);
160
+ let t = 0;
161
+ s.setUint32(t, J), t += 4, s.setUint8(t, _), t += 1, s.setUint8(t, m.clips.length), t += 1, s.setUint16(t, m.canvas.width), t += 2, s.setUint8(t, m.padding), t += 1;
162
+ for (let f = 0; f < m.clips.length; f++) {
163
+ s.setUint8(t, e[f].byteLength), t += 1, new Uint8Array(h, t, e[f].byteLength).set(e[f]), t += e[f].byteLength, s.setUint8(t, m.clips[f].frames.length), t += 1, s.setUint8(t, m.clips[f].fps), t += 1, s.setUint8(t, Math.round(m.clips[f].scale * 100)), t += 1, s.setUint8(t, Math.round(m.clips[f].aspectRatio * 100)), t += 1;
164
+ const a = m.clips[f];
165
+ for (let r = 0; r < a.frames.length; r++) {
166
+ const p = a.frames[r].cropUV, y = a.frames[r].frameUV;
167
+ s.setUint16(t, Math.round(y.u * 1e3)), t += 2, s.setUint16(t, Math.round(y.v * 1e3)), t += 2, s.setUint16(t, Math.round(y.w * 1e3)), t += 2, s.setUint16(t, Math.round(y.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;
168
+ const i = a.landmarks[r], U = r > 0 ? a.landmarks[r - 1] : null;
169
+ i.reduce((n, c) => Math.max(n, Math.abs(c.z)), 0);
170
+ for (let n = 0; n < N; n++) {
171
+ const c = Math.round(i[n].x * 1e3), l = Math.round(i[n].y * 1e3), g = Math.round(i[n].z * 1e3);
172
+ if (u)
173
+ if (U === null)
174
+ s.setUint16(t, c), t += 2, s.setUint16(t, l), t += 2, s.setInt16(t, g), t += 2;
175
+ else {
176
+ const b = Math.round(U[n].x * 1e3), M = Math.round(U[n].y * 1e3), k = Math.round(U[n].z * 1e3), A = c - b, R = l - M, L = g - k;
177
+ console.log("Deltas: ", A), s.setInt8(t, A), t += 1, s.setInt8(t, R), t += 1, s.setInt8(t, L), t += 1;
178
+ }
179
+ else
180
+ s.setUint16(t, c), t += 2, s.setUint16(t, l), t += 2, s.setInt16(t, g), t += 2;
181
+ }
182
+ }
183
+ }
184
+ return new Promise((f, a) => {
185
+ ft(new Uint8Array(h), { level: 9 }, (r, p) => {
186
+ if (r) return a(r);
187
+ const y = new Blob([p], { type: "application/octet-stream" });
188
+ f(y);
189
+ });
190
+ });
191
+ }
192
+ function xt(m, u) {
193
+ const o = [], e = [];
194
+ let v = 0;
195
+ const x = [...m].sort((h, s) => s.height - h.height);
196
+ for (const h of x) {
197
+ let s = !1;
198
+ for (const t of o)
199
+ if (h.width <= u - t.currentX && h.height <= t.height) {
200
+ e.push({ id: h.id, x: t.currentX, y: t.y, width: h.width, height: h.height }), t.currentX += h.width, s = !0;
201
+ break;
202
+ }
203
+ if (!s) {
204
+ const t = {
205
+ y: v,
206
+ height: h.height,
207
+ currentX: h.width
208
+ };
209
+ o.push(t), e.push({ id: h.id, x: 0, y: v, width: h.width, height: h.height }), v += h.height;
210
+ }
211
+ }
212
+ return e;
213
+ }
214
+ const Mt = 20;
215
+ function Lt(m, u, o = 0) {
216
+ const e = m.flatMap((n) => n.frames.map((c) => c.canvas)), v = Array.from(e.entries()).map(([n, c]) => ({
217
+ id: n,
218
+ // index of the frame after all the frames from all the clips have been flattened
219
+ width: c.width + o * 2,
220
+ height: c.height + o * 2
221
+ })), x = xt(v, u), h = Math.max(...x.map((n) => n.y + n.height)) + Mt, s = u, t = Math.min(1, u / s, u / h), f = Math.floor(s * t), a = Math.floor(h * t), r = document.createElement("canvas");
222
+ r.width = f, r.height = a;
223
+ const p = r.getContext("2d");
224
+ p.fillStyle = "#000000", p.fillRect(0, 0, r.width, r.height);
225
+ const y = [];
226
+ for (const n of x) {
227
+ const c = e[n.id], l = n.x + o, g = n.y + o, b = c.width, M = c.height;
228
+ p.drawImage(c, l * t, g * t, b * t, M * t), y[n.id] = {
229
+ u: l * t / f,
230
+ v: g * t / a,
231
+ w: b * t / f,
232
+ h: M * t / a
233
+ };
234
+ }
235
+ const i = [];
236
+ let U = 0;
237
+ for (const n of m) {
238
+ const c = {
239
+ ...n,
240
+ frames: []
241
+ };
242
+ for (const l of n.frames)
243
+ c.frames.push({
244
+ frameUV: y[U++],
245
+ cropUV: l.cropUV
246
+ });
247
+ i.push(c);
248
+ }
249
+ return p.font = `${Math.max(6, Math.floor(12 * t))}px monospace`, p.fillStyle = "#ff0000", p.fillText("Created with MeshCap : https://bandinopla.github.io/three-mediapipe-rig/?app=meshcap", 0, a - Math.max(2, 4 * t)), {
250
+ canvas: r,
251
+ clips: i,
252
+ padding: o,
253
+ async save(n) {
254
+ const c = await vt(this);
255
+ if (n) {
256
+ const l = URL.createObjectURL(c), g = document.createElement("a");
257
+ g.href = l, g.download = "atlas.mcap", g.click(), URL.revokeObjectURL(l), g.remove();
258
+ }
259
+ return c;
260
+ }
261
+ };
262
+ }
263
+ function zt(m, u, o, e) {
264
+ e ?? (e = new pt()), o.geometry.hasAttribute("landmarkIndex") || mt(o);
265
+ const v = [], x = [], h = [];
266
+ let s = 0, t = 0;
267
+ for (let d = 0; d < u.length; d++) {
268
+ const w = u[d];
269
+ v.push(s, t, w.frames.length, w.fps), s += w.frames.length, t += w.frames.length * N, x.push(w.aspectRatio), h.push(d == 0 ? 0 : h[d - 1] + u[d - 1].frames.length);
270
+ }
271
+ const f = B(new Float32Array(x), "float"), a = B(new Uint32Array(v), "uvec4"), r = new Float32Array(u.flatMap((d) => d.frames).reduce((d, w) => (d.push(w.frameUV.u, w.frameUV.v, w.frameUV.w, w.frameUV.h), d), [])), p = B(r, "vec4"), y = new Float32Array(u.flatMap((d) => d.frames.flatMap((w) => [w.cropUV.u, w.cropUV.v, w.cropUV.w, w.cropUV.h]))), i = B(y, "vec4"), U = new Float32Array(u.flatMap((d) => d.landmarks.flatMap((w) => w.flatMap((I) => [I.x, I.y, I.z]))));
272
+ u.reduce((d, w) => d + w.frames.length, 0);
273
+ const n = B(U, "vec3"), c = G(m), l = O(0), g = O(0), b = O(!0), M = f.element(l), k = a.element(l).w, A = a.element(l).z, R = g.mul(k).floor().toUint(), L = ut(
274
+ b.not().and(R.greaterThanEqual(A)),
275
+ // no loop + past end
276
+ A.sub(1),
277
+ // → clamp to last frame
278
+ R.mod(A)
279
+ // → wrap around
280
+ ), Y = B(new Uint32Array(h), "uint"), P = L, q = Y.element(l).add(L), T = p.element(a.element(l).x.add(P)), C = a.element(l).y.add(P.mul(N)), z = gt("landmarkIndex", "uint").toUint(), V = C.add(z), F = n.element(V), E = i.element(q), Q = F.xy.sub(E.xy).div(E.zw), tt = Ut(T.xy.add(Q.mul(T.zw))), et = G(c, tt);
281
+ e.colorNode = et;
282
+ const nt = n.element(C.add(234)).xy, $ = n.element(C.add(93)).xy, ot = n.element(C.add(454)).xy, Z = n.element(C.add(323)).xy, D = nt.sub($).div(2).add($), st = ot.sub(Z).div(2).add(Z).sub(D).div(2).add(D), S = o.geometry.attributes.position, j = 116, H = 346, rt = new W().subVectors(
283
+ new W(S.getX(j), S.getY(j), S.getZ(j)),
284
+ new W(S.getX(H), S.getY(H), S.getZ(H))
285
+ ).lengthSq(), at = O(rt), ct = n.element(C.add(H)).sub(n.element(C.add(j))).lengthSq(), it = at.div(ct).sqrt().mul(2), lt = F.sub(st).xzy.mul(wt(1, -1, yt(1).div(M))).mul(it);
286
+ return e.positionNode = lt, {
287
+ clips: u,
288
+ atlasTexture: m,
289
+ material: e,
290
+ goto(d, w = !0) {
291
+ let I = -1;
292
+ if (typeof d == "number")
293
+ I = d;
294
+ else if (I = u.findIndex((dt) => dt.name === d), I === -1)
295
+ throw new Error(`Clip ${d.toString()} not found`);
296
+ b.value = w, g.value = 0, l.value = I;
297
+ },
298
+ update(d) {
299
+ g.value += d;
300
+ },
301
+ dispose() {
302
+ m.dispose(), e.dispose();
303
+ },
304
+ gotoAndLoop(d) {
305
+ this.goto(d, !0);
306
+ },
307
+ gotoAndPlay(d) {
308
+ this.goto(d, !1);
309
+ }
310
+ };
311
+ }
312
+ export {
313
+ Lt as buildMeshCapAtlas,
314
+ zt as createMeshCapMaterial,
315
+ Rt as loadMeshCapFile
316
+ };
package/dist/module.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './tracking/TrackerManager';
2
+ export * from './tracking/util/face-tracker-utils';
2
3
  //# sourceMappingURL=module.d.ts.map
@@ -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"}
@@ -0,0 +1,2 @@
1
+ export * from './module'
2
+ export {}