@zappar/zappar-cv 3.0.0-beta.7 → 3.0.1-alpha.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.
package/README.md CHANGED
@@ -18,8 +18,8 @@ npm i @zappar/zappar-cv
18
18
 
19
19
  You can use our CDN from within your HTML:
20
20
  ```
21
- <script src="https://libs.zappar.com/zappar-cv/3.0.0-beta.7/zappar-cv.js"></script>
21
+ <script src="https://libs.zappar.com/zappar-cv/3.0.1-alpha.2/zappar-cv.js"></script>
22
22
  ```
23
23
 
24
24
  Or you can download and host our standalone JavaScript bundle:
25
- [https://libs.zappar.com/zappar-cv/3.0.0-beta.7/zappar-cv.zip](https://libs.zappar.com/zappar-cv/3.0.0-beta.7/zappar-cv.zip)
25
+ [https://libs.zappar.com/zappar-cv/3.0.1-alpha.2/zappar-cv.zip](https://libs.zappar.com/zappar-cv/3.0.1-alpha.2/zappar-cv.zip)
@@ -35,11 +35,15 @@ export class CameraSource extends HTMLElementSource {
35
35
  if (!pipeline)
36
36
  return;
37
37
  let timeStamp = (ev.timeStamp !== undefined && ev.timeStamp !== null) ? ev.timeStamp : performance.now();
38
- let interval = ev.interval * profile.intervalMultiplier;
39
- if (this._lastTimestamp > -1 && !profile.trustSensorIntervals) {
40
- interval = Math.max(timeStamp - this._lastTimestamp, interval);
38
+ const interval = ev.interval * profile.intervalMultiplier;
39
+ if (profile.trustSensorIntervals) {
40
+ if (this._lastTimestamp === -1)
41
+ this._lastTimestamp = timeStamp;
42
+ else {
43
+ this._lastTimestamp += interval;
44
+ timeStamp = this._lastTimestamp;
45
+ }
41
46
  }
42
- this._lastTimestamp = timeStamp;
43
47
  if (ev.acceleration !== null &&
44
48
  ev.acceleration.x !== null &&
45
49
  ev.acceleration.y !== null &&
@@ -0,0 +1 @@
1
+ export declare function launchCeresWorker(wasmUrl: string, module: WebAssembly.Module, port: MessagePort): Promise<void>;
@@ -0,0 +1,67 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { getWorkerMessageAPI } from "./worker-messages";
11
+ import * as ZNM from "./zappar-cv";
12
+ const ctx = self;
13
+ let launchHandler = (evt) => {
14
+ if (evt && evt.data && evt.data.t === "wasm") {
15
+ let url = location.href.startsWith("blob") ? evt.data.url : new URL("./zappar-cv.wasm", import.meta.url).toString();
16
+ launchCeresWorker(url, evt.data.module, evt.data.port);
17
+ ctx.removeEventListener("message", launchHandler);
18
+ }
19
+ };
20
+ ctx.addEventListener("message", launchHandler);
21
+ export function launchCeresWorker(wasmUrl, module, port) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ let mod = ZNM.default({
24
+ locateFile: (path, prefix) => {
25
+ if (path.endsWith("zappar-cv.wasm")) {
26
+ return wasmUrl;
27
+ }
28
+ return prefix + path;
29
+ },
30
+ instantiateWasm: (imports, successCallback) => {
31
+ const instance = new WebAssembly.Instance(module, imports);
32
+ successCallback(instance);
33
+ return instance.exports;
34
+ },
35
+ onRuntimeInitialized: () => {
36
+ const ceres_worker = mod.cwrap('ceres_worker', null, []);
37
+ const messageAPI = getWorkerMessageAPI(mod);
38
+ port.addEventListener('message', evt => {
39
+ if (evt.data.t !== 'msgsend')
40
+ return;
41
+ const data = evt.data.data;
42
+ const reference = evt.data.reference;
43
+ const ptr = mod._malloc(data.byteLength);
44
+ mod.HEAPU8.set(data, ptr);
45
+ messageAPI.worker_message_receive(reference, data.byteLength, ptr);
46
+ mod._free(ptr);
47
+ ceres_worker();
48
+ const toSend = messageAPI.worker_message_send_count();
49
+ for (let i = 0; i < toSend; i++) {
50
+ const reference = messageAPI.worker_message_send_reference(i);
51
+ const dataSize = messageAPI.worker_message_send_data_size(i);
52
+ const dataPtr = messageAPI.worker_message_send_data(i);
53
+ const data = mod.HEAPU8.slice(dataPtr, dataPtr + dataSize);
54
+ port.postMessage({
55
+ t: 'msgrec',
56
+ data,
57
+ reference
58
+ }, [data.buffer]);
59
+ }
60
+ messageAPI.worker_message_send_clear();
61
+ });
62
+ port.start();
63
+ }
64
+ });
65
+ });
66
+ }
67
+ ;
package/lib/direct.js CHANGED
@@ -13,6 +13,8 @@ import { messageManager as workerMessageManager } from "./worker-server";
13
13
  export let messageManager = new MsgManager();
14
14
  export function launchWorker(wasm) {
15
15
  return __awaiter(this, 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);
16
18
  messageManager.onOutgoingMessage.bind(() => {
17
19
  let msgs = messageManager.getOutgoingMessages();
18
20
  for (let msg of msgs)
@@ -23,6 +25,6 @@ export function launchWorker(wasm) {
23
25
  for (let msg of msgs)
24
26
  messageManager.postIncomingMessage(msg.msg);
25
27
  });
26
- launchWorkerServer(wasm);
28
+ launchWorkerServer(wasm, module);
27
29
  });
28
30
  }
@@ -38,7 +38,7 @@ export function getRuntimeObject(mod) {
38
38
  ]);
