@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.
- package/README.md +2 -2
- package/lib/additional.d.ts +5 -1
- package/lib/camera-source.js +8 -4
- package/lib/ceres-worker.d.ts +1 -0
- package/lib/ceres-worker.js +67 -0
- package/lib/data-download.d.ts +8 -0
- package/lib/data-download.js +8 -0
- package/lib/deserializer.d.ts +1 -0
- package/lib/deserializer.js +7 -0
- package/lib/direct.js +3 -1
- package/lib/drawgrid.d.ts +2 -0
- package/lib/drawgrid.js +136 -0
- package/lib/drawpoints.d.ts +11 -0
- package/lib/drawpoints.js +180 -0
- package/lib/gen/zappar-bridge.d.ts +20 -0
- package/lib/gen/zappar-bridge.js +1 -0
- package/lib/gen/zappar-client.d.ts +1 -0
- package/lib/gen/zappar-client.js +208 -13
- package/lib/gen/zappar-cwrap.js +144 -3
- package/lib/gen/zappar-native.d.ts +24 -1
- package/lib/gen/zappar-native.js +6 -0
- package/lib/gen/zappar-server.d.ts +3 -0
- package/lib/gen/zappar-server.js +108 -10
- package/lib/gen/zappar.d.ts +24 -0
- package/lib/gen/zappar.js +1 -0
- package/lib/html-element-source.d.ts +3 -1
- package/lib/html-element-source.js +12 -6
- package/lib/image-process-gl.d.ts +3 -2
- package/lib/image-process-gl.js +9 -7
- package/lib/imagebitmap-camera-source.d.ts +3 -1
- package/lib/imagebitmap-camera-source.js +10 -4
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/mstp-camera-source.d.ts +11 -1
- package/lib/mstp-camera-source.js +84 -6
- package/lib/native.js +56 -2
- package/lib/pipeline.d.ts +3 -1
- package/lib/pipeline.js +12 -2
- package/lib/profile.d.ts +2 -2
- package/lib/profile.js +3 -3
- package/lib/serializer.d.ts +1 -0
- package/lib/serializer.js +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/worker-client.d.ts +1 -0
- package/lib/worker-client.js +23 -1
- package/lib/worker-imagebitmap.js +5 -4
- package/lib/worker-messages.d.ts +10 -0
- package/lib/worker-messages.js +10 -0
- package/lib/worker-server.d.ts +1 -1
- package/lib/worker-server.js +83 -15
- package/lib/worker.js +2 -1
- package/lib/workerinterface.d.ts +8 -1
- package/lib/zappar-cv.js +215 -134
- package/lib/zappar-cv.wasm +0 -0
- package/package.json +4 -3
- package/umd/169.zappar-cv.js +1 -1
- package/umd/25.zappar-cv.js +1 -0
- package/umd/751.zappar-cv.js +1 -0
- package/umd/867.zappar-cv.js +1 -0
- package/umd/ca409d4e8cebe454b816.wasm +0 -0
- package/umd/zappar-cv.js +1 -1
- package/umd/zappar-cv.worker.js +1 -1
- package/umd/51b1854609f16d933fe2.wasm +0 -0
- 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
|
-
|
|
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
|
-
|
|
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.
|
|
83
|
+
profile.getDataSize = (p) => p === camera_profile_t.HIGH ? [640, 360] : [320, 180];
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
if (majorVersion === 16 && minorVersion >= 4) {
|
package/lib/serializer.d.ts
CHANGED
|
@@ -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.
|
|
1
|
+
export declare const VERSION = "3.0.1-alpha.10";
|
package/lib/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "3.0.
|
|
1
|
+
export const VERSION = "3.0.1-alpha.10";
|
package/lib/worker-client.d.ts
CHANGED
package/lib/worker-client.js
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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
|
+
}
|
package/lib/worker-server.d.ts
CHANGED
|
@@ -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>;
|
package/lib/worker-server.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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 *
|
|
269
|
+
let focalLength = 300.0 * dataWidth / 320.0;
|
|
245
270
|
cameraModel[0] = focalLength;
|
|
246
271
|
cameraModel[1] = focalLength;
|
|
247
|
-
cameraModel[2] =
|
|
248
|
-
cameraModel[3] =
|
|
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:
|
|
257
|
-
h:
|
|
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
|
-
|
|
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
|
};
|
package/lib/workerinterface.d.ts
CHANGED
|
@@ -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";
|