@zappar/zappar-cv 3.6.0 → 3.7.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/additional.d.ts +1 -0
- package/lib/bridged-world-tracker.js +8 -1
- package/lib/camera-source-map.d.ts +3 -2
- package/lib/camera-source-map.js +5 -2
- package/lib/image-blit-gl.d.ts +16 -0
- package/lib/image-blit-gl.js +212 -0
- package/lib/image-process-gl.d.ts +2 -0
- package/lib/image-process-gl.js +8 -2
- package/lib/native.js +15 -4
- package/lib/options.d.ts +1 -0
- package/lib/permission.d.ts +2 -1
- package/lib/permission.js +16 -4
- package/lib/profile.js +3 -3
- package/lib/src/additional.d.ts +1 -0
- package/lib/src/camera-source-map.d.ts +3 -2
- package/lib/src/image-blit-gl.d.ts +16 -0
- package/lib/src/image-process-gl.d.ts +2 -0
- package/lib/src/options.d.ts +1 -0
- package/lib/src/permission.d.ts +2 -1
- package/lib/src/version.d.ts +1 -1
- package/lib/src/webxr-camera-source.d.ts +79 -0
- package/lib/src/webxr-world-tracker.d.ts +19 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/webxr-camera-source.d.ts +79 -0
- package/lib/webxr-camera-source.js +537 -0
- package/lib/webxr-world-tracker.d.ts +19 -0
- package/lib/webxr-world-tracker.js +331 -0
- package/lib/worker-imagebitmap.js +13 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -18,8 +18,8 @@ npm i @zappar/zappar-cv
|
|
|
18
18
|
|
|
19
19
|
You can use our CDN from within your HTML:
|
|
20
20
|
```
|
|
21
|
-
<script src="https://libs.zappar.com/zappar-cv/3.
|
|
21
|
+
<script src="https://libs.zappar.com/zappar-cv/3.7.0/zappar-cv.js"></script>
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
Or you can download and host our standalone JavaScript bundle:
|
|
25
|
-
[https://libs.zappar.com/zappar-cv/3.
|
|
25
|
+
[https://libs.zappar.com/zappar-cv/3.7.0/zappar-cv.zip](https://libs.zappar.com/zappar-cv/3.7.0/zappar-cv.zip)
|
package/lib/additional.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BridgedCameraSource } from "./bridged-camera-source";
|
|
2
|
-
import { anchor_status_t, plane_orientation_t } from "./gen/zappar";
|
|
2
|
+
import { anchor_status_t, plane_orientation_t, world_scale_mode_t } from "./gen/zappar";
|
|
3
3
|
import { Pipeline } from "./pipeline";
|
|
4
4
|
const _emptyUint8Array = new Uint8Array(0);
|
|
5
5
|
export class BridgedWorldTracker {
|
|
@@ -217,6 +217,13 @@ export class BridgedWorldTracker {
|
|
|
217
217
|
let s = this._getWtState(o);
|
|
218
218
|
return this._emptyArray;
|
|
219
219
|
},
|
|
220
|
+
world_tracker_scale_mode_set: (o, mode) => {
|
|
221
|
+
// Stub - no-op
|
|
222
|
+
},
|
|
223
|
+
world_tracker_scale_mode: (o) => {
|
|
224
|
+
// Stub - no-op
|
|
225
|
+
return world_scale_mode_t.DEFAULT;
|
|
226
|
+
},
|
|
220
227
|
// #### custom_anchor ####
|
|
221
228
|
custom_anchor_create: (pipeline, worldtracker, id) => {
|
|
222
229
|
let newId = (this._latestId++);
|
|
@@ -3,9 +3,10 @@ import { CameraSource } from "./camera-source";
|
|
|
3
3
|
import { zappar_camera_source_t, zappar_pipeline_t } from "./gen/zappar";
|
|
4
4
|
import { ImageBitmapCameraSource } from "./imagebitmap-camera-source";
|
|
5
5
|
import { MSTPCameraSource } from "./mstp-camera-source";
|
|
6
|
-
|
|
6
|
+
import { WebXRCameraSource } from "./webxr-camera-source";
|
|
7
|
+
export declare type CameraSourceType = CameraSource | MSTPCameraSource | ImageBitmapCameraSource | BridgedCameraSource | WebXRCameraSource;
|
|
7
8
|
export declare function getNextCameraSourceId(): zappar_camera_source_t;
|
|
8
9
|
export declare function setCameraSourceId(id: zappar_camera_source_t, c: CameraSourceType): void;
|
|
9
10
|
export declare function getCameraSource(id: zappar_camera_source_t): CameraSourceType | undefined;
|
|
10
11
|
export declare function deleteCameraSource(id: zappar_camera_source_t): void;
|
|
11
|
-
export declare function createCameraSource(p: zappar_pipeline_t, deviceId: string): zappar_camera_source_t;
|
|
12
|
+
export declare function createCameraSource(p: zappar_pipeline_t, deviceId: string, preferWebXrCamera?: boolean): zappar_camera_source_t;
|
package/lib/camera-source-map.js
CHANGED
|
@@ -4,6 +4,7 @@ import { ImageBitmapCameraSource } from "./imagebitmap-camera-source";
|
|
|
4
4
|
import { zcout } from "./loglevel";
|
|
5
5
|
import { MSTPCameraSource } from "./mstp-camera-source";
|
|
6
6
|
import { profile } from "./profile";
|
|
7
|
+
import { WebXRCameraSource } from "./webxr-camera-source";
|
|
7
8
|
let latest = 1;
|
|
8
9
|
let byId = new Map();
|
|
9
10
|
export function getNextCameraSourceId() {
|
|
@@ -18,9 +19,11 @@ export function getCameraSource(id) {
|
|
|
18
19
|
export function deleteCameraSource(id) {
|
|
19
20
|
byId.delete(id);
|
|
20
21
|
}
|
|
21
|
-
export function createCameraSource(p, deviceId) {
|
|
22
|
+
export function createCameraSource(p, deviceId, preferWebXrCamera) {
|
|
22
23
|
let ret = getNextCameraSourceId();
|
|
23
|
-
if (
|
|
24
|
+
if (preferWebXrCamera && WebXRCameraSource.IsSupported() && deviceId === CameraSource.DEFAULT_DEVICE_ID)
|
|
25
|
+
setCameraSourceId(ret, new WebXRCameraSource(ret, p));
|
|
26
|
+
else if (BridgedCameraSource.IsSupported() && deviceId === CameraSource.DEFAULT_DEVICE_ID)
|
|
24
27
|
setCameraSourceId(ret, new BridgedCameraSource(ret, p, deviceId));
|
|
25
28
|
else if (profile.preferMediaStreamTrackProcessorCamera &&
|
|
26
29
|
'MediaStreamTrackProcessor' in window &&
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class ImageBlitGl {
|
|
2
|
+
private _gl;
|
|
3
|
+
private _sharedContext;
|
|
4
|
+
private _isWebGL2;
|
|
5
|
+
private _instancedArraysExtension;
|
|
6
|
+
private _program;
|
|
7
|
+
private _vertexBuffer;
|
|
8
|
+
constructor(_gl: WebGL2RenderingContext | WebGLRenderingContext, _sharedContext?: boolean);
|
|
9
|
+
resetGLContext(): void;
|
|
10
|
+
destroy(): void;
|
|
11
|
+
doBlit(): void;
|
|
12
|
+
private _getVertexAttribState;
|
|
13
|
+
private _resetVertexAttribState;
|
|
14
|
+
private _setGlobalState;
|
|
15
|
+
private _prepareContext;
|
|
16
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { compileShader, linkProgram } from "./shader";
|
|
2
|
+
import { zcout } from "./loglevel";
|
|
3
|
+
import { getSharedTracer } from "./tracing/sharedtracer";
|
|
4
|
+
// Some no-op tracing helpers for concise code and good dead code removal in bundlers
|
|
5
|
+
let tracer = null;
|
|
6
|
+
let traceStart = (name) => { };
|
|
7
|
+
let traceEnd = () => { };
|
|
8
|
+
if (!(typeof Z_TRACING)) {
|
|
9
|
+
tracer = getSharedTracer();
|
|
10
|
+
traceStart = (name) => { tracer.start(name); };
|
|
11
|
+
traceEnd = () => { tracer.end(); };
|
|
12
|
+
}
|
|
13
|
+
export class ImageBlitGl {
|
|
14
|
+
// If _sharedContext is true we will assert the required state
|
|
15
|
+
// before each draw and reset previous state when complete
|
|
16
|
+
constructor(_gl, _sharedContext = true) {
|
|
17
|
+
this._gl = _gl;
|
|
18
|
+
this._sharedContext = _sharedContext;
|
|
19
|
+
this._isWebGL2 = false;
|
|
20
|
+
this._program = null;
|
|
21
|
+
this._vertexBuffer = null;
|
|
22
|
+
this._isWebGL2 = _gl.getParameter(_gl.VERSION).indexOf("WebGL 2") >= 0;
|
|
23
|
+
if (!this._isWebGL2) {
|
|
24
|
+
this._instancedArraysExtension = this._gl.getExtension("ANGLE_instanced_arrays");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
resetGLContext() {
|
|
28
|
+
this._program = null;
|
|
29
|
+
this._vertexBuffer = null;
|
|
30
|
+
}
|
|
31
|
+
destroy() {
|
|
32
|
+
this.resetGLContext();
|
|
33
|
+
}
|
|
34
|
+
doBlit() {
|
|
35
|
+
var _a;
|
|
36
|
+
const gl = this._gl;
|
|
37
|
+
const gl2 = gl; // Must check _isWebGL2 before use
|
|
38
|
+
let previousState;
|
|
39
|
+
if (this._sharedContext) {
|
|
40
|
+
previousState = {
|
|
41
|
+
enabledScissorTest: gl.isEnabled(gl.SCISSOR_TEST),
|
|
42
|
+
enabledDepthTest: gl.isEnabled(gl.DEPTH_TEST),
|
|
43
|
+
enabledBlend: gl.isEnabled(gl.BLEND),
|
|
44
|
+
enabledCullFace: gl.isEnabled(gl.CULL_FACE),
|
|
45
|
+
enabledStencilTest: gl.isEnabled(gl.STENCIL_TEST),
|
|
46
|
+
program: gl.getParameter(gl.CURRENT_PROGRAM),
|
|
47
|
+
boundArrayBuffer: gl.getParameter(gl.ARRAY_BUFFER_BINDING),
|
|
48
|
+
posAttribState: this._getVertexAttribState(gl, 0)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// We've stored all the GL state we will need to restore, so this is the
|
|
52
|
+
// first moment we can initialize our WebGL objects safely
|
|
53
|
+
if (!this._program)
|
|
54
|
+
this._prepareContext();
|
|
55
|
+
if (!this._program || !this._vertexBuffer) {
|
|
56
|
+
// Didn't fully initialize our WebGL objects, bail out but reset the bits we may have changed
|
|
57
|
+
if (this._sharedContext && previousState) {
|
|
58
|
+
this._resetVertexAttribState(gl, 0, previousState.posAttribState);
|
|
59
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, previousState.boundArrayBuffer);
|
|
60
|
+
gl.useProgram(previousState.program);
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (this._sharedContext) {
|
|
65
|
+
// This state is initially set in _prepareContext so we
|
|
66
|
+
// only need to reset it if _sharedContext is true
|
|
67
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
|
|
68
|
+
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
|
69
|
+
if (this._isWebGL2) {
|
|
70
|
+
gl2.vertexAttribDivisor(0, 0);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
(_a = this._instancedArraysExtension) === null || _a === void 0 ? void 0 : _a.vertexAttribDivisorANGLE(0, 0);
|
|
74
|
+
}
|
|
75
|
+
gl.enableVertexAttribArray(0);
|
|
76
|
+
this._setGlobalState(gl);
|
|
77
|
+
gl.useProgram(this._program);
|
|
78
|
+
}
|
|
79
|
+
// Do the drawing...
|
|
80
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
81
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
82
|
+
// Reset the state
|
|
83
|
+
if (this._sharedContext && previousState) {
|
|
84
|
+
if (previousState.enabledBlend)
|
|
85
|
+
gl.enable(gl.BLEND);
|
|
86
|
+
if (previousState.enabledCullFace)
|
|
87
|
+
gl.enable(gl.CULL_FACE);
|
|
88
|
+
if (previousState.enabledDepthTest)
|
|
89
|
+
gl.enable(gl.DEPTH_TEST);
|
|
90
|
+
if (previousState.enabledScissorTest)
|
|
91
|
+
gl.enable(gl.SCISSOR_TEST);
|
|
92
|
+
if (previousState.enabledStencilTest)
|
|
93
|
+
gl.enable(gl.STENCIL_TEST);
|
|
94
|
+
this._resetVertexAttribState(gl, 0, previousState.posAttribState);
|
|
95
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, previousState.boundArrayBuffer);
|
|
96
|
+
gl.useProgram(previousState.program);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
_getVertexAttribState(gl, index) {
|
|
100
|
+
let divisor = 0;
|
|
101
|
+
if (this._isWebGL2) {
|
|
102
|
+
traceStart("getWebGL2Divisor");
|
|
103
|
+
divisor = gl.getVertexAttrib(index, gl.VERTEX_ATTRIB_ARRAY_DIVISOR);
|
|
104
|
+
traceEnd();
|
|
105
|
+
}
|
|
106
|
+
else if (this._instancedArraysExtension) {
|
|
107
|
+
traceStart("getExtDivisor");
|
|
108
|
+
divisor = gl.getVertexAttrib(index, this._instancedArraysExtension.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE);
|
|
109
|
+
traceEnd();
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
size: gl.getVertexAttrib(index, gl.VERTEX_ATTRIB_ARRAY_SIZE),
|
|
113
|
+
type: gl.getVertexAttrib(index, gl.VERTEX_ATTRIB_ARRAY_TYPE),
|
|
114
|
+
normalized: gl.getVertexAttrib(index, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED),
|
|
115
|
+
stride: gl.getVertexAttrib(index, gl.VERTEX_ATTRIB_ARRAY_STRIDE),
|
|
116
|
+
offset: gl.getVertexAttribOffset(index, gl.VERTEX_ATTRIB_ARRAY_POINTER),
|
|
117
|
+
bufferBinding: gl.getVertexAttrib(index, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING),
|
|
118
|
+
enabled: gl.getVertexAttrib(index, gl.VERTEX_ATTRIB_ARRAY_ENABLED),
|
|
119
|
+
divisor
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
_resetVertexAttribState(gl, index, state) {
|
|
123
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, state.bufferBinding);
|
|
124
|
+
gl.vertexAttribPointer(index, state.size, state.type, state.normalized, state.stride, state.offset);
|
|
125
|
+
if (state.divisor != 0) {
|
|
126
|
+
if (this._isWebGL2) {
|
|
127
|
+
gl.vertexAttribDivisor(index, state.divisor);
|
|
128
|
+
}
|
|
129
|
+
else if (this._instancedArraysExtension) {
|
|
130
|
+
this._instancedArraysExtension.vertexAttribDivisorANGLE(index, state.divisor);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!state.enabled)
|
|
134
|
+
gl.disableVertexAttribArray(index);
|
|
135
|
+
}
|
|
136
|
+
_setGlobalState(gl) {
|
|
137
|
+
gl.disable(gl.SCISSOR_TEST);
|
|
138
|
+
gl.disable(gl.DEPTH_TEST);
|
|
139
|
+
gl.disable(gl.BLEND);
|
|
140
|
+
gl.disable(gl.CULL_FACE);
|
|
141
|
+
gl.disable(gl.STENCIL_TEST);
|
|
142
|
+
}
|
|
143
|
+
_prepareContext() {
|
|
144
|
+
var _a;
|
|
145
|
+
const gl = this._gl;
|
|
146
|
+
gl.clearColor(0.5, 0.5, 1.0, 1.0);
|
|
147
|
+
let vertexData = new Float32Array([
|
|
148
|
+
-1.0, -1.0,
|
|
149
|
+
-1.0, 1.0,
|
|
150
|
+
1.0, -1.0,
|
|
151
|
+
1.0, 1.0
|
|
152
|
+
]);
|
|
153
|
+
this._vertexBuffer = gl.createBuffer();
|
|
154
|
+
if (!this._vertexBuffer) {
|
|
155
|
+
zcout("Couldn't create vertex buffer");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
|
|
159
|
+
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
|
|
160
|
+
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
|
161
|
+
if (this._isWebGL2) {
|
|
162
|
+
gl.vertexAttribDivisor(0, 0);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
(_a = this._instancedArraysExtension) === null || _a === void 0 ? void 0 : _a.vertexAttribDivisorANGLE(0, 0);
|
|
166
|
+
}
|
|
167
|
+
gl.enableVertexAttribArray(0);
|
|
168
|
+
let err = gl.getError();
|
|
169
|
+
if (err != gl.NO_ERROR) {
|
|
170
|
+
zcout(`Error setting up vertex buffer in ImageBlitGl::_prepareContext(): 0x${err.toString(16)}`);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
;
|
|
174
|
+
const program = gl.createProgram();
|
|
175
|
+
if (!program) {
|
|
176
|
+
zcout("Couldn't create program");
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const blitVsSource = `
|
|
180
|
+
attribute vec4 aPosition;
|
|
181
|
+
varying highp vec2 vUV;
|
|
182
|
+
|
|
183
|
+
void main(void) {
|
|
184
|
+
gl_Position = aPosition;
|
|
185
|
+
vUV = 0.5 * (aPosition.xy + vec2(1.0, 1.0));
|
|
186
|
+
}
|
|
187
|
+
`;
|
|
188
|
+
const blitFsSource = `
|
|
189
|
+
varying highp vec2 vUV;
|
|
190
|
+
uniform sampler2D uTexture;
|
|
191
|
+
|
|
192
|
+
void main(void) {
|
|
193
|
+
gl_FragColor = texture2D(uTexture, vUV);
|
|
194
|
+
}
|
|
195
|
+
`;
|
|
196
|
+
let vertexShader = compileShader(gl, gl.VERTEX_SHADER, blitVsSource);
|
|
197
|
+
let fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, blitFsSource);
|
|
198
|
+
gl.attachShader(program, vertexShader);
|
|
199
|
+
gl.attachShader(program, fragmentShader);
|
|
200
|
+
gl.bindAttribLocation(program, 0, "aPosition");
|
|
201
|
+
linkProgram(gl, program);
|
|
202
|
+
let uTextureLoc = gl.getUniformLocation(program, "uTexture");
|
|
203
|
+
gl.useProgram(program);
|
|
204
|
+
gl.uniform1i(uTextureLoc, 0);
|
|
205
|
+
err = gl.getError();
|
|
206
|
+
if (err != gl.NO_ERROR) {
|
|
207
|
+
zcout(`Error in ImageBlitGl::_prepareContext(): 0x${err.toString(16)}`);
|
|
208
|
+
}
|
|
209
|
+
this._program = program;
|
|
210
|
+
this._setGlobalState(gl);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -30,7 +30,9 @@ export declare class ImageProcessGL {
|
|
|
30
30
|
resetGLContext(): void;
|
|
31
31
|
destroy(): void;
|
|
32
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;
|
|
33
34
|
readFrame(texture: WebGLTexture, pixels: ArrayBuffer, cp: camera_profile_t): ProcessedFrame;
|
|
35
|
+
readFrameForSize(texture: WebGLTexture, pixels: ArrayBuffer, dataWidth: number, dataHeight: number): ProcessedFrame;
|
|
34
36
|
private _updateTransforms;
|
|
35
37
|
private _getCameraUvTransform;
|
|
36
38
|
private _getFramebuffer;
|
package/lib/image-process-gl.js
CHANGED
|
@@ -34,6 +34,10 @@ export class ImageProcessGL {
|
|
|
34
34
|
this.resetGLContext();
|
|
35
35
|
}
|
|
36
36
|
uploadFrame(texture, img, rotation, fc, cp) {
|
|
37
|
+
const [dataWidth, dataHeight] = profile.getDataSize(cp);
|
|
38
|
+
this.uploadFrameForSize(texture, img, rotation, fc, dataWidth, dataHeight);
|
|
39
|
+
}
|
|
40
|
+
uploadFrameForSize(texture, img, rotation, fc, dataWidth, dataHeight) {
|
|
37
41
|
let gl = this._gl;
|
|
38
42
|
const glStateManager = GLStateManager.get(gl);
|
|
39
43
|
glStateManager.push();
|
|
@@ -75,7 +79,6 @@ export class ImageProcessGL {
|
|
|
75
79
|
if (videoHeight > videoWidth)
|
|
76
80
|
videoHeight = [videoWidth, videoWidth = videoHeight][0];
|
|
77
81
|
this._updateTransforms(rotation, fc);
|
|
78
|
-
const [dataWidth, dataHeight] = profile.getDataSize(cp);
|
|
79
82
|
let framebuffer = this._getFramebuffer(gl, dataWidth / 4, dataHeight);
|
|
80
83
|
let vbo = this._getVertexBuffer(gl);
|
|
81
84
|
let ibo = this._getIndexBuffer(gl);
|
|
@@ -169,10 +172,13 @@ export class ImageProcessGL {
|
|
|
169
172
|
gl.enable(gl.STENCIL_TEST);
|
|
170
173
|
}
|
|
171
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) {
|
|
172
179
|
let gl = this._gl;
|
|
173
180
|
let pixelsView = new Uint8Array(pixels);
|
|
174
181
|
const previousBoundFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
|
|
175
|
-
const [dataWidth, dataHeight] = profile.getDataSize(cp);
|
|
176
182
|
let framebuffer = this._getFramebuffer(gl, dataWidth / 4, dataHeight);
|
|
177
183
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
|
178
184
|
gl.readPixels(0, 0, this._framebufferWidth, this._framebufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixelsView);
|
package/lib/native.js
CHANGED
|
@@ -13,7 +13,7 @@ import { drawPlane } from "./drawplane";
|
|
|
13
13
|
import { cameraRotationForScreenOrientation, projectionMatrixFromModelAndSize } from "./cameramodel";
|
|
14
14
|
import { mat4, vec3 } from "gl-matrix";
|
|
15
15
|
import { launchCeresWorkers, launchWorker, messageManager } from "./worker-client";
|
|
16
|
-
import { permissionRequestUI, permissionGrantedAll, permissionGrantedCamera, permissionGrantedMotion, permissionDeniedAny, permissionDeniedCamera, permissionDeniedMotion, permissionRequestMotion, permissionRequestCamera, permissionRequestAll, permissionDeniedUI } from "./permission";
|
|
16
|
+
import { permissionRequestUI, permissionGrantedAll, permissionGrantedCamera, permissionGrantedMotion, permissionDeniedAny, permissionDeniedCamera, permissionDeniedMotion, permissionRequestMotion, permissionRequestCamera, permissionRequestAll, permissionDeniedUI, setWebXRSupported } from "./permission";
|
|
17
17
|
import { createFaceMesh, destroyFaceMesh, getFaceMesh } from "./facemesh";
|
|
18
18
|
import { Pipeline, applyScreenCounterRotation } from "./pipeline";
|
|
19
19
|
import { CameraSource } from "./camera-source";
|
|
@@ -32,6 +32,8 @@ import { drawAxis } from "./drawaxis";
|
|
|
32
32
|
import { BridgedWorldTracker } from "./bridged-world-tracker";
|
|
33
33
|
import { BridgedD3Tracker } from "./bridged-d3-tracker";
|
|
34
34
|
import { BridgedCameraSource } from "./bridged-camera-source";
|
|
35
|
+
import { WebXRCameraSource } from "./webxr-camera-source";
|
|
36
|
+
import { WebXRWorldTracker } from "./webxr-world-tracker";
|
|
35
37
|
let client;
|
|
36
38
|
const pipelineByWorldTracker = new Map();
|
|
37
39
|
const _temporaryMatrix = mat4.create();
|
|
@@ -52,6 +54,12 @@ export function initialize(opts) {
|
|
|
52
54
|
});
|
|
53
55
|
const uid = getUID();
|
|
54
56
|
let hasPersistedUID = false;
|
|
57
|
+
let preferWebXRCamera = window.location.href.indexOf("_webxrcamera") >= 0;
|
|
58
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.preferWebXRCamera) !== undefined)
|
|
59
|
+
preferWebXRCamera = opts.preferWebXRCamera;
|
|
60
|
+
if (preferWebXRCamera && WebXRCameraSource.IsSupported()) {
|
|
61
|
+
setWebXRSupported(true);
|
|
62
|
+
}
|
|
55
63
|
let hasSetID = false;
|
|
56
64
|
try {
|
|
57
65
|
/** @ts-ignore */
|
|
@@ -173,10 +181,13 @@ export function initialize(opts) {
|
|
|
173
181
|
}
|
|
174
182
|
});
|
|
175
183
|
const customAnchors = new Map();
|
|
176
|
-
// Override world tracking functions if the bridge is available
|
|
184
|
+
// Override world tracking functions if WebXR or the bridge is available
|
|
177
185
|
let bridgedWtApi;
|
|
178
186
|
let bridgedD3Api;
|
|
179
|
-
if (
|
|
187
|
+
if (preferWebXRCamera && WebXRCameraSource.IsSupported()) {
|
|
188
|
+
bridgedWtApi = WebXRWorldTracker.SharedInstance();
|
|
189
|
+
}
|
|
190
|
+
else if (BridgedWorldTracker.IsSupported()) {
|
|
180
191
|
bridgedWtApi = BridgedWorldTracker.SharedInstance();
|
|
181
192
|
bridgedD3Api = BridgedD3Tracker.SharedInstance();
|
|
182
193
|
}
|
|
@@ -240,7 +251,7 @@ export function initialize(opts) {
|
|
|
240
251
|
mat4.multiply(res, res, scale);
|
|
241
252
|
}
|
|
242
253
|
return res;
|
|
243
|
-
} }), 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), 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) => {
|
|
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) => {
|
|
244
255
|
let res = applyScreenCounterRotation(undefined, raw_pose);
|
|
245
256
|
if (mirror) {
|
|
246
257
|
let scale = mat4.create();
|
package/lib/options.d.ts
CHANGED
package/lib/permission.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PermissionDeniedUIOptions, PermissionRequestUIOptions } from "./additional";
|
|
2
|
-
export declare function permissionGrantedCamera():
|
|
2
|
+
export declare function permissionGrantedCamera(): any;
|
|
3
3
|
export declare function permissionGrantedMotion(): boolean;
|
|
4
4
|
export declare function permissionDeniedCamera(): boolean;
|
|
5
5
|
export declare function permissionDeniedMotion(): boolean;
|
|
@@ -10,3 +10,4 @@ export declare function permissionRequestCamera(): Promise<void>;
|
|
|
10
10
|
export declare function permissionRequestMotion(): Promise<false | undefined>;
|
|
11
11
|
export declare function permissionRequestUI(options?: PermissionRequestUIOptions): Promise<boolean>;
|
|
12
12
|
export declare function permissionDeniedUI(options?: PermissionDeniedUIOptions): void;
|
|
13
|
+
export declare function setWebXRSupported(supported: boolean): void;
|
package/lib/permission.js
CHANGED
|
@@ -11,6 +11,7 @@ import { UAParser } from "ua-parser-js";
|
|
|
11
11
|
import { STRINGS, tr } from "./tr";
|
|
12
12
|
import { BridgedCameraSource } from "./bridged-camera-source";
|
|
13
13
|
let parser = new UAParser();
|
|
14
|
+
let _isWebXRSupported = false;
|
|
14
15
|
let _permissionGrantedCamera = false;
|
|
15
16
|
let _permissionGrantedMotion = false;
|
|
16
17
|
let _permissionDeniedCamera = false;
|
|
@@ -31,12 +32,18 @@ function checkForCameraPermission() {
|
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
checkForCameraPermission();
|
|
34
|
-
export function permissionGrantedCamera() {
|
|
35
|
+
export function permissionGrantedCamera() {
|
|
36
|
+
var _a;
|
|
37
|
+
if (_isWebXRSupported) {
|
|
38
|
+
return _permissionGrantedCamera && ((_a = navigator.userActivation) === null || _a === void 0 ? void 0 : _a.isActive);
|
|
39
|
+
}
|
|
40
|
+
return _permissionGrantedCamera;
|
|
41
|
+
}
|
|
35
42
|
export function permissionGrantedMotion() { return _permissionGrantedMotion; }
|
|
36
43
|
export function permissionDeniedCamera() { return _permissionDeniedCamera; }
|
|
37
44
|
export function permissionDeniedMotion() { return _permissionDeniedMotion; }
|
|
38
45
|
export function permissionDeniedAny() { return _permissionDeniedCamera || _permissionDeniedMotion; }
|
|
39
|
-
export function permissionGrantedAll() { return
|
|
46
|
+
export function permissionGrantedAll() { return permissionGrantedCamera() && _permissionGrantedMotion; }
|
|
40
47
|
export function permissionRequestAll() {
|
|
41
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42
49
|
yield permissionRequestMotion();
|
|
@@ -81,10 +88,10 @@ export function permissionRequestMotion() {
|
|
|
81
88
|
});
|
|
82
89
|
}
|
|
83
90
|
export function permissionRequestUI(options) {
|
|
84
|
-
var _a, _b, _c;
|
|
91
|
+
var _a, _b, _c, _d;
|
|
85
92
|
return __awaiter(this, void 0, void 0, function* () {
|
|
86
93
|
yield checkForCameraPermission();
|
|
87
|
-
if (permissionGrantedAll()) {
|
|
94
|
+
if (permissionGrantedAll() && !(options === null || options === void 0 ? void 0 : options.ignoreUserActivation)) {
|
|
88
95
|
return true;
|
|
89
96
|
}
|
|
90
97
|
let div = document.createElement("div");
|
|
@@ -166,6 +173,8 @@ export function permissionRequestUI(options) {
|
|
|
166
173
|
});
|
|
167
174
|
}
|
|
168
175
|
try {
|
|
176
|
+
if (_isWebXRSupported && !((_d = navigator.userActivation) === null || _d === void 0 ? void 0 : _d.isActive))
|
|
177
|
+
throw new Error("WebXR - need user interaction");
|
|
169
178
|
return yield attempt();
|
|
170
179
|
}
|
|
171
180
|
catch (err) {
|
|
@@ -297,3 +306,6 @@ function permissionDeniedUIChrome(options) {
|
|
|
297
306
|
let button = div.querySelector("#zappar-permission-reload-button");
|
|
298
307
|
button === null || button === void 0 ? void 0 : button.addEventListener("click", () => window.location.reload());
|
|
299
308
|
}
|
|
309
|
+
export function setWebXRSupported(supported) {
|
|
310
|
+
_isWebXRSupported = supported;
|
|
311
|
+
}
|
package/lib/profile.js
CHANGED
|
@@ -11,9 +11,9 @@ export let profile = {
|
|
|
11
11
|
showGyroPermissionsWarningIfNecessary: false,
|
|
12
12
|
showSafariPermissionsResetIfNecessary: false,
|
|
13
13
|
requestHighFrameRate: false,
|
|
14
|
-
videoWidth:
|
|
15
|
-
videoHeight:
|
|
16
|
-
getDataSize: (p) => p === camera_profile_t.HIGH ? [640,
|
|
14
|
+
videoWidth: 1280,
|
|
15
|
+
videoHeight: 720,
|
|
16
|
+
getDataSize: (p) => p === camera_profile_t.HIGH ? [640, 360] : [320, 180],
|
|
17
17
|
videoElementInDOM: false,
|
|
18
18
|
preferMediaStreamTrackProcessorCamera: false,
|
|
19
19
|
preferImageBitmapCamera: false,
|
package/lib/src/additional.d.ts
CHANGED
|
@@ -3,9 +3,10 @@ import { CameraSource } from "./camera-source";
|
|
|
3
3
|
import { zappar_camera_source_t, zappar_pipeline_t } from "./gen/zappar";
|
|
4
4
|
import { ImageBitmapCameraSource } from "./imagebitmap-camera-source";
|
|
5
5
|
import { MSTPCameraSource } from "./mstp-camera-source";
|
|
6
|
-
|
|
6
|
+
import { WebXRCameraSource } from "./webxr-camera-source";
|
|
7
|
+
export declare type CameraSourceType = CameraSource | MSTPCameraSource | ImageBitmapCameraSource | BridgedCameraSource | WebXRCameraSource;
|
|
7
8
|
export declare function getNextCameraSourceId(): zappar_camera_source_t;
|
|
8
9
|
export declare function setCameraSourceId(id: zappar_camera_source_t, c: CameraSourceType): void;
|
|
9
10
|
export declare function getCameraSource(id: zappar_camera_source_t): CameraSourceType | undefined;
|
|
10
11
|
export declare function deleteCameraSource(id: zappar_camera_source_t): void;
|
|
11
|
-
export declare function createCameraSource(p: zappar_pipeline_t, deviceId: string): zappar_camera_source_t;
|
|
12
|
+
export declare function createCameraSource(p: zappar_pipeline_t, deviceId: string, preferWebXrCamera?: boolean): zappar_camera_source_t;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class ImageBlitGl {
|
|
2
|
+
private _gl;
|
|
3
|
+
private _sharedContext;
|
|
4
|
+
private _isWebGL2;
|
|
5
|
+
private _instancedArraysExtension;
|
|
6
|
+
private _program;
|
|
7
|
+
private _vertexBuffer;
|
|
8
|
+
constructor(_gl: WebGL2RenderingContext | WebGLRenderingContext, _sharedContext?: boolean);
|
|
9
|
+
resetGLContext(): void;
|
|
10
|
+
destroy(): void;
|
|
11
|
+
doBlit(): void;
|
|
12
|
+
private _getVertexAttribState;
|
|
13
|
+
private _resetVertexAttribState;
|
|
14
|
+
private _setGlobalState;
|
|
15
|
+
private _prepareContext;
|
|
16
|
+
}
|
|
@@ -30,7 +30,9 @@ export declare class ImageProcessGL {
|
|
|
30
30
|
resetGLContext(): void;
|
|
31
31
|
destroy(): void;
|
|
32
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;
|
|
33
34
|
readFrame(texture: WebGLTexture, pixels: ArrayBuffer, cp: camera_profile_t): ProcessedFrame;
|
|
35
|
+
readFrameForSize(texture: WebGLTexture, pixels: ArrayBuffer, dataWidth: number, dataHeight: number): ProcessedFrame;
|
|
34
36
|
private _updateTransforms;
|
|
35
37
|
private _getCameraUvTransform;
|
|
36
38
|
private _getFramebuffer;
|
package/lib/src/options.d.ts
CHANGED
package/lib/src/permission.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PermissionDeniedUIOptions, PermissionRequestUIOptions } from "./additional";
|
|
2
|
-
export declare function permissionGrantedCamera():
|
|
2
|
+
export declare function permissionGrantedCamera(): any;
|
|
3
3
|
export declare function permissionGrantedMotion(): boolean;
|
|
4
4
|
export declare function permissionDeniedCamera(): boolean;
|
|
5
5
|
export declare function permissionDeniedMotion(): boolean;
|
|
@@ -10,3 +10,4 @@ export declare function permissionRequestCamera(): Promise<void>;
|
|
|
10
10
|
export declare function permissionRequestMotion(): Promise<false | undefined>;
|
|
11
11
|
export declare function permissionRequestUI(options?: PermissionRequestUIOptions): Promise<boolean>;
|
|
12
12
|
export declare function permissionDeniedUI(options?: PermissionDeniedUIOptions): void;
|
|
13
|
+
export declare function setWebXRSupported(supported: boolean): void;
|
package/lib/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "3.
|
|
1
|
+
export declare const VERSION = "3.7.0";
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { anchor_status_t, world_tracker_quality_t, camera_profile_t, zappar_camera_source_t, zappar_pipeline_t, zappar_custom_anchor_t } from "./gen/zappar";
|
|
2
|
+
import { CameraFrameInfo, Source } from "./source";
|
|
3
|
+
export interface WebXRPlaneAnchorData {
|
|
4
|
+
id: string;
|
|
5
|
+
horizontal: boolean;
|
|
6
|
+
status: anchor_status_t;
|
|
7
|
+
pose: Float32Array;
|
|
8
|
+
boundary: Float32Array;
|
|
9
|
+
boundaryVersion: number;
|
|
10
|
+
}
|
|
11
|
+
export interface WebXRCustomAnchorData {
|
|
12
|
+
id: number;
|
|
13
|
+
status: anchor_status_t;
|
|
14
|
+
pose: Float32Array;
|
|
15
|
+
poseVersion: number;
|
|
16
|
+
}
|
|
17
|
+
export interface WebXRWTData {
|
|
18
|
+
world_anchor_status: anchor_status_t;
|
|
19
|
+
world_anchor_pose: Float32Array;
|
|
20
|
+
ground_anchor_status: anchor_status_t;
|
|
21
|
+
ground_anchor_pose: Float32Array;
|
|
22
|
+
plane_anchors: WebXRPlaneAnchorData[];
|
|
23
|
+
custom_anchors: WebXRCustomAnchorData[];
|
|
24
|
+
quality: world_tracker_quality_t;
|
|
25
|
+
}
|
|
26
|
+
export interface WebXRWTOptions {
|
|
27
|
+
horizontalPlaneDetection: boolean;
|
|
28
|
+
verticalPlaneDetection: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare class WebXRCameraSource extends Source {
|
|
31
|
+
private _impl;
|
|
32
|
+
private _pipeline;
|
|
33
|
+
sessionNumber: number;
|
|
34
|
+
private _isPaused;
|
|
35
|
+
private _xrSession;
|
|
36
|
+
private _xrLocalSpace;
|
|
37
|
+
private _xrViewerSpace;
|
|
38
|
+
private _xrGlBinding;
|
|
39
|
+
private _xrWebGLLayer;
|
|
40
|
+
private _offscreenCanvas;
|
|
41
|
+
private _offscreenContext;
|
|
42
|
+
private _imageBlitGl;
|
|
43
|
+
private _latestFrame;
|
|
44
|
+
private _latestWtData;
|
|
45
|
+
private _wtOptions;
|
|
46
|
+
private _lastFrameTime;
|
|
47
|
+
private _cameraToDeviceTransform;
|
|
48
|
+
private _cameraModel;
|
|
49
|
+
private _rawCameraModel;
|
|
50
|
+
private _profile;
|
|
51
|
+
private _permissionRequestShown;
|
|
52
|
+
private _planeHitTestSource;
|
|
53
|
+
private _customAnchorSetRequests;
|
|
54
|
+
private _customAnchors;
|
|
55
|
+
static IsSupported(): boolean;
|
|
56
|
+
constructor(_impl: zappar_camera_source_t, _pipeline: zappar_pipeline_t);
|
|
57
|
+
destroy(): void;
|
|
58
|
+
setProfile(p: camera_profile_t): void;
|
|
59
|
+
private _stop;
|
|
60
|
+
pause(): void;
|
|
61
|
+
start(): void;
|
|
62
|
+
optionsUpdated(options: WebXRWTOptions): void;
|
|
63
|
+
resetTracking(): void;
|
|
64
|
+
getFrame(currentlyProcessing: boolean): void;
|
|
65
|
+
private _syncCamera;
|
|
66
|
+
private _onXRFrame;
|
|
67
|
+
private _onXREnd;
|
|
68
|
+
private _hasStartedOrientation;
|
|
69
|
+
private _lastTimestamp;
|
|
70
|
+
private _deviceMotionListener;
|
|
71
|
+
private _startDeviceOrientation;
|
|
72
|
+
private _startDeviceMotion;
|
|
73
|
+
private _stopDeviceMotion;
|
|
74
|
+
uploadGL(info: CameraFrameInfo): void;
|
|
75
|
+
setCustomAnchorPose(o: zappar_custom_anchor_t, version: number, pose: Float32Array): Promise<void>;
|
|
76
|
+
deleteCustomAnchor(o: zappar_custom_anchor_t): Promise<void>;
|
|
77
|
+
private _updateCameraModel;
|
|
78
|
+
private _isPlaneVertical;
|
|
79
|
+
}
|