@zappar/zappar-cv 3.0.0-beta.7 → 3.0.1-alpha.10

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 (65) hide show
  1. package/README.md +2 -2
  2. package/lib/additional.d.ts +5 -1
  3. package/lib/camera-source.js +8 -4
  4. package/lib/ceres-worker.d.ts +1 -0
  5. package/lib/ceres-worker.js +67 -0
  6. package/lib/data-download.d.ts +8 -0
  7. package/lib/data-download.js +8 -0
  8. package/lib/deserializer.d.ts +1 -0
  9. package/lib/deserializer.js +7 -0
  10. package/lib/direct.js +3 -1
  11. package/lib/drawgrid.d.ts +2 -0
  12. package/lib/drawgrid.js +136 -0
  13. package/lib/drawpoints.d.ts +11 -0
  14. package/lib/drawpoints.js +180 -0
  15. package/lib/gen/zappar-bridge.d.ts +20 -0
  16. package/lib/gen/zappar-bridge.js +1 -0
  17. package/lib/gen/zappar-client.d.ts +1 -0
  18. package/lib/gen/zappar-client.js +208 -13
  19. package/lib/gen/zappar-cwrap.js +144 -3
  20. package/lib/gen/zappar-native.d.ts +24 -1
  21. package/lib/gen/zappar-native.js +6 -0
  22. package/lib/gen/zappar-server.d.ts +3 -0
  23. package/lib/gen/zappar-server.js +108 -10
  24. package/lib/gen/zappar.d.ts +24 -0
  25. package/lib/gen/zappar.js +1 -0
  26. package/lib/html-element-source.d.ts +3 -1
  27. package/lib/html-element-source.js +12 -6
  28. package/lib/image-process-gl.d.ts +3 -2
  29. package/lib/image-process-gl.js +9 -7
  30. package/lib/imagebitmap-camera-source.d.ts +3 -1
  31. package/lib/imagebitmap-camera-source.js +10 -4
  32. package/lib/index.d.ts +1 -1
  33. package/lib/index.js +1 -1
  34. package/lib/mstp-camera-source.d.ts +11 -1
  35. package/lib/mstp-camera-source.js +84 -6
  36. package/lib/native.js +56 -2
  37. package/lib/pipeline.d.ts +3 -1
  38. package/lib/pipeline.js +12 -2
  39. package/lib/profile.d.ts +2 -2
  40. package/lib/profile.js +3 -3
  41. package/lib/serializer.d.ts +1 -0
  42. package/lib/serializer.js +1 -0
  43. package/lib/version.d.ts +1 -1
  44. package/lib/version.js +1 -1
  45. package/lib/worker-client.d.ts +1 -0
  46. package/lib/worker-client.js +23 -1
  47. package/lib/worker-imagebitmap.js +5 -4
  48. package/lib/worker-messages.d.ts +10 -0
  49. package/lib/worker-messages.js +10 -0
  50. package/lib/worker-server.d.ts +1 -1
  51. package/lib/worker-server.js +83 -15
  52. package/lib/worker.js +2 -1
  53. package/lib/workerinterface.d.ts +8 -1
  54. package/lib/zappar-cv.js +215 -134
  55. package/lib/zappar-cv.wasm +0 -0
  56. package/package.json +4 -3
  57. package/umd/169.zappar-cv.js +1 -1
  58. package/umd/25.zappar-cv.js +1 -0
  59. package/umd/751.zappar-cv.js +1 -0
  60. package/umd/867.zappar-cv.js +1 -0
  61. package/umd/ca409d4e8cebe454b816.wasm +0 -0
  62. package/umd/zappar-cv.js +1 -1
  63. package/umd/zappar-cv.worker.js +1 -1
  64. package/umd/51b1854609f16d933fe2.wasm +0 -0
  65. package/umd/56.zappar-cv.js +0 -1
package/lib/native.js CHANGED
@@ -12,7 +12,7 @@ import { zappar_client } from "./gen/zappar-client";
12
12
  import { drawPlane } from "./drawplane";
13
13
  import { cameraRotationForScreenOrientation, projectionMatrix } from "./cameramodel";
14
14
  import { mat4, vec3 } from "gl-matrix";
15
- import { launchWorker, messageManager } from "./worker-client";
15
+ import { launchCeresWorker, launchWorker, messageManager } from "./worker-client";
16
16
  import { permissionRequestUI, permissionGrantedAll, permissionGrantedCamera, permissionGrantedMotion, permissionDeniedAny, permissionDeniedCamera, permissionDeniedMotion, permissionRequestMotion, permissionRequestCamera, permissionRequestAll, permissionDeniedUI } from "./permission";
17
17
  import { createFaceMesh, destroyFaceMesh, getFaceMesh } from "./facemesh";
18
18
  import { Pipeline, applyScreenCounterRotation } from "./pipeline";
