@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.
Files changed (47) hide show
  1. package/README.md +2 -2
  2. package/lib/bridged-camera-source.d.ts +1 -0
  3. package/lib/bridged-camera-source.js +8 -0
  4. package/lib/bridged-d3-tracker.js +2 -26
  5. package/lib/camera-source.d.ts +3 -0
  6. package/lib/camera-source.js +8 -2
  7. package/lib/drawpoints.js +30 -38
  8. package/lib/gen/zappar-bridge.d.ts +12 -0
  9. package/lib/gen/zappar-client.js +173 -5
  10. package/lib/gen/zappar-cwrap.js +115 -0
  11. package/lib/gen/zappar-native.d.ts +14 -1
  12. package/lib/gen/zappar-native.js +1 -0
  13. package/lib/gen/zappar-server.js +75 -0
  14. package/lib/gen/zappar.d.ts +9 -8
  15. package/lib/html-element-source.d.ts +1 -0
  16. package/lib/html-element-source.js +4 -3
  17. package/lib/image-process-gl.d.ts +4 -5
  18. package/lib/image-process-gl.js +14 -25
  19. package/lib/imagebitmap-camera-source.d.ts +3 -0
  20. package/lib/imagebitmap-camera-source.js +12 -5
  21. package/lib/mstp-camera-source.d.ts +3 -0
  22. package/lib/mstp-camera-source.js +8 -2
  23. package/lib/native.js +39 -19
  24. package/lib/profile.d.ts +2 -1
  25. package/lib/profile.js +33 -2
  26. package/lib/sequencesource.js +2 -2
  27. package/lib/src/bridged-camera-source.d.ts +1 -0
  28. package/lib/src/camera-source.d.ts +3 -0
  29. package/lib/src/gen/zappar-bridge.d.ts +12 -0
  30. package/lib/src/gen/zappar-native.d.ts +14 -1
  31. package/lib/src/gen/zappar.d.ts +9 -8
  32. package/lib/src/html-element-source.d.ts +1 -0
  33. package/lib/src/image-process-gl.d.ts +4 -5
  34. package/lib/src/imagebitmap-camera-source.d.ts +3 -0
  35. package/lib/src/mstp-camera-source.d.ts +3 -0
  36. package/lib/src/profile.d.ts +2 -1
  37. package/lib/src/version.d.ts +1 -1
  38. package/lib/src/webxr-camera-source.d.ts +5 -0
  39. package/lib/tests/common.d.ts +3 -1
  40. package/lib/version.d.ts +1 -1
  41. package/lib/version.js +1 -1
  42. package/lib/webxr-camera-source.d.ts +5 -0
  43. package/lib/webxr-camera-source.js +67 -35
  44. package/lib/worker-imagebitmap.js +2 -14
  45. package/lib/zappar-cv.js +1 -1
  46. package/lib/zappar-cv.wasm +0 -0
  47. package/package.json +1 -1
@@ -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
  }
@@ -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
- d3_tracker_qr(o: zappar_d3_tracker_t, indx: number): string;
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] = profile.getDataSize(this._profile);
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(tex, pixels, this._profile)), { cameraModel: this._cameraModel, cameraSource: this, cameraToDevice: (this._isUserFacing ? this._cameraToDeviceTransformUserFacing : this._cameraToDeviceTransform) });
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): void;
33
- uploadFrameForSize(texture: WebGLTexture, img: HTMLVideoElement | HTMLImageElement | ImageBitmap, rotation: number, fc: boolean, dataWidth: number, dataHeight: number): void;
34
- readFrame(texture: WebGLTexture, pixels: ArrayBuffer, cp: camera_profile_t): ProcessedFrame;
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;
@@ -1,6 +1,6 @@
1
1
  import { mat4 } from "gl-matrix";
2
2
  import { GLStateManager } from "./gl-state-manager";
3
- import { profile } from "./profile";
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 [dataWidth, dataHeight] = profile.getDataSize(cp);
38
- this.uploadFrameForSize(texture, img, rotation, fc, dataWidth, dataHeight);
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
- const level = 0;
65
- const internalFormat = gl.RGBA;
66
- const srcFormat = gl.RGBA;
67
- const srcType = gl.UNSIGNED_BYTE;
68
- gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, img);
69
- let videoWidth = 0;
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(texture, pixels, cp) {
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: profile.videoWidth,
136
- height: profile.videoHeight,
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] = profile.getDataSize(this._profile);
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, null);
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: profile.videoWidth,
170
- height: profile.videoHeight,
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
- 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_create: (p) => { return -1; }, d3_tracker_destroy: (o) => { }, d3_tracker_count: (o) => { return 0; }, d3_tracker_enabled: (o) => { return false; }, d3_tracker_enabled_set: (o, v) => { }, d3_tracker_process_max_resolution_set: (o, v) => { }, d3_tracker_pose_raw: (o, indx) => { return mat4.create(); }, d3_tracker_pose0_raw: (o, indx) => { return mat4.create(); }, d3_tracker_pose1_raw: (o, indx) => { return mat4.create(); }, d3_tracker_id: (o, indx) => { return ''; }, d3_tracker_qr: (o, indx) => { return ''; }, d3_tracker_landmarks_data: (o, indx) => { return new Float32Array(0); }, d3_tracker_landmarks_data_size: (o, indx) => { return 0; }, d3_tracker_type: (o, indx) => { return 0; }, d3_tracker_dense: (o, indx) => { return 0; }, d3_tracker_category: (o, indx) => { return 0; }, d3_tracker_size_for_id_set: (o, id, size) => { return 0; }, d3_tracker_pose: (o, indx, cameraPose, mirror) => {
198
- let res = applyScreenCounterRotation(undefined, client.d3_tracker_pose_raw(o, indx));
199
- if (mirror) {
200
- let scale = mat4.create();
201
- mat4.fromScaling(scale, [-1, 1, 1]);
202
- mat4.multiply(res, scale, res);
203
- mat4.multiply(res, res, scale);
204
- }
205
- mat4.multiply(res, cameraPose, res);
206
- return res;
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
- let res = applyScreenCounterRotation(undefined, client.d3_tracker_pose_raw(o, indx));
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
- } }), bridgedWtImpl), bridgedD3Impl), { 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_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) => {
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) {
@@ -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
  }