@zappar/zappar-cv 3.9.2 → 3.11.0
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/bridged-camera-source.d.ts +1 -0
- package/lib/bridged-camera-source.js +8 -0
- package/lib/bridged-d3-tracker.js +2 -26
- package/lib/camera-source.d.ts +3 -0
- package/lib/camera-source.js +8 -2
- package/lib/drawpoints.js +30 -38
- package/lib/gen/zappar-bridge.d.ts +12 -0
- package/lib/gen/zappar-client.js +173 -5
- package/lib/gen/zappar-cwrap.js +115 -0
- package/lib/gen/zappar-native.d.ts +14 -1
- package/lib/gen/zappar-native.js +1 -0
- package/lib/gen/zappar-server.js +75 -0
- package/lib/gen/zappar.d.ts +9 -8
- package/lib/html-element-source.d.ts +1 -0
- package/lib/html-element-source.js +4 -3
- package/lib/image-process-gl.d.ts +4 -5
- package/lib/image-process-gl.js +14 -25
- package/lib/imagebitmap-camera-source.d.ts +3 -0
- package/lib/imagebitmap-camera-source.js +12 -5
- package/lib/mstp-camera-source.d.ts +3 -0
- package/lib/mstp-camera-source.js +8 -2
- package/lib/native.js +39 -19
- package/lib/profile.d.ts +2 -1
- package/lib/profile.js +33 -2
- package/lib/sequencesource.js +2 -2
- package/lib/src/bridged-camera-source.d.ts +1 -0
- package/lib/src/camera-source.d.ts +3 -0
- package/lib/src/gen/zappar-bridge.d.ts +12 -0
- package/lib/src/gen/zappar-native.d.ts +14 -1
- package/lib/src/gen/zappar.d.ts +9 -8
- package/lib/src/html-element-source.d.ts +1 -0
- package/lib/src/image-process-gl.d.ts +4 -5
- package/lib/src/imagebitmap-camera-source.d.ts +3 -0
- package/lib/src/mstp-camera-source.d.ts +3 -0
- package/lib/src/profile.d.ts +2 -1
- package/lib/src/version.d.ts +1 -1
- package/lib/src/webxr-camera-source.d.ts +5 -0
- package/lib/tests/common.d.ts +3 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/webxr-camera-source.d.ts +5 -0
- package/lib/webxr-camera-source.js +67 -35
- package/lib/worker-imagebitmap.js +2 -14
- package/lib/zappar-cv.js +1 -1
- package/lib/zappar-cv.wasm +0 -0
- package/package.json +1 -1
package/lib/gen/zappar-server.js
CHANGED
|
@@ -551,6 +551,14 @@ export class zappar_server {
|
|
|
551
551
|
this._d3_tracker_by_instance.delete(clientId);
|
|
552
552
|
break;
|
|
553
553
|
}
|
|
554
|
+
case 64: {
|
|
555
|
+
let clientId = msg.type();
|
|
556
|
+
let obj = this._d3_tracker_by_instance.get(clientId);
|
|
557
|
+
if (obj === undefined)
|
|
558
|
+
return;
|
|
559
|
+
this._impl.d3_tracker_enabled_set(obj, msg.bool());
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
554
562
|
}
|
|
555
563
|
});
|
|
556
564
|
}
|
|
@@ -913,6 +921,73 @@ export class zappar_server {
|
|
|
913
921
|
let serializer = this.serializersByPipelineId.get(pipeline);
|
|
914
922
|
if (!serializer)
|
|
915
923
|
continue;
|
|
924
|
+
serializer.sendMessage(56, msg => {
|
|
925
|
+
msg.type(k);
|
|
926
|
+
msg.int(this._impl.d3_tracker_count(v));
|
|
927
|
+
});
|
|
928
|
+
for (let i = 0; i < this._impl.d3_tracker_count(v); i++) {
|
|
929
|
+
serializer.sendMessage(57, msg => {
|
|
930
|
+
msg.type(k);
|
|
931
|
+
msg.int(i);
|
|
932
|
+
msg.string(this._impl.d3_tracker_id(v, i));
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
for (let i = 0; i < this._impl.d3_tracker_count(v); i++) {
|
|
936
|
+
serializer.sendMessage(58, msg => {
|
|
937
|
+
msg.type(k);
|
|
938
|
+
msg.int(i);
|
|
939
|
+
msg.matrix4x4(this._impl.d3_tracker_pose0_raw(v, i));
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
for (let i = 0; i < this._impl.d3_tracker_count(v); i++) {
|
|
943
|
+
serializer.sendMessage(59, msg => {
|
|
944
|
+
msg.type(k);
|
|
945
|
+
msg.int(i);
|
|
946
|
+
msg.matrix4x4(this._impl.d3_tracker_pose1_raw(v, i));
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
for (let i = 0; i < this._impl.d3_tracker_count(v); i++) {
|
|
950
|
+
serializer.sendMessage(60, msg => {
|
|
951
|
+
msg.type(k);
|
|
952
|
+
msg.int(i);
|
|
953
|
+
msg.int(this._impl.d3_tracker_type(v, i));
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
for (let i = 0; i < this._impl.d3_tracker_count(v); i++) {
|
|
957
|
+
serializer.sendMessage(61, msg => {
|
|
958
|
+
msg.type(k);
|
|
959
|
+
msg.int(i);
|
|
960
|
+
msg.int(this._impl.d3_tracker_category(v, i));
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
for (let i = 0; i < this._impl.d3_tracker_count(v); i++) {
|
|
964
|
+
serializer.sendMessage(62, msg => {
|
|
965
|
+
msg.type(k);
|
|
966
|
+
msg.int(i);
|
|
967
|
+
msg.string(this._impl.d3_tracker_qr(v, i));
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
for (let i = 0; i < this._impl.d3_tracker_count(v); i++) {
|
|
971
|
+
serializer.sendMessage(63, msg => {
|
|
972
|
+
msg.type(k);
|
|
973
|
+
msg.int(i);
|
|
974
|
+
msg.int(this._impl.d3_tracker_dense(v, i));
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
for (let i = 0; i < this._impl.d3_tracker_count(v); i++) {
|
|
978
|
+
serializer.sendMessage(64, msg => {
|
|
979
|
+
msg.type(k);
|
|
980
|
+
msg.int(i);
|
|
981
|
+
msg.floatArray(this._impl.d3_tracker_landmarks_data(v, i));
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
for (let i = 0; i < this._impl.d3_tracker_count(v); i++) {
|
|
985
|
+
serializer.sendMessage(65, msg => {
|
|
986
|
+
msg.type(k);
|
|
987
|
+
msg.int(i);
|
|
988
|
+
msg.int(this._impl.d3_tracker_landmarks_data_size(v, i));
|
|
989
|
+
});
|
|
990
|
+
}
|
|
916
991
|
}
|
|
917
992
|
}
|
|
918
993
|
}
|
package/lib/gen/zappar.d.ts
CHANGED
|
@@ -125,6 +125,7 @@ export interface zappar {
|
|
|
125
125
|
camera_source_start(o: zappar_camera_source_t): void;
|
|
126
126
|
camera_source_pause(o: zappar_camera_source_t): void;
|
|
127
127
|
camera_source_profile_set(o: zappar_camera_source_t, profile: camera_profile_t): void;
|
|
128
|
+
camera_source_preferred_resolution_set(o: zappar_camera_source_t, width: number, height: number): void;
|
|
128
129
|
sequence_source_create(pipeline: zappar_pipeline_t): zappar_sequence_source_t;
|
|
129
130
|
sequence_source_destroy(o: zappar_sequence_source_t): void;
|
|
130
131
|
sequence_source_start(o: zappar_sequence_source_t): void;
|
|
@@ -295,25 +296,25 @@ export interface zappar {
|
|
|
295
296
|
custom_anchor_pose_set_with_parent(o: zappar_custom_anchor_t, pose: Float32Array, anchor_id: string): void;
|
|
296
297
|
d3_tracker_create(pipeline: zappar_pipeline_t): zappar_d3_tracker_t;
|
|
297
298
|
d3_tracker_destroy(o: zappar_d3_tracker_t): void;
|
|
298
|
-
d3_tracker_id(o: zappar_d3_tracker_t, indx: number): string;
|
|
299
299
|
d3_tracker_enabled(o: zappar_d3_tracker_t): boolean;
|
|
300
300
|
d3_tracker_enabled_set(o: zappar_d3_tracker_t, enabled: boolean): void;
|
|
301
301
|
d3_tracker_process_max_resolution_set(o: zappar_d3_tracker_t, v: boolean): void;
|
|
302
302
|
d3_tracker_count(o: zappar_d3_tracker_t): number;
|
|
303
|
-
|
|
304
|
-
d3_tracker_pose_raw(o: zappar_d3_tracker_t, indx: number): Float32Array;
|
|
305
|
-
d3_tracker_pose_camera_relative(o: zappar_d3_tracker_t, indx: number, mirror: boolean): Float32Array;
|
|
306
|
-
d3_tracker_pose(o: zappar_d3_tracker_t, indx: number, camera_pose: Float32Array, mirror: boolean): Float32Array;
|
|
303
|
+
d3_tracker_id(o: zappar_d3_tracker_t, indx: number): string;
|
|
307
304
|
d3_tracker_pose0_raw(o: zappar_d3_tracker_t, indx: number): Float32Array;
|
|
308
305
|
d3_tracker_pose0_camera_relative(o: zappar_d3_tracker_t, indx: number, mirror: boolean): Float32Array;
|
|
309
306
|
d3_tracker_pose0(o: zappar_d3_tracker_t, indx: number, camera_pose: Float32Array, mirror: boolean): Float32Array;
|
|
310
307
|
d3_tracker_pose1_raw(o: zappar_d3_tracker_t, indx: number): Float32Array;
|
|
311
308
|
d3_tracker_pose1_camera_relative(o: zappar_d3_tracker_t, indx: number, mirror: boolean): Float32Array;
|
|
312
309
|
d3_tracker_pose1(o: zappar_d3_tracker_t, indx: number, camera_pose: Float32Array, mirror: boolean): Float32Array;
|
|
313
|
-
d3_tracker_landmarks_data(o: zappar_d3_tracker_t, indx: number): Float32Array;
|
|
314
|
-
d3_tracker_landmarks_data_size(o: zappar_d3_tracker_t, indx: number): number;
|
|
315
310
|
d3_tracker_type(o: zappar_d3_tracker_t, indx: number): number;
|
|
316
|
-
d3_tracker_dense(o: zappar_d3_tracker_t, indx: number): number;
|
|
317
311
|
d3_tracker_category(o: zappar_d3_tracker_t, indx: number): number;
|
|
312
|
+
d3_tracker_qr(o: zappar_d3_tracker_t, indx: number): string;
|
|
313
|
+
d3_tracker_dense(o: zappar_d3_tracker_t, indx: number): number;
|
|
314
|
+
d3_tracker_landmarks_data(o: zappar_d3_tracker_t, indx: number): Float32Array;
|
|
315
|
+
d3_tracker_landmarks_data_size(o: zappar_d3_tracker_t, indx: number): number;
|
|
316
|
+
d3_tracker_pose_raw(o: zappar_d3_tracker_t, indx: number): Float32Array;
|
|
317
|
+
d3_tracker_pose_camera_relative(o: zappar_d3_tracker_t, indx: number, mirror: boolean): Float32Array;
|
|
318
|
+
d3_tracker_pose(o: zappar_d3_tracker_t, indx: number, camera_pose: Float32Array, mirror: boolean): Float32Array;
|
|
318
319
|
d3_tracker_size_for_id_set(o: zappar_d3_tracker_t, id: string, size: number): void;
|
|
319
320
|
}
|
|
@@ -10,6 +10,7 @@ export declare class HTMLElementSource extends Source {
|
|
|
10
10
|
protected _cameraToScreenRotation: number;
|
|
11
11
|
private _isUploadFrame;
|
|
12
12
|
private _currentVideoTexture;
|
|
13
|
+
private _currentDataSize;
|
|
13
14
|
private _imageProcessor;
|
|
14
15
|
private _cameraToDeviceTransform;
|
|
15
16
|
private _cameraToDeviceTransformUserFacing;
|
|
@@ -17,6 +17,7 @@ export class HTMLElementSource extends Source {
|
|
|
17
17
|
this._isUserFacing = false;
|
|
18
18
|
this._cameraToScreenRotation = 0;
|
|
19
19
|
this._isUploadFrame = true;
|
|
20
|
+
this._currentDataSize = [320, 240];
|
|
20
21
|
this._cameraToDeviceTransform = mat4.create();
|
|
21
22
|
this._cameraToDeviceTransformUserFacing = mat4.create();
|
|
22
23
|
this._cameraModel = new Float32Array([300, 300, 160, 120, 0, 0]);
|
|
@@ -148,7 +149,7 @@ export class HTMLElementSource extends Source {
|
|
|
148
149
|
return undefined;
|
|
149
150
|
if (pipeline.getCameraFrameDataRGBEnabled())
|
|
150
151
|
this._currentRgbFrame = this._generateRGBFrame();
|
|
151
|
-
this._imageProcessor.uploadFrame(this._currentVideoTexture, this._video, rotation, this._isUserFacing, this._profile);
|
|
152
|
+
this._currentDataSize = this._imageProcessor.uploadFrame(this._currentVideoTexture, this._video, rotation, this._isUserFacing, this._profile);
|
|
152
153
|
this._requestVideoFrameCallback();
|
|
153
154
|
this._isUploadFrame = !this._isUploadFrame;
|
|
154
155
|
return undefined;
|
|
@@ -156,7 +157,7 @@ export class HTMLElementSource extends Source {
|
|
|
156
157
|
if (currentlyProcessing || !this._currentVideoTexture)
|
|
157
158
|
return undefined;
|
|
158
159
|
this._isUploadFrame = !this._isUploadFrame;
|
|
159
|
-
const [dataWidth, dataHeight] =
|
|
160
|
+
const [dataWidth, dataHeight] = this._currentDataSize;
|
|
160
161
|
let greySize = dataWidth * dataHeight;
|
|
161
162
|
let pixels = pipeline.cameraPixelArrays.pop();
|
|
162
163
|
while (pixels) {
|
|
@@ -174,7 +175,7 @@ export class HTMLElementSource extends Source {
|
|
|
174
175
|
this._cameraModel[1] = focalLength;
|
|
175
176
|
this._cameraModel[2] = dataWidth * 0.5;
|
|
176
177
|
this._cameraModel[3] = dataHeight * 0.5;
|
|
177
|
-
const info = Object.assign(Object.assign({}, this._imageProcessor.readFrame(
|
|
178
|
+
const info = Object.assign(Object.assign({}, this._imageProcessor.readFrame(pixels)), { texture: tex, cameraModel: this._cameraModel, cameraSource: this, cameraToDevice: (this._isUserFacing ? this._cameraToDeviceTransformUserFacing : this._cameraToDeviceTransform) });
|
|
178
179
|
if (this._currentRgbFrame) {
|
|
179
180
|
info.rgbFrame = this._currentRgbFrame;
|
|
180
181
|
this._currentRgbFrame = undefined;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { camera_profile_t } from "./gen/zappar-native";
|
|
2
2
|
export interface ProcessedFrame {
|
|
3
3
|
data?: ArrayBuffer;
|
|
4
|
-
texture: WebGLTexture | undefined;
|
|
5
4
|
dataWidth: number;
|
|
6
5
|
dataHeight: number;
|
|
7
6
|
uvTransform?: Float32Array;
|
|
@@ -17,6 +16,7 @@ export declare class ImageProcessGL {
|
|
|
17
16
|
private _computedTransformRotation;
|
|
18
17
|
private _computedFrontCameraRotation;
|
|
19
18
|
private _cameraUvTransform;
|
|
19
|
+
private _dataSize;
|
|
20
20
|
private _framebufferWidth;
|
|
21
21
|
private _framebufferHeight;
|
|
22
22
|
private _framebufferId;
|
|
@@ -29,10 +29,9 @@ export declare class ImageProcessGL {
|
|
|
29
29
|
constructor(_gl: WebGL2RenderingContext | WebGLRenderingContext);
|
|
30
30
|
resetGLContext(): void;
|
|
31
31
|
destroy(): void;
|
|
32
|
-
uploadFrame(texture: WebGLTexture, img: HTMLVideoElement | HTMLImageElement | ImageBitmap, rotation: number, fc: boolean, cp: camera_profile_t):
|
|
33
|
-
uploadFrameForSize(texture: WebGLTexture, img: HTMLVideoElement | HTMLImageElement | ImageBitmap, rotation: number, fc: boolean, dataWidth: number, dataHeight: number): void;
|
|
34
|
-
readFrame(
|
|
35
|
-
readFrameForSize(texture: WebGLTexture, pixels: ArrayBuffer, dataWidth: number, dataHeight: number): ProcessedFrame;
|
|
32
|
+
uploadFrame(texture: WebGLTexture, img: HTMLVideoElement | HTMLImageElement | ImageBitmap, rotation: number, fc: boolean, cp: camera_profile_t): [number, number];
|
|
33
|
+
uploadFrameForSize(texture: WebGLTexture, img: HTMLVideoElement | HTMLImageElement | ImageBitmap | null, rotation: number, fc: boolean, dataWidth: number, dataHeight: number): void;
|
|
34
|
+
readFrame(pixels: ArrayBuffer): ProcessedFrame;
|
|
36
35
|
private _updateTransforms;
|
|
37
36
|
private _getCameraUvTransform;
|
|
38
37
|
private _getFramebuffer;
|
package/lib/image-process-gl.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mat4 } from "gl-matrix";
|
|
2
2
|
import { GLStateManager } from "./gl-state-manager";
|
|
3
|
-
import {
|
|
3
|
+
import { getDataSizeForSource } from "./profile";
|
|
4
4
|
import { compileShader, linkProgram } from "./shader";
|
|
5
5
|
export class ImageProcessGL {
|
|
6
6
|
constructor(_gl) {
|
|
@@ -13,6 +13,7 @@ export class ImageProcessGL {
|
|
|
13
13
|
this._computedTransformRotation = -1;
|
|
14
14
|
this._computedFrontCameraRotation = false;
|
|
15
15
|
this._cameraUvTransform = mat4.create();
|
|
16
|
+
this._dataSize = [0, 0];
|
|
16
17
|
this._framebufferWidth = 0;
|
|
17
18
|
this._framebufferHeight = 0;
|
|
18
19
|
this._framebufferId = null;
|
|
@@ -34,8 +35,9 @@ export class ImageProcessGL {
|
|
|
34
35
|
this.resetGLContext();
|
|
35
36
|
}
|
|
36
37
|
uploadFrame(texture, img, rotation, fc, cp) {
|
|
37
|
-
const
|
|
38
|
-
this.uploadFrameForSize(texture, img, rotation, fc,
|
|
38
|
+
const dataSize = getDataSizeForSource(cp, img, rotation);
|
|
39
|
+
this.uploadFrameForSize(texture, img, rotation, fc, ...dataSize);
|
|
40
|
+
return dataSize;
|
|
39
41
|
}
|
|
40
42
|
uploadFrameForSize(texture, img, rotation, fc, dataWidth, dataHeight) {
|
|
41
43
|
let gl = this._gl;
|
|
@@ -61,24 +63,15 @@ export class ImageProcessGL {
|
|
|
61
63
|
gl.disable(gl.STENCIL_TEST);
|
|
62
64
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
63
65
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
let videoHeight = 0;
|
|
71
|
-
if (typeof HTMLVideoElement !== "undefined" && img instanceof HTMLVideoElement) {
|
|
72
|
-
videoWidth = img.videoWidth;
|
|
73
|
-
videoHeight = img.videoHeight;
|
|
66
|
+
if (img) {
|
|
67
|
+
const level = 0;
|
|
68
|
+
const internalFormat = gl.RGBA;
|
|
69
|
+
const srcFormat = gl.RGBA;
|
|
70
|
+
const srcType = gl.UNSIGNED_BYTE;
|
|
71
|
+
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, img);
|
|
74
72
|
}
|
|
75
|
-
else {
|
|
76
|
-
videoWidth = img.width;
|
|
77
|
-
videoHeight = img.height;
|
|
78
|
-
}
|
|
79
|
-
if (videoHeight > videoWidth)
|
|
80
|
-
videoHeight = [videoWidth, videoWidth = videoHeight][0];
|
|
81
73
|
this._updateTransforms(rotation, fc);
|
|
74
|
+
this._dataSize = [dataWidth, dataHeight];
|
|
82
75
|
let framebuffer = this._getFramebuffer(gl, dataWidth / 4, dataHeight);
|
|
83
76
|
let vbo = this._getVertexBuffer(gl);
|
|
84
77
|
let ibo = this._getIndexBuffer(gl);
|
|
@@ -171,13 +164,10 @@ export class ImageProcessGL {
|
|
|
171
164
|
if (reenableStencilTest)
|
|
172
165
|
gl.enable(gl.STENCIL_TEST);
|
|
173
166
|
}
|
|
174
|
-
readFrame(
|
|
175
|
-
const [dataWidth, dataHeight] = profile.getDataSize(cp);
|
|
176
|
-
return this.readFrameForSize(texture, pixels, dataWidth, dataHeight);
|
|
177
|
-
}
|
|
178
|
-
readFrameForSize(texture, pixels, dataWidth, dataHeight) {
|
|
167
|
+
readFrame(pixels) {
|
|
179
168
|
let gl = this._gl;
|
|
180
169
|
let pixelsView = new Uint8Array(pixels);
|
|
170
|
+
const [dataWidth, dataHeight] = this._dataSize;
|
|
181
171
|
const previousBoundFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
|
|
182
172
|
let framebuffer = this._getFramebuffer(gl, dataWidth / 4, dataHeight);
|
|
183
173
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
|
@@ -186,7 +176,6 @@ export class ImageProcessGL {
|
|
|
186
176
|
return {
|
|
187
177
|
uvTransform: this._cameraUvTransform,
|
|
188
178
|
data: pixels,
|
|
189
|
-
texture,
|
|
190
179
|
dataWidth,
|
|
191
180
|
dataHeight,
|
|
192
181
|
userFacing: this._computedFrontCameraRotation
|
|
@@ -8,6 +8,8 @@ export declare class ImageBitmapCameraSource extends Source {
|
|
|
8
8
|
static DEFAULT_DEVICE_ID: string;
|
|
9
9
|
private _currentStream;
|
|
10
10
|
private _activeDeviceId;
|
|
11
|
+
private _preferredWidth;
|
|
12
|
+
private _preferredHeight;
|
|
11
13
|
private _isPaused;
|
|
12
14
|
private _isUserFacing;
|
|
13
15
|
private _hadFrames;
|
|
@@ -22,6 +24,7 @@ export declare class ImageBitmapCameraSource extends Source {
|
|
|
22
24
|
constructor(_impl: zappar_camera_source_t, _pipeline: zappar_pipeline_t, _deviceId: string);
|
|
23
25
|
destroy(): void;
|
|
24
26
|
setProfile(p: camera_profile_t): void;
|
|
27
|
+
setPreferredResolution(w: number, h: number): void;
|
|
25
28
|
private _stop;
|
|
26
29
|
pause(): void;
|
|
27
30
|
start(): void;
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { camera_profile_t } from "./gen/zappar";
|
|
11
|
-
import { profile } from "./profile";
|
|
11
|
+
import { profile, getDataSizeForSource } from "./profile";
|
|
12
12
|
import { Pipeline } from "./pipeline";
|
|
13
13
|
import { Source } from "./source";
|
|
14
14
|
import { cameraRotationForScreenOrientation } from "./cameramodel";
|
|
@@ -23,6 +23,8 @@ export class ImageBitmapCameraSource extends Source {
|
|
|
23
23
|
this._deviceId = _deviceId;
|
|
24
24
|
this._currentStream = null;
|
|
25
25
|
this._activeDeviceId = null;
|
|
26
|
+
this._preferredWidth = profile.videoWidth;
|
|
27
|
+
this._preferredHeight = profile.videoHeight;
|
|
26
28
|
this._isPaused = true;
|
|
27
29
|
this._isUserFacing = false;
|
|
28
30
|
this._hadFrames = false;
|
|
@@ -90,6 +92,10 @@ export class ImageBitmapCameraSource extends Source {
|
|
|
90
92
|
setProfile(p) {
|
|
91
93
|
this._profile = p;
|
|
92
94
|
}
|
|
95
|
+
setPreferredResolution(w, h) {
|
|
96
|
+
this._preferredWidth = w;
|
|
97
|
+
this._preferredHeight = h;
|
|
98
|
+
}
|
|
93
99
|
_stop() {
|
|
94
100
|
if (!this._currentStream)
|
|
95
101
|
return;
|
|
@@ -132,8 +138,8 @@ export class ImageBitmapCameraSource extends Source {
|
|
|
132
138
|
audio: false,
|
|
133
139
|
video: {
|
|
134
140
|
facingMode: facingMode,
|
|
135
|
-
width:
|
|
136
|
-
height:
|
|
141
|
+
width: this._preferredWidth,
|
|
142
|
+
height: this._preferredHeight,
|
|
137
143
|
frameRate: profile.requestHighFrameRate ? 60 : undefined,
|
|
138
144
|
deviceId: deviceId
|
|
139
145
|
}
|
|
@@ -190,7 +196,7 @@ export class ImageBitmapCameraSource extends Source {
|
|
|
190
196
|
let pipeline = Pipeline.get(this._pipeline);
|
|
191
197
|
if (!pipeline)
|
|
192
198
|
return;
|
|
193
|
-
const [dataWidth, dataHeight] =
|
|
199
|
+
const [dataWidth, dataHeight] = getDataSizeForSource(this._profile, imageBitmap, rotation);
|
|
194
200
|
let focalLength = 300.0 * dataWidth / 320.0;
|
|
195
201
|
this._cameraModel[0] = focalLength;
|
|
196
202
|
this._cameraModel[1] = focalLength;
|
|
@@ -281,10 +287,11 @@ export class ImageBitmapCameraSource extends Source {
|
|
|
281
287
|
let texture = pipeline.getVideoTexture();
|
|
282
288
|
if (!texture)
|
|
283
289
|
return;
|
|
290
|
+
const previousBoundTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);
|
|
284
291
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
285
292
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
286
293
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, info.frame);
|
|
287
|
-
gl.bindTexture(gl.TEXTURE_2D,
|
|
294
|
+
gl.bindTexture(gl.TEXTURE_2D, previousBoundTexture);
|
|
288
295
|
info.texture = texture;
|
|
289
296
|
}
|
|
290
297
|
}
|
|
@@ -8,6 +8,8 @@ export declare class MSTPCameraSource extends Source {
|
|
|
8
8
|
static DEFAULT_DEVICE_ID: string;
|
|
9
9
|
private _currentStream;
|
|
10
10
|
private _activeDeviceId;
|
|
11
|
+
private _preferredWidth;
|
|
12
|
+
private _preferredHeight;
|
|
11
13
|
private _isPaused;
|
|
12
14
|
private _isUserFacing;
|
|
13
15
|
private _cameraToScreenRotation;
|
|
@@ -20,6 +22,7 @@ export declare class MSTPCameraSource extends Source {
|
|
|
20
22
|
private _stop;
|
|
21
23
|
pause(): void;
|
|
22
24
|
start(): void;
|
|
25
|
+
setPreferredResolution(w: number, h: number): void;
|
|
23
26
|
private _getConstraints;
|
|
24
27
|
getFrame(allowRead: boolean): void;
|
|
25
28
|
private _getUserMedia;
|
|
@@ -21,6 +21,8 @@ export class MSTPCameraSource extends Source {
|
|
|
21
21
|
this._deviceId = _deviceId;
|
|
22
22
|
this._currentStream = null;
|
|
23
23
|
this._activeDeviceId = null;
|
|
24
|
+
this._preferredWidth = profile.videoWidth;
|
|
25
|
+
this._preferredHeight = profile.videoHeight;
|
|
24
26
|
this._isPaused = true;
|
|
25
27
|
this._isUserFacing = false;
|
|
26
28
|
this._cameraToScreenRotation = 0;
|
|
@@ -150,6 +152,10 @@ export class MSTPCameraSource extends Source {
|
|
|
150
152
|
this._startDeviceMotion();
|
|
151
153
|
this._syncCamera();
|
|
152
154
|
}
|
|
155
|
+
setPreferredResolution(w, h) {
|
|
156
|
+
this._preferredWidth = w;
|
|
157
|
+
this._preferredHeight = h;
|
|
158
|
+
}
|
|
153
159
|
_getConstraints() {
|
|
154
160
|
return __awaiter(this, void 0, void 0, function* () {
|
|
155
161
|
let deviceId;
|
|
@@ -166,8 +172,8 @@ export class MSTPCameraSource extends Source {
|
|
|
166
172
|
audio: false,
|
|
167
173
|
video: {
|
|
168
174
|
facingMode: facingMode,
|
|
169
|
-
width:
|
|
170
|
-
height:
|
|
175
|
+
width: this._preferredWidth,
|
|
176
|
+
height: this._preferredHeight,
|
|
171
177
|
frameRate: profile.requestHighFrameRate ? 60 : 30,
|
|
172
178
|
deviceId: deviceId
|
|
173
179
|
}
|
package/lib/native.js
CHANGED
|
@@ -36,6 +36,20 @@ import { WebXRCameraSource } from "./webxr-camera-source";
|
|
|
36
36
|
import { WebXRWorldTracker } from "./webxr-world-tracker";
|
|
37
37
|
let client;
|
|
38
38
|
const pipelineByWorldTracker = new Map();
|
|
39
|
+
const d3TrackerSizeById = new Map();
|
|
40
|
+
function applyD3SizeToPose(o, indx, pose) {
|
|
41
|
+
var _a;
|
|
42
|
+
const anchor_id = client.d3_tracker_id(o, indx);
|
|
43
|
+
if (anchor_id.length <= 0)
|
|
44
|
+
return;
|
|
45
|
+
const size = (_a = d3TrackerSizeById.get(o)) === null || _a === void 0 ? void 0 : _a.get(anchor_id);
|
|
46
|
+
if (size === undefined)
|
|
47
|
+
return pose;
|
|
48
|
+
const scale = 0.5 * size;
|
|
49
|
+
pose[12] *= scale;
|
|
50
|
+
pose[13] *= scale;
|
|
51
|
+
pose[14] *= scale;
|
|
52
|
+
}
|
|
39
53
|
const _temporaryMatrix = mat4.create();
|
|
40
54
|
const _temporaryVec3 = vec3.create();
|
|
41
55
|
export function initialize(opts) {
|
|
@@ -194,25 +208,31 @@ export function initialize(opts) {
|
|
|
194
208
|
let bridgedWtImpl = (bridgedWtApi === null || bridgedWtApi === void 0 ? void 0 : bridgedWtApi.impl) || {};
|
|
195
209
|
const wtImpl = (bridgedWtApi === null || bridgedWtApi === void 0 ? void 0 : bridgedWtApi.impl) || c.impl;
|
|
196
210
|
let bridgedD3Impl = (bridgedD3Api === null || bridgedD3Api === void 0 ? void 0 : bridgedD3Api.impl) || {};
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
211
|
+
let d3Impl = (bridgedD3Api === null || bridgedD3Api === void 0 ? void 0 : bridgedD3Api.impl) || c.impl;
|
|
212
|
+
client = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, c.impl), { world_tracker_mesh_anchor_count: () => 0, world_tracker_mesh_anchor_id: () => "", world_tracker_mesh_anchor_indices: () => new Uint32Array(0), world_tracker_mesh_anchor_indices_count: () => 0, world_tracker_mesh_anchor_indices_size: () => 0, world_tracker_mesh_anchor_vertices: () => new Float32Array(0), world_tracker_mesh_anchor_vertices_count: () => 0, world_tracker_mesh_anchor_vertices_size: () => 0, world_tracker_mesh_anchor_vertices_offset: () => 0, world_tracker_mesh_anchor_vertices_stride: () => 0, world_tracker_mesh_anchor_pose_raw: () => new Float32Array(), world_tracker_mesh_anchor_status: () => anchor_status_t.ANCHOR_STATUS_STOPPED, world_tracker_mesh_anchors_enabled: () => false, world_tracker_mesh_anchors_enabled_set: () => { }, d3_tracker_process_max_resolution_set: () => { } }), bridgedWtImpl), bridgedD3Impl), { d3_tracker_create: (pipeline) => {
|
|
213
|
+
let ret = d3Impl.d3_tracker_create(pipeline);
|
|
214
|
+
d3TrackerSizeById.set(ret, new Map());
|
|
215
|
+
return ret;
|
|
216
|
+
}, d3_tracker_destroy: (o) => {
|
|
217
|
+
d3TrackerSizeById.delete(o);
|
|
218
|
+
d3Impl.d3_tracker_destroy(o);
|
|
219
|
+
}, d3_tracker_pose0_raw: (o, indx) => {
|
|
220
|
+
let pose = d3Impl.d3_tracker_pose0_raw(o, indx).slice();
|
|
221
|
+
applyD3SizeToPose(o, indx, pose);
|
|
222
|
+
return pose;
|
|
223
|
+
}, d3_tracker_pose1_raw: (o, indx) => {
|
|
224
|
+
let pose = d3Impl.d3_tracker_pose1_raw(o, indx).slice();
|
|
225
|
+
applyD3SizeToPose(o, indx, pose);
|
|
226
|
+
return pose;
|
|
227
|
+
}, d3_tracker_size_for_id_set: (o, id, size) => {
|
|
228
|
+
var _a;
|
|
229
|
+
(_a = d3TrackerSizeById.get(o)) === null || _a === void 0 ? void 0 : _a.set(id, size);
|
|
230
|
+
}, d3_tracker_pose_raw: (o, indx) => {
|
|
231
|
+
return client.d3_tracker_pose0_raw(o, indx);
|
|
232
|
+
}, d3_tracker_pose: (o, indx, cameraPose, mirror) => {
|
|
233
|
+
return client.d3_tracker_pose0(o, indx, cameraPose, mirror);
|
|
207
234
|
}, d3_tracker_pose_camera_relative: (o, indx, mirror) => {
|
|
208
|
-
|
|
209
|
-
if (mirror) {
|
|
210
|
-
let scale = mat4.create();
|
|
211
|
-
mat4.fromScaling(scale, [-1, 1, 1]);
|
|
212
|
-
mat4.multiply(res, scale, res);
|
|
213
|
-
mat4.multiply(res, res, scale);
|
|
214
|
-
}
|
|
215
|
-
return res;
|
|
235
|
+
return client.d3_tracker_pose0_camera_relative(o, indx, mirror);
|
|
216
236
|
}, d3_tracker_pose0: (o, indx, cameraPose, mirror) => {
|
|
217
237
|
let res = applyScreenCounterRotation(undefined, client.d3_tracker_pose0_raw(o, indx));
|
|
218
238
|
if (mirror) {
|
|
@@ -251,7 +271,7 @@ export function initialize(opts) {
|
|
|
251
271
|
mat4.multiply(res, res, scale);
|
|
252
272
|
}
|
|
253
273
|
return res;
|
|
254
|
-
}
|
|
274
|
+
}, 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, preferWebXRCamera), 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_source_preferred_resolution_set: (cam, w, h) => { var _a; return (_a = getCameraSource(cam)) === null || _a === void 0 ? void 0 : _a.setPreferredResolution(w, h); }, 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) => {
|
|
255
275
|
let res = applyScreenCounterRotation(undefined, raw_pose);
|
|
256
276
|
if (mirror) {
|
|
257
277
|
let scale = mat4.create();
|
package/lib/profile.d.ts
CHANGED
|
@@ -11,7 +11,6 @@ export declare let profile: {
|
|
|
11
11
|
requestHighFrameRate: boolean;
|
|
12
12
|
videoWidth: number;
|
|
13
13
|
videoHeight: number;
|
|
14
|
-
getDataSize: (p: camera_profile_t) => number[];
|
|
15
14
|
videoElementInDOM: boolean;
|
|
16
15
|
preferMediaStreamTrackProcessorCamera: boolean;
|
|
17
16
|
preferImageBitmapCamera: boolean;
|
|
@@ -22,3 +21,5 @@ export declare let profile: {
|
|
|
22
21
|
trustSensorIntervals: boolean;
|
|
23
22
|
offscreenCanvasSupported: boolean;
|
|
24
23
|
};
|
|
24
|
+
export declare function getDataSize(p: camera_profile_t, fullWidth: number, fullHeight: number): [number, number];
|
|
25
|
+
export declare function getDataSizeForSource(p: camera_profile_t, source: HTMLVideoElement | HTMLImageElement | ImageBitmap, rotation?: number): [number, number];
|
package/lib/profile.js
CHANGED
|
@@ -13,7 +13,6 @@ export let profile = {
|
|
|
13
13
|
requestHighFrameRate: false,
|
|
14
14
|
videoWidth: 1280,
|
|
15
15
|
videoHeight: 720,
|
|
16
|
-
getDataSize: (p) => p === camera_profile_t.HIGH ? [640, 360] : [320, 180],
|
|
17
16
|
videoElementInDOM: false,
|
|
18
17
|
preferMediaStreamTrackProcessorCamera: false,
|
|
19
18
|
preferImageBitmapCamera: false,
|
|
@@ -24,6 +23,39 @@ export let profile = {
|
|
|
24
23
|
trustSensorIntervals: false,
|
|
25
24
|
offscreenCanvasSupported: typeof globalThis.OffscreenCanvas !== "undefined",
|
|
26
25
|
};
|
|
26
|
+
export function getDataSize(p, fullWidth, fullHeight) {
|
|
27
|
+
if (p === camera_profile_t.FULL)
|
|
28
|
+
return [fullWidth, fullHeight];
|
|
29
|
+
let fullMax = fullWidth > fullHeight ? fullWidth : fullHeight;
|
|
30
|
+
let dataMax = p === camera_profile_t.HIGH ? 640 : 320;
|
|
31
|
+
let scale = dataMax / fullMax;
|
|
32
|
+
if (scale >= 1)
|
|
33
|
+
return [fullWidth, fullHeight];
|
|
34
|
+
// Ensure width is a multiple of 4 (required by ImageProcessGL greyscale conversion)
|
|
35
|
+
let width = Math.round(scale * fullWidth / 4) * 4;
|
|
36
|
+
let height = Math.round(width * fullHeight / fullWidth);
|
|
37
|
+
return [width, height];
|
|
38
|
+
}
|
|
39
|
+
export function getDataSizeForSource(p, source, rotation = 0) {
|
|
40
|
+
let fullWidth = source.width;
|
|
41
|
+
let fullHeight = source.height;
|
|
42
|
+
// NB: undefined checks needed as these types aren't available in workers
|
|
43
|
+
if (typeof HTMLVideoElement !== "undefined" && source instanceof HTMLVideoElement) {
|
|
44
|
+
fullWidth = source.videoWidth;
|
|
45
|
+
fullHeight = source.videoHeight;
|
|
46
|
+
}
|
|
47
|
+
else if (typeof HTMLImageElement !== "undefined" && source instanceof HTMLImageElement) {
|
|
48
|
+
fullWidth = source.naturalWidth;
|
|
49
|
+
fullHeight = source.naturalHeight;
|
|
50
|
+
}
|
|
51
|
+
if ((rotation == 90) || (rotation == 270)) {
|
|
52
|
+
// Will be rotated as part of greyscale conversion
|
|
53
|
+
return getDataSize(p, fullHeight, fullWidth);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return getDataSize(p, fullWidth, fullHeight);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
27
59
|
if (typeof window !== "undefined") {
|
|
28
60
|
window["zeeProfile"] = profile;
|
|
29
61
|
if (window.location.href.indexOf("_mstppipeline") >= 0) {
|
|
@@ -81,7 +113,6 @@ function iDevice(version) {
|
|
|
81
113
|
// Avoid bug where iOS letterboxes 16:9 into 4:3 for high fps
|
|
82
114
|
// Doesn't seem needed with newer versions of iOS, tested on 14.8.1 and 15.2
|
|
83
115
|
profile.videoHeight = 360;
|
|
84
|
-
profile.getDataSize = (p) => p === camera_profile_t.HIGH ? [640, 360] : [320, 180];
|
|
85
116
|
}
|
|
86
117
|
}
|
|
87
118
|
if (majorVersion === 16 && minorVersion >= 4) {
|
package/lib/sequencesource.js
CHANGED
|
@@ -97,7 +97,7 @@ export class SequenceSource extends Source {
|
|
|
97
97
|
// updates will be one frame later
|
|
98
98
|
this._submitMotionUpdates(pipeline);
|
|
99
99
|
const token = pipeline.registerToken(info);
|
|
100
|
-
pipeline.sendDataToWorker(info.data || new ArrayBuffer(0), token, info.dataWidth, info.dataHeight, info.userFacing, info.cameraToDevice, info.cameraModel, -1);
|
|
100
|
+
pipeline.sendDataToWorker(info.data || new ArrayBuffer(0), token, info.dataWidth, info.dataHeight, info.userFacing, info.cameraToDevice.slice(), info.cameraModel.slice(), -1);
|
|
101
101
|
}
|
|
102
102
|
destroy() {
|
|
103
103
|
byId.delete(this._impl);
|
|
@@ -154,7 +154,7 @@ export class SequenceSource extends Source {
|
|
|
154
154
|
pendingMotionUpdate = true;
|
|
155
155
|
break;
|
|
156
156
|
case SequenceRecorderPacketType.ATTITUDE_MATRIX:
|
|
157
|
-
pipeline.motionAttitudeMatrix(packet.attitude);
|
|
157
|
+
pipeline.motionAttitudeMatrix(packet.attitude.slice());
|
|
158
158
|
pendingMotionUpdate = true;
|
|
159
159
|
break;
|
|
160
160
|
case SequenceRecorderPacketType.ACCELEROMETER_WO_GRAVITY_INT:
|
|
@@ -39,6 +39,7 @@ export declare class BridgedCameraSource extends Source {
|
|
|
39
39
|
uploadGL(info: CameraFrameInfo): void;
|
|
40
40
|
recycle(info: CameraFrameInfo): void;
|
|
41
41
|
setProfile(p: camera_profile_t): void;
|
|
42
|
+
setPreferredResolution(w: number, h: number): void;
|
|
42
43
|
private _anchorPoseFloat32;
|
|
43
44
|
private _anchorPoseUint16;
|
|
44
45
|
setCustomAnchorPose(anchor: zappar_custom_anchor_t, pose_version: number, pose: Float32Array): void;
|
|
@@ -7,6 +7,8 @@ export declare class CameraSource extends HTMLElementSource {
|
|
|
7
7
|
static DEFAULT_DEVICE_ID: string;
|
|
8
8
|
private _currentStream;
|
|
9
9
|
private _activeDeviceId;
|
|
10
|
+
private _preferredWidth;
|
|
11
|
+
private _preferredHeight;
|
|
10
12
|
private _explicitUserCameraId;
|
|
11
13
|
private _explicitEnvironmentCameraId;
|
|
12
14
|
constructor(_impl: zappar_camera_source_t, pipeline: zappar_pipeline_t, _deviceId: string);
|
|
@@ -14,6 +16,7 @@ export declare class CameraSource extends HTMLElementSource {
|
|
|
14
16
|
private _stop;
|
|
15
17
|
pause(): void;
|
|
16
18
|
start(): void;
|
|
19
|
+
setPreferredResolution(w: number, h: number): void;
|
|
17
20
|
private _getConstraints;
|
|
18
21
|
getFrame(allowRead: boolean): void;
|
|
19
22
|
private _getUserMedia;
|
|
@@ -186,4 +186,16 @@ export interface zappar {
|
|
|
186
186
|
custom_anchor_pose_set_with_parent(o: zappar_custom_anchor_t, pose: Float32Array, anchor_id: string): void;
|
|
187
187
|
d3_tracker_create(pipeline: zappar_pipeline_t): zappar_d3_tracker_t;
|
|
188
188
|
d3_tracker_destroy(o: zappar_d3_tracker_t): void;
|
|
189
|
+
d3_tracker_enabled(o: zappar_d3_tracker_t): boolean;
|
|
190
|
+
d3_tracker_enabled_set(o: zappar_d3_tracker_t, enabled: boolean): void;
|
|
191
|
+
d3_tracker_count(o: zappar_d3_tracker_t): number;
|
|
192
|
+
d3_tracker_id(o: zappar_d3_tracker_t, indx: number): string;
|
|
193
|
+
d3_tracker_pose0_raw(o: zappar_d3_tracker_t, indx: number): Float32Array;
|
|
194
|
+
d3_tracker_pose1_raw(o: zappar_d3_tracker_t, indx: number): Float32Array;
|
|
195
|
+
d3_tracker_type(o: zappar_d3_tracker_t, indx: number): number;
|
|
196
|
+
d3_tracker_category(o: zappar_d3_tracker_t, indx: number): number;
|
|
197
|
+
d3_tracker_qr(o: zappar_d3_tracker_t, indx: number): string;
|
|
198
|
+
d3_tracker_dense(o: zappar_d3_tracker_t, indx: number): number;
|
|
199
|
+
d3_tracker_landmarks_data(o: zappar_d3_tracker_t, indx: number): Float32Array;
|
|
200
|
+
d3_tracker_landmarks_data_size(o: zappar_d3_tracker_t, indx: number): number;
|
|
189
201
|
}
|