@@ -26,7 +26,10 @@ import { createCameraSource, getCameraSource } from "./camera-source-map";
26
26
  import { gfx } from "./gfx";
27
27
  import { ImageTracker } from "./imagetracker";
28
28
  import { MSTPCameraSource } from "./mstp-camera-source";
29
+ import { drawGrid } from "./drawgrid";
30
+ import { getPointsDataMatrix } from "./drawpoints";
29
31
  let client;
32
+ const pipelineByWorldTracker = new Map();
30
33
  export function initialize(opts) {
31
34
  if (client)
32
35
  return client;
@@ -84,6 +87,19 @@ export function initialize(opts) {
84
87
  src.streamEnded();
85
88
  break;
86
89
  }
90
+ case "setupCeresWorker": {
91
+ launchCeresWorker(msg.port);
92
+ break;
93
+ }
94
+ case "_z_datadownload": {
95
+ let blob = new Blob([msg.data], { type: "application/octet-stream" });
96
+ let url = URL.createObjectURL(blob);
97
+ let a = document.createElement("a");
98
+ a.download = "sequencedata.bin";
99
+ a.href = url;
100
+ a.click();
101
+ break;
102
+ }
87
103
  case "licerr": {
88
104
  let div = document.createElement("div");
89
105
  div.innerHTML = "Visit <a href='https://docs.zap.works/universal-ar/licensing/' style='color: white;'>our licensing page</a> to find out about hosting on your own domain.";
@@ -133,7 +149,7 @@ export function initialize(opts) {
133
149
  }
134
150
  }
135
151
  });