39
39
  let pipeline_camera_frame_submit_raw_pointer_wrapped = mod.cwrap("zappar_pipeline_camera_frame_submit_raw_pointer", null, [
40
40
  "number",
41
- "number", "number", "number", "number", "number", "number", "number", "number", "number", "number"
41
+ "number", "number", "number", "number", "number", "number", "number", "number", "number", "number", "number"
42
42
  ]);
43
43
  let pipeline_camera_frame_camera_attitude_wrapped = mod.cwrap("zappar_pipeline_camera_frame_camera_attitude", "number", [
44
44
  "number"
@@ -324,7 +324,7 @@ export function getRuntimeObject(mod) {
324
324
  let ret = pipeline_camera_frame_submit_wrapped(o, arg_data, arg_len_data, arg_width, arg_height, arg_user_data, arg_camera_to_device_transform, arg_camera_model, arg_user_facing);
325
325
  return ret;
326
326
  },
327
- pipeline_camera_frame_submit_raw_pointer: (o, data, dataLength, format, width, height, user_data, camera_to_device_transform, rotation, camera_model, user_facing) => {
327
+ pipeline_camera_frame_submit_raw_pointer: (o, data, dataLength, format, width, height, user_data, camera_to_device_transform, rotation, camera_model, user_facing, timestamp) => {
328
328
  let arg_data = data;
329
329
  let arg_dataLength = dataLength;
330
330
  let arg_format = format;
@@ -337,7 +337,8 @@ export function getRuntimeObject(mod) {
337
337
  let arg_camera_model = getFloatDataArrayForArgIndex(8, camera_model.byteLength);
338
338
  mod.HEAPF32.set(camera_model, arg_camera_model / 4);
339
339
  let arg_user_facing = user_facing ? 1 : 0;
340
- let ret = pipeline_camera_frame_submit_raw_pointer_wrapped(o, arg_data, arg_dataLength, arg_format, arg_width, arg_height, arg_user_data, arg_camera_to_device_transform, arg_rotation, arg_camera_model, arg_user_facing);
340
+ let arg_timestamp = timestamp;
341
+ let ret = pipeline_camera_frame_submit_raw_pointer_wrapped(o, arg_data, arg_dataLength, arg_format, arg_width, arg_height, arg_user_data, arg_camera_to_device_transform, arg_rotation, arg_camera_model, arg_user_facing, arg_timestamp);
341
342
  return ret;
342
343
  },
343
344
  pipeline_camera_frame_camera_attitude: (o) => {
@@ -111,7 +111,7 @@ export interface zappar_cwrap {
111
111
  pipeline_camera_model(o: zappar_pipeline_t): Float32Array;
112
112
  pipeline_camera_frame_user_data(o: zappar_pipeline_t): number;
113
113
  pipeline_camera_frame_submit(o: zappar_pipeline_t, data: ArrayBuffer, width: number, height: number, user_data: number, camera_to_device_transform: Float32Array, camera_model: Float32Array, user_facing: boolean): void;
114
- pipeline_camera_frame_submit_raw_pointer(o: zappar_pipeline_t, data: number, dataLength: number, format: frame_pixel_format_t, width: number, height: number, user_data: number, camera_to_device_transform: Float32Array, rotation: number, camera_model: Float32Array, user_facing: boolean): void;
114
+ pipeline_camera_frame_submit_raw_pointer(o: zappar_pipeline_t, data: number, dataLength: number, format: frame_pixel_format_t, width: number, height: number, user_data: number, camera_to_device_transform: Float32Array, rotation: number, camera_model: Float32Array, user_facing: boolean, timestamp: number): void;
115
115
  pipeline_camera_frame_camera_attitude(o: zappar_pipeline_t): Float32Array;
116
116
  pipeline_camera_frame_device_attitude(o: zappar_pipeline_t): Float32Array;
117
117
  pipeline_motion_accelerometer_submit(o: zappar_pipeline_t, time: number, x: number, y: number, z: number): void;
@@ -11,6 +11,9 @@ export declare class MSTPCameraSource extends Source {
11
11
  private _isPaused;
12
12
  private _isUserFacing;
13
13
  private _cameraToScreenRotation;
14
+ private _accelerometer?;
15
+ private _linearAcceleration?;
16
+ private _gyroscope?;
14
17
  constructor(_impl: zappar_camera_source_t, _pipeline: zappar_pipeline_t, _deviceId: string);
15
18
  destroy(): void;
16
19
  private _stop;
@@ -26,6 +29,12 @@ export declare class MSTPCameraSource extends Source {
26
29
  private _deviceMotionListener;
27
30
  private _startDeviceOrientation;
28
31
  private _startDeviceMotion;
32
+ private _lastAccelerometerTimestamp;
33
+ private _accelerometerReading;
34
+ private _lastLinearAccelerationTimestamp;
35
+ private _linearAccelerationReading;
36
+ private _lastGyroscopeReading;
37
+ private _gyroscopeReading;
29
38
  private _stopDeviceMotion;
30
39
  uploadGL(info: CameraFrameInfo): void;
31
40
  }
@@ -31,12 +31,15 @@ export class MSTPCameraSource extends Source {
31
31
  if (!pipeline)
32
32
  return;
33
33
  let timeStamp = (ev.timeStamp !== undefined && ev.timeStamp !== null) ? ev.timeStamp : performance.now();
34
- let interval = ev.interval;
35
- if (this._lastTimestamp > -1 && !profile.trustSensorIntervals) {
36
- interval = Math.max(timeStamp - this._lastTimestamp, interval);
34
+ const interval = ev.interval * profile.intervalMultiplier;
35
+ if (profile.trustSensorIntervals) {
36
+ if (this._lastTimestamp === -1)
37
+ this._lastTimestamp = timeStamp;
38
+ else {
39
+ this._lastTimestamp += interval;
40
+ timeStamp = this._lastTimestamp;
41
+ }
37
42
  }
38
- this._lastTimestamp = timeStamp;
39
- interval *= profile.intervalMultiplier;
40
43
  if (ev.acceleration !== null &&
41
44
  ev.acceleration.x !== null &&
42
45
  ev.acceleration.y !== null &&
@@ -61,6 +64,47 @@ export class MSTPCameraSource extends Source {
61
64
  this._startDeviceOrientation();
62
65
  }
63
66
  };
67
+ this._lastAccelerometerTimestamp = -1;
68
+ this._accelerometerReading = () => {
69
+ var _a;
70
+ if (!this._accelerometer || this._accelerometer.x === undefined || this._accelerometer.y === undefined || this._accelerometer.z === undefined)
71
+ return;
72
+ let pipeline = Pipeline.get(this._pipeline);
73
+ if (!pipeline)
74
+ return;
75
+ const timestamp = (_a = this._accelerometer.timestamp) !== null && _a !== void 0 ? _a : performance.now();
76
+ const interval = this._lastAccelerometerTimestamp > -1 ? timestamp - this._lastAccelerometerTimestamp : 30;
77
+ this._lastAccelerometerTimestamp = timestamp;
78
+ pipeline.motionAccelerometerSubmit(timestamp, this._accelerometer.x * profile.deviceMotionMutliplier, this._accelerometer.y * profile.deviceMotionMutliplier, this._accelerometer.z * profile.deviceMotionMutliplier);
79
+ pipeline.motionAccelerometerWithGravitySubmitInt(timestamp, interval, this._accelerometer.x * profile.deviceMotionMutliplier, this._accelerometer.y * profile.deviceMotionMutliplier, this._accelerometer.z * profile.deviceMotionMutliplier);
80
+ };
81
+ this._lastLinearAccelerationTimestamp = -1;
82
+ this._linearAccelerationReading = () => {
83
+ var _a;
84
+ if (!this._linearAcceleration || this._linearAcceleration.x === undefined || this._linearAcceleration.y === undefined || this._linearAcceleration.z === undefined)
85
+ return;
86
+ let pipeline = Pipeline.get(this._pipeline);
87
+ if (!pipeline)
88
+ return;
89
+ const timestamp = (_a = this._linearAcceleration.timestamp) !== null && _a !== void 0 ? _a : performance.now();
90
+ const interval = this._lastLinearAccelerationTimestamp > -1 ? timestamp - this._lastLinearAccelerationTimestamp : 30;
91
+ this._lastLinearAccelerationTimestamp = timestamp;
92
+ pipeline.motionAccelerometerWithoutGravitySubmitInt(timestamp, interval, this._linearAcceleration.x * profile.deviceMotionMutliplier, this._linearAcceleration.y * profile.deviceMotionMutliplier, this._linearAcceleration.z * profile.deviceMotionMutliplier);
93
+ };
94
+ this._lastGyroscopeReading = -1;
95
+ this._gyroscopeReading = () => {
96
+ var _a;
97
+ if (!this._gyroscope || this._gyroscope.x === undefined || this._gyroscope.y === undefined || this._gyroscope.z === undefined)
98
+ return;
99
+ let pipeline = Pipeline.get(this._pipeline);
100
+ if (!pipeline)
101
+ return;
102
+ const timestamp = (_a = this._gyroscope.timestamp) !== null && _a !== void 0 ? _a : performance.now();
103
+ const interval = this._lastGyroscopeReading > -1 ? timestamp - this._lastGyroscopeReading : 30;
104
+ this._lastGyroscopeReading = timestamp;
105
+ pipeline.motionRotationRateSubmit(timestamp, -this._gyroscope.x, -this._gyroscope.y, -this._gyroscope.z);
106
+ pipeline.motionRotationRateSubmitInt(timestamp, interval, this._gyroscope.x * 180 / Math.PI, this._gyroscope.y * 180 / Math.PI, this._gyroscope.z * 180 / Math.PI);
107
+ };
64
108
  zcout("Using MSTP camera source");
65
109
  }
66
110
  destroy() {
@@ -221,9 +265,38 @@ export class MSTPCameraSource extends Source {
221
265
  });
222
266
  }
223
267
  _startDeviceMotion() {
224
- window.addEventListener("devicemotion", this._deviceMotionListener, false);
268
+ try {
269
+ this._accelerometer = new Accelerometer({ frequency: 60 });
270
+ this._linearAcceleration = new LinearAccelerationSensor({ frequency: 60 });
271
+ this._gyroscope = new Gyroscope({ frequency: 60 });
272
+ // throw new Error();
273
+ this._accelerometer.addEventListener('reading', this._accelerometerReading);
274
+ this._accelerometer.start();
275
+ this._linearAcceleration.addEventListener('reading', this._linearAccelerationReading);
276
+ this._linearAcceleration.start();
277
+ this._gyroscope.addEventListener('reading', this._gyroscopeReading);
278
+ this._gyroscope.start();
279
+ }
280
+ catch (err) {
281
+ window.addEventListener("devicemotion", this._deviceMotionListener, false);
282
+ }
225
283
  }
226
284
  _stopDeviceMotion() {
285
+ if (this._accelerometer) {
286
+ this._accelerometer.stop();
287
+ this._accelerometer.removeEventListener('reading', this._accelerometerReading);
288
+ delete this._accelerometer;
289
+ }
290
+ if (this._linearAcceleration) {
291
+ this._linearAcceleration.stop();
292
+ this._linearAcceleration.removeEventListener('reading', this._linearAccelerationReading);
293
+ delete this._linearAcceleration;
294
+ }
295
+ if (this._gyroscope) {
296
+ this._gyroscope.stop();
297
+ this._gyroscope.removeEventListener('reading', this._gyroscopeReading);
298
+ delete this._gyroscope;
299
+ }
227
300
  window.removeEventListener("devicemotion", this._deviceMotionListener);
228
301
  }
229
302
  uploadGL(info) {
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";
@@ -84,6 +84,10 @@ export function initialize(opts) {
84
84
  src.streamEnded();
85
85
  break;
86
86
  }
87
+ case "setupCeresWorker": {
88
+ launchCeresWorker(msg.port);
89
+ break;
90
+ }
87
91
  case "licerr": {
88
92
  let div = document.createElement("div");
89
93
  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.";
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.2";
package/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "3.0.0-beta.7";
1
+ export const VERSION = "3.0.1-alpha.2";
@@ -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>;
@@ -9,13 +9,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { MsgManager } from "./messages";
11
11
  export let messageManager = new MsgManager();
12
+ const wasmModule = (() => __awaiter(void 0, void 0, void 0, function* () {
13
+ const response = yield fetch(new URL("./zappar-cv.wasm", import.meta.url).toString());
14
+ const module = yield WebAssembly.compileStreaming(response);
15
+ return module;
16
+ }))();
12
17
  export function launchWorker(worker) {
13
18
  return __awaiter(this, void 0, void 0, function* () {
14
19
  if (!worker)
15
20
  worker = new Worker(new URL("./worker", import.meta.url), { type: 'module' });
16
21
  worker.postMessage({
17
22
  t: "wasm",
18
- url: new URL("./zappar-cv.wasm", import.meta.url).toString()
23
+ url: new URL("./zappar-cv.wasm", import.meta.url).toString(),
24
+ module: yield wasmModule
19
25
  });
20
26
  yield waitForLoad(worker);
21
27
  function sendOutgoing() {
@@ -31,6 +37,18 @@ export function launchWorker(worker) {
31
37
  });
32
38
  });
33
39
  }
40
+ export function launchCeresWorker(port, worker) {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ if (!worker)
43
+ worker = new Worker(new URL("./ceres-worker", import.meta.url), { type: 'module' });
44
+ worker.postMessage({
45
+ t: "wasm",
46
+ url: new URL("./zappar-cv.wasm", import.meta.url).toString(),
47
+ module: yield wasmModule,
48
+ port
49
+ }, [port]);
50
+ });
51
+ }
34
52
  function waitForLoad(w) {
35
53
  return new Promise(resolve => {
36
54
  let listener = (msg) => {
@@ -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): Promise<void>;
@@ -15,11 +15,13 @@ import { mat4 } from "gl-matrix";
15
15
  import { frame_pixel_format_t } from "./gen/zappar-native";
16
16
  import { handleImageBitmap } from "./worker-imagebitmap";
17
17
  import { profile } from "./profile";
18
+ import { getWorkerMessageAPI } from "./worker-messages";
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
+ export function launchWorkerServer(wasmUrl, module) {
23
25
  return __awaiter(this, void 0, void 0, function* () {
24
26
  let mod = ZNM.default({
25
27
  locateFile: (path, prefix) => {
@@ -28,8 +30,14 @@ export function launchWorkerServer(wasmUrl) {
28
30
  }
29
31
  return prefix + path;
30
32
  },
33
+ instantiateWasm: (imports, successCallback) => {
34
+ const instance = new WebAssembly.Instance(module, imports);
35
+ successCallback(instance);
36
+ return instance.exports;
37
+ },
31
38
  onRuntimeInitialized: () => {
32
39
  let r = getRuntimeObject(mod);
40
+ const workerMessageAPI = getWorkerMessageAPI(mod);
33
41
  let server = new zappar_server(r, (pipelineId, ab) => {
34
42
  messageManager.postOutgoingMessage({
35
43
  p: pipelineId,
@@ -57,6 +65,7 @@ export function launchWorkerServer(wasmUrl) {
57
65
  r.pipeline_frame_update(pipeline);
58
66
  att = r.pipeline_camera_frame_device_attitude(pipeline);
59
67
  server.exploreState();
68
+ handleMessages(mod, workerMessageAPI);
60
69
  }
61
70
  let ret = {
62
71
  token: msgt.token,
@@ -87,7 +96,7 @@ export function launchWorkerServer(wasmUrl) {
87
96
  }
88
97
  case "streamC2S": {
89
98
  let msgt = msg;
90
- consumeStream(mod, r, msgt.s, msgt.p, msgt.userFacing, server, msgt.source).then(() => {
99
+ consumeStream(mod, r, msgt.s, msgt.p, msgt.userFacing, server, msgt.source, workerMessageAPI).then(() => {
91
100
  let m = { t: "streamEndedS2C", p: msgt.p, source: msgt.source };
92
101
  // console.log('Stream ended, requesting new stream');
93
102
  messageManager.postOutgoingMessage(m, []);
@@ -151,7 +160,7 @@ export function launchWorkerServer(wasmUrl) {
151
160
  });
152
161
  }
153
162
  ;
154
- function consumeStream(mod, r, stream, p, userFacing, server, source) {
163
+ function consumeStream(mod, r, stream, p, userFacing, server, source, workerMessageAPI) {
155
164
  return __awaiter(this, void 0, void 0, function* () {
156
165
  while (true) {
157
166
  let reader;
@@ -164,7 +173,7 @@ function consumeStream(mod, r, stream, p, userFacing, server, source) {
164
173
  continue;
165
174
  }
166
175
  try {
167
- yield consumeReader(mod, r, reader, p, userFacing, server, source);
176
+ yield consumeReader(mod, r, reader, p, userFacing, server, source, workerMessageAPI);
168
177
  return;
169
178
  }
170
179
  catch (err) {
@@ -192,8 +201,8 @@ function getFrameOrTimeout(reader) {
192
201
  }
193
202
  const cameraToDeviceTransform = mat4.create();
194
203
  const cameraModel = new Float32Array([300, 300, 160, 120, 0, 0]);
195
- function consumeReader(mod, r, reader, p, userFacing, server, source) {
196
- var _a;
204
+ function consumeReader(mod, r, reader, p, userFacing, server, source, workerMessageAPI) {
205
+ var _a, _b;
197
206
  return __awaiter(this, void 0, void 0, function* () {
198
207
  while (true) {
199
208
  let result = yield getFrameOrTimeout(reader);
@@ -263,10 +272,11 @@ function consumeReader(mod, r, reader, p, userFacing, server, source) {
263
272
  const pipeline = server._pipeline_by_instance.get(p);
264
273
  if (pipeline) {
265
274
  try {
266
- r.pipeline_camera_frame_submit_raw_pointer(pipeline, streamDataBufferPointer, size, framePixelFormatFromFormat(frame.format), width, height, token, cameraToDeviceTransform, latestCameraToScreenRotation, cameraModel, userFacing);
275
+ 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);
276
+ handleMessages(mod, workerMessageAPI);
267
277
  }
268
278
  catch (err) {
269
- // console.log('Exception during camera processing', err);
279
+ console.log('Exception during camera processing', err);
270
280
  // const func = mod.cwrap('what_to_stderr', 'number', ['number']);
271
281
  // func(err);
272
282
  // (mod as any).ccall('what_to_stderr', 'number', ['number'], [err]);
@@ -326,3 +336,34 @@ function framePixelFormatFromFormat(f) {
326
336
  }
327
337
  return frame_pixel_format_t.FRAME_PIXEL_FORMAT_Y;
328
338
  }
339
+ function handleMessages(mod, m) {
340
+ const toSend = m.worker_message_send_count();
341
+ if (toSend === 0)
342
+ return;
343
+ if (!workerMessageChannel) {
344
+ workerMessageChannel = new MessageChannel();
345
+ workerMessageChannel.port1.start();
346
+ workerMessageChannel.port1.addEventListener('message', evt => {
347
+ if (evt.data.t !== 'msgrec')
348
+ return;
349
+ const data = evt.data.data;
350
+ const ptr = mod._malloc(data.byteLength);
351
+ mod.HEAPU8.set(data, ptr);
352
+ m.worker_message_receive(evt.data.reference, data.byteLength, ptr);
353
+ mod._free(ptr);
354
+ });
355
+ messageManager.postOutgoingMessage({ t: 'setupCeresWorker', port: workerMessageChannel.port2 }, [workerMessageChannel.port2]);
356
+ }
357
+ for (let i = 0; i < toSend; i++) {
358
+ const reference = m.worker_message_send_reference(i);
359
+ const dataSize = m.worker_message_send_data_size(i);
360
+ const dataPtr = m.worker_message_send_data(i);
361
+ const data = mod.HEAPU8.slice(dataPtr, dataPtr + dataSize);
362
+ workerMessageChannel.port1.postMessage({
363
+ t: 'msgsend',
364
+ data,
365
+ reference
366
+ }, [data.buffer]);
367
+ }
368
+ m.worker_message_send_clear();
369
+ }
package/lib/worker.js CHANGED
@@ -9,7 +9,7 @@ messageManager.onOutgoingMessage.bind(() => {
9
9
  let launchHandler = (evt) => {
10
10
  if (evt && evt.data && evt.data.t === "wasm") {
11
11
  let url = location.href.startsWith("blob") ? evt.data.url : new URL("./zappar-cv.wasm", import.meta.url).toString();
12
- launchWorkerServer(url);
12
+ launchWorkerServer(url, evt.data.module);
13
13
  ctx.removeEventListener("message", launchHandler);
14
14
  }
15
15
  };