136
- client = Object.assign(Object.assign({}, c.impl), { loaded: () => loaded, camera_default_device_id: userFacing => userFacing ? CameraSource.USER_DEFAULT_DEVICE_ID : CameraSource.DEFAULT_DEVICE_ID, camera_source_create: (p, deviceId) => createCameraSource(p, deviceId), camera_source_destroy: cam => { var _a; return (_a = getCameraSource(cam)) === null || _a === void 0 ? void 0 : _a.destroy(); }, camera_source_pause: cam => { var _a; return (_a = getCameraSource(cam)) === null || _a === void 0 ? void 0 : _a.pause(); }, camera_source_start: cam => { var _a; return (_a = getCameraSource(cam)) === null || _a === void 0 ? void 0 : _a.start(); }, camera_count: () => 2, camera_id: indx => indx === 0 ? CameraSource.DEFAULT_DEVICE_ID : CameraSource.USER_DEFAULT_DEVICE_ID, camera_name: indx => indx === 0 ? "Rear-facing Camera" : "User-facing Camera", camera_user_facing: indx => indx !== 0, pose_from_raw: (raw_pose, mirror) => {
152
+ client = Object.assign(Object.assign({}, c.impl), { loaded: () => loaded, camera_default_device_id: userFacing => userFacing ? CameraSource.USER_DEFAULT_DEVICE_ID : CameraSource.DEFAULT_DEVICE_ID, camera_source_create: (p, deviceId) => createCameraSource(p, deviceId), camera_source_destroy: cam => { var _a; return (_a = getCameraSource(cam)) === null || _a === void 0 ? void 0 : _a.destroy(); }, camera_source_pause: cam => { var _a; return (_a = getCameraSource(cam)) === null || _a === void 0 ? void 0 : _a.pause(); }, camera_source_start: cam => { var _a; return (_a = getCameraSource(cam)) === null || _a === void 0 ? void 0 : _a.start(); }, camera_source_profile_set: (cam, p) => { var _a; return (_a = getCameraSource(cam)) === null || _a === void 0 ? void 0 : _a.setProfile(p); }, camera_count: () => 2, camera_id: indx => indx === 0 ? CameraSource.DEFAULT_DEVICE_ID : CameraSource.USER_DEFAULT_DEVICE_ID, camera_name: indx => indx === 0 ? "Rear-facing Camera" : "User-facing Camera", camera_user_facing: indx => indx !== 0, pose_from_raw: (raw_pose, mirror) => {
137
153
  let res = applyScreenCounterRotation(undefined, raw_pose);
138
154
  if (mirror) {
139
155
  let scale = mat4.create();
@@ -145,8 +161,18 @@ export function initialize(opts) {
145
161
  }, pipeline_create: () => Pipeline.create(c.impl, messageManager), pipeline_frame_update: (p) => { var _a; return (_a = Pipeline.get(p)) === null || _a === void 0 ? void 0 : _a.frameUpdate(c); }, pipeline_camera_frame_draw_gl: (pipeline, screenWidth, screenHeight, mirror) => {
146
162
  var _a;
147
163
  (_a = Pipeline.get(pipeline)) === null || _a === void 0 ? void 0 : _a.cameraFrameDrawGL(screenWidth, screenHeight, mirror);
164
+ }, pipeline_camera_frame_data_width: (pipeline) => {
165
+ var _a, _b;
166
+ const info = (_a = Pipeline.get(pipeline)) === null || _a === void 0 ? void 0 : _a.getCurrentCameraInfo();
167
+ return (_b = info === null || info === void 0 ? void 0 : info.dataWidth) !== null && _b !== void 0 ? _b : 0;
168
+ }, pipeline_camera_frame_data_height: (pipeline) => {
169
+ var _a, _b;
170
+ const info = (_a = Pipeline.get(pipeline)) === null || _a === void 0 ? void 0 : _a.getCurrentCameraInfo();
171
+ return (_b = info === null || info === void 0 ? void 0 : info.dataHeight) !== null && _b !== void 0 ? _b : 0;
148
172
  }, draw_plane: (gl, projectionMatrix, cameraMatrix, targetMatrix, texture) => {
149
173
  drawPlane(gl, projectionMatrix, cameraMatrix, targetMatrix, texture);
174
+ }, draw_grid: (gl, projectionMatrix, cameraMatrix, targetMatrix) => {
175
+ drawGrid(gl, projectionMatrix, cameraMatrix, targetMatrix);
150
176
  }, pipeline_draw_face: (p, projectionMatrix, cameraMatrix, targetMatrix, o) => {
151
177
  var _a;
152
178
  let obj = getFaceMesh(o);
@@ -353,6 +379,25 @@ export function initialize(opts) {
353
379
  return 0;
354
380
  }
355
381
  return obj.getPreviewMesh(indx).normals.length;
382
+ }, zapcode_tracker_anchor_pose_camera_relative: (o, indx, mirror) => {
383
+ let res = applyScreenCounterRotation(undefined, c.impl.zapcode_tracker_anchor_pose_raw(o, indx));
384
+ if (mirror) {
385
+ let scale = mat4.create();
386
+ mat4.fromScaling(scale, [-1, 1, 1]);
387
+ mat4.multiply(res, scale, res);
388
+ mat4.multiply(res, res, scale);
389
+ }
390
+ return res;
391
+ }, zapcode_tracker_anchor_pose: (o, indx, cameraPose, mirror) => {
392
+ let res = applyScreenCounterRotation(undefined, c.impl.zapcode_tracker_anchor_pose_raw(o, indx));
393
+ if (mirror) {
394
+ let scale = mat4.create();
395
+ mat4.fromScaling(scale, [-1, 1, 1]);
396
+ mat4.multiply(res, scale, res);
397
+ mat4.multiply(res, res, scale);
398
+ }
399
+ mat4.multiply(res, cameraPose, res);
400
+ return res;
356
401
  }, face_tracker_anchor_pose_camera_relative: (o, indx, mirror) => {
357
402
  let res = applyScreenCounterRotation(undefined, c.impl.face_tracker_anchor_pose_raw(o, indx));
358
403
  if (mirror) {
@@ -500,6 +545,15 @@ export function initialize(opts) {
500
545
  return mat4.create();
501
546
  }
502
547
  return obj.anchor_pose;
548
+ }, world_tracker_create: (pipeline) => {
549
+ const ret = c.impl.world_tracker_create(pipeline);
550
+ pipelineByWorldTracker.set(ret, pipeline);
551
+ return ret;
552
+ }, world_tracker_points_data_matrix: (wt, screenWidth, screenHeight, mirror) => {
553
+ const pipeline = pipelineByWorldTracker.get(wt);
554
+ if (pipeline === undefined || !client)
555
+ return mat4.create();
556
+ return getPointsDataMatrix(client.pipeline_camera_frame_data_width(pipeline), client.pipeline_camera_frame_data_height(pipeline), screenWidth, screenHeight, mirror);
503
557
  }, world_tracker_plane_pose_camera_relative: (o, indx, mirror) => {
504
558
  let res = applyScreenCounterRotation(undefined, c.impl.world_tracker_plane_pose_raw(o, indx));
505
559
  if (mirror) {
package/lib/pipeline.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /// <reference types="dom-webcodecs" />
2
2
  import { zappar_pipeline_t, zappar_camera_source_t } from "./gen/zappar";
3
+ import { camera_profile_t } from "./gen/zappar-native";
3
4
  import { zappar_client } from "./gen/zappar-client";
4
5
  import { MsgManager } from "./messages";
5
6
  import { Source, CameraFrameInfo } from "./source";
@@ -74,8 +75,9 @@ export declare class Pipeline {
74
75
  motionAttitudeSubmit(timestamp: number, x: number, y: number, z: number): void;
75
76
  motionAttitudeMatrix(m: Float32Array): void;
76
77
  sendCameraStreamToWorker(source: zappar_camera_source_t, stream: ReadableStream<VideoFrame>, userFacing: boolean): void;
78
+ sendCameraProfileToWorker(source: zappar_camera_source_t, profile: camera_profile_t): void;
77
79
  sendCameraToScreenRotationToWorker(rot: number): void;
78
- sendImageBitmapToWorker(img: ImageBitmap, rot: number, userFacing: boolean, tokenId: number, cameraModel: Float32Array, cameraToDevice: Float32Array): void;
80
+ sendImageBitmapToWorker(img: ImageBitmap, rot: number, userFacing: boolean, tokenId: number, cameraModel: Float32Array, cameraToDevice: Float32Array, cp: camera_profile_t): void;
79
81
  sendDataToWorker(data: ArrayBuffer, token: number, width: number, height: number, userFacing: boolean, cameraToDevice: Float32Array, cameraModel: Float32Array): void;
80
82
  }
81
83
  export declare function applyScreenCounterRotation(info: CameraFrameInfo | undefined, inp: Float32Array): Float32Array;
package/lib/pipeline.js CHANGED
@@ -448,6 +448,15 @@ export class Pipeline {
448
448
  };
449
449
  this._mgr.postOutgoingMessage(msg, [msg.s]);
450
450
  }
451
+ sendCameraProfileToWorker(source, profile) {
452
+ let msg = {
453
+ t: "cameraProfileC2S",
454
+ p: this._impl,
455
+ source,
456
+ profile
457
+ };
458
+ this._mgr.postOutgoingMessage(msg, []);
459
+ }
451
460
  sendCameraToScreenRotationToWorker(rot) {
452
461
  let msg = {
453
462
  p: this._impl,
@@ -456,7 +465,7 @@ export class Pipeline {
456
465
  };
457
466
  this._mgr.postOutgoingMessage(msg, []);
458
467
  }
459
- sendImageBitmapToWorker(img, rot, userFacing, tokenId, cameraModel, cameraToDevice) {
468
+ sendImageBitmapToWorker(img, rot, userFacing, tokenId, cameraModel, cameraToDevice, cp) {
460
469
  let msg = {
461
470
  p: this._impl,
462
471
  t: "imageBitmapC2S",
@@ -465,7 +474,8 @@ export class Pipeline {
465
474
  tokenId,
466
475
  userFacing,
467
476
  cameraModel,
468
- cameraToDevice
477
+ cameraToDevice,
478
+ cp
469
479
  };
470
480
  this._mgr.postOutgoingMessage(msg, [img]);
471
481
  }
package/lib/profile.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { camera_profile_t } from "./gen/zappar-native";
1
2
  export declare enum EmbeddedVideoImplementation {
2
3
  OBJECT_URL = 0,
3
4
  SRC_OBJECT = 1
@@ -10,8 +11,7 @@ export declare let profile: {
10
11
  requestHighFrameRate: boolean;
11
12
  videoWidth: number;
12
13
  videoHeight: number;
13
- dataWidth: number;
14
- dataHeight: number;
14
+ getDataSize: (p: camera_profile_t) => number[];
15
15
  videoElementInDOM: boolean;
16
16
  preferMediaStreamTrackProcessorCamera: boolean;
17
17
  preferImageBitmapCamera: boolean;
package/lib/profile.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as UAParser from "ua-parser-js";
2
+ import { camera_profile_t } from "./gen/zappar-native";
2
3
  export var EmbeddedVideoImplementation;
3
4
  (function (EmbeddedVideoImplementation) {
4
5
  EmbeddedVideoImplementation[EmbeddedVideoImplementation["OBJECT_URL"] = 0] = "OBJECT_URL";
@@ -12,8 +13,7 @@ export let profile = {
12
13
  requestHighFrameRate: false,
13
14
  videoWidth: 640,
14
15
  videoHeight: 480,
15
- dataWidth: 320,
16
- dataHeight: 240,
16
+ getDataSize: (p) => p === camera_profile_t.HIGH ? [640, 480] : [320, 240],
17
17
  videoElementInDOM: false,
18
18
  preferMediaStreamTrackProcessorCamera: true,
19
19
  preferImageBitmapCamera: false,
@@ -80,7 +80,7 @@ function iDevice(version) {
80
80
  // Avoid bug where iOS letterboxes 16:9 into 4:3 for high fps
81
81
  // Doesn't seem needed with newer versions of iOS, tested on 14.8.1 and 15.2
82
82
  profile.videoHeight = 360;
83
- profile.dataHeight = 180;
83
+ profile.getDataSize = (p) => p === camera_profile_t.HIGH ? [640, 360] : [320, 180];
84
84
  }
85
85
  }
86
86
  if (majorVersion === 16 && minorVersion >= 4) {
@@ -8,6 +8,7 @@ export interface MessageAppender {
8
8
  type: (t: number) => void;
9
9
  matrix4x4: (a: Float32Array) => void;
10
10
  matrix3x3: (a: Float32Array) => void;
11
+ floatArray: (a: Float32Array) => void;
11
12
  cameraModel: (a: Float32Array) => void;
12
13
  identityCoefficients: (a: Float32Array) => void;
13
14
  expressionCoefficients: (a: Float32Array) => void;
package/lib/serializer.js CHANGED
@@ -22,6 +22,7 @@ export class MessageSerializer {
22
22
  type: i => this.int(i),
23
23
  matrix4x4: i => this.float32ArrayBuffer(i),
24
24
  matrix3x3: i => this.float32ArrayBuffer(i),
25
+ floatArray: i => this.float32ArrayBuffer(i),
25
26
  identityCoefficients: i => this.float32ArrayBuffer(i),
26
27
  expressionCoefficients: i => this.float32ArrayBuffer(i),
27
28
  cameraModel: i => this.float32ArrayBuffer(i),
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "3.0.0-beta.7";
1
+ export declare const VERSION = "3.0.1-alpha.10";
package/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "3.0.0-beta.7";
1
+ export const VERSION = "3.0.1-alpha.10";
@@ -1,3 +1,4 @@
1
1
  import { MsgManager } from "./messages";
2
2
  export declare let messageManager: MsgManager;
3
3
  export declare function launchWorker(worker?: Worker): Promise<void>;
4
+ export declare function launchCeresWorker(port: MessagePort, worker?: Worker): Promise<void>;
@@ -7,15 +7,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ var _a;
10
11
  import { MsgManager } from "./messages";
11
12
  export let messageManager = new MsgManager();
13
+ const params = new URLSearchParams(window.location.search);
14
+ const shouldRecordData = parseInt((_a = params.get('_zrecorddata')) !== null && _a !== void 0 ? _a : '0');
15
+ const wasmModule = (() => __awaiter(void 0, void 0, void 0, function* () {
16
+ const response = yield fetch(new URL("./zappar-cv.wasm", import.meta.url).toString());
17
+ const module = yield WebAssembly.compileStreaming(response);
18
+ return module;
19
+ }))();
12
20
  export function launchWorker(worker) {
13
21
  return __awaiter(this, void 0, void 0, function* () {
14
22
  if (!worker)
15
23
  worker = new Worker(new URL("./worker", import.meta.url), { type: 'module' });
16
24
  worker.postMessage({
17
25
  t: "wasm",
18
- url: new URL("./zappar-cv.wasm", import.meta.url).toString()
26
+ url: new URL("./zappar-cv.wasm", import.meta.url).toString(),
27
+ module: yield wasmModule,
28
+ shouldRecordData
19
29
  });
20
30
  yield waitForLoad(worker);
21
31
  function sendOutgoing() {
@@ -31,6 +41,18 @@ export function launchWorker(worker) {
31
41
  });
32
42
  });
33
43
  }
44
+ export function launchCeresWorker(port, worker) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ if (!worker)
47
+ worker = new Worker(new URL("./ceres-worker", import.meta.url), { type: 'module' });
48
+ worker.postMessage({
49
+ t: "wasm",
50
+ url: new URL("./zappar-cv.wasm", import.meta.url).toString(),
51
+ module: yield wasmModule,
52
+ port
53
+ }, [port]);
54
+ });
55
+ }
34
56
  function waitForLoad(w) {
35
57
  return new Promise(resolve => {
36
58
  let listener = (msg) => {
@@ -34,12 +34,13 @@ export function handleImageBitmap(m, r, server, mgr) {
34
34
  }
35
35
  if (!texture)
36
36
  return;
37
- if (!pixels || pixels.byteLength < profile.dataWidth * profile.dataHeight) {
37
+ const [dataWidth, dataHeight] = profile.getDataSize(m.cp);
38
+ if (!pixels || pixels.byteLength < dataWidth * dataHeight) {
38
39
  // console.log("Generating pixel buffer", profile.dataWidth * profile.dataHeight);
39
- pixels = new ArrayBuffer(profile.dataWidth * profile.dataHeight);
40
+ pixels = new ArrayBuffer(dataWidth * dataHeight);
40
41
  }
41
- imageProcessor.uploadFrame(texture, m.i, m.r, m.userFacing);
42
- let info = imageProcessor.readFrame(texture, pixels);
42
+ imageProcessor.uploadFrame(texture, m.i, m.r, m.userFacing, m.cp);
43
+ let info = imageProcessor.readFrame(texture, pixels, m.cp);
43
44
  let msg = {
44
45
  t: "imageBitmapS2C",
45
46
  dataWidth: info.dataWidth,
@@ -0,0 +1,10 @@
1
+ import type * as ZNM from "./zappar-cv";
2
+ export interface WorkerMessageAPI {
3
+ worker_message_send_count: () => number;
4
+ worker_message_send_clear: () => void;
5
+ worker_message_send_data_size: (index: number) => number;
6
+ worker_message_send_data: (index: number) => number;
7
+ worker_message_send_reference: (index: number) => number;
8
+ worker_message_receive: (ref: number, size: number, data: number) => void;
9
+ }
10
+ export declare function getWorkerMessageAPI(mod: ZNM.Module): WorkerMessageAPI;
@@ -0,0 +1,10 @@
1
+ export function getWorkerMessageAPI(mod) {
2
+ return {
3
+ worker_message_send_count: mod.cwrap("worker_message_send_count", "number", []),
4
+ worker_message_send_clear: mod.cwrap("worker_message_send_clear", null, []),
5
+ worker_message_send_data_size: mod.cwrap("worker_message_send_data_size", "number", ["number"]),
6
+ worker_message_send_data: mod.cwrap("worker_message_send_data", "number", ["number"]),
7
+ worker_message_send_reference: mod.cwrap("worker_message_send_reference", "number", ["number"]),
8
+ worker_message_receive: mod.cwrap("worker_message_receive", null, ["number", "number", "number"]),
9
+ };
10
+ }
@@ -1,3 +1,3 @@
1
1
  import { MsgManager } from "./messages";
2
2
  export declare let messageManager: MsgManager;
3
- export declare function launchWorkerServer(wasmUrl: string): Promise<void>;
3
+ export declare function launchWorkerServer(wasmUrl: string, module: WebAssembly.Module, shouldRecordData: number): Promise<void>;
@@ -12,14 +12,17 @@ import { getRuntimeObject } from "./gen/zappar-cwrap";
12
12
  import { zappar_server } from "./gen/zappar-server";
13
13
  import { MsgManager } from "./messages";
14
14
  import { mat4 } from "gl-matrix";
15
- import { frame_pixel_format_t } from "./gen/zappar-native";
15
+ import { camera_profile_t, frame_pixel_format_t } from "./gen/zappar-native";
16
16
  import { handleImageBitmap } from "./worker-imagebitmap";
17
- import { profile } from "./profile";
17
+ import { getWorkerMessageAPI } from "./worker-messages";
18
+ import { getDataDownloadAPI } from "./data-download";
18
19
  export let messageManager = new MsgManager();
20
+ let workerMessageChannel;
19
21
  let latestCameraToScreenRotation = 0;
20
22
  let rawDataAccessEnabled = false;
21
23
  const rawCameraFrameBuffersByPipeline = new Map();
22
- export function launchWorkerServer(wasmUrl) {
24
+ const cameraProfileBySource = new Map();
25
+ export function launchWorkerServer(wasmUrl, module, shouldRecordData) {
23
26
  return __awaiter(this, void 0, void 0, function* () {
24
27
  let mod = ZNM.default({
25
28
  locateFile: (path, prefix) => {
@@ -28,8 +31,16 @@ export function launchWorkerServer(wasmUrl) {
28
31
  }
29
32
  return prefix + path;
30
33
  },
34
+ instantiateWasm: (imports, successCallback) => {
35
+ const instance = new WebAssembly.Instance(module, imports);
36
+ successCallback(instance);
37
+ return instance.exports;
38
+ },
31
39
  onRuntimeInitialized: () => {
32
40
  let r = getRuntimeObject(mod);
41
+ const workerMessageAPI = getWorkerMessageAPI(mod);
42
+ const dataDownloadAPI = (shouldRecordData > 0) ? getDataDownloadAPI(mod) : undefined;
43
+ dataDownloadAPI === null || dataDownloadAPI === void 0 ? void 0 : dataDownloadAPI.data_should_record_set(shouldRecordData); // Only happens if dataDownloadAPI is defined
33
44
  let server = new zappar_server(r, (pipelineId, ab) => {
34
45
  messageManager.postOutgoingMessage({
35
46
  p: pipelineId,
@@ -57,6 +68,9 @@ export function launchWorkerServer(wasmUrl) {
57
68
  r.pipeline_frame_update(pipeline);
58
69
  att = r.pipeline_camera_frame_device_attitude(pipeline);
59
70
  server.exploreState();
71
+ handleMessages(mod, workerMessageAPI);
72
+ if (dataDownloadAPI)
73
+ handleDataDownload(mod, dataDownloadAPI);
60
74
  }
61
75
  let ret = {
62
76
  token: msgt.token,
@@ -85,9 +99,14 @@ export function launchWorkerServer(wasmUrl) {
85
99
  messageManager.postOutgoingMessage(ret, []);
86
100
  break;
87
101
  }
102
+ case "cameraProfileC2S": {
103
+ let msgt = msg;
104
+ cameraProfileBySource.set(msgt.source, msgt.p);
105
+ break;
106
+ }
88
107
  case "streamC2S": {
89
108
  let msgt = msg;
90
- consumeStream(mod, r, msgt.s, msgt.p, msgt.userFacing, server, msgt.source).then(() => {
109
+ consumeStream(mod, r, msgt.s, msgt.p, msgt.userFacing, server, msgt.source, workerMessageAPI, dataDownloadAPI).then(() => {
91
110
  let m = { t: "streamEndedS2C", p: msgt.p, source: msgt.source };
92
111
  // console.log('Stream ended, requesting new stream');
93
112
  messageManager.postOutgoingMessage(m, []);
@@ -151,7 +170,7 @@ export function launchWorkerServer(wasmUrl) {
151
170
  });
152
171
  }
153
172
  ;
154
- function consumeStream(mod, r, stream, p, userFacing, server, source) {
173
+ function consumeStream(mod, r, stream, p, userFacing, server, source, workerMessageAPI, dataDownloadAPI) {
155
174
  return __awaiter(this, void 0, void 0, function* () {
156
175
  while (true) {
157
176
  let reader;
@@ -164,7 +183,7 @@ function consumeStream(mod, r, stream, p, userFacing, server, source) {
164
183
  continue;
165
184
  }
166
185
  try {
167
- yield consumeReader(mod, r, reader, p, userFacing, server, source);
186
+ yield consumeReader(mod, r, reader, p, userFacing, server, source, workerMessageAPI, dataDownloadAPI);
168
187
  return;
169
188
  }
170
189
  catch (err) {
@@ -192,8 +211,8 @@ function getFrameOrTimeout(reader) {
192
211
  }
193
212
  const cameraToDeviceTransform = mat4.create();
194
213
  const cameraModel = new Float32Array([300, 300, 160, 120, 0, 0]);
195
- function consumeReader(mod, r, reader, p, userFacing, server, source) {
196
- var _a;
214
+ function consumeReader(mod, r, reader, p, userFacing, server, source, workerMessageAPI, dataDownloadAPI) {
215
+ var _a, _b;
197
216
  return __awaiter(this, void 0, void 0, function* () {
198
217
  while (true) {
199
218
  let result = yield getFrameOrTimeout(reader);
@@ -236,16 +255,22 @@ function consumeReader(mod, r, reader, p, userFacing, server, source) {
236
255
  uvTransform = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
237
256
  break;
238
257
  }
258
+ let downSample = false;
259
+ if (cameraProfileBySource.get(source) !== camera_profile_t.HIGH) {
260
+ dataWidth /= 2;
261
+ dataHeight /= 2;
262
+ downSample = true;
263
+ }
239
264
  let clone = frame.clone();
240
265
  if (userFacing)
241
266
  mat4.fromScaling(cameraToDeviceTransform, [-1, 1, -1]);
242
267
  else
243
268
  mat4.identity(cameraToDeviceTransform);
244
- let focalLength = 300.0 * profile.dataWidth / 320.0;
269
+ let focalLength = 300.0 * dataWidth / 320.0;
245
270
  cameraModel[0] = focalLength;
246
271
  cameraModel[1] = focalLength;
247
- cameraModel[2] = profile.dataWidth * 0.5;
248
- cameraModel[3] = profile.dataHeight * 0.5;
272
+ cameraModel[2] = dataWidth * 0.5;
273
+ cameraModel[3] = dataHeight * 0.5;
249
274
  const ret = {
250
275
  token: token,
251
276
  d: clone,
@@ -253,8 +278,8 @@ function consumeReader(mod, r, reader, p, userFacing, server, source) {
253
278
  t: "videoFrameS2C",
254
279
  userFacing,
255
280
  uvTransform,
256
- w: profile.dataWidth,
257
- h: profile.dataHeight,
281
+ w: dataWidth,
282
+ h: dataHeight,
258
283
  cameraToDevice: cameraToDeviceTransform,
259
284
  cameraModel,
260
285
  source
@@ -263,10 +288,13 @@ function consumeReader(mod, r, reader, p, userFacing, server, source) {
263
288
  const pipeline = server._pipeline_by_instance.get(p);
264
289
  if (pipeline) {
265
290
  try {
266
- r.pipeline_camera_frame_submit_raw_pointer(pipeline, streamDataBufferPointer, size, framePixelFormatFromFormat(frame.format), width, height, token, cameraToDeviceTransform, latestCameraToScreenRotation, cameraModel, userFacing);
291
+ r.pipeline_camera_frame_submit_raw_pointer(pipeline, streamDataBufferPointer, size, framePixelFormatFromFormat(frame.format), width, height, token, cameraToDeviceTransform, latestCameraToScreenRotation, cameraModel, userFacing, (_b = frame.timestamp) !== null && _b !== void 0 ? _b : -1, downSample);
292
+ handleMessages(mod, workerMessageAPI);
293
+ if (dataDownloadAPI)
294
+ handleDataDownload(mod, dataDownloadAPI);
267
295
  }
268
296
  catch (err) {
269
- // console.log('Exception during camera processing', err);
297
+ console.log('Exception during camera processing', err);
270
298
  // const func = mod.cwrap('what_to_stderr', 'number', ['number']);
271
299
  // func(err);
272
300
  // (mod as any).ccall('what_to_stderr', 'number', ['number'], [err]);
@@ -326,3 +354,43 @@ function framePixelFormatFromFormat(f) {
326
354
  }
327
355
  return frame_pixel_format_t.FRAME_PIXEL_FORMAT_Y;
328
356
  }
357
+ function handleMessages(mod, m) {
358
+ const toSend = m.worker_message_send_count();
359
+ if (toSend === 0)
360
+ return;
361
+ if (!workerMessageChannel) {
362
+ workerMessageChannel = new MessageChannel();
363
+ workerMessageChannel.port1.start();
364
+ workerMessageChannel.port1.addEventListener('message', evt => {
365
+ if (evt.data.t !== 'msgrec')
366
+ return;
367
+ const data = evt.data.data;
368
+ const ptr = mod._malloc(data.byteLength);
369
+ mod.HEAPU8.set(data, ptr);
370
+ m.worker_message_receive(evt.data.reference, data.byteLength, ptr);
371
+ mod._free(ptr);
372
+ });
373
+ messageManager.postOutgoingMessage({ t: 'setupCeresWorker', port: workerMessageChannel.port2 }, [workerMessageChannel.port2]);
374
+ }
375
+ for (let i = 0; i < toSend; i++) {
376
+ const reference = m.worker_message_send_reference(i);
377
+ const dataSize = m.worker_message_send_data_size(i);
378
+ const dataPtr = m.worker_message_send_data(i);
379
+ const data = mod.HEAPU8.slice(dataPtr, dataPtr + dataSize);
380
+ workerMessageChannel.port1.postMessage({
381
+ t: 'msgsend',
382
+ data,
383
+ reference
384
+ }, [data.buffer]);
385
+ }
386
+ m.worker_message_send_clear();
387
+ }
388
+ function handleDataDownload(mod, d) {
389
+ const size = d.data_download_size();
390
+ if (size === 0)
391
+ return;
392
+ const dataPtr = d.data_download();
393
+ const data = mod.HEAPU8.slice(dataPtr, dataPtr + size);
394
+ messageManager.postOutgoingMessage({ t: '_z_datadownload', data }, [data.buffer]);
395
+ d.data_download_clear();
396
+ }
package/lib/worker.js CHANGED
@@ -7,9 +7,10 @@ messageManager.onOutgoingMessage.bind(() => {
7
7
  }
8
8
  });
9
9
  let launchHandler = (evt) => {
10
+ var _a;
10
11
  if (evt && evt.data && evt.data.t === "wasm") {
11
12
  let url = location.href.startsWith("blob") ? evt.data.url : new URL("./zappar-cv.wasm", import.meta.url).toString();
12
- launchWorkerServer(url);
13
+ launchWorkerServer(url, evt.data.module, (_a = evt.data.shouldRecordData) !== null && _a !== void 0 ? _a : 0);
13
14
  ctx.removeEventListener("message", launchHandler);
14
15
  }
15
16
  };
@@ -1,6 +1,6 @@
1
1
  /// <reference types="dom-webcodecs" />
2
2
  import { CameraFrameData } from "./camera-frame-data";
3
- import { zappar_camera_source_t, zappar_pipeline_t } from "./gen/zappar-native";
3
+ import { camera_profile_t, zappar_camera_source_t, zappar_pipeline_t } from "./gen/zappar-native";
4
4
  export interface CameraFrameC2S {
5
5
  t: "cameraFrameC2S";
6
6
  d: ArrayBuffer;
@@ -39,6 +39,12 @@ export interface StreamC2S {
39
39
  userFacing: boolean;
40
40
  source: zappar_camera_source_t;
41
41
  }
42
+ export interface CameraProfileC2S {
43
+ t: "cameraProfileC2S";
44
+ p: zappar_pipeline_t;
45
+ source: zappar_camera_source_t;
46
+ profile: camera_profile_t;
47
+ }
42
48
  export interface CameraToScreenRotationC2S {
43
49
  t: "cameraToScreenC2S";
44
50
  p: zappar_pipeline_t;
@@ -53,6 +59,7 @@ export interface ImageBitmapC2S {
53
59
  tokenId: number;
54
60
  cameraModel: Float32Array;
55
61
  cameraToDevice: Float32Array;
62
+ cp: camera_profile_t;
56
63
  }
57
64
  export interface ImageBitmapS2C {
58
65
  t: "imageBitmapS2C";