iwer 2.0.1 → 2.1.1
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/build/iwer.js +3304 -374
- package/build/iwer.min.js +204 -1
- package/build/iwer.module.js +3304 -374
- package/build/iwer.module.min.js +204 -1
- package/lib/action/ActionPlayer.d.ts.map +1 -1
- package/lib/action/ActionPlayer.js.map +1 -1
- package/lib/action/ActionRecorder.d.ts.map +1 -1
- package/lib/action/ActionRecorder.js +1 -1
- package/lib/action/ActionRecorder.js.map +1 -1
- package/lib/anchors/XRAnchor.d.ts.map +1 -1
- package/lib/anchors/XRAnchor.js.map +1 -1
- package/lib/device/XRController.d.ts.map +1 -1
- package/lib/device/XRController.js.map +1 -1
- package/lib/device/XRDevice.d.ts +7 -2
- package/lib/device/XRDevice.d.ts.map +1 -1
- package/lib/device/XRDevice.js +21 -4
- package/lib/device/XRDevice.js.map +1 -1
- package/lib/device/XRHandInput.d.ts.map +1 -1
- package/lib/device/XRHandInput.js.map +1 -1
- package/lib/device/XRTrackedInput.d.ts.map +1 -1
- package/lib/device/XRTrackedInput.js.map +1 -1
- package/lib/device/configs/controller/meta.js.map +1 -1
- package/lib/device/configs/hand/pinch.js.map +1 -1
- package/lib/device/configs/hand/point.js.map +1 -1
- package/lib/device/configs/hand/relaxed.js.map +1 -1
- package/lib/device/configs/headset/meta.js.map +1 -1
- package/lib/events/XRInputSourceEvent.d.ts.map +1 -1
- package/lib/events/XRInputSourceEvent.js.map +1 -1
- package/lib/events/XRInputSourcesChangeEvent.d.ts.map +1 -1
- package/lib/events/XRInputSourcesChangeEvent.js.map +1 -1
- package/lib/events/XRReferenceSpaceEvent.d.ts.map +1 -1
- package/lib/events/XRReferenceSpaceEvent.js.map +1 -1
- package/lib/events/XRSessionEvent.d.ts.map +1 -1
- package/lib/events/XRSessionEvent.js.map +1 -1
- package/lib/frameloop/XRFrame.d.ts.map +1 -1
- package/lib/frameloop/XRFrame.js.map +1 -1
- package/lib/gamepad/Gamepad.d.ts.map +1 -1
- package/lib/gamepad/Gamepad.js.map +1 -1
- package/lib/hittest/XRHitTest.d.ts.map +1 -1
- package/lib/hittest/XRHitTest.js.map +1 -1
- package/lib/hittest/XRRay.d.ts.map +1 -1
- package/lib/hittest/XRRay.js +1 -1
- package/lib/hittest/XRRay.js.map +1 -1
- package/lib/initialization/XRSystem.d.ts.map +1 -1
- package/lib/initialization/XRSystem.js.map +1 -1
- package/lib/input/XRHand.d.ts.map +1 -1
- package/lib/input/XRHand.js.map +1 -1
- package/lib/input/XRInputSource.d.ts.map +1 -1
- package/lib/input/XRInputSource.js.map +1 -1
- package/lib/labels/labels.d.ts.map +1 -1
- package/lib/labels/labels.js.map +1 -1
- package/lib/layers/XRWebGLBinding.d.ts +92 -0
- package/lib/layers/XRWebGLBinding.d.ts.map +1 -0
- package/lib/layers/XRWebGLBinding.js +186 -0
- package/lib/layers/XRWebGLBinding.js.map +1 -0
- package/lib/layers/XRWebGLLayer.d.ts.map +1 -1
- package/lib/layers/XRWebGLLayer.js.map +1 -1
- package/lib/meshes/XRMesh.d.ts.map +1 -1
- package/lib/meshes/XRMesh.js.map +1 -1
- package/lib/planes/XRPlane.d.ts.map +1 -1
- package/lib/planes/XRPlane.js.map +1 -1
- package/lib/pose/XRJointPose.d.ts.map +1 -1
- package/lib/pose/XRJointPose.js.map +1 -1
- package/lib/pose/XRPose.d.ts.map +1 -1
- package/lib/pose/XRPose.js.map +1 -1
- package/lib/pose/XRViewerPose.d.ts.map +1 -1
- package/lib/pose/XRViewerPose.js.map +1 -1
- package/lib/primitives/XRRigidTransform.d.ts.map +1 -1
- package/lib/primitives/XRRigidTransform.js +0 -1
- package/lib/primitives/XRRigidTransform.js.map +1 -1
- package/lib/session/XRRenderState.d.ts.map +1 -1
- package/lib/session/XRRenderState.js.map +1 -1
- package/lib/session/XRSession.d.ts.map +1 -1
- package/lib/session/XRSession.js.map +1 -1
- package/lib/spaces/XRJointSpace.d.ts.map +1 -1
- package/lib/spaces/XRJointSpace.js.map +1 -1
- package/lib/spaces/XRReferenceSpace.d.ts.map +1 -1
- package/lib/spaces/XRReferenceSpace.js.map +1 -1
- package/lib/spaces/XRSpace.d.ts.map +1 -1
- package/lib/spaces/XRSpace.js.map +1 -1
- package/lib/utils/Math.d.ts.map +1 -1
- package/lib/utils/Math.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/views/XRView.d.ts.map +1 -1
- package/lib/views/XRView.js.map +1 -1
- package/lib/views/XRViewport.d.ts.map +1 -1
- package/lib/views/XRViewport.js.map +1 -1
- package/package.json +61 -60
- package/lib/action/Capture.d.ts +0 -3
- package/lib/action/Capture.d.ts.map +0 -1
- package/lib/action/Capture.js +0 -26907
- package/lib/action/Capture.js.map +0 -1
- package/lib/device/controllers.d.ts +0 -31
- package/lib/device/controllers.d.ts.map +0 -1
- package/lib/device/controllers.js +0 -8
- package/lib/device/controllers.js.map +0 -1
- package/lib/input/XRInputSourceArray.d.ts +0 -11
- package/lib/input/XRInputSourceArray.d.ts.map +0 -1
- package/lib/input/XRInputSourceArray.js +0 -17
- package/lib/input/XRInputSourceArray.js.map +0 -1
- package/lib/utils/DOMPointReadOnly.d.ts +0 -23
- package/lib/utils/DOMPointReadOnly.d.ts.map +0 -1
- package/lib/utils/DOMPointReadOnly.js +0 -32
- package/lib/utils/DOMPointReadOnly.js.map +0 -1
package/build/iwer.module.js
CHANGED
|
@@ -2,19 +2,10 @@
|
|
|
2
2
|
* Common utilities
|
|
3
3
|
* @module glMatrix
|
|
4
4
|
*/
|
|
5
|
+
|
|
5
6
|
// Configuration Constants
|
|
6
7
|
var EPSILON = 0.000001;
|
|
7
|
-
var ARRAY_TYPE = typeof Float32Array !==
|
|
8
|
-
if (!Math.hypot) Math.hypot = function () {
|
|
9
|
-
var y = 0,
|
|
10
|
-
i = arguments.length;
|
|
11
|
-
|
|
12
|
-
while (i--) {
|
|
13
|
-
y += arguments[i] * arguments[i];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return Math.sqrt(y);
|
|
17
|
-
};
|
|
8
|
+
var ARRAY_TYPE$1 = typeof Float32Array !== "undefined" ? Float32Array : Array;
|
|
18
9
|
|
|
19
10
|
/**
|
|
20
11
|
* 3x3 Matrix
|
|
@@ -26,11 +17,9 @@ if (!Math.hypot) Math.hypot = function () {
|
|
|
26
17
|
*
|
|
27
18
|
* @returns {mat3} a new 3x3 matrix
|
|
28
19
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (ARRAY_TYPE != Float32Array) {
|
|
20
|
+
function create$6() {
|
|
21
|
+
var out = new ARRAY_TYPE$1(9);
|
|
22
|
+
if (ARRAY_TYPE$1 != Float32Array) {
|
|
34
23
|
out[1] = 0;
|
|
35
24
|
out[2] = 0;
|
|
36
25
|
out[3] = 0;
|
|
@@ -38,7 +27,6 @@ function create$4() {
|
|
|
38
27
|
out[6] = 0;
|
|
39
28
|
out[7] = 0;
|
|
40
29
|
}
|
|
41
|
-
|
|
42
30
|
out[0] = 1;
|
|
43
31
|
out[4] = 1;
|
|
44
32
|
out[8] = 1;
|
|
@@ -55,11 +43,9 @@ function create$4() {
|
|
|
55
43
|
*
|
|
56
44
|
* @returns {mat4} a new 4x4 matrix
|
|
57
45
|
*/
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (ARRAY_TYPE != Float32Array) {
|
|
46
|
+
function create$5() {
|
|
47
|
+
var out = new ARRAY_TYPE$1(16);
|
|
48
|
+
if (ARRAY_TYPE$1 != Float32Array) {
|
|
63
49
|
out[1] = 0;
|
|
64
50
|
out[2] = 0;
|
|
65
51
|
out[3] = 0;
|
|
@@ -73,22 +59,21 @@ function create$3() {
|
|
|
73
59
|
out[13] = 0;
|
|
74
60
|
out[14] = 0;
|
|
75
61
|
}
|
|
76
|
-
|
|
77
62
|
out[0] = 1;
|
|
78
63
|
out[5] = 1;
|
|
79
64
|
out[10] = 1;
|
|
80
65
|
out[15] = 1;
|
|
81
66
|
return out;
|
|
82
67
|
}
|
|
68
|
+
|
|
83
69
|
/**
|
|
84
70
|
* Creates a new mat4 initialized with values from an existing matrix
|
|
85
71
|
*
|
|
86
72
|
* @param {ReadonlyMat4} a matrix to clone
|
|
87
73
|
* @returns {mat4} a new 4x4 matrix
|
|
88
74
|
*/
|
|
89
|
-
|
|
90
75
|
function clone(a) {
|
|
91
|
-
var out = new ARRAY_TYPE(16);
|
|
76
|
+
var out = new ARRAY_TYPE$1(16);
|
|
92
77
|
out[0] = a[0];
|
|
93
78
|
out[1] = a[1];
|
|
94
79
|
out[2] = a[2];
|
|
@@ -107,6 +92,7 @@ function clone(a) {
|
|
|
107
92
|
out[15] = a[15];
|
|
108
93
|
return out;
|
|
109
94
|
}
|
|
95
|
+
|
|
110
96
|
/**
|
|
111
97
|
* Copy the values from one mat4 to another
|
|
112
98
|
*
|
|
@@ -114,7 +100,6 @@ function clone(a) {
|
|
|
114
100
|
* @param {ReadonlyMat4} a the source matrix
|
|
115
101
|
* @returns {mat4} out
|
|
116
102
|
*/
|
|
117
|
-
|
|
118
103
|
function copy$3(out, a) {
|
|
119
104
|
out[0] = a[0];
|
|
120
105
|
out[1] = a[1];
|
|
@@ -134,13 +119,13 @@ function copy$3(out, a) {
|
|
|
134
119
|
out[15] = a[15];
|
|
135
120
|
return out;
|
|
136
121
|
}
|
|
122
|
+
|
|
137
123
|
/**
|
|
138
124
|
* Set a mat4 to the identity matrix
|
|
139
125
|
*
|
|
140
126
|
* @param {mat4} out the receiving matrix
|
|
141
127
|
* @returns {mat4} out
|
|
142
128
|
*/
|
|
143
|
-
|
|
144
129
|
function identity(out) {
|
|
145
130
|
out[0] = 1;
|
|
146
131
|
out[1] = 0;
|
|
@@ -160,31 +145,31 @@ function identity(out) {
|
|
|
160
145
|
out[15] = 1;
|
|
161
146
|
return out;
|
|
162
147
|
}
|
|
148
|
+
|
|
163
149
|
/**
|
|
164
150
|
* Inverts a mat4
|
|
165
151
|
*
|
|
166
152
|
* @param {mat4} out the receiving matrix
|
|
167
153
|
* @param {ReadonlyMat4} a the source matrix
|
|
168
|
-
* @returns {mat4} out
|
|
154
|
+
* @returns {mat4 | null} out, or null if source matrix is not invertible
|
|
169
155
|
*/
|
|
170
|
-
|
|
171
156
|
function invert(out, a) {
|
|
172
157
|
var a00 = a[0],
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
158
|
+
a01 = a[1],
|
|
159
|
+
a02 = a[2],
|
|
160
|
+
a03 = a[3];
|
|
176
161
|
var a10 = a[4],
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
162
|
+
a11 = a[5],
|
|
163
|
+
a12 = a[6],
|
|
164
|
+
a13 = a[7];
|
|
180
165
|
var a20 = a[8],
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
166
|
+
a21 = a[9],
|
|
167
|
+
a22 = a[10],
|
|
168
|
+
a23 = a[11];
|
|
184
169
|
var a30 = a[12],
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
170
|
+
a31 = a[13],
|
|
171
|
+
a32 = a[14],
|
|
172
|
+
a33 = a[15];
|
|
188
173
|
var b00 = a00 * a11 - a01 * a10;
|
|
189
174
|
var b01 = a00 * a12 - a02 * a10;
|
|
190
175
|
var b02 = a00 * a13 - a03 * a10;
|
|
@@ -196,14 +181,13 @@ function invert(out, a) {
|
|
|
196
181
|
var b08 = a20 * a33 - a23 * a30;
|
|
197
182
|
var b09 = a21 * a32 - a22 * a31;
|
|
198
183
|
var b10 = a21 * a33 - a23 * a31;
|
|
199
|
-
var b11 = a22 * a33 - a23 * a32;
|
|
184
|
+
var b11 = a22 * a33 - a23 * a32;
|
|
200
185
|
|
|
186
|
+
// Calculate the determinant
|
|
201
187
|
var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
202
|
-
|
|
203
188
|
if (!det) {
|
|
204
189
|
return null;
|
|
205
190
|
}
|
|
206
|
-
|
|
207
191
|
det = 1.0 / det;
|
|
208
192
|
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
|
|
209
193
|
out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
|
|
@@ -223,6 +207,7 @@ function invert(out, a) {
|
|
|
223
207
|
out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
|
|
224
208
|
return out;
|
|
225
209
|
}
|
|
210
|
+
|
|
226
211
|
/**
|
|
227
212
|
* Multiplies two mat4s
|
|
228
213
|
*
|
|
@@ -231,29 +216,29 @@ function invert(out, a) {
|
|
|
231
216
|
* @param {ReadonlyMat4} b the second operand
|
|
232
217
|
* @returns {mat4} out
|
|
233
218
|
*/
|
|
234
|
-
|
|
235
|
-
function multiply$1(out, a, b) {
|
|
219
|
+
function multiply$2(out, a, b) {
|
|
236
220
|
var a00 = a[0],
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
221
|
+
a01 = a[1],
|
|
222
|
+
a02 = a[2],
|
|
223
|
+
a03 = a[3];
|
|
240
224
|
var a10 = a[4],
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
225
|
+
a11 = a[5],
|
|
226
|
+
a12 = a[6],
|
|
227
|
+
a13 = a[7];
|
|
244
228
|
var a20 = a[8],
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
229
|
+
a21 = a[9],
|
|
230
|
+
a22 = a[10],
|
|
231
|
+
a23 = a[11];
|
|
248
232
|
var a30 = a[12],
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
233
|
+
a31 = a[13],
|
|
234
|
+
a32 = a[14],
|
|
235
|
+
a33 = a[15];
|
|
252
236
|
|
|
237
|
+
// Cache only the current line of the second matrix
|
|
253
238
|
var b0 = b[0],
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
239
|
+
b1 = b[1],
|
|
240
|
+
b2 = b[2],
|
|
241
|
+
b3 = b[3];
|
|
257
242
|
out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
258
243
|
out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
259
244
|
out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
@@ -284,6 +269,7 @@ function multiply$1(out, a, b) {
|
|
|
284
269
|
out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
285
270
|
return out;
|
|
286
271
|
}
|
|
272
|
+
|
|
287
273
|
/**
|
|
288
274
|
* Creates a matrix from a vector translation
|
|
289
275
|
* This is equivalent to (but much faster than):
|
|
@@ -295,7 +281,6 @@ function multiply$1(out, a, b) {
|
|
|
295
281
|
* @param {ReadonlyVec3} v Translation vector
|
|
296
282
|
* @returns {mat4} out
|
|
297
283
|
*/
|
|
298
|
-
|
|
299
284
|
function fromTranslation(out, v) {
|
|
300
285
|
out[0] = 1;
|
|
301
286
|
out[1] = 0;
|
|
@@ -315,6 +300,7 @@ function fromTranslation(out, v) {
|
|
|
315
300
|
out[15] = 1;
|
|
316
301
|
return out;
|
|
317
302
|
}
|
|
303
|
+
|
|
318
304
|
/**
|
|
319
305
|
* Creates a matrix from a given angle around a given axis
|
|
320
306
|
* This is equivalent to (but much faster than):
|
|
@@ -327,26 +313,24 @@ function fromTranslation(out, v) {
|
|
|
327
313
|
* @param {ReadonlyVec3} axis the axis to rotate around
|
|
328
314
|
* @returns {mat4} out
|
|
329
315
|
*/
|
|
330
|
-
|
|
331
316
|
function fromRotation(out, rad, axis) {
|
|
332
317
|
var x = axis[0],
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
var len = Math.
|
|
318
|
+
y = axis[1],
|
|
319
|
+
z = axis[2];
|
|
320
|
+
var len = Math.sqrt(x * x + y * y + z * z);
|
|
336
321
|
var s, c, t;
|
|
337
|
-
|
|
338
322
|
if (len < EPSILON) {
|
|
339
323
|
return null;
|
|
340
324
|
}
|
|
341
|
-
|
|
342
325
|
len = 1 / len;
|
|
343
326
|
x *= len;
|
|
344
327
|
y *= len;
|
|
345
328
|
z *= len;
|
|
346
329
|
s = Math.sin(rad);
|
|
347
330
|
c = Math.cos(rad);
|
|
348
|
-
t = 1 - c;
|
|
331
|
+
t = 1 - c;
|
|
349
332
|
|
|
333
|
+
// Perform rotation-specific matrix multiplication
|
|
350
334
|
out[0] = x * x * t + c;
|
|
351
335
|
out[1] = y * x * t + z * s;
|
|
352
336
|
out[2] = z * x * t - y * s;
|
|
@@ -365,28 +349,28 @@ function fromRotation(out, rad, axis) {
|
|
|
365
349
|
out[15] = 1;
|
|
366
350
|
return out;
|
|
367
351
|
}
|
|
352
|
+
|
|
368
353
|
/**
|
|
369
354
|
* Creates a matrix from a quaternion rotation and vector translation
|
|
370
355
|
* This is equivalent to (but much faster than):
|
|
371
356
|
*
|
|
372
357
|
* mat4.identity(dest);
|
|
373
|
-
* mat4.translate(dest, vec);
|
|
358
|
+
* mat4.translate(dest, dest, vec);
|
|
374
359
|
* let quatMat = mat4.create();
|
|
375
|
-
*
|
|
376
|
-
* mat4.multiply(dest, quatMat);
|
|
360
|
+
* mat4.fromQuat(quatMat, quat);
|
|
361
|
+
* mat4.multiply(dest, dest, quatMat);
|
|
377
362
|
*
|
|
378
363
|
* @param {mat4} out mat4 receiving operation result
|
|
379
|
-
* @param {
|
|
364
|
+
* @param {quat} q Rotation quaternion
|
|
380
365
|
* @param {ReadonlyVec3} v Translation vector
|
|
381
366
|
* @returns {mat4} out
|
|
382
367
|
*/
|
|
383
|
-
|
|
384
368
|
function fromRotationTranslation(out, q, v) {
|
|
385
369
|
// Quaternion math
|
|
386
370
|
var x = q[0],
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
371
|
+
y = q[1],
|
|
372
|
+
z = q[2],
|
|
373
|
+
w = q[3];
|
|
390
374
|
var x2 = x + x;
|
|
391
375
|
var y2 = y + y;
|
|
392
376
|
var z2 = z + z;
|
|
@@ -417,6 +401,7 @@ function fromRotationTranslation(out, q, v) {
|
|
|
417
401
|
out[15] = 1;
|
|
418
402
|
return out;
|
|
419
403
|
}
|
|
404
|
+
|
|
420
405
|
/**
|
|
421
406
|
* Returns the translation vector component of a transformation
|
|
422
407
|
* matrix. If a matrix is built with fromRotationTranslation,
|
|
@@ -426,24 +411,23 @@ function fromRotationTranslation(out, q, v) {
|
|
|
426
411
|
* @param {ReadonlyMat4} mat Matrix to be decomposed (input)
|
|
427
412
|
* @return {vec3} out
|
|
428
413
|
*/
|
|
429
|
-
|
|
430
414
|
function getTranslation(out, mat) {
|
|
431
415
|
out[0] = mat[12];
|
|
432
416
|
out[1] = mat[13];
|
|
433
417
|
out[2] = mat[14];
|
|
434
418
|
return out;
|
|
435
419
|
}
|
|
420
|
+
|
|
436
421
|
/**
|
|
437
422
|
* Returns the scaling factor component of a transformation
|
|
438
423
|
* matrix. If a matrix is built with fromRotationTranslationScale
|
|
439
|
-
* with a normalized Quaternion
|
|
424
|
+
* with a normalized Quaternion parameter, the returned vector will be
|
|
440
425
|
* the same as the scaling vector
|
|
441
426
|
* originally supplied.
|
|
442
427
|
* @param {vec3} out Vector to receive scaling factor component
|
|
443
428
|
* @param {ReadonlyMat4} mat Matrix to be decomposed (input)
|
|
444
429
|
* @return {vec3} out
|
|
445
430
|
*/
|
|
446
|
-
|
|
447
431
|
function getScaling(out, mat) {
|
|
448
432
|
var m11 = mat[0];
|
|
449
433
|
var m12 = mat[1];
|
|
@@ -454,11 +438,12 @@ function getScaling(out, mat) {
|
|
|
454
438
|
var m31 = mat[8];
|
|
455
439
|
var m32 = mat[9];
|
|
456
440
|
var m33 = mat[10];
|
|
457
|
-
out[0] = Math.
|
|
458
|
-
out[1] = Math.
|
|
459
|
-
out[2] = Math.
|
|
441
|
+
out[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13);
|
|
442
|
+
out[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23);
|
|
443
|
+
out[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33);
|
|
460
444
|
return out;
|
|
461
445
|
}
|
|
446
|
+
|
|
462
447
|
/**
|
|
463
448
|
* Returns a quaternion representing the rotational component
|
|
464
449
|
* of a transformation matrix. If a matrix is built with
|
|
@@ -468,9 +453,8 @@ function getScaling(out, mat) {
|
|
|
468
453
|
* @param {ReadonlyMat4} mat Matrix to be decomposed (input)
|
|
469
454
|
* @return {quat} out
|
|
470
455
|
*/
|
|
471
|
-
|
|
472
456
|
function getRotation(out, mat) {
|
|
473
|
-
var scaling = new ARRAY_TYPE(3);
|
|
457
|
+
var scaling = new ARRAY_TYPE$1(3);
|
|
474
458
|
getScaling(scaling, mat);
|
|
475
459
|
var is1 = 1 / scaling[0];
|
|
476
460
|
var is2 = 1 / scaling[1];
|
|
@@ -486,7 +470,6 @@ function getRotation(out, mat) {
|
|
|
486
470
|
var sm33 = mat[10] * is3;
|
|
487
471
|
var trace = sm11 + sm22 + sm33;
|
|
488
472
|
var S = 0;
|
|
489
|
-
|
|
490
473
|
if (trace > 0) {
|
|
491
474
|
S = Math.sqrt(trace + 1.0) * 2;
|
|
492
475
|
out[3] = 0.25 * S;
|
|
@@ -512,33 +495,32 @@ function getRotation(out, mat) {
|
|
|
512
495
|
out[1] = (sm23 + sm32) / S;
|
|
513
496
|
out[2] = 0.25 * S;
|
|
514
497
|
}
|
|
515
|
-
|
|
516
498
|
return out;
|
|
517
499
|
}
|
|
500
|
+
|
|
518
501
|
/**
|
|
519
502
|
* Creates a matrix from a quaternion rotation, vector translation and vector scale
|
|
520
503
|
* This is equivalent to (but much faster than):
|
|
521
504
|
*
|
|
522
505
|
* mat4.identity(dest);
|
|
523
|
-
* mat4.translate(dest, vec);
|
|
506
|
+
* mat4.translate(dest, dest, vec);
|
|
524
507
|
* let quatMat = mat4.create();
|
|
525
|
-
*
|
|
526
|
-
* mat4.multiply(dest, quatMat);
|
|
527
|
-
* mat4.scale(dest, scale)
|
|
508
|
+
* mat4.fromQuat(quatMat, quat);
|
|
509
|
+
* mat4.multiply(dest, dest, quatMat);
|
|
510
|
+
* mat4.scale(dest, dest, scale)
|
|
528
511
|
*
|
|
529
512
|
* @param {mat4} out mat4 receiving operation result
|
|
530
|
-
* @param {
|
|
513
|
+
* @param {quat} q Rotation quaternion
|
|
531
514
|
* @param {ReadonlyVec3} v Translation vector
|
|
532
515
|
* @param {ReadonlyVec3} s Scaling vector
|
|
533
516
|
* @returns {mat4} out
|
|
534
517
|
*/
|
|
535
|
-
|
|
536
518
|
function fromRotationTranslationScale(out, q, v, s) {
|
|
537
519
|
// Quaternion math
|
|
538
520
|
var x = q[0],
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
521
|
+
y = q[1],
|
|
522
|
+
z = q[2],
|
|
523
|
+
w = q[3];
|
|
542
524
|
var x2 = x + x;
|
|
543
525
|
var y2 = y + y;
|
|
544
526
|
var z2 = z + z;
|
|
@@ -572,6 +554,7 @@ function fromRotationTranslationScale(out, q, v, s) {
|
|
|
572
554
|
out[15] = 1;
|
|
573
555
|
return out;
|
|
574
556
|
}
|
|
557
|
+
|
|
575
558
|
/**
|
|
576
559
|
* Generates a perspective projection matrix with the given bounds.
|
|
577
560
|
* The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],
|
|
@@ -585,10 +568,8 @@ function fromRotationTranslationScale(out, q, v, s) {
|
|
|
585
568
|
* @param {number} far Far bound of the frustum, can be null or Infinity
|
|
586
569
|
* @returns {mat4} out
|
|
587
570
|
*/
|
|
588
|
-
|
|
589
571
|
function perspectiveNO(out, fovy, aspect, near, far) {
|
|
590
|
-
var f = 1.0 / Math.tan(fovy / 2)
|
|
591
|
-
nf;
|
|
572
|
+
var f = 1.0 / Math.tan(fovy / 2);
|
|
592
573
|
out[0] = f / aspect;
|
|
593
574
|
out[1] = 0;
|
|
594
575
|
out[2] = 0;
|
|
@@ -603,23 +584,21 @@ function perspectiveNO(out, fovy, aspect, near, far) {
|
|
|
603
584
|
out[12] = 0;
|
|
604
585
|
out[13] = 0;
|
|
605
586
|
out[15] = 0;
|
|
606
|
-
|
|
607
587
|
if (far != null && far !== Infinity) {
|
|
608
|
-
nf = 1 / (near - far);
|
|
588
|
+
var nf = 1 / (near - far);
|
|
609
589
|
out[10] = (far + near) * nf;
|
|
610
590
|
out[14] = 2 * far * near * nf;
|
|
611
591
|
} else {
|
|
612
592
|
out[10] = -1;
|
|
613
593
|
out[14] = -2 * near;
|
|
614
594
|
}
|
|
615
|
-
|
|
616
595
|
return out;
|
|
617
596
|
}
|
|
597
|
+
|
|
618
598
|
/**
|
|
619
599
|
* Alias for {@link mat4.perspectiveNO}
|
|
620
600
|
* @function
|
|
621
601
|
*/
|
|
622
|
-
|
|
623
602
|
var perspective = perspectiveNO;
|
|
624
603
|
|
|
625
604
|
/**
|
|
@@ -632,31 +611,29 @@ var perspective = perspectiveNO;
|
|
|
632
611
|
*
|
|
633
612
|
* @returns {vec3} a new 3D vector
|
|
634
613
|
*/
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
if (ARRAY_TYPE != Float32Array) {
|
|
614
|
+
function create$4() {
|
|
615
|
+
var out = new ARRAY_TYPE$1(3);
|
|
616
|
+
if (ARRAY_TYPE$1 != Float32Array) {
|
|
640
617
|
out[0] = 0;
|
|
641
618
|
out[1] = 0;
|
|
642
619
|
out[2] = 0;
|
|
643
620
|
}
|
|
644
|
-
|
|
645
621
|
return out;
|
|
646
622
|
}
|
|
623
|
+
|
|
647
624
|
/**
|
|
648
625
|
* Calculates the length of a vec3
|
|
649
626
|
*
|
|
650
627
|
* @param {ReadonlyVec3} a vector to calculate length of
|
|
651
628
|
* @returns {Number} length of a
|
|
652
629
|
*/
|
|
653
|
-
|
|
654
630
|
function length(a) {
|
|
655
631
|
var x = a[0];
|
|
656
632
|
var y = a[1];
|
|
657
633
|
var z = a[2];
|
|
658
|
-
return Math.
|
|
634
|
+
return Math.sqrt(x * x + y * y + z * z);
|
|
659
635
|
}
|
|
636
|
+
|
|
660
637
|
/**
|
|
661
638
|
* Creates a new vec3 initialized with the given values
|
|
662
639
|
*
|
|
@@ -665,14 +642,14 @@ function length(a) {
|
|
|
665
642
|
* @param {Number} z Z component
|
|
666
643
|
* @returns {vec3} a new 3D vector
|
|
667
644
|
*/
|
|
668
|
-
|
|
669
645
|
function fromValues$2(x, y, z) {
|
|
670
|
-
var out = new ARRAY_TYPE(3);
|
|
646
|
+
var out = new ARRAY_TYPE$1(3);
|
|
671
647
|
out[0] = x;
|
|
672
648
|
out[1] = y;
|
|
673
649
|
out[2] = z;
|
|
674
650
|
return out;
|
|
675
651
|
}
|
|
652
|
+
|
|
676
653
|
/**
|
|
677
654
|
* Copy the values from one vec3 to another
|
|
678
655
|
*
|
|
@@ -680,13 +657,13 @@ function fromValues$2(x, y, z) {
|
|
|
680
657
|
* @param {ReadonlyVec3} a the source vector
|
|
681
658
|
* @returns {vec3} out
|
|
682
659
|
*/
|
|
683
|
-
|
|
684
660
|
function copy$2(out, a) {
|
|
685
661
|
out[0] = a[0];
|
|
686
662
|
out[1] = a[1];
|
|
687
663
|
out[2] = a[2];
|
|
688
664
|
return out;
|
|
689
665
|
}
|
|
666
|
+
|
|
690
667
|
/**
|
|
691
668
|
* Set the components of a vec3 to the given values
|
|
692
669
|
*
|
|
@@ -696,13 +673,13 @@ function copy$2(out, a) {
|
|
|
696
673
|
* @param {Number} z Z component
|
|
697
674
|
* @returns {vec3} out
|
|
698
675
|
*/
|
|
699
|
-
|
|
700
676
|
function set$2(out, x, y, z) {
|
|
701
677
|
out[0] = x;
|
|
702
678
|
out[1] = y;
|
|
703
679
|
out[2] = z;
|
|
704
680
|
return out;
|
|
705
681
|
}
|
|
682
|
+
|
|
706
683
|
/**
|
|
707
684
|
* Adds two vec3's
|
|
708
685
|
*
|
|
@@ -711,13 +688,13 @@ function set$2(out, x, y, z) {
|
|
|
711
688
|
* @param {ReadonlyVec3} b the second operand
|
|
712
689
|
* @returns {vec3} out
|
|
713
690
|
*/
|
|
714
|
-
|
|
715
691
|
function add(out, a, b) {
|
|
716
692
|
out[0] = a[0] + b[0];
|
|
717
693
|
out[1] = a[1] + b[1];
|
|
718
694
|
out[2] = a[2] + b[2];
|
|
719
695
|
return out;
|
|
720
696
|
}
|
|
697
|
+
|
|
721
698
|
/**
|
|
722
699
|
* Normalize a vec3
|
|
723
700
|
*
|
|
@@ -725,23 +702,21 @@ function add(out, a, b) {
|
|
|
725
702
|
* @param {ReadonlyVec3} a vector to normalize
|
|
726
703
|
* @returns {vec3} out
|
|
727
704
|
*/
|
|
728
|
-
|
|
729
705
|
function normalize$2(out, a) {
|
|
730
706
|
var x = a[0];
|
|
731
707
|
var y = a[1];
|
|
732
708
|
var z = a[2];
|
|
733
709
|
var len = x * x + y * y + z * z;
|
|
734
|
-
|
|
735
710
|
if (len > 0) {
|
|
736
711
|
//TODO: evaluate use of glm_invsqrt here?
|
|
737
712
|
len = 1 / Math.sqrt(len);
|
|
738
713
|
}
|
|
739
|
-
|
|
740
714
|
out[0] = a[0] * len;
|
|
741
715
|
out[1] = a[1] * len;
|
|
742
716
|
out[2] = a[2] * len;
|
|
743
717
|
return out;
|
|
744
718
|
}
|
|
719
|
+
|
|
745
720
|
/**
|
|
746
721
|
* Calculates the dot product of two vec3's
|
|
747
722
|
*
|
|
@@ -749,10 +724,10 @@ function normalize$2(out, a) {
|
|
|
749
724
|
* @param {ReadonlyVec3} b the second operand
|
|
750
725
|
* @returns {Number} dot product of a and b
|
|
751
726
|
*/
|
|
752
|
-
|
|
753
727
|
function dot(a, b) {
|
|
754
728
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
755
729
|
}
|
|
730
|
+
|
|
756
731
|
/**
|
|
757
732
|
* Computes the cross product of two vec3's
|
|
758
733
|
*
|
|
@@ -761,19 +736,19 @@ function dot(a, b) {
|
|
|
761
736
|
* @param {ReadonlyVec3} b the second operand
|
|
762
737
|
* @returns {vec3} out
|
|
763
738
|
*/
|
|
764
|
-
|
|
765
739
|
function cross(out, a, b) {
|
|
766
740
|
var ax = a[0],
|
|
767
|
-
|
|
768
|
-
|
|
741
|
+
ay = a[1],
|
|
742
|
+
az = a[2];
|
|
769
743
|
var bx = b[0],
|
|
770
|
-
|
|
771
|
-
|
|
744
|
+
by = b[1],
|
|
745
|
+
bz = b[2];
|
|
772
746
|
out[0] = ay * bz - az * by;
|
|
773
747
|
out[1] = az * bx - ax * bz;
|
|
774
748
|
out[2] = ax * by - ay * bx;
|
|
775
749
|
return out;
|
|
776
750
|
}
|
|
751
|
+
|
|
777
752
|
/**
|
|
778
753
|
* Performs a linear interpolation between two vec3's
|
|
779
754
|
*
|
|
@@ -783,7 +758,6 @@ function cross(out, a, b) {
|
|
|
783
758
|
* @param {Number} t interpolation amount, in the range [0-1], between the two inputs
|
|
784
759
|
* @returns {vec3} out
|
|
785
760
|
*/
|
|
786
|
-
|
|
787
761
|
function lerp(out, a, b, t) {
|
|
788
762
|
var ax = a[0];
|
|
789
763
|
var ay = a[1];
|
|
@@ -793,55 +767,51 @@ function lerp(out, a, b, t) {
|
|
|
793
767
|
out[2] = az + t * (b[2] - az);
|
|
794
768
|
return out;
|
|
795
769
|
}
|
|
770
|
+
|
|
796
771
|
/**
|
|
797
772
|
* Transforms the vec3 with a quat
|
|
798
773
|
* Can also be used for dual quaternions. (Multiply it with the real part)
|
|
799
774
|
*
|
|
800
775
|
* @param {vec3} out the receiving vector
|
|
801
776
|
* @param {ReadonlyVec3} a the vector to transform
|
|
802
|
-
* @param {ReadonlyQuat} q quaternion to transform with
|
|
777
|
+
* @param {ReadonlyQuat} q normalized quaternion to transform with
|
|
803
778
|
* @returns {vec3} out
|
|
804
779
|
*/
|
|
805
|
-
|
|
806
780
|
function transformQuat(out, a, q) {
|
|
807
|
-
//
|
|
781
|
+
// Fast Vector Rotation using Quaternions by Robert Eisele
|
|
782
|
+
// https://raw.org/proof/vector-rotation-using-quaternions/
|
|
783
|
+
|
|
808
784
|
var qx = q[0],
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
var
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
var
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
uuvx *= 2;
|
|
831
|
-
uuvy *= 2;
|
|
832
|
-
uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv));
|
|
833
|
-
|
|
834
|
-
out[0] = x + uvx + uuvx;
|
|
835
|
-
out[1] = y + uvy + uuvy;
|
|
836
|
-
out[2] = z + uvz + uuvz;
|
|
785
|
+
qy = q[1],
|
|
786
|
+
qz = q[2],
|
|
787
|
+
qw = q[3];
|
|
788
|
+
var vx = a[0],
|
|
789
|
+
vy = a[1],
|
|
790
|
+
vz = a[2];
|
|
791
|
+
|
|
792
|
+
// t = q x v
|
|
793
|
+
var tx = qy * vz - qz * vy;
|
|
794
|
+
var ty = qz * vx - qx * vz;
|
|
795
|
+
var tz = qx * vy - qy * vx;
|
|
796
|
+
|
|
797
|
+
// t = 2t
|
|
798
|
+
tx = tx + tx;
|
|
799
|
+
ty = ty + ty;
|
|
800
|
+
tz = tz + tz;
|
|
801
|
+
|
|
802
|
+
// v + w t + q x t
|
|
803
|
+
out[0] = vx + qw * tx + qy * tz - qz * ty;
|
|
804
|
+
out[1] = vy + qw * ty + qz * tx - qx * tz;
|
|
805
|
+
out[2] = vz + qw * tz + qx * ty - qy * tx;
|
|
837
806
|
return out;
|
|
838
807
|
}
|
|
808
|
+
|
|
839
809
|
/**
|
|
840
810
|
* Alias for {@link vec3.length}
|
|
841
811
|
* @function
|
|
842
812
|
*/
|
|
843
|
-
|
|
844
813
|
var len = length;
|
|
814
|
+
|
|
845
815
|
/**
|
|
846
816
|
* Perform some operation over an array of vec3s.
|
|
847
817
|
*
|
|
@@ -854,26 +824,21 @@ var len = length;
|
|
|
854
824
|
* @returns {Array} a
|
|
855
825
|
* @function
|
|
856
826
|
*/
|
|
857
|
-
|
|
858
827
|
(function () {
|
|
859
|
-
var vec = create$
|
|
828
|
+
var vec = create$4();
|
|
860
829
|
return function (a, stride, offset, count, fn, arg) {
|
|
861
830
|
var i, l;
|
|
862
|
-
|
|
863
831
|
if (!stride) {
|
|
864
832
|
stride = 3;
|
|
865
833
|
}
|
|
866
|
-
|
|
867
834
|
if (!offset) {
|
|
868
835
|
offset = 0;
|
|
869
836
|
}
|
|
870
|
-
|
|
871
837
|
if (count) {
|
|
872
838
|
l = Math.min(count * stride + offset, a.length);
|
|
873
839
|
} else {
|
|
874
840
|
l = a.length;
|
|
875
841
|
}
|
|
876
|
-
|
|
877
842
|
for (i = offset; i < l; i += stride) {
|
|
878
843
|
vec[0] = a[i];
|
|
879
844
|
vec[1] = a[i + 1];
|
|
@@ -883,7 +848,6 @@ var len = length;
|
|
|
883
848
|
a[i + 1] = vec[1];
|
|
884
849
|
a[i + 2] = vec[2];
|
|
885
850
|
}
|
|
886
|
-
|
|
887
851
|
return a;
|
|
888
852
|
};
|
|
889
853
|
})();
|
|
@@ -898,19 +862,17 @@ var len = length;
|
|
|
898
862
|
*
|
|
899
863
|
* @returns {vec4} a new 4D vector
|
|
900
864
|
*/
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
if (ARRAY_TYPE != Float32Array) {
|
|
865
|
+
function create$3() {
|
|
866
|
+
var out = new ARRAY_TYPE$1(4);
|
|
867
|
+
if (ARRAY_TYPE$1 != Float32Array) {
|
|
906
868
|
out[0] = 0;
|
|
907
869
|
out[1] = 0;
|
|
908
870
|
out[2] = 0;
|
|
909
871
|
out[3] = 0;
|
|
910
872
|
}
|
|
911
|
-
|
|
912
873
|
return out;
|
|
913
874
|
}
|
|
875
|
+
|
|
914
876
|
/**
|
|
915
877
|
* Creates a new vec4 initialized with the given values
|
|
916
878
|
*
|
|
@@ -920,15 +882,15 @@ function create$1() {
|
|
|
920
882
|
* @param {Number} w W component
|
|
921
883
|
* @returns {vec4} a new 4D vector
|
|
922
884
|
*/
|
|
923
|
-
|
|
924
885
|
function fromValues$1(x, y, z, w) {
|
|
925
|
-
var out = new ARRAY_TYPE(4);
|
|
886
|
+
var out = new ARRAY_TYPE$1(4);
|
|
926
887
|
out[0] = x;
|
|
927
888
|
out[1] = y;
|
|
928
889
|
out[2] = z;
|
|
929
890
|
out[3] = w;
|
|
930
891
|
return out;
|
|
931
892
|
}
|
|
893
|
+
|
|
932
894
|
/**
|
|
933
895
|
* Copy the values from one vec4 to another
|
|
934
896
|
*
|
|
@@ -936,7 +898,6 @@ function fromValues$1(x, y, z, w) {
|
|
|
936
898
|
* @param {ReadonlyVec4} a the source vector
|
|
937
899
|
* @returns {vec4} out
|
|
938
900
|
*/
|
|
939
|
-
|
|
940
901
|
function copy$1(out, a) {
|
|
941
902
|
out[0] = a[0];
|
|
942
903
|
out[1] = a[1];
|
|
@@ -944,6 +905,7 @@ function copy$1(out, a) {
|
|
|
944
905
|
out[3] = a[3];
|
|
945
906
|
return out;
|
|
946
907
|
}
|
|
908
|
+
|
|
947
909
|
/**
|
|
948
910
|
* Set the components of a vec4 to the given values
|
|
949
911
|
*
|
|
@@ -954,7 +916,6 @@ function copy$1(out, a) {
|
|
|
954
916
|
* @param {Number} w W component
|
|
955
917
|
* @returns {vec4} out
|
|
956
918
|
*/
|
|
957
|
-
|
|
958
919
|
function set$1(out, x, y, z, w) {
|
|
959
920
|
out[0] = x;
|
|
960
921
|
out[1] = y;
|
|
@@ -962,6 +923,7 @@ function set$1(out, x, y, z, w) {
|
|
|
962
923
|
out[3] = w;
|
|
963
924
|
return out;
|
|
964
925
|
}
|
|
926
|
+
|
|
965
927
|
/**
|
|
966
928
|
* Normalize a vec4
|
|
967
929
|
*
|
|
@@ -969,24 +931,22 @@ function set$1(out, x, y, z, w) {
|
|
|
969
931
|
* @param {ReadonlyVec4} a vector to normalize
|
|
970
932
|
* @returns {vec4} out
|
|
971
933
|
*/
|
|
972
|
-
|
|
973
934
|
function normalize$1(out, a) {
|
|
974
935
|
var x = a[0];
|
|
975
936
|
var y = a[1];
|
|
976
937
|
var z = a[2];
|
|
977
938
|
var w = a[3];
|
|
978
939
|
var len = x * x + y * y + z * z + w * w;
|
|
979
|
-
|
|
980
940
|
if (len > 0) {
|
|
981
941
|
len = 1 / Math.sqrt(len);
|
|
982
942
|
}
|
|
983
|
-
|
|
984
943
|
out[0] = x * len;
|
|
985
944
|
out[1] = y * len;
|
|
986
945
|
out[2] = z * len;
|
|
987
946
|
out[3] = w * len;
|
|
988
947
|
return out;
|
|
989
948
|
}
|
|
949
|
+
|
|
990
950
|
/**
|
|
991
951
|
* Transforms the vec4 with a mat4.
|
|
992
952
|
*
|
|
@@ -995,18 +955,18 @@ function normalize$1(out, a) {
|
|
|
995
955
|
* @param {ReadonlyMat4} m matrix to transform with
|
|
996
956
|
* @returns {vec4} out
|
|
997
957
|
*/
|
|
998
|
-
|
|
999
958
|
function transformMat4(out, a, m) {
|
|
1000
959
|
var x = a[0],
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
960
|
+
y = a[1],
|
|
961
|
+
z = a[2],
|
|
962
|
+
w = a[3];
|
|
1004
963
|
out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
|
|
1005
964
|
out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
|
|
1006
965
|
out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
|
|
1007
966
|
out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
|
|
1008
967
|
return out;
|
|
1009
968
|
}
|
|
969
|
+
|
|
1010
970
|
/**
|
|
1011
971
|
* Perform some operation over an array of vec4s.
|
|
1012
972
|
*
|
|
@@ -1019,26 +979,21 @@ function transformMat4(out, a, m) {
|
|
|
1019
979
|
* @returns {Array} a
|
|
1020
980
|
* @function
|
|
1021
981
|
*/
|
|
1022
|
-
|
|
1023
982
|
(function () {
|
|
1024
|
-
var vec = create$
|
|
983
|
+
var vec = create$3();
|
|
1025
984
|
return function (a, stride, offset, count, fn, arg) {
|
|
1026
985
|
var i, l;
|
|
1027
|
-
|
|
1028
986
|
if (!stride) {
|
|
1029
987
|
stride = 4;
|
|
1030
988
|
}
|
|
1031
|
-
|
|
1032
989
|
if (!offset) {
|
|
1033
990
|
offset = 0;
|
|
1034
991
|
}
|
|
1035
|
-
|
|
1036
992
|
if (count) {
|
|
1037
993
|
l = Math.min(count * stride + offset, a.length);
|
|
1038
994
|
} else {
|
|
1039
995
|
l = a.length;
|
|
1040
996
|
}
|
|
1041
|
-
|
|
1042
997
|
for (i = offset; i < l; i += stride) {
|
|
1043
998
|
vec[0] = a[i];
|
|
1044
999
|
vec[1] = a[i + 1];
|
|
@@ -1050,13 +1005,12 @@ function transformMat4(out, a, m) {
|
|
|
1050
1005
|
a[i + 2] = vec[2];
|
|
1051
1006
|
a[i + 3] = vec[3];
|
|
1052
1007
|
}
|
|
1053
|
-
|
|
1054
1008
|
return a;
|
|
1055
1009
|
};
|
|
1056
1010
|
})();
|
|
1057
1011
|
|
|
1058
1012
|
/**
|
|
1059
|
-
* Quaternion
|
|
1013
|
+
* Quaternion in the format XYZW
|
|
1060
1014
|
* @module quat
|
|
1061
1015
|
*/
|
|
1062
1016
|
|
|
@@ -1065,19 +1019,17 @@ function transformMat4(out, a, m) {
|
|
|
1065
1019
|
*
|
|
1066
1020
|
* @returns {quat} a new quaternion
|
|
1067
1021
|
*/
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
if (ARRAY_TYPE != Float32Array) {
|
|
1022
|
+
function create$2() {
|
|
1023
|
+
var out = new ARRAY_TYPE$1(4);
|
|
1024
|
+
if (ARRAY_TYPE$1 != Float32Array) {
|
|
1073
1025
|
out[0] = 0;
|
|
1074
1026
|
out[1] = 0;
|
|
1075
1027
|
out[2] = 0;
|
|
1076
1028
|
}
|
|
1077
|
-
|
|
1078
1029
|
out[3] = 1;
|
|
1079
1030
|
return out;
|
|
1080
1031
|
}
|
|
1032
|
+
|
|
1081
1033
|
/**
|
|
1082
1034
|
* Sets a quat from the given angle and rotation axis,
|
|
1083
1035
|
* then returns it.
|
|
@@ -1087,7 +1039,6 @@ function create() {
|
|
|
1087
1039
|
* @param {Number} rad the angle in radians
|
|
1088
1040
|
* @returns {quat} out
|
|
1089
1041
|
**/
|
|
1090
|
-
|
|
1091
1042
|
function setAxisAngle(out, axis, rad) {
|
|
1092
1043
|
rad = rad * 0.5;
|
|
1093
1044
|
var s = Math.sin(rad);
|
|
@@ -1097,6 +1048,7 @@ function setAxisAngle(out, axis, rad) {
|
|
|
1097
1048
|
out[3] = Math.cos(rad);
|
|
1098
1049
|
return out;
|
|
1099
1050
|
}
|
|
1051
|
+
|
|
1100
1052
|
/**
|
|
1101
1053
|
* Multiplies two quat's
|
|
1102
1054
|
*
|
|
@@ -1105,22 +1057,22 @@ function setAxisAngle(out, axis, rad) {
|
|
|
1105
1057
|
* @param {ReadonlyQuat} b the second operand
|
|
1106
1058
|
* @returns {quat} out
|
|
1107
1059
|
*/
|
|
1108
|
-
|
|
1109
|
-
function multiply(out, a, b) {
|
|
1060
|
+
function multiply$1(out, a, b) {
|
|
1110
1061
|
var ax = a[0],
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1062
|
+
ay = a[1],
|
|
1063
|
+
az = a[2],
|
|
1064
|
+
aw = a[3];
|
|
1114
1065
|
var bx = b[0],
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1066
|
+
by = b[1],
|
|
1067
|
+
bz = b[2],
|
|
1068
|
+
bw = b[3];
|
|
1118
1069
|
out[0] = ax * bw + aw * bx + ay * bz - az * by;
|
|
1119
1070
|
out[1] = ay * bw + aw * by + az * bx - ax * bz;
|
|
1120
1071
|
out[2] = az * bw + aw * bz + ax * by - ay * bx;
|
|
1121
1072
|
out[3] = aw * bw - ax * bx - ay * by - az * bz;
|
|
1122
1073
|
return out;
|
|
1123
1074
|
}
|
|
1075
|
+
|
|
1124
1076
|
/**
|
|
1125
1077
|
* Performs a spherical linear interpolation between two quat
|
|
1126
1078
|
*
|
|
@@ -1130,31 +1082,30 @@ function multiply(out, a, b) {
|
|
|
1130
1082
|
* @param {Number} t interpolation amount, in the range [0-1], between the two inputs
|
|
1131
1083
|
* @returns {quat} out
|
|
1132
1084
|
*/
|
|
1133
|
-
|
|
1134
1085
|
function slerp(out, a, b, t) {
|
|
1135
1086
|
// benchmarks:
|
|
1136
1087
|
// http://jsperf.com/quaternion-slerp-implementations
|
|
1137
1088
|
var ax = a[0],
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1089
|
+
ay = a[1],
|
|
1090
|
+
az = a[2],
|
|
1091
|
+
aw = a[3];
|
|
1141
1092
|
var bx = b[0],
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
var omega, cosom, sinom, scale0, scale1;
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1093
|
+
by = b[1],
|
|
1094
|
+
bz = b[2],
|
|
1095
|
+
bw = b[3];
|
|
1096
|
+
var omega, cosom, sinom, scale0, scale1;
|
|
1097
|
+
|
|
1098
|
+
// calc cosine
|
|
1099
|
+
cosom = ax * bx + ay * by + az * bz + aw * bw;
|
|
1100
|
+
// adjust signs (if necessary)
|
|
1149
1101
|
if (cosom < 0.0) {
|
|
1150
1102
|
cosom = -cosom;
|
|
1151
1103
|
bx = -bx;
|
|
1152
1104
|
by = -by;
|
|
1153
1105
|
bz = -bz;
|
|
1154
1106
|
bw = -bw;
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1107
|
+
}
|
|
1108
|
+
// calculate coefficients
|
|
1158
1109
|
if (1.0 - cosom > EPSILON) {
|
|
1159
1110
|
// standard case (slerp)
|
|
1160
1111
|
omega = Math.acos(cosom);
|
|
@@ -1166,15 +1117,15 @@ function slerp(out, a, b, t) {
|
|
|
1166
1117
|
// ... so we can do a linear interpolation
|
|
1167
1118
|
scale0 = 1.0 - t;
|
|
1168
1119
|
scale1 = t;
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
|
|
1120
|
+
}
|
|
1121
|
+
// calculate final values
|
|
1172
1122
|
out[0] = scale0 * ax + scale1 * bx;
|
|
1173
1123
|
out[1] = scale0 * ay + scale1 * by;
|
|
1174
1124
|
out[2] = scale0 * az + scale1 * bz;
|
|
1175
1125
|
out[3] = scale0 * aw + scale1 * bw;
|
|
1176
1126
|
return out;
|
|
1177
1127
|
}
|
|
1128
|
+
|
|
1178
1129
|
/**
|
|
1179
1130
|
* Calculates the conjugate of a quat
|
|
1180
1131
|
* If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
|
|
@@ -1183,7 +1134,6 @@ function slerp(out, a, b, t) {
|
|
|
1183
1134
|
* @param {ReadonlyQuat} a quat to calculate conjugate of
|
|
1184
1135
|
* @returns {quat} out
|
|
1185
1136
|
*/
|
|
1186
|
-
|
|
1187
1137
|
function conjugate(out, a) {
|
|
1188
1138
|
out[0] = -a[0];
|
|
1189
1139
|
out[1] = -a[1];
|
|
@@ -1191,6 +1141,7 @@ function conjugate(out, a) {
|
|
|
1191
1141
|
out[3] = a[3];
|
|
1192
1142
|
return out;
|
|
1193
1143
|
}
|
|
1144
|
+
|
|
1194
1145
|
/**
|
|
1195
1146
|
* Creates a quaternion from the given 3x3 rotation matrix.
|
|
1196
1147
|
*
|
|
@@ -1202,20 +1153,16 @@ function conjugate(out, a) {
|
|
|
1202
1153
|
* @returns {quat} out
|
|
1203
1154
|
* @function
|
|
1204
1155
|
*/
|
|
1205
|
-
|
|
1206
1156
|
function fromMat3(out, m) {
|
|
1207
1157
|
// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
|
|
1208
1158
|
// article "Quaternion Calculus and Fast Animation".
|
|
1209
1159
|
var fTrace = m[0] + m[4] + m[8];
|
|
1210
1160
|
var fRoot;
|
|
1211
|
-
|
|
1212
1161
|
if (fTrace > 0.0) {
|
|
1213
1162
|
// |w| > 1/2, may as well choose w > 1/2
|
|
1214
1163
|
fRoot = Math.sqrt(fTrace + 1.0); // 2w
|
|
1215
|
-
|
|
1216
1164
|
out[3] = 0.5 * fRoot;
|
|
1217
1165
|
fRoot = 0.5 / fRoot; // 1/(4w)
|
|
1218
|
-
|
|
1219
1166
|
out[0] = (m[5] - m[7]) * fRoot;
|
|
1220
1167
|
out[1] = (m[6] - m[2]) * fRoot;
|
|
1221
1168
|
out[2] = (m[1] - m[3]) * fRoot;
|
|
@@ -1233,9 +1180,9 @@ function fromMat3(out, m) {
|
|
|
1233
1180
|
out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;
|
|
1234
1181
|
out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;
|
|
1235
1182
|
}
|
|
1236
|
-
|
|
1237
1183
|
return out;
|
|
1238
1184
|
}
|
|
1185
|
+
|
|
1239
1186
|
/**
|
|
1240
1187
|
* Creates a new quat initialized with the given values
|
|
1241
1188
|
*
|
|
@@ -1246,8 +1193,8 @@ function fromMat3(out, m) {
|
|
|
1246
1193
|
* @returns {quat} a new quaternion
|
|
1247
1194
|
* @function
|
|
1248
1195
|
*/
|
|
1249
|
-
|
|
1250
1196
|
var fromValues = fromValues$1;
|
|
1197
|
+
|
|
1251
1198
|
/**
|
|
1252
1199
|
* Copy the values from one quat to another
|
|
1253
1200
|
*
|
|
@@ -1256,8 +1203,8 @@ var fromValues = fromValues$1;
|
|
|
1256
1203
|
* @returns {quat} out
|
|
1257
1204
|
* @function
|
|
1258
1205
|
*/
|
|
1259
|
-
|
|
1260
1206
|
var copy = copy$1;
|
|
1207
|
+
|
|
1261
1208
|
/**
|
|
1262
1209
|
* Set the components of a quat to the given values
|
|
1263
1210
|
*
|
|
@@ -1269,8 +1216,8 @@ var copy = copy$1;
|
|
|
1269
1216
|
* @returns {quat} out
|
|
1270
1217
|
* @function
|
|
1271
1218
|
*/
|
|
1272
|
-
|
|
1273
1219
|
var set = set$1;
|
|
1220
|
+
|
|
1274
1221
|
/**
|
|
1275
1222
|
* Normalize a quat
|
|
1276
1223
|
*
|
|
@@ -1279,8 +1226,8 @@ var set = set$1;
|
|
|
1279
1226
|
* @returns {quat} out
|
|
1280
1227
|
* @function
|
|
1281
1228
|
*/
|
|
1282
|
-
|
|
1283
1229
|
var normalize = normalize$1;
|
|
1230
|
+
|
|
1284
1231
|
/**
|
|
1285
1232
|
* Sets a quaternion to represent the shortest rotation from one
|
|
1286
1233
|
* vector to another.
|
|
@@ -1292,14 +1239,12 @@ var normalize = normalize$1;
|
|
|
1292
1239
|
* @param {ReadonlyVec3} b the destination vector
|
|
1293
1240
|
* @returns {quat} out
|
|
1294
1241
|
*/
|
|
1295
|
-
|
|
1296
1242
|
(function () {
|
|
1297
|
-
var tmpvec3 = create$
|
|
1243
|
+
var tmpvec3 = create$4();
|
|
1298
1244
|
var xUnitVec3 = fromValues$2(1, 0, 0);
|
|
1299
1245
|
var yUnitVec3 = fromValues$2(0, 1, 0);
|
|
1300
1246
|
return function (out, a, b) {
|
|
1301
1247
|
var dot$1 = dot(a, b);
|
|
1302
|
-
|
|
1303
1248
|
if (dot$1 < -0.999999) {
|
|
1304
1249
|
cross(tmpvec3, xUnitVec3, a);
|
|
1305
1250
|
if (len(tmpvec3) < 0.000001) cross(tmpvec3, yUnitVec3, a);
|
|
@@ -1322,6 +1267,7 @@ var normalize = normalize$1;
|
|
|
1322
1267
|
}
|
|
1323
1268
|
};
|
|
1324
1269
|
})();
|
|
1270
|
+
|
|
1325
1271
|
/**
|
|
1326
1272
|
* Performs a spherical linear interpolation with two control points
|
|
1327
1273
|
*
|
|
@@ -1333,10 +1279,9 @@ var normalize = normalize$1;
|
|
|
1333
1279
|
* @param {Number} t interpolation amount, in the range [0-1], between the two inputs
|
|
1334
1280
|
* @returns {quat} out
|
|
1335
1281
|
*/
|
|
1336
|
-
|
|
1337
1282
|
(function () {
|
|
1338
|
-
var temp1 = create();
|
|
1339
|
-
var temp2 = create();
|
|
1283
|
+
var temp1 = create$2();
|
|
1284
|
+
var temp2 = create$2();
|
|
1340
1285
|
return function (out, a, b, c, d, t) {
|
|
1341
1286
|
slerp(temp1, a, d, t);
|
|
1342
1287
|
slerp(temp2, b, c, t);
|
|
@@ -1344,6 +1289,7 @@ var normalize = normalize$1;
|
|
|
1344
1289
|
return out;
|
|
1345
1290
|
};
|
|
1346
1291
|
})();
|
|
1292
|
+
|
|
1347
1293
|
/**
|
|
1348
1294
|
* Sets the specified quaternion with values corresponding to the given
|
|
1349
1295
|
* axes. Each axis is a vec3 and is expected to be unit length and
|
|
@@ -1354,9 +1300,8 @@ var normalize = normalize$1;
|
|
|
1354
1300
|
* @param {ReadonlyVec3} up the vector representing the local "up" direction
|
|
1355
1301
|
* @returns {quat} out
|
|
1356
1302
|
*/
|
|
1357
|
-
|
|
1358
1303
|
(function () {
|
|
1359
|
-
var matr = create$
|
|
1304
|
+
var matr = create$6();
|
|
1360
1305
|
return function (out, view, right, up) {
|
|
1361
1306
|
matr[0] = right[0];
|
|
1362
1307
|
matr[3] = right[1];
|
|
@@ -1416,14 +1361,14 @@ class XRSpace extends EventTarget {
|
|
|
1416
1361
|
super();
|
|
1417
1362
|
this[P_SPACE] = {
|
|
1418
1363
|
parentSpace,
|
|
1419
|
-
offsetMatrix: offsetMatrix ? clone(offsetMatrix) : create$
|
|
1364
|
+
offsetMatrix: offsetMatrix ? clone(offsetMatrix) : create$5(),
|
|
1420
1365
|
emulated: true,
|
|
1421
1366
|
};
|
|
1422
1367
|
}
|
|
1423
1368
|
}
|
|
1424
1369
|
class GlobalSpace extends XRSpace {
|
|
1425
1370
|
constructor() {
|
|
1426
|
-
super(undefined, create$
|
|
1371
|
+
super(undefined, create$5()); // GlobalSpace has no parent
|
|
1427
1372
|
}
|
|
1428
1373
|
}
|
|
1429
1374
|
class XRSpaceUtils {
|
|
@@ -1435,7 +1380,7 @@ class XRSpaceUtils {
|
|
|
1435
1380
|
// Update the rotation component of the offsetMatrix of a given XRSpace using a quaternion
|
|
1436
1381
|
static updateOffsetQuaternion(space, quaternion) {
|
|
1437
1382
|
const offsetMatrix = space[P_SPACE].offsetMatrix;
|
|
1438
|
-
const translation = create$
|
|
1383
|
+
const translation = create$4();
|
|
1439
1384
|
getTranslation(translation, offsetMatrix);
|
|
1440
1385
|
fromRotationTranslation(offsetMatrix, quaternion, translation);
|
|
1441
1386
|
}
|
|
@@ -1445,11 +1390,11 @@ class XRSpaceUtils {
|
|
|
1445
1390
|
copy$3(offsetMatrix, matrix);
|
|
1446
1391
|
}
|
|
1447
1392
|
// Calculate the global offset matrix for a given XRSpace
|
|
1448
|
-
static calculateGlobalOffsetMatrix(space, globalOffset = create$
|
|
1393
|
+
static calculateGlobalOffsetMatrix(space, globalOffset = create$5()) {
|
|
1449
1394
|
const parentOffset = space[P_SPACE].parentSpace
|
|
1450
1395
|
? XRSpaceUtils.calculateGlobalOffsetMatrix(space[P_SPACE].parentSpace)
|
|
1451
|
-
: create$
|
|
1452
|
-
multiply$
|
|
1396
|
+
: create$5(); // Identity matrix for GlobalSpace
|
|
1397
|
+
multiply$2(globalOffset, parentOffset, space[P_SPACE].offsetMatrix);
|
|
1453
1398
|
return globalOffset;
|
|
1454
1399
|
}
|
|
1455
1400
|
}
|
|
@@ -1467,7 +1412,7 @@ class XRSpaceUtils {
|
|
|
1467
1412
|
class Vector3 {
|
|
1468
1413
|
constructor(x = 0, y = 0, z = 0) {
|
|
1469
1414
|
this.vec3 = fromValues$2(x, y, z);
|
|
1470
|
-
this.tempVec3 = create$
|
|
1415
|
+
this.tempVec3 = create$4();
|
|
1471
1416
|
}
|
|
1472
1417
|
get x() {
|
|
1473
1418
|
return this.vec3[0];
|
|
@@ -1529,7 +1474,7 @@ class Vector3 {
|
|
|
1529
1474
|
class Quaternion {
|
|
1530
1475
|
constructor(x = 0, y = 0, z = 0, w = 1) {
|
|
1531
1476
|
this.quat = fromValues(x, y, z, w);
|
|
1532
|
-
this.tempQuat = create();
|
|
1477
|
+
this.tempQuat = create$2();
|
|
1533
1478
|
}
|
|
1534
1479
|
get x() {
|
|
1535
1480
|
return this.quat[0];
|
|
@@ -1578,7 +1523,7 @@ class Quaternion {
|
|
|
1578
1523
|
}
|
|
1579
1524
|
multiply(q) {
|
|
1580
1525
|
copy(this.tempQuat, this.quat);
|
|
1581
|
-
multiply(this.quat, this.tempQuat, q.quat);
|
|
1526
|
+
multiply$1(this.quat, this.tempQuat, q.quat);
|
|
1582
1527
|
return this;
|
|
1583
1528
|
}
|
|
1584
1529
|
setFromAxisAngle(axis, angle) {
|
|
@@ -2194,38 +2139,6 @@ class XRAnchorUtils {
|
|
|
2194
2139
|
}
|
|
2195
2140
|
}
|
|
2196
2141
|
|
|
2197
|
-
/**
|
|
2198
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2199
|
-
*
|
|
2200
|
-
* This source code is licensed under the MIT license found in the
|
|
2201
|
-
* LICENSE file in the root directory of this source tree.
|
|
2202
|
-
*/
|
|
2203
|
-
class PolyfillDOMPointReadOnly {
|
|
2204
|
-
constructor(x = 0, y = 0, z = 0, w = 1) {
|
|
2205
|
-
this.x = x;
|
|
2206
|
-
this.y = y;
|
|
2207
|
-
this.z = z;
|
|
2208
|
-
this.w = w;
|
|
2209
|
-
Object.freeze(this);
|
|
2210
|
-
}
|
|
2211
|
-
static fromPoint(other) {
|
|
2212
|
-
return new PolyfillDOMPointReadOnly(other.x, other.y, other.z, other.w);
|
|
2213
|
-
}
|
|
2214
|
-
matrixTransform(_matrix) {
|
|
2215
|
-
// Implement matrix transformation logic here
|
|
2216
|
-
// This is a placeholder implementation
|
|
2217
|
-
return new PolyfillDOMPointReadOnly();
|
|
2218
|
-
}
|
|
2219
|
-
toJSON() {
|
|
2220
|
-
// Implement toJSON logic here
|
|
2221
|
-
// This is a placeholder implementation
|
|
2222
|
-
return { x: this.x, y: this.y, z: this.z, w: this.w };
|
|
2223
|
-
}
|
|
2224
|
-
}
|
|
2225
|
-
const DOMPointReadOnly$1 = typeof globalThis.DOMPointReadOnly !== 'undefined'
|
|
2226
|
-
? globalThis.DOMPointReadOnly
|
|
2227
|
-
: PolyfillDOMPointReadOnly;
|
|
2228
|
-
|
|
2229
2142
|
/**
|
|
2230
2143
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2231
2144
|
*
|
|
@@ -2236,14 +2149,14 @@ class XRRigidTransform {
|
|
|
2236
2149
|
constructor(position, orientation) {
|
|
2237
2150
|
// Default values
|
|
2238
2151
|
const defaultPosition = fromValues$2(0, 0, 0);
|
|
2239
|
-
const defaultOrientation = create();
|
|
2152
|
+
const defaultOrientation = create$2();
|
|
2240
2153
|
this[P_RIGID_TRANSFORM] = {
|
|
2241
|
-
matrix: create$
|
|
2154
|
+
matrix: create$5(),
|
|
2242
2155
|
position: position
|
|
2243
2156
|
? fromValues$2(position.x, position.y, position.z)
|
|
2244
2157
|
: defaultPosition,
|
|
2245
2158
|
orientation: orientation
|
|
2246
|
-
? normalize(create(), fromValues(orientation.x, orientation.y, orientation.z, orientation.w))
|
|
2159
|
+
? normalize(create$2(), fromValues(orientation.x, orientation.y, orientation.z, orientation.w))
|
|
2247
2160
|
: defaultOrientation,
|
|
2248
2161
|
inverse: null,
|
|
2249
2162
|
};
|
|
@@ -2257,25 +2170,25 @@ class XRRigidTransform {
|
|
|
2257
2170
|
}
|
|
2258
2171
|
get position() {
|
|
2259
2172
|
const pos = this[P_RIGID_TRANSFORM].position;
|
|
2260
|
-
return new DOMPointReadOnly
|
|
2173
|
+
return new DOMPointReadOnly(pos[0], pos[1], pos[2], 1);
|
|
2261
2174
|
}
|
|
2262
2175
|
get orientation() {
|
|
2263
2176
|
const ori = this[P_RIGID_TRANSFORM].orientation;
|
|
2264
|
-
return new DOMPointReadOnly
|
|
2177
|
+
return new DOMPointReadOnly(ori[0], ori[1], ori[2], ori[3]);
|
|
2265
2178
|
}
|
|
2266
2179
|
get inverse() {
|
|
2267
2180
|
if (!this[P_RIGID_TRANSFORM].inverse) {
|
|
2268
|
-
const invMatrix = create$
|
|
2181
|
+
const invMatrix = create$5();
|
|
2269
2182
|
if (!invert(invMatrix, this[P_RIGID_TRANSFORM].matrix)) {
|
|
2270
2183
|
throw new Error('Matrix is not invertible.');
|
|
2271
2184
|
}
|
|
2272
2185
|
// Decomposing the inverse matrix into position and orientation
|
|
2273
|
-
let invPosition = create$
|
|
2186
|
+
let invPosition = create$4();
|
|
2274
2187
|
getTranslation(invPosition, invMatrix);
|
|
2275
|
-
let invOrientation = create();
|
|
2188
|
+
let invOrientation = create$2();
|
|
2276
2189
|
getRotation(invOrientation, invMatrix);
|
|
2277
2190
|
// Creating a new XRRigidTransform for the inverse
|
|
2278
|
-
this[P_RIGID_TRANSFORM].inverse = new XRRigidTransform(new DOMPointReadOnly
|
|
2191
|
+
this[P_RIGID_TRANSFORM].inverse = new XRRigidTransform(new DOMPointReadOnly(invPosition[0], invPosition[1], invPosition[2], 1), new DOMPointReadOnly(invOrientation[0], invOrientation[1], invOrientation[2], invOrientation[3]));
|
|
2279
2192
|
// Setting the inverse of the inverse to be this transform
|
|
2280
2193
|
this[P_RIGID_TRANSFORM].inverse[P_RIGID_TRANSFORM].inverse = this;
|
|
2281
2194
|
}
|
|
@@ -2283,7 +2196,7 @@ class XRRigidTransform {
|
|
|
2283
2196
|
}
|
|
2284
2197
|
}
|
|
2285
2198
|
|
|
2286
|
-
class DOMPointReadOnly {
|
|
2199
|
+
class DOMPointReadOnly$1 {
|
|
2287
2200
|
constructor(x = 0, y = 0, z = 0, w = 1) {
|
|
2288
2201
|
this.x = x;
|
|
2289
2202
|
this.y = y;
|
|
@@ -2298,8 +2211,8 @@ class XRRay {
|
|
|
2298
2211
|
if (origin instanceof XRRigidTransform) {
|
|
2299
2212
|
const transform = origin;
|
|
2300
2213
|
const matrix = transform.matrix;
|
|
2301
|
-
const originVec4 = set$1(create$
|
|
2302
|
-
const directionVec4 = set$1(create$
|
|
2214
|
+
const originVec4 = set$1(create$3(), _origin.x, _origin.y, _origin.z, _origin.w);
|
|
2215
|
+
const directionVec4 = set$1(create$3(), _direction.x, _direction.y, _direction.z, _direction.w);
|
|
2303
2216
|
transformMat4(originVec4, originVec4, matrix);
|
|
2304
2217
|
transformMat4(directionVec4, directionVec4, matrix);
|
|
2305
2218
|
_origin.x = originVec4[0];
|
|
@@ -2320,7 +2233,7 @@ class XRRay {
|
|
|
2320
2233
|
}
|
|
2321
2234
|
if (direction) {
|
|
2322
2235
|
if ((direction.x === 0 && direction.y === 0 && direction.z === 0) ||
|
|
2323
|
-
direction.w !==
|
|
2236
|
+
direction.w !== 0) {
|
|
2324
2237
|
throw new DOMException('Invalid direction value to construct XRRay', 'TypeError');
|
|
2325
2238
|
}
|
|
2326
2239
|
_direction.x = direction.x;
|
|
@@ -2336,8 +2249,8 @@ class XRRay {
|
|
|
2336
2249
|
_direction.y = _direction.y / length;
|
|
2337
2250
|
_direction.z = _direction.z / length;
|
|
2338
2251
|
this[P_RAY] = {
|
|
2339
|
-
origin: new DOMPointReadOnly(_origin.x, _origin.y, _origin.z, _origin.w),
|
|
2340
|
-
direction: new DOMPointReadOnly(_direction.x, _direction.y, _direction.z, _direction.w),
|
|
2252
|
+
origin: new DOMPointReadOnly$1(_origin.x, _origin.y, _origin.z, _origin.w),
|
|
2253
|
+
direction: new DOMPointReadOnly$1(_direction.x, _direction.y, _direction.z, _direction.w),
|
|
2341
2254
|
matrix: null,
|
|
2342
2255
|
};
|
|
2343
2256
|
}
|
|
@@ -2351,23 +2264,23 @@ class XRRay {
|
|
|
2351
2264
|
if (this[P_RAY].matrix) {
|
|
2352
2265
|
return this[P_RAY].matrix;
|
|
2353
2266
|
}
|
|
2354
|
-
const z = set$2(create$
|
|
2355
|
-
const origin = set$2(create$
|
|
2356
|
-
const direction = set$2(create$
|
|
2357
|
-
const axis = cross(create$
|
|
2267
|
+
const z = set$2(create$4(), 0, 0, -1);
|
|
2268
|
+
const origin = set$2(create$4(), this[P_RAY].origin.x, this[P_RAY].origin.y, this[P_RAY].origin.z);
|
|
2269
|
+
const direction = set$2(create$4(), this[P_RAY].direction.x, this[P_RAY].direction.y, this[P_RAY].direction.z);
|
|
2270
|
+
const axis = cross(create$4(), direction, z);
|
|
2358
2271
|
const cosAngle = dot(direction, z);
|
|
2359
|
-
const rotation = create$
|
|
2272
|
+
const rotation = create$5();
|
|
2360
2273
|
if (cosAngle > -1 && cosAngle < 1) {
|
|
2361
2274
|
fromRotation(rotation, Math.acos(cosAngle), axis);
|
|
2362
2275
|
}
|
|
2363
2276
|
else if (cosAngle === -1) {
|
|
2364
|
-
fromRotation(rotation, Math.acos(cosAngle), set$2(create$
|
|
2277
|
+
fromRotation(rotation, Math.acos(cosAngle), set$2(create$4(), 1, 0, 0));
|
|
2365
2278
|
}
|
|
2366
2279
|
else {
|
|
2367
2280
|
identity(rotation);
|
|
2368
2281
|
}
|
|
2369
|
-
const translation = fromTranslation(create$
|
|
2370
|
-
const matrix = multiply$
|
|
2282
|
+
const translation = fromTranslation(create$5(), origin);
|
|
2283
|
+
const matrix = multiply$2(create$5(), translation, rotation);
|
|
2371
2284
|
this[P_RAY].matrix = new Float32Array(matrix);
|
|
2372
2285
|
return this[P_RAY].matrix;
|
|
2373
2286
|
}
|
|
@@ -2634,14 +2547,14 @@ class XRViewerPose extends XRPose {
|
|
|
2634
2547
|
* This source code is licensed under the MIT license found in the
|
|
2635
2548
|
* LICENSE file in the root directory of this source tree.
|
|
2636
2549
|
*/
|
|
2637
|
-
const spaceGlobalMatrix = create$
|
|
2638
|
-
const baseSpaceGlobalMatrix = create$
|
|
2639
|
-
const baseSpaceGlobalMatrixInverse = create$
|
|
2550
|
+
const spaceGlobalMatrix = create$5();
|
|
2551
|
+
const baseSpaceGlobalMatrix = create$5();
|
|
2552
|
+
const baseSpaceGlobalMatrixInverse = create$5();
|
|
2640
2553
|
const getOffsetMatrix = (offsetMatrix, space, baseSpace) => {
|
|
2641
2554
|
XRSpaceUtils.calculateGlobalOffsetMatrix(space, spaceGlobalMatrix);
|
|
2642
2555
|
XRSpaceUtils.calculateGlobalOffsetMatrix(baseSpace, baseSpaceGlobalMatrix);
|
|
2643
2556
|
invert(baseSpaceGlobalMatrixInverse, baseSpaceGlobalMatrix);
|
|
2644
|
-
multiply$
|
|
2557
|
+
multiply$2(offsetMatrix, baseSpaceGlobalMatrixInverse, spaceGlobalMatrix);
|
|
2645
2558
|
};
|
|
2646
2559
|
class XRFrame {
|
|
2647
2560
|
constructor(session, id, active, animationFrame, predictedDisplayTime) {
|
|
@@ -2651,7 +2564,7 @@ class XRFrame {
|
|
|
2651
2564
|
active,
|
|
2652
2565
|
animationFrame,
|
|
2653
2566
|
predictedDisplayTime,
|
|
2654
|
-
tempMat4: create$
|
|
2567
|
+
tempMat4: create$5(),
|
|
2655
2568
|
detectedPlanes: new XRPlaneSet(),
|
|
2656
2569
|
detectedMeshes: new XRMeshSet(),
|
|
2657
2570
|
trackedAnchors: session[P_SESSION].frameTrackedAnchors,
|
|
@@ -2669,9 +2582,9 @@ class XRFrame {
|
|
|
2669
2582
|
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2670
2583
|
}
|
|
2671
2584
|
getOffsetMatrix(this[P_FRAME].tempMat4, space, baseSpace);
|
|
2672
|
-
const position = create$
|
|
2585
|
+
const position = create$4();
|
|
2673
2586
|
getTranslation(position, this[P_FRAME].tempMat4);
|
|
2674
|
-
const orientation = create();
|
|
2587
|
+
const orientation = create$2();
|
|
2675
2588
|
getRotation(orientation, this[P_FRAME].tempMat4);
|
|
2676
2589
|
return new XRPose(new XRRigidTransform({ x: position[0], y: position[1], z: position[2], w: 1.0 }, {
|
|
2677
2590
|
x: orientation[0],
|
|
@@ -2822,9 +2735,9 @@ class XRSession extends EventTarget {
|
|
|
2822
2735
|
isSystemKeyboardSupported: false,
|
|
2823
2736
|
ended: false,
|
|
2824
2737
|
projectionMatrices: {
|
|
2825
|
-
[XREye.Left]: create$
|
|
2826
|
-
[XREye.Right]: create$
|
|
2827
|
-
[XREye.None]: create$
|
|
2738
|
+
[XREye.Left]: create$5(),
|
|
2739
|
+
[XREye.Right]: create$5(),
|
|
2740
|
+
[XREye.None]: create$5(),
|
|
2828
2741
|
},
|
|
2829
2742
|
getProjectionMatrix: (eye) => {
|
|
2830
2743
|
return this[P_SESSION].projectionMatrices[eye];
|
|
@@ -3073,8 +2986,8 @@ class XRSession extends EventTarget {
|
|
|
3073
2986
|
const sourceSpace = hitTestSource[P_HIT_TEST].space;
|
|
3074
2987
|
const sourceGlobalOffset = XRSpaceUtils.calculateGlobalOffsetMatrix(sourceSpace);
|
|
3075
2988
|
const rayLocalOffset = hitTestSource[P_HIT_TEST].offsetRay.matrix;
|
|
3076
|
-
const rayGlobalOffset = create$
|
|
3077
|
-
multiply$
|
|
2989
|
+
const rayGlobalOffset = create$5();
|
|
2990
|
+
multiply$2(rayGlobalOffset, sourceGlobalOffset, rayLocalOffset);
|
|
3078
2991
|
const hitTestResults = [];
|
|
3079
2992
|
sem.computeHitTestResults(rayGlobalOffset).forEach((matrix) => {
|
|
3080
2993
|
const offsetSpace = new XRSpace(globalSpace, matrix);
|
|
@@ -4246,15 +4159,15 @@ const XRHandGamepadConfig = {
|
|
|
4246
4159
|
buttons: [{ id: 'pinch', type: 'analog', eventTrigger: 'select' }],
|
|
4247
4160
|
axes: [],
|
|
4248
4161
|
};
|
|
4249
|
-
const fromPosition = create$
|
|
4250
|
-
const fromQuaternion = create();
|
|
4251
|
-
const fromScale = create$
|
|
4252
|
-
const toPosition = create$
|
|
4253
|
-
const toQuaternion = create();
|
|
4254
|
-
const toScale = create$
|
|
4255
|
-
const interpolatedPosition = create$
|
|
4256
|
-
const interpolatedQuaternion = create();
|
|
4257
|
-
const interpolatedScale = create$
|
|
4162
|
+
const fromPosition = create$4();
|
|
4163
|
+
const fromQuaternion = create$2();
|
|
4164
|
+
const fromScale = create$4();
|
|
4165
|
+
const toPosition = create$4();
|
|
4166
|
+
const toQuaternion = create$2();
|
|
4167
|
+
const toScale = create$4();
|
|
4168
|
+
const interpolatedPosition = create$4();
|
|
4169
|
+
const interpolatedQuaternion = create$2();
|
|
4170
|
+
const interpolatedScale = create$4();
|
|
4258
4171
|
const interpolateMatrix = (out, fromMatrix, toMatrix, alpha) => {
|
|
4259
4172
|
getTranslation(fromPosition, fromMatrix);
|
|
4260
4173
|
getRotation(fromQuaternion, fromMatrix);
|
|
@@ -4447,8 +4360,8 @@ class ActionPlayer {
|
|
|
4447
4360
|
playing: false,
|
|
4448
4361
|
viewerSpace,
|
|
4449
4362
|
viewSpaces,
|
|
4450
|
-
vec3: create$
|
|
4451
|
-
quat: create(),
|
|
4363
|
+
vec3: create$4(),
|
|
4364
|
+
quat: create$2(),
|
|
4452
4365
|
};
|
|
4453
4366
|
fromTranslation(this[P_ACTION_PLAYER].viewSpaces[XREye.Left][P_SPACE].offsetMatrix, fromValues$2(-ipd / 2, 0, 0));
|
|
4454
4367
|
fromTranslation(this[P_ACTION_PLAYER].viewSpaces[XREye.Right][P_SPACE].offsetMatrix, fromValues$2(ipd / 2, 0, 0));
|
|
@@ -4614,7 +4527,7 @@ class ActionPlayer {
|
|
|
4614
4527
|
}
|
|
4615
4528
|
}
|
|
4616
4529
|
|
|
4617
|
-
const VERSION = "2.
|
|
4530
|
+
const VERSION = "2.1.1";
|
|
4618
4531
|
|
|
4619
4532
|
/**
|
|
4620
4533
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -4755,39 +4668,3041 @@ class XRViewport {
|
|
|
4755
4668
|
}
|
|
4756
4669
|
|
|
4757
4670
|
/**
|
|
4758
|
-
*
|
|
4759
|
-
*
|
|
4760
|
-
*
|
|
4761
|
-
*
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4671
|
+
* @license
|
|
4672
|
+
* webxr-layers-polyfill
|
|
4673
|
+
* Version 1.1.0
|
|
4674
|
+
* Copyright (c) 2021 Facebook, Inc. and its affiliates.
|
|
4675
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4676
|
+
* you may not use this file except in compliance with the License.
|
|
4677
|
+
* You may obtain a copy of the License at
|
|
4678
|
+
*
|
|
4679
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
4680
|
+
*
|
|
4681
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
4682
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
4683
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
4684
|
+
* See the License for the specific language governing permissions and
|
|
4685
|
+
* limitations under the License.
|
|
4686
|
+
*/
|
|
4687
|
+
|
|
4774
4688
|
/**
|
|
4775
|
-
*
|
|
4776
|
-
*
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4689
|
+
* @license
|
|
4690
|
+
* gl-matrix
|
|
4691
|
+
* Version 3.4.3
|
|
4692
|
+
* Copyright (c) 2015-2021, Brandon Jones, Colin MacKenzie IV.
|
|
4693
|
+
*
|
|
4694
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4695
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
4696
|
+
* in the Software without restriction, including without limitation the rights
|
|
4697
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
4698
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
4699
|
+
* furnished to do so, subject to the following conditions:
|
|
4700
|
+
*
|
|
4701
|
+
* The above copyright notice and this permission notice shall be included in
|
|
4702
|
+
* all copies or substantial portions of the Software.
|
|
4703
|
+
*
|
|
4704
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
4705
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
4706
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
4707
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
4708
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
4709
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
4710
|
+
* THE SOFTWARE.
|
|
4711
|
+
*/
|
|
4712
|
+
|
|
4713
|
+
var XRTextureType;
|
|
4714
|
+
(function (XRTextureType) {
|
|
4715
|
+
XRTextureType["texture"] = "texture";
|
|
4716
|
+
XRTextureType["texture-array"] = "texture-array";
|
|
4717
|
+
})(XRTextureType || (XRTextureType = {}));
|
|
4718
|
+
var XRLayerLayout;
|
|
4719
|
+
(function (XRLayerLayout) {
|
|
4720
|
+
XRLayerLayout["default"] = "default";
|
|
4721
|
+
XRLayerLayout["mono"] = "mono";
|
|
4722
|
+
XRLayerLayout["stereo"] = "stereo";
|
|
4723
|
+
XRLayerLayout["stereo-left-right"] = "stereo-left-right";
|
|
4724
|
+
XRLayerLayout["stereo-top-bottom"] = "stereo-top-bottom";
|
|
4725
|
+
})(XRLayerLayout || (XRLayerLayout = {}));
|
|
4726
|
+
|
|
4727
|
+
const isReferenceSpace = (arg) => {
|
|
4728
|
+
return arg && typeof arg.getOffsetReferenceSpace === 'function';
|
|
4729
|
+
};
|
|
4730
|
+
|
|
4731
|
+
const getGlobal = () => {
|
|
4732
|
+
return typeof global !== 'undefined'
|
|
4733
|
+
? global
|
|
4734
|
+
: typeof self !== 'undefined'
|
|
4735
|
+
? self
|
|
4736
|
+
: typeof window !== 'undefined'
|
|
4737
|
+
? window
|
|
4738
|
+
: {};
|
|
4739
|
+
};
|
|
4740
|
+
|
|
4741
|
+
const getFormatsFromInternalFormat = (context, providedFormat) => {
|
|
4742
|
+
switch (providedFormat) {
|
|
4743
|
+
case context.RGBA8:
|
|
4744
|
+
case context.RGB5_A1:
|
|
4745
|
+
case context.RGBA4:
|
|
4746
|
+
case context.SRGB8_ALPHA8:
|
|
4747
|
+
return {
|
|
4748
|
+
internalFormat: providedFormat,
|
|
4749
|
+
textureFormat: context.RGBA,
|
|
4750
|
+
type: context.UNSIGNED_BYTE,
|
|
4751
|
+
};
|
|
4752
|
+
case context.RGBA8_SNORM:
|
|
4753
|
+
return {
|
|
4754
|
+
internalFormat: providedFormat,
|
|
4755
|
+
textureFormat: context.RGBA,
|
|
4756
|
+
type: context.BYTE,
|
|
4757
|
+
};
|
|
4758
|
+
case context.RGB10_A2:
|
|
4759
|
+
return {
|
|
4760
|
+
internalFormat: providedFormat,
|
|
4761
|
+
textureFormat: context.RGBA,
|
|
4762
|
+
type: context.UNSIGNED_INT_2_10_10_10_REV,
|
|
4763
|
+
};
|
|
4764
|
+
case context.RGBA16F:
|
|
4765
|
+
return {
|
|
4766
|
+
internalFormat: providedFormat,
|
|
4767
|
+
textureFormat: context.RGBA,
|
|
4768
|
+
type: context.HALF_FLOAT,
|
|
4769
|
+
};
|
|
4770
|
+
case context.RGBA32F:
|
|
4771
|
+
return {
|
|
4772
|
+
internalFormat: providedFormat,
|
|
4773
|
+
textureFormat: context.RGBA,
|
|
4774
|
+
type: context.FLOAT,
|
|
4775
|
+
};
|
|
4776
|
+
case context.RGBA8UI:
|
|
4777
|
+
return {
|
|
4778
|
+
internalFormat: providedFormat,
|
|
4779
|
+
textureFormat: context.RGBA_INTEGER,
|
|
4780
|
+
type: context.UNSIGNED_BYTE,
|
|
4781
|
+
};
|
|
4782
|
+
case context.RGBA8I:
|
|
4783
|
+
return {
|
|
4784
|
+
internalFormat: providedFormat,
|
|
4785
|
+
textureFormat: context.RGBA_INTEGER,
|
|
4786
|
+
type: context.BYTE,
|
|
4787
|
+
};
|
|
4788
|
+
case context.RGBA16UI:
|
|
4789
|
+
return {
|
|
4790
|
+
internalFormat: providedFormat,
|
|
4791
|
+
textureFormat: context.RGBA_INTEGER,
|
|
4792
|
+
type: context.UNSIGNED_SHORT,
|
|
4793
|
+
};
|
|
4794
|
+
case context.RGBA16I:
|
|
4795
|
+
return {
|
|
4796
|
+
internalFormat: providedFormat,
|
|
4797
|
+
textureFormat: context.RGBA_INTEGER,
|
|
4798
|
+
type: context.SHORT,
|
|
4799
|
+
};
|
|
4800
|
+
case context.RGBA32UI:
|
|
4801
|
+
return {
|
|
4802
|
+
internalFormat: providedFormat,
|
|
4803
|
+
textureFormat: context.RGBA_INTEGER,
|
|
4804
|
+
type: context.UNSIGNED_INT,
|
|
4805
|
+
};
|
|
4806
|
+
case context.RGBA32I:
|
|
4807
|
+
return {
|
|
4808
|
+
internalFormat: providedFormat,
|
|
4809
|
+
textureFormat: context.RGBA_INTEGER,
|
|
4810
|
+
type: context.INT,
|
|
4811
|
+
};
|
|
4812
|
+
case context.RGB10_A2UI:
|
|
4813
|
+
return {
|
|
4814
|
+
internalFormat: providedFormat,
|
|
4815
|
+
textureFormat: context.RGBA_INTEGER,
|
|
4816
|
+
type: context.UNSIGNED_INT_2_10_10_10_REV,
|
|
4817
|
+
};
|
|
4818
|
+
case context.RGB8:
|
|
4819
|
+
case context.RGB565:
|
|
4820
|
+
case context.SRGB8:
|
|
4821
|
+
return {
|
|
4822
|
+
internalFormat: providedFormat,
|
|
4823
|
+
textureFormat: context.RGB,
|
|
4824
|
+
type: context.UNSIGNED_BYTE,
|
|
4825
|
+
};
|
|
4826
|
+
case context.RGB8_SNORM:
|
|
4827
|
+
return {
|
|
4828
|
+
internalFormat: providedFormat,
|
|
4829
|
+
textureFormat: context.RGB,
|
|
4830
|
+
type: context.BYTE,
|
|
4831
|
+
};
|
|
4832
|
+
case context.RGB16F:
|
|
4833
|
+
case context.R11F_G11F_B10F:
|
|
4834
|
+
case context.RGB9_E5:
|
|
4835
|
+
return {
|
|
4836
|
+
internalFormat: providedFormat,
|
|
4837
|
+
textureFormat: context.RGB,
|
|
4838
|
+
type: context.HALF_FLOAT,
|
|
4839
|
+
};
|
|
4840
|
+
case context.RGB32F:
|
|
4841
|
+
return {
|
|
4842
|
+
internalFormat: providedFormat,
|
|
4843
|
+
textureFormat: context.RGB,
|
|
4844
|
+
type: context.FLOAT,
|
|
4845
|
+
};
|
|
4846
|
+
case context.RGB8UI:
|
|
4847
|
+
return {
|
|
4848
|
+
internalFormat: providedFormat,
|
|
4849
|
+
textureFormat: context.RGB_INTEGER,
|
|
4850
|
+
type: context.UNSIGNED_BYTE,
|
|
4851
|
+
};
|
|
4852
|
+
case context.RGB8I:
|
|
4853
|
+
return {
|
|
4854
|
+
internalFormat: providedFormat,
|
|
4855
|
+
textureFormat: context.RGB_INTEGER,
|
|
4856
|
+
type: context.BYTE,
|
|
4857
|
+
};
|
|
4858
|
+
case context.RGB16UI:
|
|
4859
|
+
return {
|
|
4860
|
+
internalFormat: providedFormat,
|
|
4861
|
+
textureFormat: context.RGB_INTEGER,
|
|
4862
|
+
type: context.UNSIGNED_SHORT,
|
|
4863
|
+
};
|
|
4864
|
+
case context.RGB16I:
|
|
4865
|
+
return {
|
|
4866
|
+
internalFormat: providedFormat,
|
|
4867
|
+
textureFormat: context.RGB_INTEGER,
|
|
4868
|
+
type: context.SHORT,
|
|
4869
|
+
};
|
|
4870
|
+
case context.RGB32UI:
|
|
4871
|
+
return {
|
|
4872
|
+
internalFormat: providedFormat,
|
|
4873
|
+
textureFormat: context.RGB_INTEGER,
|
|
4874
|
+
type: context.UNSIGNED_INT,
|
|
4875
|
+
};
|
|
4876
|
+
case context.RGB32I:
|
|
4877
|
+
return {
|
|
4878
|
+
internalFormat: providedFormat,
|
|
4879
|
+
textureFormat: context.RGB_INTEGER,
|
|
4880
|
+
type: context.INT,
|
|
4881
|
+
};
|
|
4882
|
+
case context.DEPTH_COMPONENT16:
|
|
4883
|
+
return {
|
|
4884
|
+
internalFormat: providedFormat,
|
|
4885
|
+
textureFormat: context.DEPTH_COMPONENT,
|
|
4886
|
+
type: context.UNSIGNED_SHORT,
|
|
4887
|
+
};
|
|
4888
|
+
case context.DEPTH_COMPONENT24:
|
|
4889
|
+
return {
|
|
4890
|
+
internalFormat: providedFormat,
|
|
4891
|
+
textureFormat: context.DEPTH_COMPONENT,
|
|
4892
|
+
type: context.UNSIGNED_INT,
|
|
4893
|
+
};
|
|
4894
|
+
case context.DEPTH_COMPONENT32F:
|
|
4895
|
+
return {
|
|
4896
|
+
internalFormat: providedFormat,
|
|
4897
|
+
textureFormat: context.DEPTH_COMPONENT,
|
|
4898
|
+
type: context.FLOAT,
|
|
4899
|
+
};
|
|
4900
|
+
case context.DEPTH24_STENCIL8:
|
|
4901
|
+
return {
|
|
4902
|
+
internalFormat: providedFormat,
|
|
4903
|
+
textureFormat: context.DEPTH_STENCIL,
|
|
4904
|
+
type: context.UNSIGNED_INT_24_8,
|
|
4905
|
+
};
|
|
4906
|
+
case context.DEPTH32F_STENCIL8:
|
|
4907
|
+
return {
|
|
4908
|
+
internalFormat: providedFormat,
|
|
4909
|
+
textureFormat: context.DEPTH_STENCIL,
|
|
4910
|
+
type: context.FLOAT_32_UNSIGNED_INT_24_8_REV,
|
|
4911
|
+
};
|
|
4912
|
+
case context.DEPTH_COMPONENT:
|
|
4913
|
+
return getFormatsFromInternalFormat(context, context.DEPTH_COMPONENT24);
|
|
4914
|
+
case context.DEPTH_STENCIL:
|
|
4915
|
+
return getFormatsFromInternalFormat(context, context.DEPTH24_STENCIL8);
|
|
4916
|
+
case context.RGBA:
|
|
4917
|
+
case context.RGB:
|
|
4918
|
+
case context.LUMINANCE_ALPHA:
|
|
4919
|
+
case context.LUMINANCE:
|
|
4920
|
+
case context.ALPHA:
|
|
4921
|
+
return {
|
|
4922
|
+
internalFormat: providedFormat,
|
|
4923
|
+
textureFormat: providedFormat,
|
|
4924
|
+
type: context.UNSIGNED_BYTE,
|
|
4925
|
+
};
|
|
4926
|
+
default:
|
|
4927
|
+
throw new Error('Attempted to create polyfill with unsupported format.');
|
|
4928
|
+
}
|
|
4929
|
+
};
|
|
4930
|
+
|
|
4931
|
+
class XRCompositionLayerPolyfill {
|
|
4932
|
+
constructor() {
|
|
4933
|
+
this._hasRunDeferredInitialize = false;
|
|
4934
|
+
this._media = null;
|
|
4935
|
+
}
|
|
4936
|
+
initialize(session, context) {
|
|
4937
|
+
this.session = session;
|
|
4938
|
+
if (context) {
|
|
4939
|
+
this.context = context;
|
|
4940
|
+
}
|
|
4941
|
+
this.blendTextureSourceAlpha = true;
|
|
4942
|
+
}
|
|
4943
|
+
destroy() {
|
|
4944
|
+
this._colorTextures = [];
|
|
4945
|
+
this._depthStencilTextures = [];
|
|
4946
|
+
}
|
|
4947
|
+
addEventListener(type, listener, options) { }
|
|
4948
|
+
dispatchEvent(event) {
|
|
4949
|
+
return false;
|
|
4950
|
+
}
|
|
4951
|
+
removeEventListener(type, callback, options) { }
|
|
4952
|
+
getContext() {
|
|
4953
|
+
return this.context;
|
|
4954
|
+
}
|
|
4955
|
+
getTextureType() {
|
|
4956
|
+
throw new Error('Unimplemented');
|
|
4957
|
+
}
|
|
4958
|
+
get colorTextures() {
|
|
4959
|
+
return this._colorTextures;
|
|
4960
|
+
}
|
|
4961
|
+
get depthStencilTextures() {
|
|
4962
|
+
return this._depthStencilTextures;
|
|
4963
|
+
}
|
|
4964
|
+
get colorTexturesMeta() {
|
|
4965
|
+
return this._texturesMeta;
|
|
4966
|
+
}
|
|
4967
|
+
get media() {
|
|
4968
|
+
if (!this.isMediaLayer()) {
|
|
4969
|
+
console.warn('Attempted to retrieve media from a non-media layer');
|
|
4970
|
+
}
|
|
4971
|
+
return this._media;
|
|
4972
|
+
}
|
|
4973
|
+
determineLayoutAttribute(textureType, context, layout) {
|
|
4974
|
+
if (!(context instanceof WebGL2RenderingContext) &&
|
|
4975
|
+
textureType === XRTextureType['texture-array']) {
|
|
4976
|
+
throw new TypeError();
|
|
4977
|
+
}
|
|
4978
|
+
if (layout === XRLayerLayout.mono) {
|
|
4979
|
+
return layout;
|
|
4980
|
+
}
|
|
4981
|
+
if (layout === XRLayerLayout.default) {
|
|
4982
|
+
if (this.session.internalViews && this.session.internalViews.length === 1) {
|
|
4983
|
+
return XRLayerLayout['mono'];
|
|
4984
|
+
}
|
|
4985
|
+
if (textureType === XRTextureType['texture-array']) {
|
|
4986
|
+
return layout;
|
|
4987
|
+
}
|
|
4988
|
+
}
|
|
4989
|
+
if (layout === XRLayerLayout.default || layout === XRLayerLayout.stereo) {
|
|
4990
|
+
return XRLayerLayout['stereo-left-right'];
|
|
4991
|
+
}
|
|
4992
|
+
return layout;
|
|
4993
|
+
}
|
|
4994
|
+
isMediaLayer() {
|
|
4995
|
+
return this._media !== null;
|
|
4996
|
+
}
|
|
4997
|
+
_deferredInitialize() { }
|
|
4998
|
+
initializeIfNeeded() {
|
|
4999
|
+
if (!this._hasRunDeferredInitialize) {
|
|
5000
|
+
this._hasRunDeferredInitialize = true;
|
|
5001
|
+
this._deferredInitialize();
|
|
5002
|
+
}
|
|
5003
|
+
}
|
|
5004
|
+
_allocateColorTexturesInternal(textureType, init) {
|
|
5005
|
+
let session = this.session;
|
|
5006
|
+
let views = session.internalViews;
|
|
5007
|
+
if (!views || views.length === 0) {
|
|
5008
|
+
console.warn("We can't allocate color textures without views");
|
|
5009
|
+
return;
|
|
5010
|
+
}
|
|
5011
|
+
this.initializeIfNeeded();
|
|
5012
|
+
if (this.layout === XRLayerLayout.mono) {
|
|
5013
|
+
if (textureType === XRTextureType['texture-array']) {
|
|
5014
|
+
const newTexture = this._createNewColorTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.colorFormat);
|
|
5015
|
+
this._texturesMeta = [newTexture];
|
|
5016
|
+
this._colorTextures = [newTexture.texture];
|
|
5017
|
+
return;
|
|
5018
|
+
}
|
|
5019
|
+
else {
|
|
5020
|
+
const newTexture = this._createNewColorTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.colorFormat);
|
|
5021
|
+
this._texturesMeta = [newTexture];
|
|
5022
|
+
this._colorTextures = [newTexture.texture];
|
|
5023
|
+
return;
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
else if (this.layout === XRLayerLayout.stereo) {
|
|
5027
|
+
if (textureType === XRTextureType['texture-array']) {
|
|
5028
|
+
const newTexture = this._createNewColorTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.colorFormat, 2);
|
|
5029
|
+
this._texturesMeta = [newTexture];
|
|
5030
|
+
this._colorTextures = [newTexture.texture];
|
|
5031
|
+
return;
|
|
5032
|
+
}
|
|
5033
|
+
else {
|
|
5034
|
+
const texture1 = this._createNewColorTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.colorFormat);
|
|
5035
|
+
const texture2 = this._createNewColorTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.colorFormat);
|
|
5036
|
+
this._texturesMeta = [texture1, texture2];
|
|
5037
|
+
this._colorTextures = [texture1.texture, texture2.texture];
|
|
5038
|
+
return;
|
|
5039
|
+
}
|
|
5040
|
+
}
|
|
5041
|
+
else if (this.layout === XRLayerLayout['stereo-left-right']) {
|
|
5042
|
+
const newTexture = this._createNewColorTexture(init.viewPixelWidth * 2, init.viewPixelHeight, textureType, init.colorFormat);
|
|
5043
|
+
this._texturesMeta = [newTexture];
|
|
5044
|
+
this._colorTextures = [newTexture.texture];
|
|
5045
|
+
return;
|
|
5046
|
+
}
|
|
5047
|
+
else if (this.layout === XRLayerLayout['stereo-top-bottom']) {
|
|
5048
|
+
const newTexture = this._createNewColorTexture(init.viewPixelWidth, init.viewPixelHeight * 2, textureType, init.colorFormat);
|
|
5049
|
+
this._texturesMeta = [newTexture];
|
|
5050
|
+
this._colorTextures = [newTexture.texture];
|
|
5051
|
+
return;
|
|
5052
|
+
}
|
|
5053
|
+
}
|
|
5054
|
+
_allocateDepthStencilTexturesInternal(textureType, init) {
|
|
5055
|
+
if (!init.depthFormat) {
|
|
5056
|
+
this._depthStencilTextures = [];
|
|
5057
|
+
return;
|
|
5058
|
+
}
|
|
5059
|
+
if (this._getSupportedDepthFormats().indexOf(init.depthFormat) < 0) {
|
|
5060
|
+
throw new Error('Depth format provided is not supported in non-projection layers.');
|
|
5061
|
+
}
|
|
5062
|
+
if (init.mipLevels < 1) {
|
|
5063
|
+
throw new Error('Invalid miplevel. Miplevel needs to be >= 1');
|
|
5064
|
+
}
|
|
5065
|
+
if (this.layout === XRLayerLayout.mono) {
|
|
5066
|
+
if (textureType === XRTextureType['texture-array']) {
|
|
5067
|
+
const newTexture = this._createNewDepthStencilTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.depthFormat);
|
|
5068
|
+
this._depthStencilTextures = [newTexture.texture];
|
|
5069
|
+
return;
|
|
5070
|
+
}
|
|
5071
|
+
else {
|
|
5072
|
+
const newTexture = this._createNewColorTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.depthFormat);
|
|
5073
|
+
this._depthStencilTextures = [newTexture.texture];
|
|
5074
|
+
return;
|
|
5075
|
+
}
|
|
5076
|
+
}
|
|
5077
|
+
else if (this.layout === XRLayerLayout.stereo) {
|
|
5078
|
+
if (textureType === XRTextureType['texture-array']) {
|
|
5079
|
+
const newTexture = this._createNewDepthStencilTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.depthFormat, 2);
|
|
5080
|
+
this._depthStencilTextures = [newTexture.texture];
|
|
5081
|
+
return;
|
|
5082
|
+
}
|
|
5083
|
+
else {
|
|
5084
|
+
const texture1 = this._createNewDepthStencilTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.depthFormat);
|
|
5085
|
+
const texture2 = this._createNewDepthStencilTexture(init.viewPixelWidth, init.viewPixelHeight, textureType, init.depthFormat);
|
|
5086
|
+
this._depthStencilTextures = [texture1.texture, texture2.texture];
|
|
5087
|
+
return;
|
|
5088
|
+
}
|
|
5089
|
+
}
|
|
5090
|
+
else if (this.layout === XRLayerLayout['stereo-left-right']) {
|
|
5091
|
+
const newTexture = this._createNewDepthStencilTexture(init.viewPixelWidth * 2, init.viewPixelHeight, textureType, init.depthFormat);
|
|
5092
|
+
this._depthStencilTextures = [newTexture.texture];
|
|
5093
|
+
return;
|
|
5094
|
+
}
|
|
5095
|
+
else if (this.layout === XRLayerLayout['stereo-top-bottom']) {
|
|
5096
|
+
const newTexture = this._createNewDepthStencilTexture(init.viewPixelWidth, init.viewPixelHeight * 2, textureType, init.depthFormat);
|
|
5097
|
+
this._depthStencilTextures = [newTexture.texture];
|
|
5098
|
+
return;
|
|
5099
|
+
}
|
|
5100
|
+
}
|
|
5101
|
+
_createNewColorTexture(width, height, textureType, colorFormat, layers = 1) {
|
|
5102
|
+
return this._createGenericPolyfillTexture(textureType, width, height, colorFormat, 0, layers);
|
|
5103
|
+
}
|
|
5104
|
+
_createNewDepthStencilTexture(width, height, textureType, depthFormat, layers = 1) {
|
|
5105
|
+
return this._createGenericPolyfillTexture(textureType, width, height, depthFormat, 0, layers);
|
|
5106
|
+
}
|
|
5107
|
+
_createGenericPolyfillTexture(textureType, width, height, textureFormat, mipmapLevel = 0, numLayers = 1) {
|
|
5108
|
+
if (textureType === XRTextureType['texture-array'] && numLayers <= 1) {
|
|
5109
|
+
console.warn('creating a texture array with a single layer...');
|
|
5110
|
+
}
|
|
5111
|
+
if (textureType === XRTextureType['texture-array'] &&
|
|
5112
|
+
this.context instanceof WebGLRenderingContext) {
|
|
5113
|
+
throw new Error('WebGL 1 does not support texture array');
|
|
5114
|
+
}
|
|
5115
|
+
let texture = this.context.createTexture();
|
|
5116
|
+
let textureMeta = {
|
|
5117
|
+
width,
|
|
5118
|
+
height,
|
|
5119
|
+
layers: numLayers,
|
|
5120
|
+
type: textureType,
|
|
5121
|
+
textureFormat: textureFormat,
|
|
5122
|
+
texture,
|
|
5123
|
+
};
|
|
5124
|
+
let internalFormat = textureFormat;
|
|
5125
|
+
let texImageType = this.context.UNSIGNED_BYTE;
|
|
5126
|
+
if (this.context instanceof WebGL2RenderingContext) {
|
|
5127
|
+
const expectedFormats = getFormatsFromInternalFormat(this.context, textureFormat);
|
|
5128
|
+
internalFormat = expectedFormats.internalFormat;
|
|
5129
|
+
textureFormat = expectedFormats.textureFormat;
|
|
5130
|
+
texImageType = expectedFormats.type;
|
|
5131
|
+
}
|
|
5132
|
+
else {
|
|
5133
|
+
if (textureFormat === this.context.DEPTH_COMPONENT) {
|
|
5134
|
+
texImageType = this.context.UNSIGNED_INT;
|
|
5135
|
+
}
|
|
5136
|
+
if (textureFormat === this.context.DEPTH_STENCIL) {
|
|
5137
|
+
texImageType = this.context.UNSIGNED_INT_24_8_WEBGL;
|
|
5138
|
+
}
|
|
5139
|
+
}
|
|
5140
|
+
if (textureType === XRTextureType['texture-array'] &&
|
|
5141
|
+
this.context instanceof WebGL2RenderingContext) {
|
|
5142
|
+
console.warn('texture-array layers are supported...questionably in the polyfill at the moment. Use at your own risk.');
|
|
5143
|
+
const existingTextureBinding = this.context.getParameter(this.context.TEXTURE_BINDING_2D_ARRAY);
|
|
5144
|
+
this.context.bindTexture(this.context.TEXTURE_2D_ARRAY, texture);
|
|
5145
|
+
if (this._getSupportedDepthFormats().indexOf(textureFormat) >= 0) {
|
|
5146
|
+
this.context.texStorage3D(this.context.TEXTURE_2D_ARRAY, 1, internalFormat, width, height, numLayers);
|
|
5147
|
+
}
|
|
5148
|
+
else {
|
|
5149
|
+
this.context.texImage3D(this.context.TEXTURE_2D_ARRAY, 0, internalFormat, width, height, numLayers, 0, textureFormat, texImageType, null);
|
|
5150
|
+
}
|
|
5151
|
+
this.context.bindTexture(this.context.TEXTURE_2D_ARRAY, existingTextureBinding);
|
|
5152
|
+
}
|
|
5153
|
+
else {
|
|
5154
|
+
const existingTextureBinding = this.context.getParameter(this.context.TEXTURE_BINDING_2D);
|
|
5155
|
+
this.context.bindTexture(this.context.TEXTURE_2D, texture);
|
|
5156
|
+
this.context.texImage2D(this.context.TEXTURE_2D, 0, internalFormat, width, height, 0, textureFormat, texImageType, null);
|
|
5157
|
+
this.context.bindTexture(this.context.TEXTURE_2D, existingTextureBinding);
|
|
5158
|
+
}
|
|
5159
|
+
return textureMeta;
|
|
5160
|
+
}
|
|
5161
|
+
_getSupportedDepthFormats() {
|
|
5162
|
+
const supportedDepthFormats = [];
|
|
5163
|
+
if (this.context instanceof WebGLRenderingContext) {
|
|
5164
|
+
if (!this.context.getExtension('WEBGL_depth_texture')) {
|
|
5165
|
+
return supportedDepthFormats;
|
|
5166
|
+
}
|
|
5167
|
+
}
|
|
5168
|
+
supportedDepthFormats.push(this.context.DEPTH_COMPONENT, this.context.DEPTH_STENCIL);
|
|
5169
|
+
if (this.context instanceof WebGL2RenderingContext) {
|
|
5170
|
+
supportedDepthFormats.push(this.context.DEPTH_COMPONENT24, this.context.DEPTH24_STENCIL8);
|
|
5171
|
+
}
|
|
5172
|
+
return supportedDepthFormats;
|
|
5173
|
+
}
|
|
5174
|
+
}
|
|
5175
|
+
|
|
5176
|
+
const defaultCylinderLayerInit = {
|
|
5177
|
+
colorFormat: 0x1908,
|
|
5178
|
+
mipLevels: 1,
|
|
5179
|
+
layout: XRLayerLayout.mono,
|
|
5180
|
+
isStatic: false,
|
|
5181
|
+
space: null,
|
|
5182
|
+
viewPixelHeight: 0,
|
|
5183
|
+
viewPixelWidth: 0,
|
|
5184
|
+
textureType: XRTextureType.texture,
|
|
5185
|
+
radius: 2.0,
|
|
5186
|
+
centralAngle: 0.78539,
|
|
5187
|
+
aspectRatio: 2.0,
|
|
5188
|
+
};
|
|
5189
|
+
const defaultMediaCylinderLayerInit = {
|
|
5190
|
+
layout: XRLayerLayout.mono,
|
|
5191
|
+
invertStereo: false,
|
|
5192
|
+
space: null,
|
|
5193
|
+
radius: 2.0,
|
|
5194
|
+
centralAngle: 0.78539,
|
|
5195
|
+
};
|
|
5196
|
+
class XRCylinderLayer extends XRCompositionLayerPolyfill {
|
|
5197
|
+
constructor(init, media) {
|
|
5198
|
+
super();
|
|
5199
|
+
this._media = media !== null && media !== void 0 ? media : null;
|
|
5200
|
+
if (this.isMediaLayer()) {
|
|
5201
|
+
this.init = Object.assign(Object.assign({}, defaultMediaCylinderLayerInit), init);
|
|
5202
|
+
}
|
|
5203
|
+
else {
|
|
5204
|
+
this.init = Object.assign(Object.assign({}, defaultCylinderLayerInit), init);
|
|
5205
|
+
}
|
|
5206
|
+
this.radius = this.init.radius;
|
|
5207
|
+
this.centralAngle = this.init.centralAngle;
|
|
5208
|
+
this.aspectRatio = this.init.aspectRatio;
|
|
5209
|
+
this.space = this.init.space;
|
|
5210
|
+
this.layout = this.init.layout;
|
|
5211
|
+
const _global = getGlobal();
|
|
5212
|
+
if (this.init.transform) {
|
|
5213
|
+
this.transform = new _global.XRRigidTransform(init.transform.position, init.transform.orientation);
|
|
5214
|
+
}
|
|
5215
|
+
else {
|
|
5216
|
+
this.transform = new _global.XRRigidTransform({
|
|
5217
|
+
x: 0,
|
|
5218
|
+
y: 0,
|
|
5219
|
+
z: 0,
|
|
5220
|
+
w: 1,
|
|
5221
|
+
});
|
|
5222
|
+
}
|
|
5223
|
+
if (!this.isMediaLayer()) {
|
|
5224
|
+
this.isStatic = init.isStatic;
|
|
5225
|
+
}
|
|
5226
|
+
}
|
|
5227
|
+
getTextureType() {
|
|
5228
|
+
if (this.isMediaLayer()) {
|
|
5229
|
+
return XRTextureType.texture;
|
|
5230
|
+
}
|
|
5231
|
+
return this.init.textureType;
|
|
5232
|
+
}
|
|
5233
|
+
_deferredInitialize() {
|
|
5234
|
+
let layout = this.determineLayoutAttribute(this.init.textureType, this.context, this.init.layout);
|
|
5235
|
+
this.layout = layout;
|
|
5236
|
+
this.needsRedraw = true;
|
|
5237
|
+
}
|
|
5238
|
+
get colorTextures() {
|
|
5239
|
+
if (this.isMediaLayer()) {
|
|
5240
|
+
throw new Error('Media layers do not have associated textures');
|
|
5241
|
+
}
|
|
5242
|
+
if (!this._colorTextures || !this._colorTextures.length) {
|
|
5243
|
+
this._allocateColorTexturesInternal(this.getTextureType(), this.init);
|
|
5244
|
+
}
|
|
5245
|
+
return this._colorTextures;
|
|
5246
|
+
}
|
|
5247
|
+
get depthStencilTextures() {
|
|
5248
|
+
if (this.isMediaLayer()) {
|
|
5249
|
+
throw new Error('Media layers do not have associated textures');
|
|
5250
|
+
}
|
|
5251
|
+
if (!this._depthStencilTextures || !this._depthStencilTextures.length) {
|
|
5252
|
+
this._allocateDepthStencilTexturesInternal(this.getTextureType(), this.init);
|
|
5253
|
+
}
|
|
5254
|
+
return this._depthStencilTextures;
|
|
5255
|
+
}
|
|
5256
|
+
get colorTexturesMeta() {
|
|
5257
|
+
if (this.isMediaLayer()) {
|
|
5258
|
+
throw new Error('Media layers do not have associated textures');
|
|
5259
|
+
}
|
|
5260
|
+
if (!this._colorTextures || !this._colorTextures.length) {
|
|
5261
|
+
this._allocateColorTexturesInternal(this.getTextureType(), this.init);
|
|
5262
|
+
}
|
|
5263
|
+
return this._texturesMeta;
|
|
5264
|
+
}
|
|
5265
|
+
get width() {
|
|
5266
|
+
const circumference = 2 * this.radius * Math.PI;
|
|
5267
|
+
const percentage = this.centralAngle / (2 * Math.PI);
|
|
5268
|
+
return circumference * percentage;
|
|
5269
|
+
}
|
|
5270
|
+
get height() {
|
|
5271
|
+
return this.width / this.aspectRatio;
|
|
5272
|
+
}
|
|
5273
|
+
}
|
|
5274
|
+
|
|
5275
|
+
const defaultEquirectLayerInit = {
|
|
5276
|
+
colorFormat: 0x1908,
|
|
5277
|
+
mipLevels: 1,
|
|
5278
|
+
layout: XRLayerLayout.mono,
|
|
5279
|
+
isStatic: false,
|
|
5280
|
+
space: null,
|
|
5281
|
+
viewPixelHeight: 0,
|
|
5282
|
+
viewPixelWidth: 0,
|
|
5283
|
+
textureType: XRTextureType.texture,
|
|
5284
|
+
radius: 0,
|
|
5285
|
+
centralHorizontalAngle: 6.28318,
|
|
5286
|
+
upperVerticalAngle: 1.570795,
|
|
5287
|
+
lowerVerticalAngle: -1.570795,
|
|
5288
|
+
};
|
|
5289
|
+
const defaultMediaEquirectLayerInit = {
|
|
5290
|
+
space: null,
|
|
5291
|
+
layout: XRLayerLayout.mono,
|
|
5292
|
+
invertStereo: false,
|
|
5293
|
+
radius: 0,
|
|
5294
|
+
centralHorizontalAngle: 6.28318,
|
|
5295
|
+
upperVerticalAngle: 1.570795,
|
|
5296
|
+
lowerVerticalAngle: -1.570795,
|
|
5297
|
+
};
|
|
5298
|
+
class XREquirectLayer extends XRCompositionLayerPolyfill {
|
|
5299
|
+
constructor(init, media) {
|
|
5300
|
+
super();
|
|
5301
|
+
this._media = media !== null && media !== void 0 ? media : null;
|
|
5302
|
+
if (this.isMediaLayer()) {
|
|
5303
|
+
this.init = Object.assign(Object.assign({}, defaultMediaEquirectLayerInit), init);
|
|
5304
|
+
}
|
|
5305
|
+
else {
|
|
5306
|
+
this.init = Object.assign(Object.assign({}, defaultEquirectLayerInit), init);
|
|
5307
|
+
}
|
|
5308
|
+
if (!isReferenceSpace(this.init.space)) {
|
|
5309
|
+
throw new TypeError("Equirect layer's space needs to be an XRReferenceSpace");
|
|
5310
|
+
}
|
|
5311
|
+
this.radius = this.init.radius;
|
|
5312
|
+
this.centralHorizontalAngle = this.init.centralHorizontalAngle;
|
|
5313
|
+
this.upperVerticalAngle = this.init.upperVerticalAngle;
|
|
5314
|
+
this.lowerVerticalAngle = this.init.lowerVerticalAngle;
|
|
5315
|
+
this.space = this.init.space;
|
|
5316
|
+
this.layout = this.init.layout;
|
|
5317
|
+
const _global = getGlobal();
|
|
5318
|
+
if (init.transform) {
|
|
5319
|
+
this.transform = new _global.XRRigidTransform(init.transform.position, init.transform.orientation);
|
|
5320
|
+
}
|
|
5321
|
+
else {
|
|
5322
|
+
this.transform = new _global.XRRigidTransform({
|
|
5323
|
+
x: 0,
|
|
5324
|
+
y: 0,
|
|
5325
|
+
z: 0,
|
|
5326
|
+
w: 1,
|
|
5327
|
+
});
|
|
5328
|
+
}
|
|
5329
|
+
if (!this.isMediaLayer()) {
|
|
5330
|
+
this.isStatic = init.isStatic;
|
|
5331
|
+
}
|
|
5332
|
+
}
|
|
5333
|
+
getTextureType() {
|
|
5334
|
+
if (this.isMediaLayer()) {
|
|
5335
|
+
return XRTextureType.texture;
|
|
5336
|
+
}
|
|
5337
|
+
return this.init.textureType;
|
|
5338
|
+
}
|
|
5339
|
+
_deferredInitialize() {
|
|
5340
|
+
let layout = this.determineLayoutAttribute(this.init.textureType, this.context, this.init.layout);
|
|
5341
|
+
this.layout = layout;
|
|
5342
|
+
this.needsRedraw = true;
|
|
5343
|
+
}
|
|
5344
|
+
get colorTextures() {
|
|
5345
|
+
if (this.isMediaLayer()) {
|
|
5346
|
+
throw new Error('Media layers do not have associated textures');
|
|
5347
|
+
}
|
|
5348
|
+
if (!this._colorTextures || !this._colorTextures.length) {
|
|
5349
|
+
this._allocateColorTexturesInternal(this.getTextureType(), this.init);
|
|
5350
|
+
}
|
|
5351
|
+
return this._colorTextures;
|
|
5352
|
+
}
|
|
5353
|
+
get depthStencilTextures() {
|
|
5354
|
+
if (this.isMediaLayer()) {
|
|
5355
|
+
throw new Error('Media layers do not have associated textures');
|
|
5356
|
+
}
|
|
5357
|
+
if (!this._depthStencilTextures || !this._depthStencilTextures.length) {
|
|
5358
|
+
this._allocateDepthStencilTexturesInternal(this.getTextureType(), this.init);
|
|
5359
|
+
}
|
|
5360
|
+
return this._depthStencilTextures;
|
|
5361
|
+
}
|
|
5362
|
+
get colorTexturesMeta() {
|
|
5363
|
+
if (this.isMediaLayer()) {
|
|
5364
|
+
throw new Error('Media layers do not have associated textures');
|
|
5365
|
+
}
|
|
5366
|
+
if (!this._colorTextures || !this._colorTextures.length) {
|
|
5367
|
+
this._allocateColorTexturesInternal(this.getTextureType(), this.init);
|
|
5368
|
+
}
|
|
5369
|
+
return this._texturesMeta;
|
|
5370
|
+
}
|
|
5371
|
+
}
|
|
5372
|
+
|
|
5373
|
+
const defaultQuadLayerInit = {
|
|
5374
|
+
colorFormat: 0x1908,
|
|
5375
|
+
mipLevels: 1,
|
|
5376
|
+
layout: XRLayerLayout.mono,
|
|
5377
|
+
isStatic: false,
|
|
5378
|
+
space: null,
|
|
5379
|
+
viewPixelHeight: 0,
|
|
5380
|
+
viewPixelWidth: 0,
|
|
5381
|
+
textureType: XRTextureType.texture,
|
|
5382
|
+
width: 1.0,
|
|
5383
|
+
height: 1.0,
|
|
5384
|
+
};
|
|
5385
|
+
const defaultMediaQuadLayerInit = {
|
|
5386
|
+
space: null,
|
|
5387
|
+
layout: XRLayerLayout.mono,
|
|
5388
|
+
invertStereo: false,
|
|
5389
|
+
};
|
|
5390
|
+
class XRQuadLayer extends XRCompositionLayerPolyfill {
|
|
5391
|
+
constructor(init, media) {
|
|
5392
|
+
super();
|
|
5393
|
+
this._media = media !== null && media !== void 0 ? media : null;
|
|
5394
|
+
if (this.isMediaLayer()) {
|
|
5395
|
+
this.init = Object.assign(Object.assign({}, defaultMediaQuadLayerInit), init);
|
|
5396
|
+
}
|
|
5397
|
+
else {
|
|
5398
|
+
this.init = Object.assign(Object.assign({}, defaultQuadLayerInit), init);
|
|
5399
|
+
}
|
|
5400
|
+
this.width = this.init.width;
|
|
5401
|
+
this.height = this.init.height;
|
|
5402
|
+
this.space = this.init.space;
|
|
5403
|
+
this.layout = this.init.layout;
|
|
5404
|
+
const _global = getGlobal();
|
|
5405
|
+
if (this.init.transform) {
|
|
5406
|
+
this.transform = new _global.XRRigidTransform(init.transform.position, init.transform.orientation);
|
|
5407
|
+
}
|
|
5408
|
+
else {
|
|
5409
|
+
this.transform = new _global.XRRigidTransform({
|
|
5410
|
+
x: 0,
|
|
5411
|
+
y: 0,
|
|
5412
|
+
z: 0,
|
|
5413
|
+
w: 1,
|
|
5414
|
+
});
|
|
5415
|
+
}
|
|
5416
|
+
if (!this.isMediaLayer()) {
|
|
5417
|
+
this.isStatic = init.isStatic;
|
|
5418
|
+
}
|
|
5419
|
+
}
|
|
5420
|
+
getTextureType() {
|
|
5421
|
+
if (this.isMediaLayer()) {
|
|
5422
|
+
return XRTextureType.texture;
|
|
5423
|
+
}
|
|
5424
|
+
return this.init.textureType;
|
|
5425
|
+
}
|
|
5426
|
+
_deferredInitialize() {
|
|
5427
|
+
let layout = this.determineLayoutAttribute(this.init.textureType, this.context, this.init.layout);
|
|
5428
|
+
this.layout = layout;
|
|
5429
|
+
this.needsRedraw = true;
|
|
5430
|
+
}
|
|
5431
|
+
get colorTextures() {
|
|
5432
|
+
if (this.isMediaLayer()) {
|
|
5433
|
+
throw new Error('Media layers do not have associated textures');
|
|
5434
|
+
}
|
|
5435
|
+
if (!this._colorTextures || !this._colorTextures.length) {
|
|
5436
|
+
this._allocateColorTexturesInternal(this.getTextureType(), this.init);
|
|
5437
|
+
}
|
|
5438
|
+
return this._colorTextures;
|
|
5439
|
+
}
|
|
5440
|
+
get depthStencilTextures() {
|
|
5441
|
+
if (this.isMediaLayer()) {
|
|
5442
|
+
throw new Error('Media layers do not have associated textures');
|
|
5443
|
+
}
|
|
5444
|
+
if (!this._depthStencilTextures || !this._depthStencilTextures.length) {
|
|
5445
|
+
this._allocateDepthStencilTexturesInternal(this.getTextureType(), this.init);
|
|
5446
|
+
}
|
|
5447
|
+
return this._depthStencilTextures;
|
|
5448
|
+
}
|
|
5449
|
+
get colorTexturesMeta() {
|
|
5450
|
+
if (this.isMediaLayer()) {
|
|
5451
|
+
throw new Error('Media layers do not have associated textures');
|
|
5452
|
+
}
|
|
5453
|
+
if (!this._colorTextures || !this._colorTextures.length) {
|
|
5454
|
+
this._allocateColorTexturesInternal(this.getTextureType(), this.init);
|
|
5455
|
+
}
|
|
5456
|
+
return this._texturesMeta;
|
|
5457
|
+
}
|
|
5458
|
+
}
|
|
5459
|
+
|
|
5460
|
+
class XRMediaBindingPolyfill {
|
|
5461
|
+
constructor(session) {
|
|
5462
|
+
this.session = session;
|
|
5463
|
+
if (this.session.ended) {
|
|
5464
|
+
throw new Error('Session has ended');
|
|
5465
|
+
}
|
|
5466
|
+
}
|
|
5467
|
+
createQuadLayer(video, init) {
|
|
5468
|
+
if (this.session.ended) {
|
|
5469
|
+
throw new Error('Session has ended');
|
|
5470
|
+
}
|
|
5471
|
+
if (init.layout === XRLayerLayout.default) {
|
|
5472
|
+
throw new TypeError('Media Quad layer cannot be created with layout of default');
|
|
5473
|
+
}
|
|
5474
|
+
let aspectRatio = this.calculateAspectRatio(video, init.layout);
|
|
5475
|
+
if (init.width === undefined && init.height === undefined) {
|
|
5476
|
+
init.width = 1;
|
|
5477
|
+
}
|
|
5478
|
+
if (init.height === undefined) {
|
|
5479
|
+
init.height = init.width / aspectRatio;
|
|
5480
|
+
}
|
|
5481
|
+
if (init.width === undefined) {
|
|
5482
|
+
init.width = init.height / aspectRatio;
|
|
5483
|
+
}
|
|
5484
|
+
let layer = new XRQuadLayer(init, video);
|
|
5485
|
+
layer.needsRedraw = false;
|
|
5486
|
+
layer.initialize(this.session);
|
|
5487
|
+
return layer;
|
|
5488
|
+
}
|
|
5489
|
+
createCylinderLayer(video, init) {
|
|
5490
|
+
if (this.session.ended) {
|
|
5491
|
+
throw new Error('Session has ended');
|
|
5492
|
+
}
|
|
5493
|
+
if (init.layout === XRLayerLayout.default) {
|
|
5494
|
+
throw new TypeError('Media Cylinder layer cannot be created with layout of default');
|
|
5495
|
+
}
|
|
5496
|
+
let aspectRatio = this.calculateAspectRatio(video, init.layout);
|
|
5497
|
+
if (init.aspectRatio === undefined) {
|
|
5498
|
+
init.aspectRatio = aspectRatio;
|
|
5499
|
+
}
|
|
5500
|
+
let layer = new XRCylinderLayer(init, video);
|
|
5501
|
+
layer.needsRedraw = false;
|
|
5502
|
+
layer.initialize(this.session);
|
|
5503
|
+
return layer;
|
|
5504
|
+
}
|
|
5505
|
+
createEquirectLayer(video, init) {
|
|
5506
|
+
if (this.session.ended) {
|
|
5507
|
+
throw new Error('Session has ended');
|
|
5508
|
+
}
|
|
5509
|
+
if (init.layout === XRLayerLayout.default) {
|
|
5510
|
+
throw new TypeError('Media Equirect layer cannot be created with layout of default');
|
|
5511
|
+
}
|
|
5512
|
+
if (!isReferenceSpace(init.space)) {
|
|
5513
|
+
throw new Error("Media Equirect layer's space must be of type XRReferenceSpace");
|
|
5514
|
+
}
|
|
5515
|
+
let layer = new XREquirectLayer(init, video);
|
|
5516
|
+
layer.needsRedraw = false;
|
|
5517
|
+
layer.initialize(this.session);
|
|
5518
|
+
return layer;
|
|
5519
|
+
}
|
|
5520
|
+
calculateAspectRatio(video, layout) {
|
|
5521
|
+
let width = video.videoWidth;
|
|
5522
|
+
let height = video.videoHeight;
|
|
5523
|
+
if (layout === XRLayerLayout['stereo-left-right']) {
|
|
5524
|
+
width /= 2;
|
|
5525
|
+
}
|
|
5526
|
+
if (layout === XRLayerLayout['stereo-top-bottom']) {
|
|
5527
|
+
height /= 2;
|
|
5528
|
+
}
|
|
5529
|
+
return width / height;
|
|
5530
|
+
}
|
|
5531
|
+
}
|
|
5532
|
+
|
|
5533
|
+
const defaultXRProjectionLayerInit = {
|
|
5534
|
+
textureType: XRTextureType.texture,
|
|
5535
|
+
colorFormat: 0x1908,
|
|
5536
|
+
depthFormat: 0x1902,
|
|
5537
|
+
scaleFactor: 1.0,
|
|
5538
|
+
};
|
|
5539
|
+
class XRProjectionLayer extends XRCompositionLayerPolyfill {
|
|
5540
|
+
constructor(init = defaultXRProjectionLayerInit) {
|
|
5541
|
+
super();
|
|
5542
|
+
this.init = Object.assign(Object.assign({}, defaultXRProjectionLayerInit), init);
|
|
5543
|
+
}
|
|
5544
|
+
initialize(session, context) {
|
|
5545
|
+
super.initialize(session, context);
|
|
5546
|
+
this.initializeIfNeeded();
|
|
5547
|
+
let baseLayer = session.getBaseLayer();
|
|
5548
|
+
this.textureWidth = baseLayer.framebufferWidth * this.init.scaleFactor;
|
|
5549
|
+
this.textureHeight = baseLayer.framebufferHeight * this.init.scaleFactor;
|
|
5550
|
+
}
|
|
5551
|
+
_allocateProjectionColorTextures() {
|
|
5552
|
+
let array = [];
|
|
5553
|
+
let polyFillArray = [];
|
|
5554
|
+
const createTextureArray = () => {
|
|
5555
|
+
array = [];
|
|
5556
|
+
for (let tex of polyFillArray) {
|
|
5557
|
+
array.push(tex.texture);
|
|
5558
|
+
}
|
|
5559
|
+
};
|
|
5560
|
+
let session = this.session;
|
|
5561
|
+
let views = session.internalViews;
|
|
5562
|
+
if (!views || views.length === 0) {
|
|
5563
|
+
console.warn("We can't allocate color textures without views");
|
|
5564
|
+
return;
|
|
5565
|
+
}
|
|
5566
|
+
let baseLayer = session.getBaseLayer();
|
|
5567
|
+
let numViews = views.length;
|
|
5568
|
+
let width = baseLayer.framebufferWidth * this.init.scaleFactor / views.length;
|
|
5569
|
+
let height = baseLayer.framebufferHeight * this.init.scaleFactor;
|
|
5570
|
+
if (this.layout === XRLayerLayout.mono || this.layout === XRLayerLayout.default) {
|
|
5571
|
+
if (this.init.textureType === XRTextureType['texture-array']) {
|
|
5572
|
+
let texture = this._createNewColorTexture(width, height, XRTextureType['texture-array'], this.init.colorFormat, numViews);
|
|
5573
|
+
polyFillArray = [texture];
|
|
5574
|
+
}
|
|
5575
|
+
else {
|
|
5576
|
+
for (let view of views) {
|
|
5577
|
+
let texture = this._createNewColorTexture(width, height, XRTextureType.texture, this.init.colorFormat);
|
|
5578
|
+
polyFillArray.push(texture);
|
|
5579
|
+
}
|
|
5580
|
+
}
|
|
5581
|
+
createTextureArray();
|
|
5582
|
+
this._colorTexturesMeta = polyFillArray;
|
|
5583
|
+
this._colorTextures = array;
|
|
5584
|
+
return;
|
|
5585
|
+
}
|
|
5586
|
+
if (this.layout === XRLayerLayout['stereo-left-right']) {
|
|
5587
|
+
let texture = this._createNewColorTexture(width * numViews, height, this.init.textureType, this.init.colorFormat);
|
|
5588
|
+
polyFillArray = [texture];
|
|
5589
|
+
}
|
|
5590
|
+
else if (this.layout === XRLayerLayout['stereo-top-bottom']) {
|
|
5591
|
+
let texture = this._createNewColorTexture(width, height * numViews, this.init.textureType, this.init.colorFormat);
|
|
5592
|
+
polyFillArray = [texture];
|
|
5593
|
+
}
|
|
5594
|
+
createTextureArray();
|
|
5595
|
+
this._colorTexturesMeta = polyFillArray;
|
|
5596
|
+
this._colorTextures = array;
|
|
5597
|
+
return;
|
|
5598
|
+
}
|
|
5599
|
+
_allocateProjectionDepthStencilTextures() {
|
|
5600
|
+
let session = this.session;
|
|
5601
|
+
let views = session.internalViews;
|
|
5602
|
+
if (!views || views.length === 0) {
|
|
5603
|
+
return;
|
|
5604
|
+
}
|
|
5605
|
+
if (this.init.depthFormat === 0) {
|
|
5606
|
+
this._depthStencilTextures = [];
|
|
5607
|
+
return;
|
|
5608
|
+
}
|
|
5609
|
+
if (this.context instanceof WebGLRenderingContext) {
|
|
5610
|
+
let depthExtension = this.context.getExtension('WEBGL_depth_texture');
|
|
5611
|
+
if (!depthExtension) {
|
|
5612
|
+
this._depthStencilTextures = [];
|
|
5613
|
+
return;
|
|
5614
|
+
}
|
|
5615
|
+
}
|
|
5616
|
+
let array = [];
|
|
5617
|
+
let polyFillArray = [];
|
|
5618
|
+
const createTextureArray = () => {
|
|
5619
|
+
array = [];
|
|
5620
|
+
for (let tex of polyFillArray) {
|
|
5621
|
+
array.push(tex.texture);
|
|
5622
|
+
}
|
|
5623
|
+
};
|
|
5624
|
+
this.initializeIfNeeded();
|
|
5625
|
+
let baseLayer = session.getBaseLayer();
|
|
5626
|
+
let numViews = views.length;
|
|
5627
|
+
let width = baseLayer.framebufferWidth * this.init.scaleFactor / views.length;
|
|
5628
|
+
let height = baseLayer.framebufferHeight * this.init.scaleFactor;
|
|
5629
|
+
if (this.layout === XRLayerLayout.mono || this.layout === XRLayerLayout.default) {
|
|
5630
|
+
if (this.init.textureType === XRTextureType['texture-array']) {
|
|
5631
|
+
let texture = this._createNewDepthStencilTexture(width, height, this.init.textureType, this.init.depthFormat, numViews);
|
|
5632
|
+
polyFillArray = [texture];
|
|
5633
|
+
}
|
|
5634
|
+
else {
|
|
5635
|
+
for (let view of views) {
|
|
5636
|
+
let texture = this._createNewDepthStencilTexture(width, height, this.init.textureType, this.init.depthFormat);
|
|
5637
|
+
polyFillArray.push(texture);
|
|
5638
|
+
}
|
|
5639
|
+
}
|
|
5640
|
+
createTextureArray();
|
|
5641
|
+
this._depthStencilTextures = array;
|
|
5642
|
+
return;
|
|
5643
|
+
}
|
|
5644
|
+
if (this.layout === XRLayerLayout['stereo-left-right']) {
|
|
5645
|
+
let texture = this._createNewDepthStencilTexture(width * numViews, height, this.init.textureType, this.init.depthFormat);
|
|
5646
|
+
polyFillArray = [texture];
|
|
5647
|
+
}
|
|
5648
|
+
else if (this.layout === XRLayerLayout['stereo-top-bottom']) {
|
|
5649
|
+
let texture = this._createNewDepthStencilTexture(width, height * numViews, this.init.textureType, this.init.depthFormat);
|
|
5650
|
+
polyFillArray = [texture];
|
|
5651
|
+
}
|
|
5652
|
+
createTextureArray();
|
|
5653
|
+
this._depthStencilTextures = array;
|
|
5654
|
+
return;
|
|
5655
|
+
}
|
|
5656
|
+
get colorTextures() {
|
|
5657
|
+
if (!this._colorTextures || !this._colorTextures.length) {
|
|
5658
|
+
this._allocateProjectionColorTextures();
|
|
5659
|
+
}
|
|
5660
|
+
return this._colorTextures;
|
|
5661
|
+
}
|
|
5662
|
+
get depthStencilTextures() {
|
|
5663
|
+
if (this._depthStencilTextures === undefined) {
|
|
5664
|
+
this._allocateProjectionDepthStencilTextures();
|
|
5665
|
+
}
|
|
5666
|
+
return this._depthStencilTextures || [];
|
|
5667
|
+
}
|
|
5668
|
+
get colorTexturesMeta() {
|
|
5669
|
+
if (!this._colorTextures || !this._colorTextures.length) {
|
|
5670
|
+
this._allocateProjectionColorTextures();
|
|
5671
|
+
}
|
|
5672
|
+
return this._colorTexturesMeta;
|
|
5673
|
+
}
|
|
5674
|
+
getTextureType() {
|
|
5675
|
+
return this.init.textureType;
|
|
5676
|
+
}
|
|
5677
|
+
_deferredInitialize() {
|
|
5678
|
+
this.isStatic = false;
|
|
5679
|
+
this.ignoreDepthValues = false;
|
|
5680
|
+
this.fixedFoveation = 0;
|
|
5681
|
+
let layout = this.determineLayoutAttribute(this.init.textureType, this.context, XRLayerLayout.default);
|
|
5682
|
+
this.layout = layout;
|
|
5683
|
+
this.needsRedraw = true;
|
|
5684
|
+
let maxScaleFactor = this.determineMaximumScaleFactor();
|
|
5685
|
+
let scaleFactor = Math.min(this.init.scaleFactor, maxScaleFactor);
|
|
5686
|
+
this.init.scaleFactor = scaleFactor;
|
|
5687
|
+
}
|
|
5688
|
+
determineMaximumScaleFactor() {
|
|
5689
|
+
let baseLayer = this.session.getBaseLayer(this.context);
|
|
5690
|
+
let largestWidth = baseLayer.framebufferWidth;
|
|
5691
|
+
let largestHeight = baseLayer.framebufferHeight;
|
|
5692
|
+
if (this.layout === XRLayerLayout['stereo-left-right']) {
|
|
5693
|
+
largestWidth *= 2;
|
|
5694
|
+
}
|
|
5695
|
+
if (this.layout === XRLayerLayout['stereo-top-bottom']) {
|
|
5696
|
+
largestHeight *= 2;
|
|
5697
|
+
}
|
|
5698
|
+
let largestViewDimension = Math.max(largestWidth, largestHeight);
|
|
5699
|
+
let largestTextureDimension = this.context.getParameter(this.context.MAX_TEXTURE_SIZE);
|
|
5700
|
+
return largestTextureDimension / largestViewDimension;
|
|
5701
|
+
}
|
|
5702
|
+
}
|
|
5703
|
+
|
|
5704
|
+
const initializeViewport = (viewport, texture, layout, offset, numViews) => {
|
|
5705
|
+
let x = 0;
|
|
5706
|
+
let y = 0;
|
|
5707
|
+
let width = texture.width;
|
|
5708
|
+
let height = texture.height;
|
|
5709
|
+
if (layout === XRLayerLayout['stereo-left-right']) {
|
|
5710
|
+
x = (texture.width * offset) / numViews;
|
|
5711
|
+
width = texture.width / numViews;
|
|
5712
|
+
}
|
|
5713
|
+
else if (layout === XRLayerLayout['stereo-top-bottom']) {
|
|
5714
|
+
y = (texture.height * offset) / numViews;
|
|
5715
|
+
height = texture.height / numViews;
|
|
5716
|
+
}
|
|
5717
|
+
viewport.x = x;
|
|
5718
|
+
viewport.y = y;
|
|
5719
|
+
viewport.width = width;
|
|
5720
|
+
viewport.height = height;
|
|
5721
|
+
};
|
|
5722
|
+
|
|
5723
|
+
const compileShader = (gl, shaderSource, shaderType) => {
|
|
5724
|
+
var shader = gl.createShader(shaderType);
|
|
5725
|
+
gl.shaderSource(shader, shaderSource);
|
|
5726
|
+
gl.compileShader(shader);
|
|
5727
|
+
var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
|
|
5728
|
+
if (!success) {
|
|
5729
|
+
throw 'could not compile shader:' + gl.getShaderInfoLog(shader);
|
|
5730
|
+
}
|
|
5731
|
+
return shader;
|
|
5732
|
+
};
|
|
5733
|
+
const createProgram = (gl, vertexShader, fragmentShader) => {
|
|
5734
|
+
const program = gl.createProgram();
|
|
5735
|
+
const compiledVS = compileShader(gl, vertexShader, gl.VERTEX_SHADER);
|
|
5736
|
+
const compiledFS = compileShader(gl, fragmentShader, gl.FRAGMENT_SHADER);
|
|
5737
|
+
gl.attachShader(program, compiledVS);
|
|
5738
|
+
gl.attachShader(program, compiledFS);
|
|
5739
|
+
gl.deleteShader(compiledVS);
|
|
5740
|
+
gl.deleteShader(compiledFS);
|
|
5741
|
+
gl.linkProgram(program);
|
|
5742
|
+
var success = gl.getProgramParameter(program, gl.LINK_STATUS);
|
|
5743
|
+
if (!success) {
|
|
5744
|
+
throw 'program failed to link:' + gl.getProgramInfoLog(program);
|
|
5745
|
+
}
|
|
5746
|
+
return program;
|
|
5747
|
+
};
|
|
5748
|
+
const setRectangle = (gl, x, y, width, height) => {
|
|
5749
|
+
var x1 = x;
|
|
5750
|
+
var x2 = x + width;
|
|
5751
|
+
var y1 = y;
|
|
5752
|
+
var y2 = y + height;
|
|
5753
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2]), gl.DYNAMIC_DRAW);
|
|
5754
|
+
};
|
|
5755
|
+
const applyVAOExtension = (gl) => {
|
|
5756
|
+
if (gl instanceof WebGL2RenderingContext) {
|
|
5757
|
+
return gl;
|
|
5758
|
+
}
|
|
5759
|
+
const ext = gl.getExtension('OES_vertex_array_object');
|
|
5760
|
+
if (!ext) {
|
|
5761
|
+
throw new Error('Cannot use VAOs.');
|
|
5762
|
+
}
|
|
5763
|
+
return {
|
|
5764
|
+
VERTEX_ARRAY_BINDING: ext.VERTEX_ARRAY_BINDING_OES,
|
|
5765
|
+
bindVertexArray: ext.bindVertexArrayOES.bind(ext),
|
|
5766
|
+
createVertexArray: ext.createVertexArrayOES.bind(ext),
|
|
5767
|
+
deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),
|
|
5768
|
+
isVertexArray: ext.isVertexArrayOES.bind(ext),
|
|
5769
|
+
};
|
|
5770
|
+
};
|
|
5771
|
+
|
|
5772
|
+
const glsl = (x) => x;
|
|
5773
|
+
const vertexShader = glsl `
|
|
5774
|
+
attribute vec2 a_position;
|
|
5775
|
+
attribute vec2 a_texCoord;
|
|
5776
|
+
|
|
5777
|
+
varying vec2 v_texCoord;
|
|
5778
|
+
|
|
5779
|
+
void main() {
|
|
5780
|
+
// convert the rectangle from pixels to 0.0 to 1.0
|
|
5781
|
+
vec2 zeroToOne = a_position;
|
|
5782
|
+
|
|
5783
|
+
// convert from 0->1 to 0->2
|
|
5784
|
+
vec2 zeroToTwo = zeroToOne * 2.0;
|
|
5785
|
+
|
|
5786
|
+
// convert from 0->2 to -1->+1 (clipspace)
|
|
5787
|
+
vec2 clipSpace = zeroToTwo - 1.0;
|
|
5788
|
+
|
|
5789
|
+
gl_Position = vec4(clipSpace * vec2(1, 1), 0, 1);
|
|
5790
|
+
|
|
5791
|
+
// pass the texCoord to the fragment shader
|
|
5792
|
+
// The GPU will interpolate this value between points.
|
|
5793
|
+
v_texCoord = a_texCoord;
|
|
5794
|
+
}
|
|
5795
|
+
`;
|
|
5796
|
+
const fragmentShader = glsl `
|
|
5797
|
+
precision mediump float;
|
|
5798
|
+
|
|
5799
|
+
// our texture
|
|
5800
|
+
uniform sampler2D u_image;
|
|
5801
|
+
|
|
5802
|
+
// the texCoords passed in from the vertex shader.
|
|
5803
|
+
varying vec2 v_texCoord;
|
|
5804
|
+
|
|
5805
|
+
void main() {
|
|
5806
|
+
vec4 tex = texture2D(u_image, v_texCoord);
|
|
5807
|
+
gl_FragColor = vec4(tex.rgb, tex.a);
|
|
5808
|
+
}
|
|
5809
|
+
`;
|
|
5810
|
+
class ProjectionRenderer {
|
|
5811
|
+
constructor(layer, context) {
|
|
5812
|
+
this.gl = context;
|
|
5813
|
+
this.layer = layer;
|
|
5814
|
+
this.program = createProgram(this.gl, vertexShader, fragmentShader);
|
|
5815
|
+
this.programInfo = {
|
|
5816
|
+
attribLocations: {
|
|
5817
|
+
a_position: this.gl.getAttribLocation(this.program, 'a_position'),
|
|
5818
|
+
a_texCoord: this.gl.getAttribLocation(this.program, 'a_texCoord'),
|
|
5819
|
+
},
|
|
5820
|
+
};
|
|
5821
|
+
this._createVAOs();
|
|
5822
|
+
}
|
|
5823
|
+
render(session) {
|
|
5824
|
+
let gl = this.gl;
|
|
5825
|
+
let baseLayer = session.getBaseLayer();
|
|
5826
|
+
gl.viewport(0, 0, baseLayer.framebufferWidth, baseLayer.framebufferHeight);
|
|
5827
|
+
const textureType = this.layer.getTextureType();
|
|
5828
|
+
const existingTextureBinding = gl.getParameter(gl.TEXTURE_BINDING_2D);
|
|
5829
|
+
const existingActiveTexture = gl.getParameter(gl.ACTIVE_TEXTURE);
|
|
5830
|
+
if (textureType === XRTextureType.texture) {
|
|
5831
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
5832
|
+
gl.bindTexture(gl.TEXTURE_2D, this.layer.colorTextures[0]);
|
|
5833
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
5834
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
5835
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
5836
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
5837
|
+
}
|
|
5838
|
+
else {
|
|
5839
|
+
throw new Error(`Created a texture projection renderer instead of a texture-array projection renderer for a texture-array layer.
|
|
5840
|
+
This is probably an error with the polyfill itself; please file an issue on Github if you run into this.`);
|
|
5841
|
+
}
|
|
5842
|
+
for (let view of session.internalViews) {
|
|
5843
|
+
let viewport = baseLayer.getViewport(view);
|
|
5844
|
+
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
|
|
5845
|
+
if (this._shouldUseStereoTexturePoints()) {
|
|
5846
|
+
this._renderInternalStereo(view);
|
|
5847
|
+
}
|
|
5848
|
+
else {
|
|
5849
|
+
this._renderInternal();
|
|
5850
|
+
}
|
|
5851
|
+
}
|
|
5852
|
+
gl.activeTexture(existingActiveTexture);
|
|
5853
|
+
gl.bindTexture(gl.TEXTURE_2D, existingTextureBinding);
|
|
5854
|
+
}
|
|
5855
|
+
_renderInternal() {
|
|
5856
|
+
let gl = this.gl;
|
|
5857
|
+
const existingProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
5858
|
+
gl.useProgram(this.program);
|
|
5859
|
+
this.vaoGl.bindVertexArray(this.vao);
|
|
5860
|
+
var primitiveType = gl.TRIANGLES;
|
|
5861
|
+
var offset = 0;
|
|
5862
|
+
var count = 6;
|
|
5863
|
+
gl.drawArrays(primitiveType, offset, count);
|
|
5864
|
+
this.vaoGl.bindVertexArray(null);
|
|
5865
|
+
gl.useProgram(existingProgram);
|
|
5866
|
+
}
|
|
5867
|
+
_renderInternalStereo(view) {
|
|
5868
|
+
if (view.eye === 'none') {
|
|
5869
|
+
return this._renderInternal();
|
|
5870
|
+
}
|
|
5871
|
+
let gl = this.gl;
|
|
5872
|
+
this.vaoGl.bindVertexArray(this.vao);
|
|
5873
|
+
const existingProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
5874
|
+
gl.useProgram(this.program);
|
|
5875
|
+
this._setStereoTextureBuffer(view.eye === 'right' ? 1 : 0);
|
|
5876
|
+
var primitiveType = gl.TRIANGLES;
|
|
5877
|
+
var offset = 0;
|
|
5878
|
+
var count = 6;
|
|
5879
|
+
gl.drawArrays(primitiveType, offset, count);
|
|
5880
|
+
this.vaoGl.bindVertexArray(null);
|
|
5881
|
+
gl.useProgram(existingProgram);
|
|
5882
|
+
}
|
|
5883
|
+
_createVAOs() {
|
|
5884
|
+
this._createTextureUVs();
|
|
5885
|
+
let gl = this.gl;
|
|
5886
|
+
this.vaoGl = applyVAOExtension(gl);
|
|
5887
|
+
let positionBuffer = gl.createBuffer();
|
|
5888
|
+
this.vao = this.vaoGl.createVertexArray();
|
|
5889
|
+
this.vaoGl.bindVertexArray(this.vao);
|
|
5890
|
+
gl.enableVertexAttribArray(this.programInfo.attribLocations.a_position);
|
|
5891
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
|
5892
|
+
setRectangle(gl, 0, 0, 1.0, 1.0);
|
|
5893
|
+
let size = 2;
|
|
5894
|
+
let type = gl.FLOAT;
|
|
5895
|
+
let normalize = false;
|
|
5896
|
+
let stride = 0;
|
|
5897
|
+
let offset = 0;
|
|
5898
|
+
gl.vertexAttribPointer(this.programInfo.attribLocations.a_position, size, type, normalize, stride, offset);
|
|
5899
|
+
this.texcoordBuffer = gl.createBuffer();
|
|
5900
|
+
gl.enableVertexAttribArray(this.programInfo.attribLocations.a_texCoord);
|
|
5901
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
|
|
5902
|
+
gl.bufferData(gl.ARRAY_BUFFER, this.texturePoints, gl.DYNAMIC_DRAW);
|
|
5903
|
+
gl.vertexAttribPointer(this.programInfo.attribLocations.a_texCoord, size, type, normalize, stride, offset);
|
|
5904
|
+
this.vaoGl.bindVertexArray(null);
|
|
5905
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
5906
|
+
}
|
|
5907
|
+
_setStereoTextureBuffer(index) {
|
|
5908
|
+
let gl = this.gl;
|
|
5909
|
+
gl.enableVertexAttribArray(this.programInfo.attribLocations.a_texCoord);
|
|
5910
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
|
|
5911
|
+
gl.bufferData(gl.ARRAY_BUFFER, this.stereoTexturePoints[index], gl.STATIC_DRAW);
|
|
5912
|
+
var size = 2;
|
|
5913
|
+
var type = gl.FLOAT;
|
|
5914
|
+
var normalize = false;
|
|
5915
|
+
var stride = 0;
|
|
5916
|
+
var offset = 0;
|
|
5917
|
+
gl.vertexAttribPointer(this.programInfo.attribLocations.a_texCoord, size, type, normalize, stride, offset);
|
|
5918
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
5919
|
+
}
|
|
5920
|
+
_createTextureUVs() {
|
|
5921
|
+
this.texturePoints = new Float32Array([
|
|
5922
|
+
0.0,
|
|
5923
|
+
0.0,
|
|
5924
|
+
1.0,
|
|
5925
|
+
0.0,
|
|
5926
|
+
0.0,
|
|
5927
|
+
1.0,
|
|
5928
|
+
0.0,
|
|
5929
|
+
1.0,
|
|
5930
|
+
1.0,
|
|
5931
|
+
0.0,
|
|
5932
|
+
1.0,
|
|
5933
|
+
1.0,
|
|
5934
|
+
]);
|
|
5935
|
+
const viewport = {
|
|
5936
|
+
x: 0,
|
|
5937
|
+
y: 0,
|
|
5938
|
+
width: 1,
|
|
5939
|
+
height: 1,
|
|
5940
|
+
};
|
|
5941
|
+
if (this._shouldUseStereoTexturePoints()) {
|
|
5942
|
+
this.stereoTexturePoints = [];
|
|
5943
|
+
initializeViewport(viewport, this.layer.colorTexturesMeta[0], this.layer.layout, 0, 2);
|
|
5944
|
+
this.stereoTexturePoints[0] = this._offsetTextureUVsByRect(this.layer.colorTexturesMeta[0], this.texturePoints, viewport);
|
|
5945
|
+
initializeViewport(viewport, this.layer.colorTexturesMeta[0], this.layer.layout, 1, 2);
|
|
5946
|
+
this.stereoTexturePoints[1] = this._offsetTextureUVsByRect(this.layer.colorTexturesMeta[0], this.texturePoints, viewport);
|
|
5947
|
+
}
|
|
5948
|
+
}
|
|
5949
|
+
_offsetTextureUVsByRect(texture, inArray, textureRect) {
|
|
5950
|
+
textureRect = textureRect !== null && textureRect !== void 0 ? textureRect : {
|
|
5951
|
+
x: 0,
|
|
5952
|
+
y: 0,
|
|
5953
|
+
width: texture.width,
|
|
5954
|
+
height: texture.height,
|
|
5955
|
+
};
|
|
5956
|
+
const uX = textureRect.x / texture.width;
|
|
5957
|
+
const vY = textureRect.y / texture.height;
|
|
5958
|
+
const uW = textureRect.width / texture.width;
|
|
5959
|
+
const vH = textureRect.height / texture.height;
|
|
5960
|
+
const outArray = [];
|
|
5961
|
+
for (let i = 0; i < inArray.length; i += 2) {
|
|
5962
|
+
let u = inArray[i];
|
|
5963
|
+
let v = inArray[i + 1];
|
|
5964
|
+
let newU = u * uW + uX;
|
|
5965
|
+
let newV = v * vH + vY;
|
|
5966
|
+
outArray[i] = newU;
|
|
5967
|
+
outArray[i + 1] = newV;
|
|
5968
|
+
}
|
|
5969
|
+
return new Float32Array(outArray);
|
|
5970
|
+
}
|
|
5971
|
+
_shouldUseStereoTexturePoints() {
|
|
5972
|
+
return (this.layer.layout === XRLayerLayout['stereo-left-right'] ||
|
|
5973
|
+
this.layer.layout === XRLayerLayout['stereo-top-bottom']);
|
|
5974
|
+
}
|
|
5975
|
+
}
|
|
5976
|
+
const texArrayVertexShader = glsl `#version 300 es
|
|
5977
|
+
|
|
5978
|
+
in vec2 a_position;
|
|
5979
|
+
in vec2 a_texCoord;
|
|
5980
|
+
|
|
5981
|
+
out vec2 v_texCoord;
|
|
5982
|
+
|
|
5983
|
+
void main() {
|
|
5984
|
+
// convert the rectangle from pixels to 0.0 to 1.0
|
|
5985
|
+
vec2 zeroToOne = a_position;
|
|
5986
|
+
|
|
5987
|
+
// convert from 0->1 to 0->2
|
|
5988
|
+
vec2 zeroToTwo = zeroToOne * 2.0;
|
|
5989
|
+
|
|
5990
|
+
// convert from 0->2 to -1->+1 (clipspace)
|
|
5991
|
+
vec2 clipSpace = zeroToTwo - 1.0;
|
|
5992
|
+
|
|
5993
|
+
gl_Position = vec4(clipSpace * vec2(1, 1), 0, 1);
|
|
5994
|
+
|
|
5995
|
+
// pass the texCoord to the fragment shader
|
|
5996
|
+
// The GPU will interpolate this value between points.
|
|
5997
|
+
v_texCoord = a_texCoord;
|
|
5998
|
+
}
|
|
5999
|
+
`;
|
|
6000
|
+
const texArrayFragmentShader = glsl `#version 300 es
|
|
6001
|
+
precision mediump float;
|
|
6002
|
+
precision mediump int;
|
|
6003
|
+
precision mediump sampler2DArray;
|
|
6004
|
+
|
|
6005
|
+
uniform sampler2DArray u_image;
|
|
6006
|
+
uniform int u_layer;
|
|
6007
|
+
|
|
6008
|
+
in vec2 v_texCoord;
|
|
6009
|
+
|
|
6010
|
+
out vec4 fragColor;
|
|
6011
|
+
|
|
6012
|
+
void main() {
|
|
6013
|
+
vec4 tex = texture(u_image, vec3(v_texCoord.x, v_texCoord.y, u_layer));
|
|
6014
|
+
fragColor = vec4(tex.rgb, tex.a);
|
|
6015
|
+
}
|
|
6016
|
+
|
|
6017
|
+
`;
|
|
6018
|
+
class ProjectionTextureArrayRenderer extends ProjectionRenderer {
|
|
6019
|
+
constructor(layer, context) {
|
|
6020
|
+
super(layer, context);
|
|
6021
|
+
this.program = createProgram(this.gl, texArrayVertexShader, texArrayFragmentShader);
|
|
6022
|
+
this._createVAOs();
|
|
6023
|
+
this.u_layerInfo = this.gl.getUniformLocation(this.program, 'u_layer');
|
|
6024
|
+
}
|
|
6025
|
+
render(session) {
|
|
6026
|
+
let gl = this.gl;
|
|
6027
|
+
let textureType = this.layer.getTextureType();
|
|
6028
|
+
if (textureType === XRTextureType.texture) {
|
|
6029
|
+
throw new Error('Using texture array projection renderer on a layer without texture array.');
|
|
6030
|
+
}
|
|
6031
|
+
let baseLayer = session.getBaseLayer();
|
|
6032
|
+
const existingTextureBinding = gl.getParameter(gl.TEXTURE_BINDING_2D_ARRAY);
|
|
6033
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.layer.colorTextures[0]);
|
|
6034
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
6035
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
6036
|
+
for (let view of session.internalViews) {
|
|
6037
|
+
let index = session.getViewIndex(view);
|
|
6038
|
+
let viewport = baseLayer.getViewport(view);
|
|
6039
|
+
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
|
|
6040
|
+
this._renderInternal(index);
|
|
6041
|
+
}
|
|
6042
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, existingTextureBinding);
|
|
6043
|
+
}
|
|
6044
|
+
_renderInternal(layer = 0) {
|
|
6045
|
+
let gl = this.gl;
|
|
6046
|
+
const existingProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
6047
|
+
gl.useProgram(this.program);
|
|
6048
|
+
gl.bindVertexArray(this.vao);
|
|
6049
|
+
gl.uniform1i(this.u_layerInfo, layer);
|
|
6050
|
+
var primitiveType = gl.TRIANGLES;
|
|
6051
|
+
var offset = 0;
|
|
6052
|
+
var count = 6;
|
|
6053
|
+
gl.drawArrays(primitiveType, offset, count);
|
|
6054
|
+
gl.bindVertexArray(null);
|
|
6055
|
+
gl.useProgram(existingProgram);
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
6058
|
+
const createProjectionRenderer = (layer, context) => {
|
|
6059
|
+
if (layer.getTextureType() === XRTextureType['texture-array']) {
|
|
6060
|
+
if (context instanceof WebGL2RenderingContext) {
|
|
6061
|
+
return new ProjectionTextureArrayRenderer(layer, context);
|
|
6062
|
+
}
|
|
6063
|
+
}
|
|
6064
|
+
return new ProjectionRenderer(layer, context);
|
|
6065
|
+
};
|
|
6066
|
+
|
|
6067
|
+
var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array;
|
|
6068
|
+
if (!Math.hypot) Math.hypot = function () {
|
|
6069
|
+
var y = 0,
|
|
6070
|
+
i = arguments.length;
|
|
6071
|
+
while (i--) {
|
|
6072
|
+
y += arguments[i] * arguments[i];
|
|
6073
|
+
}
|
|
6074
|
+
return Math.sqrt(y);
|
|
6075
|
+
};
|
|
6076
|
+
|
|
6077
|
+
function create() {
|
|
6078
|
+
var out = new ARRAY_TYPE(16);
|
|
6079
|
+
if (ARRAY_TYPE != Float32Array) {
|
|
6080
|
+
out[1] = 0;
|
|
6081
|
+
out[2] = 0;
|
|
6082
|
+
out[3] = 0;
|
|
6083
|
+
out[4] = 0;
|
|
6084
|
+
out[6] = 0;
|
|
6085
|
+
out[7] = 0;
|
|
6086
|
+
out[8] = 0;
|
|
6087
|
+
out[9] = 0;
|
|
6088
|
+
out[11] = 0;
|
|
6089
|
+
out[12] = 0;
|
|
6090
|
+
out[13] = 0;
|
|
6091
|
+
out[14] = 0;
|
|
6092
|
+
}
|
|
6093
|
+
out[0] = 1;
|
|
6094
|
+
out[5] = 1;
|
|
6095
|
+
out[10] = 1;
|
|
6096
|
+
out[15] = 1;
|
|
6097
|
+
return out;
|
|
6098
|
+
}
|
|
6099
|
+
function multiply(out, a, b) {
|
|
6100
|
+
var a00 = a[0],
|
|
6101
|
+
a01 = a[1],
|
|
6102
|
+
a02 = a[2],
|
|
6103
|
+
a03 = a[3];
|
|
6104
|
+
var a10 = a[4],
|
|
6105
|
+
a11 = a[5],
|
|
6106
|
+
a12 = a[6],
|
|
6107
|
+
a13 = a[7];
|
|
6108
|
+
var a20 = a[8],
|
|
6109
|
+
a21 = a[9],
|
|
6110
|
+
a22 = a[10],
|
|
6111
|
+
a23 = a[11];
|
|
6112
|
+
var a30 = a[12],
|
|
6113
|
+
a31 = a[13],
|
|
6114
|
+
a32 = a[14],
|
|
6115
|
+
a33 = a[15];
|
|
6116
|
+
var b0 = b[0],
|
|
6117
|
+
b1 = b[1],
|
|
6118
|
+
b2 = b[2],
|
|
6119
|
+
b3 = b[3];
|
|
6120
|
+
out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
6121
|
+
out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
6122
|
+
out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
6123
|
+
out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
6124
|
+
b0 = b[4];
|
|
6125
|
+
b1 = b[5];
|
|
6126
|
+
b2 = b[6];
|
|
6127
|
+
b3 = b[7];
|
|
6128
|
+
out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
6129
|
+
out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
6130
|
+
out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
6131
|
+
out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
6132
|
+
b0 = b[8];
|
|
6133
|
+
b1 = b[9];
|
|
6134
|
+
b2 = b[10];
|
|
6135
|
+
b3 = b[11];
|
|
6136
|
+
out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
6137
|
+
out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
6138
|
+
out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
6139
|
+
out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
6140
|
+
b0 = b[12];
|
|
6141
|
+
b1 = b[13];
|
|
6142
|
+
b2 = b[14];
|
|
6143
|
+
b3 = b[15];
|
|
6144
|
+
out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
|
6145
|
+
out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
|
6146
|
+
out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
|
6147
|
+
out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
|
6148
|
+
return out;
|
|
6149
|
+
}
|
|
6150
|
+
function fromQuat(out, q) {
|
|
6151
|
+
var x = q[0],
|
|
6152
|
+
y = q[1],
|
|
6153
|
+
z = q[2],
|
|
6154
|
+
w = q[3];
|
|
6155
|
+
var x2 = x + x;
|
|
6156
|
+
var y2 = y + y;
|
|
6157
|
+
var z2 = z + z;
|
|
6158
|
+
var xx = x * x2;
|
|
6159
|
+
var yx = y * x2;
|
|
6160
|
+
var yy = y * y2;
|
|
6161
|
+
var zx = z * x2;
|
|
6162
|
+
var zy = z * y2;
|
|
6163
|
+
var zz = z * z2;
|
|
6164
|
+
var wx = w * x2;
|
|
6165
|
+
var wy = w * y2;
|
|
6166
|
+
var wz = w * z2;
|
|
6167
|
+
out[0] = 1 - yy - zz;
|
|
6168
|
+
out[1] = yx + wz;
|
|
6169
|
+
out[2] = zx - wy;
|
|
6170
|
+
out[3] = 0;
|
|
6171
|
+
out[4] = yx - wz;
|
|
6172
|
+
out[5] = 1 - xx - zz;
|
|
6173
|
+
out[6] = zy + wx;
|
|
6174
|
+
out[7] = 0;
|
|
6175
|
+
out[8] = zx + wy;
|
|
6176
|
+
out[9] = zy - wx;
|
|
6177
|
+
out[10] = 1 - xx - yy;
|
|
6178
|
+
out[11] = 0;
|
|
6179
|
+
out[12] = 0;
|
|
6180
|
+
out[13] = 0;
|
|
6181
|
+
out[14] = 0;
|
|
6182
|
+
out[15] = 1;
|
|
6183
|
+
return out;
|
|
6184
|
+
}
|
|
6185
|
+
|
|
6186
|
+
function create$1() {
|
|
6187
|
+
var out = new ARRAY_TYPE(2);
|
|
6188
|
+
if (ARRAY_TYPE != Float32Array) {
|
|
6189
|
+
out[0] = 0;
|
|
6190
|
+
out[1] = 0;
|
|
6191
|
+
}
|
|
6192
|
+
return out;
|
|
6193
|
+
}
|
|
6194
|
+
(function () {
|
|
6195
|
+
var vec = create$1();
|
|
6196
|
+
return function (a, stride, offset, count, fn, arg) {
|
|
6197
|
+
var i, l;
|
|
6198
|
+
if (!stride) {
|
|
6199
|
+
stride = 2;
|
|
6200
|
+
}
|
|
6201
|
+
if (!offset) {
|
|
6202
|
+
offset = 0;
|
|
6203
|
+
}
|
|
6204
|
+
if (count) {
|
|
6205
|
+
l = Math.min(count * stride + offset, a.length);
|
|
6206
|
+
} else {
|
|
6207
|
+
l = a.length;
|
|
6208
|
+
}
|
|
6209
|
+
for (i = offset; i < l; i += stride) {
|
|
6210
|
+
vec[0] = a[i];
|
|
6211
|
+
vec[1] = a[i + 1];
|
|
6212
|
+
fn(vec, vec, arg);
|
|
6213
|
+
a[i] = vec[0];
|
|
6214
|
+
a[i + 1] = vec[1];
|
|
6215
|
+
}
|
|
6216
|
+
return a;
|
|
6217
|
+
};
|
|
6218
|
+
})();
|
|
6219
|
+
|
|
6220
|
+
const glsl$1 = (x) => x;
|
|
6221
|
+
const vertexShader$1 = glsl$1 `
|
|
6222
|
+
attribute vec4 a_position;
|
|
6223
|
+
attribute vec2 a_texCoord;
|
|
6224
|
+
|
|
6225
|
+
uniform mat4 u_matrix;
|
|
6226
|
+
uniform mat4 u_projectionMatrix;
|
|
6227
|
+
|
|
6228
|
+
varying vec2 v_texCoord;
|
|
6229
|
+
|
|
6230
|
+
void main() {
|
|
6231
|
+
// Multiply the position by the matrix.
|
|
6232
|
+
gl_Position = u_projectionMatrix * u_matrix * a_position;
|
|
6233
|
+
|
|
6234
|
+
// pass the texCoord to the fragment shader
|
|
6235
|
+
// The GPU will interpolate this value between points.
|
|
6236
|
+
v_texCoord = a_texCoord;
|
|
6237
|
+
}
|
|
6238
|
+
`;
|
|
6239
|
+
const fragmentShader$1 = glsl$1 `
|
|
6240
|
+
precision mediump float;
|
|
6241
|
+
|
|
6242
|
+
// our texture
|
|
6243
|
+
uniform sampler2D u_image;
|
|
6244
|
+
|
|
6245
|
+
// the texCoords passed in from the vertex shader.
|
|
6246
|
+
varying vec2 v_texCoord;
|
|
6247
|
+
|
|
6248
|
+
void main() {
|
|
6249
|
+
vec4 tex = texture2D(u_image, v_texCoord);
|
|
6250
|
+
gl_FragColor = vec4(tex.rgb, tex.a);
|
|
6251
|
+
// gl_FragColor = vec4(1.0, 0, 0, 1.0);
|
|
6252
|
+
}
|
|
6253
|
+
`;
|
|
6254
|
+
const texArrayVertexShader$1 = glsl$1 `#version 300 es
|
|
6255
|
+
|
|
6256
|
+
in vec4 a_position;
|
|
6257
|
+
in vec2 a_texCoord;
|
|
6258
|
+
|
|
6259
|
+
uniform mat4 u_matrix;
|
|
6260
|
+
uniform mat4 u_projectionMatrix;
|
|
6261
|
+
|
|
6262
|
+
out vec2 v_texCoord;
|
|
6263
|
+
|
|
6264
|
+
void main() {
|
|
6265
|
+
// Multiply the position by the matrix.
|
|
6266
|
+
gl_Position = u_projectionMatrix * u_matrix * a_position;
|
|
6267
|
+
|
|
6268
|
+
// pass the texCoord to the fragment shader
|
|
6269
|
+
// The GPU will interpolate this value between points.
|
|
6270
|
+
v_texCoord = a_texCoord;
|
|
6271
|
+
}
|
|
6272
|
+
`;
|
|
6273
|
+
const texArrayFragmentShader$1 = glsl$1 `#version 300 es
|
|
6274
|
+
precision mediump float;
|
|
6275
|
+
precision mediump int;
|
|
6276
|
+
precision mediump sampler2DArray;
|
|
6277
|
+
|
|
6278
|
+
uniform sampler2DArray u_image;
|
|
6279
|
+
uniform int u_layer;
|
|
6280
|
+
|
|
6281
|
+
in vec2 v_texCoord;
|
|
6282
|
+
|
|
6283
|
+
out vec4 fragColor;
|
|
6284
|
+
|
|
6285
|
+
void main() {
|
|
6286
|
+
vec4 tex = texture(u_image, vec3(v_texCoord.x, v_texCoord.y, u_layer));
|
|
6287
|
+
fragColor = vec4(tex.rgb, tex.a);
|
|
6288
|
+
}
|
|
6289
|
+
|
|
6290
|
+
`;
|
|
6291
|
+
class CompositionLayerRenderer {
|
|
6292
|
+
constructor(layer, context) {
|
|
6293
|
+
this.usesTextureArrayShaders = false;
|
|
6294
|
+
this.savedVaoState = { vao: null, arrayBuffer: null };
|
|
6295
|
+
this.hasMipmap = false;
|
|
6296
|
+
this.gl = context;
|
|
6297
|
+
this.layer = layer;
|
|
6298
|
+
let gl = this.gl;
|
|
6299
|
+
this.transformMatrix = create();
|
|
6300
|
+
if (context instanceof WebGL2RenderingContext &&
|
|
6301
|
+
this.layer.getTextureType() === XRTextureType['texture-array']) {
|
|
6302
|
+
this.usesTextureArrayShaders = true;
|
|
6303
|
+
}
|
|
6304
|
+
if (this.usesTextureArrayShaders) {
|
|
6305
|
+
this.program = createProgram(gl, texArrayVertexShader$1, texArrayFragmentShader$1);
|
|
6306
|
+
}
|
|
6307
|
+
else {
|
|
6308
|
+
this.program = createProgram(gl, vertexShader$1, fragmentShader$1);
|
|
6309
|
+
}
|
|
6310
|
+
this.programInfo = {
|
|
6311
|
+
attribLocations: {
|
|
6312
|
+
a_position: gl.getAttribLocation(this.program, 'a_position'),
|
|
6313
|
+
a_texCoord: gl.getAttribLocation(this.program, 'a_texCoord'),
|
|
6314
|
+
},
|
|
6315
|
+
uniformLocations: {
|
|
6316
|
+
u_matrix: gl.getUniformLocation(this.program, 'u_matrix'),
|
|
6317
|
+
u_projectionMatrix: gl.getUniformLocation(this.program, 'u_projectionMatrix'),
|
|
6318
|
+
},
|
|
6319
|
+
};
|
|
6320
|
+
if (this.usesTextureArrayShaders) {
|
|
6321
|
+
this.programInfo.uniformLocations.u_layer = gl.getUniformLocation(this.program, 'u_layer');
|
|
6322
|
+
}
|
|
6323
|
+
}
|
|
6324
|
+
saveVaoState() {
|
|
6325
|
+
this.savedVaoState.vao = this.gl.getParameter(this.vaoGl.VERTEX_ARRAY_BINDING);
|
|
6326
|
+
this.savedVaoState.arrayBuffer = this.gl.getParameter(this.gl.ARRAY_BUFFER_BINDING);
|
|
6327
|
+
}
|
|
6328
|
+
restoreVaoState() {
|
|
6329
|
+
this.vaoGl.bindVertexArray(this.savedVaoState.vao);
|
|
6330
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.savedVaoState.arrayBuffer);
|
|
6331
|
+
this.savedVaoState.vao = this.savedVaoState.arrayBuffer = null;
|
|
6332
|
+
}
|
|
6333
|
+
initialize() {
|
|
6334
|
+
let gl = this.gl;
|
|
6335
|
+
if (this.layer.isMediaLayer()) {
|
|
6336
|
+
this.mediaTexture = gl.createTexture();
|
|
6337
|
+
this.mediaTexturePolyfill = {
|
|
6338
|
+
texture: this.mediaTexture,
|
|
6339
|
+
textureFormat: gl.RGBA,
|
|
6340
|
+
width: this.layer.media.videoWidth,
|
|
6341
|
+
height: this.layer.media.videoHeight,
|
|
6342
|
+
type: XRTextureType.texture,
|
|
6343
|
+
};
|
|
6344
|
+
const existingTextureBinding = gl.getParameter(gl.TEXTURE_BINDING_2D);
|
|
6345
|
+
gl.bindTexture(gl.TEXTURE_2D, this.mediaTexture);
|
|
6346
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.layer.media.videoWidth, this.layer.media.videoHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
6347
|
+
gl.bindTexture(gl.TEXTURE_2D, existingTextureBinding);
|
|
6348
|
+
}
|
|
6349
|
+
this._createVAOs();
|
|
6350
|
+
}
|
|
6351
|
+
render(session, frame) {
|
|
6352
|
+
this.saveVaoState();
|
|
6353
|
+
let gl = this.gl;
|
|
6354
|
+
let baseLayer = session.getBaseLayer();
|
|
6355
|
+
let basePose = frame.getViewerPose(session.getReferenceSpace());
|
|
6356
|
+
const existingActiveTexture = gl.getParameter(gl.ACTIVE_TEXTURE);
|
|
6357
|
+
for (let view of basePose.views) {
|
|
6358
|
+
let viewport = baseLayer.getViewport(view);
|
|
6359
|
+
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
|
|
6360
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
6361
|
+
if (this.usesTextureArrayShaders) {
|
|
6362
|
+
if (gl instanceof WebGLRenderingContext) {
|
|
6363
|
+
throw new Error('This should never happen; texture-arrays only supported on WebGL2.');
|
|
6364
|
+
}
|
|
6365
|
+
if (this.layer.isMediaLayer()) {
|
|
6366
|
+
throw new Error('This should never happen. Media layers should never be created with texture-array');
|
|
6367
|
+
}
|
|
6368
|
+
const existingTextureBinding = gl.getParameter(gl.TEXTURE_BINDING_2D_ARRAY);
|
|
6369
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.layer.colorTextures[0]);
|
|
6370
|
+
if (this.layer.isStatic) {
|
|
6371
|
+
if (this.layer.needsRedraw === true) {
|
|
6372
|
+
gl.generateMipmap(gl.TEXTURE_2D_ARRAY);
|
|
6373
|
+
}
|
|
6374
|
+
this.hasMipmap = true;
|
|
6375
|
+
}
|
|
6376
|
+
else {
|
|
6377
|
+
this.hasMipmap = this.layer.mipLevels > 0;
|
|
6378
|
+
}
|
|
6379
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, this.hasMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
|
|
6380
|
+
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, this.hasMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
|
|
6381
|
+
let layer = 0;
|
|
6382
|
+
if (this.layer.layout === XRLayerLayout.stereo) {
|
|
6383
|
+
switch (view.eye) {
|
|
6384
|
+
case 'right':
|
|
6385
|
+
layer = 1;
|
|
6386
|
+
break;
|
|
6387
|
+
}
|
|
6388
|
+
}
|
|
6389
|
+
if (this._shouldUseStereoTexturePoints()) {
|
|
6390
|
+
this._renderInternalStereo(session, frame, view, layer);
|
|
6391
|
+
}
|
|
6392
|
+
else {
|
|
6393
|
+
this._renderInternal(session, frame, view, layer);
|
|
6394
|
+
}
|
|
6395
|
+
gl.activeTexture(existingActiveTexture);
|
|
6396
|
+
gl.bindTexture(gl.TEXTURE_2D_ARRAY, existingTextureBinding);
|
|
6397
|
+
}
|
|
6398
|
+
else {
|
|
6399
|
+
const existingTextureBinding = gl.getParameter(gl.TEXTURE_BINDING_2D);
|
|
6400
|
+
if (this.layer.isMediaLayer()) {
|
|
6401
|
+
gl.bindTexture(gl.TEXTURE_2D, this.mediaTexture);
|
|
6402
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
|
6403
|
+
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.layer.media.videoWidth, this.layer.media.videoHeight, gl.RGBA, gl.UNSIGNED_BYTE, this.layer.media);
|
|
6404
|
+
}
|
|
6405
|
+
else if (this.layer.layout === XRLayerLayout.stereo) {
|
|
6406
|
+
switch (view.eye) {
|
|
6407
|
+
case 'right':
|
|
6408
|
+
gl.bindTexture(gl.TEXTURE_2D, this.layer.colorTextures[1]);
|
|
6409
|
+
break;
|
|
6410
|
+
default:
|
|
6411
|
+
gl.bindTexture(gl.TEXTURE_2D, this.layer.colorTextures[0]);
|
|
6412
|
+
}
|
|
6413
|
+
}
|
|
6414
|
+
else {
|
|
6415
|
+
gl.bindTexture(gl.TEXTURE_2D, this.layer.colorTextures[0]);
|
|
6416
|
+
}
|
|
6417
|
+
if (this.layer.isStatic) {
|
|
6418
|
+
if (this.layer.needsRedraw === true) {
|
|
6419
|
+
gl.generateMipmap(gl.TEXTURE_2D);
|
|
6420
|
+
}
|
|
6421
|
+
this.hasMipmap = true;
|
|
6422
|
+
}
|
|
6423
|
+
else {
|
|
6424
|
+
this.hasMipmap = this.layer.mipLevels > 0;
|
|
6425
|
+
}
|
|
6426
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
6427
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
6428
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.hasMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
|
|
6429
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.hasMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
|
|
6430
|
+
if (this._shouldUseStereoTexturePoints()) {
|
|
6431
|
+
this._renderInternalStereo(session, frame, view);
|
|
6432
|
+
}
|
|
6433
|
+
else {
|
|
6434
|
+
this._renderInternal(session, frame, view);
|
|
6435
|
+
}
|
|
6436
|
+
gl.activeTexture(existingActiveTexture);
|
|
6437
|
+
gl.bindTexture(gl.TEXTURE_2D, existingTextureBinding);
|
|
6438
|
+
}
|
|
6439
|
+
}
|
|
6440
|
+
this.restoreVaoState();
|
|
6441
|
+
}
|
|
6442
|
+
createPositionPoints() {
|
|
6443
|
+
return new Float32Array([]);
|
|
6444
|
+
}
|
|
6445
|
+
createTextureUVs() {
|
|
6446
|
+
return new Float32Array([]);
|
|
6447
|
+
}
|
|
6448
|
+
_offsetTextureUVsByRect(texture, inArray, textureRect) {
|
|
6449
|
+
textureRect = textureRect !== null && textureRect !== void 0 ? textureRect : {
|
|
6450
|
+
x: 0,
|
|
6451
|
+
y: 0,
|
|
6452
|
+
width: texture.width,
|
|
6453
|
+
height: texture.height,
|
|
6454
|
+
};
|
|
6455
|
+
const uX = textureRect.x / texture.width;
|
|
6456
|
+
const vY = textureRect.y / texture.height;
|
|
6457
|
+
const uW = textureRect.width / texture.width;
|
|
6458
|
+
const vH = textureRect.height / texture.height;
|
|
6459
|
+
const outArray = [];
|
|
6460
|
+
for (let i = 0; i < inArray.length; i += 2) {
|
|
6461
|
+
let u = inArray[i];
|
|
6462
|
+
let v = inArray[i + 1];
|
|
6463
|
+
let newU = u * uW + uX;
|
|
6464
|
+
let newV = v * vH + vY;
|
|
6465
|
+
outArray[i] = newU;
|
|
6466
|
+
outArray[i + 1] = newV;
|
|
6467
|
+
}
|
|
6468
|
+
return new Float32Array(outArray);
|
|
6469
|
+
}
|
|
6470
|
+
_shouldUseStereoTexturePoints() {
|
|
6471
|
+
return (this.layer.layout === XRLayerLayout['stereo-left-right'] ||
|
|
6472
|
+
this.layer.layout === XRLayerLayout['stereo-top-bottom']);
|
|
6473
|
+
}
|
|
6474
|
+
_setStereoTextureBuffer(index) {
|
|
6475
|
+
let gl = this.gl;
|
|
6476
|
+
gl.enableVertexAttribArray(this.programInfo.attribLocations.a_texCoord);
|
|
6477
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
|
|
6478
|
+
gl.bufferData(gl.ARRAY_BUFFER, this.stereoTexturePoints[index], gl.STATIC_DRAW);
|
|
6479
|
+
var size = 2;
|
|
6480
|
+
var type = gl.FLOAT;
|
|
6481
|
+
var normalize = false;
|
|
6482
|
+
var stride = 0;
|
|
6483
|
+
var offset = 0;
|
|
6484
|
+
gl.vertexAttribPointer(this.programInfo.attribLocations.a_texCoord, size, type, normalize, stride, offset);
|
|
6485
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
6486
|
+
}
|
|
6487
|
+
_recalculateVertices() {
|
|
6488
|
+
this.positionPoints = this.createPositionPoints();
|
|
6489
|
+
this.texturePoints = this.createTextureUVs();
|
|
6490
|
+
const viewport = {
|
|
6491
|
+
x: 0,
|
|
6492
|
+
y: 0,
|
|
6493
|
+
width: 1,
|
|
6494
|
+
height: 1,
|
|
6495
|
+
};
|
|
6496
|
+
if (this._shouldUseStereoTexturePoints()) {
|
|
6497
|
+
this.stereoTexturePoints = [];
|
|
6498
|
+
if (this.layer.isMediaLayer()) {
|
|
6499
|
+
initializeViewport(viewport, this.mediaTexturePolyfill, this.layer.layout, 0, 2);
|
|
6500
|
+
this.stereoTexturePoints[0] = this._offsetTextureUVsByRect(this.mediaTexturePolyfill, this.texturePoints, viewport);
|
|
6501
|
+
initializeViewport(viewport, this.mediaTexturePolyfill, this.layer.layout, 1, 2);
|
|
6502
|
+
this.stereoTexturePoints[1] = this._offsetTextureUVsByRect(this.mediaTexturePolyfill, this.texturePoints, viewport);
|
|
6503
|
+
if (this.layer.layout === XRLayerLayout['stereo-top-bottom']) {
|
|
6504
|
+
[this.stereoTexturePoints[0], this.stereoTexturePoints[1]] = [
|
|
6505
|
+
this.stereoTexturePoints[1],
|
|
6506
|
+
this.stereoTexturePoints[0],
|
|
6507
|
+
];
|
|
6508
|
+
}
|
|
6509
|
+
return;
|
|
6510
|
+
}
|
|
6511
|
+
initializeViewport(viewport, this.layer.colorTexturesMeta[0], this.layer.layout, 0, 2);
|
|
6512
|
+
this.stereoTexturePoints[0] = this._offsetTextureUVsByRect(this.layer.colorTexturesMeta[0], this.texturePoints, viewport);
|
|
6513
|
+
initializeViewport(viewport, this.layer.colorTexturesMeta[0], this.layer.layout, 1, 2);
|
|
6514
|
+
this.stereoTexturePoints[1] = this._offsetTextureUVsByRect(this.layer.colorTexturesMeta[0], this.texturePoints, viewport);
|
|
6515
|
+
if (this.layer.layout === XRLayerLayout['stereo-top-bottom']) {
|
|
6516
|
+
[this.stereoTexturePoints[0], this.stereoTexturePoints[1]] = [
|
|
6517
|
+
this.stereoTexturePoints[1],
|
|
6518
|
+
this.stereoTexturePoints[0],
|
|
6519
|
+
];
|
|
6520
|
+
}
|
|
6521
|
+
}
|
|
6522
|
+
}
|
|
6523
|
+
_createVAOs() {
|
|
6524
|
+
this._recalculateVertices();
|
|
6525
|
+
let gl = this.gl;
|
|
6526
|
+
this.vaoGl = applyVAOExtension(gl);
|
|
6527
|
+
this.saveVaoState();
|
|
6528
|
+
let positionBuffer = gl.createBuffer();
|
|
6529
|
+
this.vao = this.vaoGl.createVertexArray();
|
|
6530
|
+
this.vaoGl.bindVertexArray(this.vao);
|
|
6531
|
+
gl.enableVertexAttribArray(this.programInfo.attribLocations.a_position);
|
|
6532
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
|
6533
|
+
const positions = this.positionPoints;
|
|
6534
|
+
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
|
|
6535
|
+
var size = 3;
|
|
6536
|
+
var type = gl.FLOAT;
|
|
6537
|
+
var normalize = false;
|
|
6538
|
+
var stride = 0;
|
|
6539
|
+
var offset = 0;
|
|
6540
|
+
gl.vertexAttribPointer(this.programInfo.attribLocations.a_position, size, type, normalize, stride, offset);
|
|
6541
|
+
gl.enableVertexAttribArray(this.programInfo.attribLocations.a_texCoord);
|
|
6542
|
+
this.texcoordBuffer = gl.createBuffer();
|
|
6543
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
|
|
6544
|
+
gl.bufferData(gl.ARRAY_BUFFER, this.texturePoints, gl.STATIC_DRAW);
|
|
6545
|
+
var size = 2;
|
|
6546
|
+
var type = gl.FLOAT;
|
|
6547
|
+
var normalize = false;
|
|
6548
|
+
var stride = 0;
|
|
6549
|
+
var offset = 0;
|
|
6550
|
+
gl.vertexAttribPointer(this.programInfo.attribLocations.a_texCoord, size, type, normalize, stride, offset);
|
|
6551
|
+
this.restoreVaoState();
|
|
6552
|
+
}
|
|
6553
|
+
_renderInternal(session, frame, view, layer) {
|
|
6554
|
+
let gl = this.gl;
|
|
6555
|
+
const existingProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
6556
|
+
gl.useProgram(this.program);
|
|
6557
|
+
this.vaoGl.bindVertexArray(this.vao);
|
|
6558
|
+
if (this.usesTextureArrayShaders) {
|
|
6559
|
+
gl.uniform1i(this.programInfo.uniformLocations.u_layer, layer);
|
|
6560
|
+
}
|
|
6561
|
+
this._setTransformMatrix(session, frame, view);
|
|
6562
|
+
gl.uniformMatrix4fv(this.programInfo.uniformLocations.u_matrix, false, this.transformMatrix);
|
|
6563
|
+
gl.uniformMatrix4fv(this.programInfo.uniformLocations.u_projectionMatrix, false, view.projectionMatrix);
|
|
6564
|
+
var primitiveType = gl.TRIANGLES;
|
|
6565
|
+
var offset = 0;
|
|
6566
|
+
var count = this.positionPoints.length / 3;
|
|
6567
|
+
gl.drawArrays(primitiveType, offset, count);
|
|
6568
|
+
this.vaoGl.bindVertexArray(null);
|
|
6569
|
+
gl.useProgram(existingProgram);
|
|
6570
|
+
}
|
|
6571
|
+
_renderInternalStereo(session, frame, view, layer) {
|
|
6572
|
+
if (view.eye === 'none') {
|
|
6573
|
+
return this._renderInternal(session, frame, view);
|
|
6574
|
+
}
|
|
6575
|
+
let gl = this.gl;
|
|
6576
|
+
this.vaoGl.bindVertexArray(this.vao);
|
|
6577
|
+
const existingProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
6578
|
+
gl.useProgram(this.program);
|
|
6579
|
+
this._setStereoTextureBuffer(view.eye === 'right' ? 1 : 0);
|
|
6580
|
+
if (this.usesTextureArrayShaders) {
|
|
6581
|
+
gl.uniform1i(this.programInfo.uniformLocations.u_layer, layer);
|
|
6582
|
+
}
|
|
6583
|
+
this._setTransformMatrix(session, frame, view);
|
|
6584
|
+
gl.uniformMatrix4fv(this.programInfo.uniformLocations.u_matrix, false, this.transformMatrix);
|
|
6585
|
+
gl.uniformMatrix4fv(this.programInfo.uniformLocations.u_projectionMatrix, false, view.projectionMatrix);
|
|
6586
|
+
var primitiveType = gl.TRIANGLES;
|
|
6587
|
+
var offset = 0;
|
|
6588
|
+
var count = this.positionPoints.length / 3;
|
|
6589
|
+
gl.drawArrays(primitiveType, offset, count);
|
|
6590
|
+
this.vaoGl.bindVertexArray(null);
|
|
6591
|
+
gl.useProgram(existingProgram);
|
|
6592
|
+
}
|
|
6593
|
+
_setTransformMatrix(session, frame, view) {
|
|
6594
|
+
let objPose = frame.getPose(this.layer.space, session.getReferenceSpace());
|
|
6595
|
+
multiply(this.transformMatrix, objPose.transform.matrix, this.layer.transform.matrix);
|
|
6596
|
+
multiply(this.transformMatrix, view.transform.inverse.matrix, this.transformMatrix);
|
|
6597
|
+
}
|
|
6598
|
+
}
|
|
6599
|
+
|
|
6600
|
+
class QuadRenderer extends CompositionLayerRenderer {
|
|
6601
|
+
constructor(layer, context) {
|
|
6602
|
+
super(layer, context);
|
|
6603
|
+
this.initialize();
|
|
6604
|
+
}
|
|
6605
|
+
createPositionPoints() {
|
|
6606
|
+
const width = this.layer.width;
|
|
6607
|
+
const height = this.layer.height;
|
|
6608
|
+
const z = 0;
|
|
6609
|
+
const positions = [
|
|
6610
|
+
-width,
|
|
6611
|
+
-height,
|
|
6612
|
+
z,
|
|
6613
|
+
width,
|
|
6614
|
+
-height,
|
|
6615
|
+
z,
|
|
6616
|
+
-width,
|
|
6617
|
+
height,
|
|
6618
|
+
z,
|
|
6619
|
+
-width,
|
|
6620
|
+
height,
|
|
6621
|
+
z,
|
|
6622
|
+
width,
|
|
6623
|
+
-height,
|
|
6624
|
+
z,
|
|
6625
|
+
width,
|
|
6626
|
+
height,
|
|
6627
|
+
z,
|
|
6628
|
+
];
|
|
6629
|
+
return new Float32Array(positions);
|
|
6630
|
+
}
|
|
6631
|
+
createTextureUVs() {
|
|
6632
|
+
return new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0]);
|
|
6633
|
+
}
|
|
6634
|
+
}
|
|
6635
|
+
|
|
6636
|
+
class CylinderRenderer extends CompositionLayerRenderer {
|
|
6637
|
+
constructor(layer, context) {
|
|
6638
|
+
super(layer, context);
|
|
6639
|
+
this.segments = 16;
|
|
6640
|
+
this.initialize();
|
|
6641
|
+
}
|
|
6642
|
+
createPositionPoints() {
|
|
6643
|
+
const positions = [];
|
|
6644
|
+
const angle = this.layer.centralAngle;
|
|
6645
|
+
const height = this.layer.height;
|
|
6646
|
+
const radius = this.layer.radius;
|
|
6647
|
+
const radiansPerSegment = angle / this.segments;
|
|
6648
|
+
const theta = Math.PI / 2 - angle / 2;
|
|
6649
|
+
const unitCirclePositions = [];
|
|
6650
|
+
const firstUnitPoint = create$1();
|
|
6651
|
+
firstUnitPoint[0] = radius * Math.cos(theta);
|
|
6652
|
+
firstUnitPoint[1] = -radius * Math.sin(theta);
|
|
6653
|
+
unitCirclePositions.push(firstUnitPoint);
|
|
6654
|
+
for (let i = 0; i < this.segments; i++) {
|
|
6655
|
+
const nextPoint = create$1();
|
|
6656
|
+
nextPoint[0] = radius * Math.cos(theta + radiansPerSegment * (i + 1));
|
|
6657
|
+
nextPoint[1] = -radius * Math.sin(theta + radiansPerSegment * (i + 1));
|
|
6658
|
+
unitCirclePositions.push(nextPoint);
|
|
6659
|
+
}
|
|
6660
|
+
unitCirclePositions.reverse();
|
|
6661
|
+
for (let i = 0; i < this.segments; i++) {
|
|
6662
|
+
const u = unitCirclePositions[i];
|
|
6663
|
+
const v = unitCirclePositions[i + 1];
|
|
6664
|
+
positions.push(u[0], -height / 2, u[1]);
|
|
6665
|
+
positions.push(v[0], -height / 2, v[1]);
|
|
6666
|
+
positions.push(u[0], height / 2, u[1]);
|
|
6667
|
+
positions.push(u[0], height / 2, u[1]);
|
|
6668
|
+
positions.push(v[0], -height / 2, v[1]);
|
|
6669
|
+
positions.push(v[0], height / 2, v[1]);
|
|
6670
|
+
}
|
|
6671
|
+
return new Float32Array(positions);
|
|
6672
|
+
}
|
|
6673
|
+
createTextureUVs() {
|
|
6674
|
+
let textureUVs = [];
|
|
6675
|
+
const texturePercent = 1.0 / this.segments;
|
|
6676
|
+
for (let i = 0; i < this.segments; i++) {
|
|
6677
|
+
let leftX = texturePercent * i;
|
|
6678
|
+
let rightX = texturePercent * (i + 1);
|
|
6679
|
+
textureUVs.push(leftX, 0);
|
|
6680
|
+
textureUVs.push(rightX, 0);
|
|
6681
|
+
textureUVs.push(leftX, 1);
|
|
6682
|
+
textureUVs.push(leftX, 1);
|
|
6683
|
+
textureUVs.push(rightX, 0);
|
|
6684
|
+
textureUVs.push(rightX, 1);
|
|
6685
|
+
}
|
|
6686
|
+
return new Float32Array(textureUVs);
|
|
6687
|
+
}
|
|
6688
|
+
}
|
|
6689
|
+
|
|
6690
|
+
class EquirectRenderer extends CompositionLayerRenderer {
|
|
6691
|
+
constructor(layer, context) {
|
|
6692
|
+
super(layer, context);
|
|
6693
|
+
this.segmentsPerAxis = 40;
|
|
6694
|
+
this.initialize();
|
|
6695
|
+
}
|
|
6696
|
+
createPositionPoints() {
|
|
6697
|
+
const positions = [];
|
|
6698
|
+
let radius = this.layer.radius;
|
|
6699
|
+
if (radius === 0) {
|
|
6700
|
+
radius = 25;
|
|
6701
|
+
}
|
|
6702
|
+
if (radius > 25) {
|
|
6703
|
+
radius = 25;
|
|
6704
|
+
}
|
|
6705
|
+
const horizAngle = this.layer.centralHorizontalAngle;
|
|
6706
|
+
const phi1 = this.layer.upperVerticalAngle + Math.PI / 2;
|
|
6707
|
+
const phi2 = this.layer.lowerVerticalAngle + Math.PI / 2;
|
|
6708
|
+
const startPhi = phi1;
|
|
6709
|
+
const endPhi = phi2;
|
|
6710
|
+
const startTheta = Math.PI / 2 - horizAngle / 2;
|
|
6711
|
+
const endTheta = startTheta + horizAngle;
|
|
6712
|
+
const phiRange = endPhi - startPhi;
|
|
6713
|
+
const thetaRange = endTheta - startTheta;
|
|
6714
|
+
const basePoints = [];
|
|
6715
|
+
for (let y = 0; y <= this.segmentsPerAxis; y++) {
|
|
6716
|
+
for (let x = 0; x <= this.segmentsPerAxis; x++) {
|
|
6717
|
+
const u = x / this.segmentsPerAxis;
|
|
6718
|
+
const v = y / this.segmentsPerAxis;
|
|
6719
|
+
let r = radius;
|
|
6720
|
+
let theta = endTheta - thetaRange * u;
|
|
6721
|
+
let phi = phiRange * v + startPhi;
|
|
6722
|
+
const ux = Math.cos(theta) * Math.sin(phi);
|
|
6723
|
+
const uy = Math.cos(phi);
|
|
6724
|
+
const uz = -Math.sin(theta) * Math.sin(phi);
|
|
6725
|
+
basePoints.push([r * ux, r * uy, r * uz]);
|
|
6726
|
+
}
|
|
6727
|
+
}
|
|
6728
|
+
const numVertsAround = this.segmentsPerAxis + 1;
|
|
6729
|
+
for (let x = 0; x < this.segmentsPerAxis; x++) {
|
|
6730
|
+
for (let y = 0; y < this.segmentsPerAxis; y++) {
|
|
6731
|
+
positions.push(...basePoints[y * numVertsAround + x]);
|
|
6732
|
+
positions.push(...basePoints[y * numVertsAround + x + 1]);
|
|
6733
|
+
positions.push(...basePoints[(y + 1) * numVertsAround + x]);
|
|
6734
|
+
positions.push(...basePoints[(y + 1) * numVertsAround + x]);
|
|
6735
|
+
positions.push(...basePoints[y * numVertsAround + x + 1]);
|
|
6736
|
+
positions.push(...basePoints[(y + 1) * numVertsAround + x + 1]);
|
|
6737
|
+
}
|
|
6738
|
+
}
|
|
6739
|
+
return new Float32Array(positions);
|
|
6740
|
+
}
|
|
6741
|
+
createTextureUVs() {
|
|
6742
|
+
const triUVs = [];
|
|
6743
|
+
const baseUVs = [];
|
|
6744
|
+
for (let y = 0; y <= this.segmentsPerAxis; y++) {
|
|
6745
|
+
for (let x = 0; x <= this.segmentsPerAxis; x++) {
|
|
6746
|
+
const u = x / this.segmentsPerAxis;
|
|
6747
|
+
const v = y / this.segmentsPerAxis;
|
|
6748
|
+
baseUVs.push([u, v]);
|
|
6749
|
+
}
|
|
6750
|
+
}
|
|
6751
|
+
const numVertsAround = this.segmentsPerAxis + 1;
|
|
6752
|
+
for (let x = 0; x < this.segmentsPerAxis; x++) {
|
|
6753
|
+
for (let y = 0; y < this.segmentsPerAxis; y++) {
|
|
6754
|
+
triUVs.push(...baseUVs[y * numVertsAround + x]);
|
|
6755
|
+
triUVs.push(...baseUVs[y * numVertsAround + x + 1]);
|
|
6756
|
+
triUVs.push(...baseUVs[(y + 1) * numVertsAround + x]);
|
|
6757
|
+
triUVs.push(...baseUVs[(y + 1) * numVertsAround + x]);
|
|
6758
|
+
triUVs.push(...baseUVs[y * numVertsAround + x + 1]);
|
|
6759
|
+
triUVs.push(...baseUVs[(y + 1) * numVertsAround + x + 1]);
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
6762
|
+
return new Float32Array(triUVs);
|
|
6763
|
+
}
|
|
6764
|
+
}
|
|
6765
|
+
|
|
6766
|
+
const defaultCubeLayerInit = {
|
|
6767
|
+
colorFormat: 0x1908,
|
|
6768
|
+
mipLevels: 1,
|
|
6769
|
+
layout: XRLayerLayout.mono,
|
|
6770
|
+
isStatic: false,
|
|
6771
|
+
space: null,
|
|
6772
|
+
viewPixelHeight: 0,
|
|
6773
|
+
viewPixelWidth: 0,
|
|
6774
|
+
};
|
|
6775
|
+
class XRCubeLayer extends XRCompositionLayerPolyfill {
|
|
6776
|
+
constructor(init = defaultCubeLayerInit) {
|
|
6777
|
+
super();
|
|
6778
|
+
if (!isReferenceSpace(init.space)) {
|
|
6779
|
+
throw new TypeError("XRCubeLayer's space needs to be an XRReferenceSpace");
|
|
6780
|
+
}
|
|
6781
|
+
this.init = Object.assign(Object.assign({}, defaultCubeLayerInit), init);
|
|
6782
|
+
this.space = this.init.space;
|
|
6783
|
+
this.isStatic = this.init.isStatic;
|
|
6784
|
+
if (this.init.orientation) {
|
|
6785
|
+
this.orientation = DOMPointReadOnly.fromPoint(this.init.orientation);
|
|
6786
|
+
}
|
|
6787
|
+
else {
|
|
6788
|
+
this.orientation = new DOMPointReadOnly();
|
|
6789
|
+
}
|
|
6790
|
+
switch (this.init.layout) {
|
|
6791
|
+
case XRLayerLayout.default:
|
|
6792
|
+
case XRLayerLayout['stereo-left-right']:
|
|
6793
|
+
case XRLayerLayout['stereo-top-bottom']:
|
|
6794
|
+
throw new TypeError('Invalid layout format for XRCubeLayer');
|
|
6795
|
+
}
|
|
6796
|
+
this.layout = this.init.layout;
|
|
6797
|
+
this.needsRedraw = true;
|
|
6798
|
+
}
|
|
6799
|
+
initialize(session, context) {
|
|
6800
|
+
super.initialize(session, context);
|
|
6801
|
+
this._allocateColorTexturesInternal();
|
|
6802
|
+
this._allocateDepthStencilTexturesInternal();
|
|
6803
|
+
}
|
|
6804
|
+
_allocateColorTexturesInternal() {
|
|
6805
|
+
this._colorTextures = [];
|
|
6806
|
+
this._texturesMeta = [];
|
|
6807
|
+
if (this.layout === XRLayerLayout.mono) {
|
|
6808
|
+
const colorTexture = this._createCubeColorTexture();
|
|
6809
|
+
this._texturesMeta.push(colorTexture);
|
|
6810
|
+
this._colorTextures.push(colorTexture.texture);
|
|
6811
|
+
return;
|
|
6812
|
+
}
|
|
6813
|
+
else {
|
|
6814
|
+
const texture1 = this._createCubeColorTexture();
|
|
6815
|
+
const texture2 = this._createCubeColorTexture();
|
|
6816
|
+
this._texturesMeta.push(texture1, texture2);
|
|
6817
|
+
this._colorTextures.push(texture1.texture, texture2.texture);
|
|
6818
|
+
return;
|
|
6819
|
+
}
|
|
6820
|
+
}
|
|
6821
|
+
_allocateDepthStencilTexturesInternal() {
|
|
6822
|
+
this._depthStencilTextures = [];
|
|
6823
|
+
if (!this.init.depthFormat) {
|
|
6824
|
+
return;
|
|
6825
|
+
}
|
|
6826
|
+
if (this.context instanceof WebGLRenderingContext) {
|
|
6827
|
+
let depthExtension = this.context.getExtension('WEBGL_depth_texture');
|
|
6828
|
+
if (!depthExtension) {
|
|
6829
|
+
throw new TypeError('Depth textures not supported in the current context');
|
|
6830
|
+
}
|
|
6831
|
+
}
|
|
6832
|
+
if (this.layout === XRLayerLayout.mono) {
|
|
6833
|
+
const depthTexture = this._createCubeDepthTexture();
|
|
6834
|
+
this._depthStencilTextures.push(depthTexture.texture);
|
|
6835
|
+
return;
|
|
6836
|
+
}
|
|
6837
|
+
else {
|
|
6838
|
+
const texture1 = this._createCubeDepthTexture();
|
|
6839
|
+
const texture2 = this._createCubeDepthTexture();
|
|
6840
|
+
this._depthStencilTextures.push(texture1.texture, texture2.texture);
|
|
6841
|
+
return;
|
|
6842
|
+
}
|
|
6843
|
+
}
|
|
6844
|
+
_createCubeColorTexture() {
|
|
6845
|
+
let texture = this.context.createTexture();
|
|
6846
|
+
let textureMeta = {
|
|
6847
|
+
width: this.init.viewPixelWidth,
|
|
6848
|
+
height: this.init.viewPixelHeight,
|
|
6849
|
+
layers: 1,
|
|
6850
|
+
type: XRTextureType.texture,
|
|
6851
|
+
textureFormat: this.init.colorFormat,
|
|
6852
|
+
texture,
|
|
6853
|
+
};
|
|
6854
|
+
const existingTextureBinding = this.context.getParameter(this.context.TEXTURE_BINDING_CUBE_MAP);
|
|
6855
|
+
this.context.bindTexture(this.context.TEXTURE_CUBE_MAP, texture);
|
|
6856
|
+
for (let i = 0; i < 6; i++) {
|
|
6857
|
+
this.context.texImage2D(this.context.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, textureMeta.textureFormat, textureMeta.width, textureMeta.height, 0, textureMeta.textureFormat, this.context.UNSIGNED_BYTE, null);
|
|
6858
|
+
}
|
|
6859
|
+
this.context.bindTexture(this.context.TEXTURE_CUBE_MAP, existingTextureBinding);
|
|
6860
|
+
return textureMeta;
|
|
6861
|
+
}
|
|
6862
|
+
_createCubeDepthTexture() {
|
|
6863
|
+
let texture = this.context.createTexture();
|
|
6864
|
+
let textureMeta = {
|
|
6865
|
+
width: this.init.viewPixelWidth,
|
|
6866
|
+
height: this.init.viewPixelHeight,
|
|
6867
|
+
layers: 1,
|
|
6868
|
+
type: XRTextureType.texture,
|
|
6869
|
+
textureFormat: this.init.depthFormat,
|
|
6870
|
+
texture,
|
|
6871
|
+
};
|
|
6872
|
+
const existingTextureBinding = this.context.getParameter(this.context.TEXTURE_BINDING_CUBE_MAP);
|
|
6873
|
+
this.context.bindTexture(this.context.TEXTURE_CUBE_MAP, texture);
|
|
6874
|
+
let internalFormat = this.init.depthFormat;
|
|
6875
|
+
if (this.context instanceof WebGL2RenderingContext) {
|
|
6876
|
+
if (internalFormat === this.context.DEPTH_COMPONENT) {
|
|
6877
|
+
internalFormat = this.context.DEPTH_COMPONENT24;
|
|
6878
|
+
}
|
|
6879
|
+
if (internalFormat === this.context.DEPTH_STENCIL) {
|
|
6880
|
+
internalFormat = this.context.DEPTH24_STENCIL8;
|
|
6881
|
+
}
|
|
6882
|
+
}
|
|
6883
|
+
for (let i = 0; i < 6; i++) {
|
|
6884
|
+
this.context.texImage2D(this.context.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalFormat, textureMeta.width, textureMeta.height, 0, textureMeta.textureFormat, this.context.UNSIGNED_INT, null);
|
|
6885
|
+
}
|
|
6886
|
+
this.context.bindTexture(this.context.TEXTURE_CUBE_MAP, existingTextureBinding);
|
|
6887
|
+
return textureMeta;
|
|
6888
|
+
}
|
|
6889
|
+
getTextureType() {
|
|
6890
|
+
return XRTextureType.texture;
|
|
6891
|
+
}
|
|
6892
|
+
}
|
|
6893
|
+
|
|
6894
|
+
const glsl$2 = (x) => x;
|
|
6895
|
+
const vertexShader$2 = glsl$2 `
|
|
6896
|
+
attribute vec4 a_position;
|
|
6897
|
+
uniform mat4 u_projectionMatrix;
|
|
6898
|
+
uniform mat4 u_matrix;
|
|
6899
|
+
varying vec3 v_normal;
|
|
6900
|
+
|
|
6901
|
+
void main() {
|
|
6902
|
+
gl_Position = u_projectionMatrix * u_matrix * a_position;
|
|
6903
|
+
|
|
6904
|
+
v_normal = normalize(a_position.xyz);
|
|
6905
|
+
}
|
|
6906
|
+
`;
|
|
6907
|
+
const fragmentShader$2 = glsl$2 `
|
|
6908
|
+
precision mediump float;
|
|
6909
|
+
|
|
6910
|
+
varying vec3 v_normal;
|
|
6911
|
+
|
|
6912
|
+
uniform samplerCube u_texture;
|
|
6913
|
+
|
|
6914
|
+
void main() {
|
|
6915
|
+
gl_FragColor = textureCube(u_texture, normalize(v_normal));
|
|
6916
|
+
}
|
|
6917
|
+
`;
|
|
6918
|
+
class CubeRenderer {
|
|
6919
|
+
constructor(layer, gl) {
|
|
6920
|
+
this.savedVaoState = { vao: null, arrayBuffer: null };
|
|
6921
|
+
this.hasMipmap = false;
|
|
6922
|
+
this.layer = layer;
|
|
6923
|
+
this.gl = gl;
|
|
6924
|
+
this.transformMatrix = create();
|
|
6925
|
+
this.program = createProgram(gl, vertexShader$2, fragmentShader$2);
|
|
6926
|
+
this.programInfo = {
|
|
6927
|
+
attribLocations: {
|
|
6928
|
+
a_position: gl.getAttribLocation(this.program, 'a_position'),
|
|
6929
|
+
},
|
|
6930
|
+
uniformLocations: {
|
|
6931
|
+
u_matrix: gl.getUniformLocation(this.program, 'u_matrix'),
|
|
6932
|
+
u_texture: gl.getUniformLocation(this.program, 'u_texture'),
|
|
6933
|
+
u_projectionMatrix: gl.getUniformLocation(this.program, 'u_projectionMatrix'),
|
|
6934
|
+
},
|
|
6935
|
+
};
|
|
6936
|
+
this._createVAOs();
|
|
6937
|
+
}
|
|
6938
|
+
saveVaoState() {
|
|
6939
|
+
this.savedVaoState.vao = this.gl.getParameter(this.vaoGl.VERTEX_ARRAY_BINDING);
|
|
6940
|
+
this.savedVaoState.arrayBuffer = this.gl.getParameter(this.gl.ARRAY_BUFFER_BINDING);
|
|
6941
|
+
}
|
|
6942
|
+
restoreVaoState() {
|
|
6943
|
+
this.vaoGl.bindVertexArray(this.savedVaoState.vao);
|
|
6944
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.savedVaoState.arrayBuffer);
|
|
6945
|
+
this.savedVaoState.vao = this.savedVaoState.arrayBuffer = null;
|
|
6946
|
+
}
|
|
6947
|
+
render(session, frame) {
|
|
6948
|
+
this.saveVaoState();
|
|
6949
|
+
let gl = this.gl;
|
|
6950
|
+
let baseLayer = session.getBaseLayer();
|
|
6951
|
+
let basePose = frame.getViewerPose(session.getReferenceSpace());
|
|
6952
|
+
const existingActiveTexture = gl.getParameter(gl.ACTIVE_TEXTURE);
|
|
6953
|
+
for (let view of basePose.views) {
|
|
6954
|
+
let viewport = baseLayer.getViewport(view);
|
|
6955
|
+
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
|
|
6956
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
6957
|
+
const existingTextureBinding = gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP);
|
|
6958
|
+
if (this.layer.layout === XRLayerLayout.stereo) {
|
|
6959
|
+
const index = view.eye === 'right' ? 1 : 0;
|
|
6960
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.layer.colorTextures[index]);
|
|
6961
|
+
}
|
|
6962
|
+
else {
|
|
6963
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.layer.colorTextures[0]);
|
|
6964
|
+
}
|
|
6965
|
+
if (this.layer.isStatic) {
|
|
6966
|
+
if (this.layer.needsRedraw === true) {
|
|
6967
|
+
gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
|
|
6968
|
+
}
|
|
6969
|
+
this.hasMipmap = true;
|
|
6970
|
+
}
|
|
6971
|
+
else {
|
|
6972
|
+
this.hasMipmap = this.layer.mipLevels > 0;
|
|
6973
|
+
}
|
|
6974
|
+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, this.hasMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
|
|
6975
|
+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, this.hasMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
|
|
6976
|
+
this._renderInternal(this.layer.orientation, view);
|
|
6977
|
+
gl.activeTexture(existingActiveTexture);
|
|
6978
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, existingTextureBinding);
|
|
6979
|
+
}
|
|
6980
|
+
this.restoreVaoState();
|
|
6981
|
+
}
|
|
6982
|
+
createPositionPoints() {
|
|
6983
|
+
const w = 0.5;
|
|
6984
|
+
const positions = [
|
|
6985
|
+
-w, -w, -w,
|
|
6986
|
+
-w, w, -w,
|
|
6987
|
+
w, -w, -w,
|
|
6988
|
+
-w, w, -w,
|
|
6989
|
+
w, w, -w,
|
|
6990
|
+
w, -w, -w,
|
|
6991
|
+
-w, -w, w,
|
|
6992
|
+
w, -w, w,
|
|
6993
|
+
-w, w, w,
|
|
6994
|
+
-w, w, w,
|
|
6995
|
+
w, -w, w,
|
|
6996
|
+
w, w, w,
|
|
6997
|
+
-w, w, -w,
|
|
6998
|
+
-w, w, w,
|
|
6999
|
+
w, w, -w,
|
|
7000
|
+
-w, w, w,
|
|
7001
|
+
w, w, w,
|
|
7002
|
+
w, w, -w,
|
|
7003
|
+
-w, -w, -w,
|
|
7004
|
+
w, -w, -w,
|
|
7005
|
+
-w, -w, w,
|
|
7006
|
+
-w, -w, w,
|
|
7007
|
+
w, -w, -w,
|
|
7008
|
+
w, -w, w,
|
|
7009
|
+
-w, -w, -w,
|
|
7010
|
+
-w, -w, w,
|
|
7011
|
+
-w, w, -w,
|
|
7012
|
+
-w, -w, w,
|
|
7013
|
+
-w, w, w,
|
|
7014
|
+
-w, w, -w,
|
|
7015
|
+
w, -w, -w,
|
|
7016
|
+
w, w, -w,
|
|
7017
|
+
w, -w, w,
|
|
7018
|
+
w, -w, w,
|
|
7019
|
+
w, w, -w,
|
|
7020
|
+
w, w, w,
|
|
7021
|
+
];
|
|
7022
|
+
return new Float32Array(positions);
|
|
7023
|
+
}
|
|
7024
|
+
_renderInternal(orientation, view) {
|
|
7025
|
+
let gl = this.gl;
|
|
7026
|
+
const existingProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
7027
|
+
gl.useProgram(this.program);
|
|
7028
|
+
this.vaoGl.bindVertexArray(this.vao);
|
|
7029
|
+
fromQuat(this.transformMatrix, [
|
|
7030
|
+
orientation.x,
|
|
7031
|
+
orientation.y,
|
|
7032
|
+
orientation.z,
|
|
7033
|
+
orientation.w,
|
|
7034
|
+
]);
|
|
7035
|
+
if (!this._poseOrientationMatrix) {
|
|
7036
|
+
this._poseOrientationMatrix = create();
|
|
7037
|
+
}
|
|
7038
|
+
fromQuat(this._poseOrientationMatrix, [
|
|
7039
|
+
view.transform.inverse.orientation.x,
|
|
7040
|
+
view.transform.inverse.orientation.y,
|
|
7041
|
+
view.transform.inverse.orientation.z,
|
|
7042
|
+
view.transform.inverse.orientation.w,
|
|
7043
|
+
]);
|
|
7044
|
+
multiply(this.transformMatrix, this.transformMatrix, this._poseOrientationMatrix);
|
|
7045
|
+
gl.uniformMatrix4fv(this.programInfo.uniformLocations.u_matrix, false, this.transformMatrix);
|
|
7046
|
+
gl.uniformMatrix4fv(this.programInfo.uniformLocations.u_projectionMatrix, false, view.projectionMatrix);
|
|
7047
|
+
gl.uniform1i(this.programInfo.uniformLocations.u_texture, 0);
|
|
7048
|
+
var primitiveType = gl.TRIANGLES;
|
|
7049
|
+
var offset = 0;
|
|
7050
|
+
var count = this.positionPoints.length / 3;
|
|
7051
|
+
gl.drawArrays(primitiveType, offset, count);
|
|
7052
|
+
this.vaoGl.bindVertexArray(null);
|
|
7053
|
+
gl.useProgram(existingProgram);
|
|
7054
|
+
}
|
|
7055
|
+
_recalculateVertices() {
|
|
7056
|
+
this.positionPoints = this.createPositionPoints();
|
|
7057
|
+
}
|
|
7058
|
+
_createVAOs() {
|
|
7059
|
+
this._recalculateVertices();
|
|
7060
|
+
let gl = this.gl;
|
|
7061
|
+
this.vaoGl = applyVAOExtension(gl);
|
|
7062
|
+
this.saveVaoState();
|
|
7063
|
+
let positionBuffer = gl.createBuffer();
|
|
7064
|
+
this.vao = this.vaoGl.createVertexArray();
|
|
7065
|
+
this.vaoGl.bindVertexArray(this.vao);
|
|
7066
|
+
gl.enableVertexAttribArray(this.programInfo.attribLocations.a_position);
|
|
7067
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
|
7068
|
+
const positions = this.positionPoints;
|
|
7069
|
+
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
|
|
7070
|
+
var size = 3;
|
|
7071
|
+
var type = gl.FLOAT;
|
|
7072
|
+
var normalize = false;
|
|
7073
|
+
var stride = 0;
|
|
7074
|
+
var offset = 0;
|
|
7075
|
+
gl.vertexAttribPointer(this.programInfo.attribLocations.a_position, size, type, normalize, stride, offset);
|
|
7076
|
+
this.restoreVaoState();
|
|
7077
|
+
}
|
|
7078
|
+
}
|
|
7079
|
+
|
|
7080
|
+
class XRSessionWithLayer {
|
|
7081
|
+
constructor() {
|
|
7082
|
+
this.mode = 'inline';
|
|
7083
|
+
this.layers = [];
|
|
7084
|
+
this.views = [];
|
|
7085
|
+
this.initializedViews = false;
|
|
7086
|
+
this.isPolyfillActive = false;
|
|
7087
|
+
this.taskQueue = [];
|
|
7088
|
+
}
|
|
7089
|
+
requestAnimationFrame(animationFrameCallback) {
|
|
7090
|
+
if (!this.injectedFrameCallback) {
|
|
7091
|
+
this.injectedFrameCallback = (time, frame) => {
|
|
7092
|
+
let gl = this.context;
|
|
7093
|
+
if (!this.initializedViews && this.referenceSpace) {
|
|
7094
|
+
let pose = frame.getViewerPose(this.referenceSpace);
|
|
7095
|
+
if (pose) {
|
|
7096
|
+
this.views = pose.views;
|
|
7097
|
+
this.initializedViews = true;
|
|
7098
|
+
}
|
|
7099
|
+
}
|
|
7100
|
+
if (this.isPolyfillActive && this.initializedViews) {
|
|
7101
|
+
if (!this.tempFramebuffer) {
|
|
7102
|
+
this.tempFramebuffer = gl.createFramebuffer();
|
|
7103
|
+
}
|
|
7104
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this.tempFramebuffer);
|
|
7105
|
+
const existingClearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
|
|
7106
|
+
const existingFrameBuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
|
|
7107
|
+
gl.clearColor(0, 0, 0, 0);
|
|
7108
|
+
for (let layer of this.layers) {
|
|
7109
|
+
if (!(layer instanceof XRProjectionLayer)) {
|
|
7110
|
+
continue;
|
|
7111
|
+
}
|
|
7112
|
+
for (let i = 0; i < layer.colorTextures.length; i++) {
|
|
7113
|
+
let textureType = layer.colorTexturesMeta[i].type;
|
|
7114
|
+
if (textureType === XRTextureType['texture-array']) ;
|
|
7115
|
+
else {
|
|
7116
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, layer.colorTextures[i], 0);
|
|
7117
|
+
if (layer.depthStencilTextures && i < layer.depthStencilTextures.length) {
|
|
7118
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, layer.depthStencilTextures[i], 0);
|
|
7119
|
+
}
|
|
7120
|
+
else {
|
|
7121
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, null, 0);
|
|
7122
|
+
}
|
|
7123
|
+
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
7124
|
+
}
|
|
7125
|
+
}
|
|
7126
|
+
}
|
|
7127
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, existingFrameBuffer);
|
|
7128
|
+
gl.clearColor(existingClearColor[0], existingClearColor[1], existingClearColor[2], existingClearColor[3]);
|
|
7129
|
+
}
|
|
7130
|
+
animationFrameCallback(time, frame);
|
|
7131
|
+
if (this.isPolyfillActive && this.initializedViews) {
|
|
7132
|
+
let prevBlend = gl.isEnabled(gl.BLEND);
|
|
7133
|
+
let prevDepthTest = gl.isEnabled(gl.DEPTH_TEST);
|
|
7134
|
+
let prevCullFace = gl.isEnabled(gl.CULL_FACE);
|
|
7135
|
+
const existingFrameBuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
|
|
7136
|
+
const existingClearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
|
|
7137
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this.getBaseLayer().framebuffer);
|
|
7138
|
+
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
7139
|
+
gl.clearColor(existingClearColor[0], existingClearColor[1], existingClearColor[2], existingClearColor[3]);
|
|
7140
|
+
gl.enable(gl.BLEND);
|
|
7141
|
+
gl.disable(gl.DEPTH_TEST);
|
|
7142
|
+
gl.disable(gl.CULL_FACE);
|
|
7143
|
+
let prevBlendSrcRGB = gl.getParameter(gl.BLEND_SRC_RGB);
|
|
7144
|
+
let prevBlendSrcAlpha = gl.getParameter(gl.BLEND_SRC_ALPHA);
|
|
7145
|
+
let prevBlendDestRGB = gl.getParameter(gl.BLEND_DST_RGB);
|
|
7146
|
+
let prevBlendDestAlpha = gl.getParameter(gl.BLEND_DST_ALPHA);
|
|
7147
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
7148
|
+
for (let layer of this.layers) {
|
|
7149
|
+
if (!this.renderers) {
|
|
7150
|
+
this.renderers = new WeakMap();
|
|
7151
|
+
}
|
|
7152
|
+
if (layer instanceof XRProjectionLayer) {
|
|
7153
|
+
if (!this.renderers.has(layer)) {
|
|
7154
|
+
this.renderers.set(layer, createProjectionRenderer(layer, this.context));
|
|
7155
|
+
}
|
|
7156
|
+
const renderer = this.renderers.get(layer);
|
|
7157
|
+
renderer.render(this);
|
|
7158
|
+
}
|
|
7159
|
+
else if (layer instanceof XRQuadLayer) {
|
|
7160
|
+
if (!this.renderers.has(layer)) {
|
|
7161
|
+
this.renderers.set(layer, new QuadRenderer(layer, this.context));
|
|
7162
|
+
}
|
|
7163
|
+
const renderer = this.renderers.get(layer);
|
|
7164
|
+
renderer.render(this, frame);
|
|
7165
|
+
}
|
|
7166
|
+
else if (layer instanceof XRCylinderLayer) {
|
|
7167
|
+
if (!this.renderers.has(layer)) {
|
|
7168
|
+
this.renderers.set(layer, new CylinderRenderer(layer, this.context));
|
|
7169
|
+
}
|
|
7170
|
+
const renderer = this.renderers.get(layer);
|
|
7171
|
+
renderer.render(this, frame);
|
|
7172
|
+
}
|
|
7173
|
+
else if (layer instanceof XREquirectLayer) {
|
|
7174
|
+
if (!this.renderers.has(layer)) {
|
|
7175
|
+
this.renderers.set(layer, new EquirectRenderer(layer, this.context));
|
|
7176
|
+
}
|
|
7177
|
+
const renderer = this.renderers.get(layer);
|
|
7178
|
+
renderer.render(this, frame);
|
|
7179
|
+
}
|
|
7180
|
+
else if (layer instanceof XRCubeLayer) {
|
|
7181
|
+
if (!this.renderers.has(layer)) {
|
|
7182
|
+
this.renderers.set(layer, new CubeRenderer(layer, this.context));
|
|
7183
|
+
}
|
|
7184
|
+
const renderer = this.renderers.get(layer);
|
|
7185
|
+
renderer.render(this, frame);
|
|
7186
|
+
}
|
|
7187
|
+
else {
|
|
7188
|
+
const webglLayer = layer;
|
|
7189
|
+
if (webglLayer.framebuffer === null) {
|
|
7190
|
+
continue;
|
|
7191
|
+
}
|
|
7192
|
+
if (gl instanceof WebGL2RenderingContext) {
|
|
7193
|
+
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, webglLayer.framebuffer);
|
|
7194
|
+
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.getBaseLayer().framebuffer);
|
|
7195
|
+
gl.blitFramebuffer(0, 0, webglLayer.framebufferWidth, webglLayer.framebufferHeight, 0, 0, this.getBaseLayer().framebufferWidth, this.getBaseLayer().framebufferHeight, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.LINEAR);
|
|
7196
|
+
}
|
|
7197
|
+
else {
|
|
7198
|
+
console.warn('GL blitFramebuffer is not supported on WebGL1, so XRWebGLLayers may not show up properly when polyfilled.');
|
|
7199
|
+
}
|
|
7200
|
+
}
|
|
7201
|
+
}
|
|
7202
|
+
if (!prevBlend) {
|
|
7203
|
+
gl.disable(gl.BLEND);
|
|
7204
|
+
}
|
|
7205
|
+
if (prevDepthTest) {
|
|
7206
|
+
gl.enable(gl.DEPTH_TEST);
|
|
7207
|
+
}
|
|
7208
|
+
if (prevCullFace) {
|
|
7209
|
+
gl.enable(gl.CULL_FACE);
|
|
7210
|
+
}
|
|
7211
|
+
gl.blendFuncSeparate(prevBlendSrcRGB, prevBlendDestRGB, prevBlendSrcAlpha, prevBlendDestAlpha);
|
|
7212
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, existingFrameBuffer);
|
|
7213
|
+
while (this.taskQueue.length > 0) {
|
|
7214
|
+
const task = this.taskQueue.shift();
|
|
7215
|
+
task();
|
|
7216
|
+
}
|
|
7217
|
+
}
|
|
7218
|
+
};
|
|
7219
|
+
}
|
|
7220
|
+
this._requestAnimationFrame(this.injectedFrameCallback);
|
|
7221
|
+
}
|
|
7222
|
+
updateRenderState(XRRenderStateInit) {
|
|
7223
|
+
this.existingBaseLayer = XRRenderStateInit.baseLayer;
|
|
7224
|
+
if (XRRenderStateInit.layers) {
|
|
7225
|
+
this.layers = XRRenderStateInit.layers;
|
|
7226
|
+
}
|
|
7227
|
+
if (!this.activeRenderState) {
|
|
7228
|
+
this.createActiveRenderState();
|
|
7229
|
+
}
|
|
7230
|
+
this.activeRenderState = Object.assign(Object.assign({}, this.activeRenderState), XRRenderStateInit);
|
|
7231
|
+
if (!XRRenderStateInit.layers) {
|
|
7232
|
+
this._updateRenderState(XRRenderStateInit);
|
|
7233
|
+
return;
|
|
7234
|
+
}
|
|
7235
|
+
let layerRenderStateInit = Object.assign({}, XRRenderStateInit);
|
|
7236
|
+
delete layerRenderStateInit.layers;
|
|
7237
|
+
let context = undefined;
|
|
7238
|
+
for (let layer of this.layers) {
|
|
7239
|
+
if (layer instanceof XRCompositionLayerPolyfill) {
|
|
7240
|
+
context = layer.getContext();
|
|
7241
|
+
break;
|
|
7242
|
+
}
|
|
7243
|
+
}
|
|
7244
|
+
if (!context && !this.context) {
|
|
7245
|
+
console.log('No existing context! Have the session make one');
|
|
7246
|
+
const canvas = document.createElement('canvas');
|
|
7247
|
+
context = canvas.getContext('webgl2', { xrCompatible: true });
|
|
7248
|
+
if (!context) {
|
|
7249
|
+
context = canvas.getContext('webgl', { xrCompatible: true });
|
|
7250
|
+
}
|
|
7251
|
+
if (!context) {
|
|
7252
|
+
throw new Error('No webGL support detected.');
|
|
7253
|
+
}
|
|
7254
|
+
document.body.appendChild(context.canvas);
|
|
7255
|
+
function onResize() {
|
|
7256
|
+
context.canvas.width = context.canvas.clientWidth * window.devicePixelRatio;
|
|
7257
|
+
context.canvas.height = context.canvas.clientHeight * window.devicePixelRatio;
|
|
7258
|
+
}
|
|
7259
|
+
window.addEventListener('resize', onResize);
|
|
7260
|
+
onResize();
|
|
7261
|
+
}
|
|
7262
|
+
this.createInternalLayer(context);
|
|
7263
|
+
this.isPolyfillActive = true;
|
|
7264
|
+
this._updateRenderState(Object.assign(Object.assign({}, layerRenderStateInit), { baseLayer: this.internalLayer }));
|
|
7265
|
+
}
|
|
7266
|
+
initializeSession(mode) {
|
|
7267
|
+
this.mode = mode;
|
|
7268
|
+
this
|
|
7269
|
+
.requestReferenceSpace('local')
|
|
7270
|
+
.then((refSpace) => {
|
|
7271
|
+
this.referenceSpace = refSpace;
|
|
7272
|
+
})
|
|
7273
|
+
.catch((e) => {
|
|
7274
|
+
});
|
|
7275
|
+
this.requestReferenceSpace('viewer').then((viewerSpace) => {
|
|
7276
|
+
this.viewerSpace = viewerSpace;
|
|
7277
|
+
});
|
|
7278
|
+
}
|
|
7279
|
+
getBaseLayer(context) {
|
|
7280
|
+
if (!this.internalLayer && !this.existingBaseLayer && context) {
|
|
7281
|
+
this.createInternalLayer(context);
|
|
7282
|
+
}
|
|
7283
|
+
return this.internalLayer || this.existingBaseLayer;
|
|
7284
|
+
}
|
|
7285
|
+
getReferenceSpace() {
|
|
7286
|
+
return !this.referenceSpace ? this.viewerSpace : this.referenceSpace;
|
|
7287
|
+
}
|
|
7288
|
+
getViewerSpace() {
|
|
7289
|
+
return this.viewerSpace;
|
|
7290
|
+
}
|
|
7291
|
+
queueTask(task) {
|
|
7292
|
+
this.taskQueue.push(task);
|
|
7293
|
+
}
|
|
7294
|
+
get renderState() {
|
|
7295
|
+
if (!this.activeRenderState) {
|
|
7296
|
+
this.createActiveRenderState();
|
|
7297
|
+
}
|
|
7298
|
+
return this.activeRenderState;
|
|
7299
|
+
}
|
|
7300
|
+
get internalViews() {
|
|
7301
|
+
return this.views;
|
|
7302
|
+
}
|
|
7303
|
+
getViewIndex(view) {
|
|
7304
|
+
for (let i = 0; i < this.views.length; i++) {
|
|
7305
|
+
let testView = this.views[i];
|
|
7306
|
+
if (view.eye === testView.eye &&
|
|
7307
|
+
view.recommendedViewportScale === testView.recommendedViewportScale) {
|
|
7308
|
+
return i;
|
|
7309
|
+
}
|
|
7310
|
+
}
|
|
7311
|
+
return -1;
|
|
7312
|
+
}
|
|
7313
|
+
createInternalLayer(context) {
|
|
7314
|
+
if (!context && this.internalLayer) {
|
|
7315
|
+
return this.internalLayer;
|
|
7316
|
+
}
|
|
7317
|
+
if (context === this.context && this.internalLayer) {
|
|
7318
|
+
return this.internalLayer;
|
|
7319
|
+
}
|
|
7320
|
+
const _global = getGlobal();
|
|
7321
|
+
this.internalLayer = new _global.XRWebGLLayer(this, context);
|
|
7322
|
+
this.setContext(context);
|
|
7323
|
+
return this.internalLayer;
|
|
7324
|
+
}
|
|
7325
|
+
setContext(context) {
|
|
7326
|
+
this.context = context;
|
|
7327
|
+
this.tempFramebuffer = context.createFramebuffer();
|
|
7328
|
+
this.renderers = new WeakMap();
|
|
7329
|
+
}
|
|
7330
|
+
createActiveRenderState() {
|
|
7331
|
+
const _global = getGlobal();
|
|
7332
|
+
let prototypeNames = Object.getOwnPropertyNames(_global.XRRenderState.prototype);
|
|
7333
|
+
const renderStateClone = {};
|
|
7334
|
+
for (let item of prototypeNames) {
|
|
7335
|
+
renderStateClone[item] = this._renderState[item];
|
|
7336
|
+
}
|
|
7337
|
+
renderStateClone.layers = [];
|
|
7338
|
+
this.activeRenderState = renderStateClone;
|
|
7339
|
+
}
|
|
7340
|
+
}
|
|
7341
|
+
|
|
7342
|
+
class XRWebGLSubImagePolyfill {
|
|
7343
|
+
constructor() {
|
|
7344
|
+
this.viewport = {
|
|
7345
|
+
x: 0,
|
|
7346
|
+
y: 0,
|
|
7347
|
+
width: 0,
|
|
7348
|
+
height: 0,
|
|
7349
|
+
};
|
|
7350
|
+
}
|
|
7351
|
+
}
|
|
7352
|
+
|
|
7353
|
+
class XRWebGLBindingPolyfill {
|
|
7354
|
+
constructor(session, context) {
|
|
7355
|
+
this.session = session;
|
|
7356
|
+
this.context = context;
|
|
7357
|
+
this.subImageCache = new SubImageCache();
|
|
7358
|
+
}
|
|
7359
|
+
createProjectionLayer(init = defaultXRProjectionLayerInit) {
|
|
7360
|
+
const layer = new XRProjectionLayer(init);
|
|
7361
|
+
if (this.session.ended) {
|
|
7362
|
+
throw new Error('Session has ended');
|
|
7363
|
+
}
|
|
7364
|
+
if (this.context.isContextLost()) {
|
|
7365
|
+
throw new Error('context is lost');
|
|
7366
|
+
}
|
|
7367
|
+
layer.initialize(this.session, this.context);
|
|
7368
|
+
return layer;
|
|
7369
|
+
}
|
|
7370
|
+
createQuadLayer(init = defaultQuadLayerInit) {
|
|
7371
|
+
if (this.session.ended) {
|
|
7372
|
+
throw new Error('Session has ended');
|
|
7373
|
+
}
|
|
7374
|
+
if (this.context.isContextLost()) {
|
|
7375
|
+
throw new Error('context is lost');
|
|
7376
|
+
}
|
|
7377
|
+
if (init.layout === XRLayerLayout.default) {
|
|
7378
|
+
throw new TypeError('Trying to create a quad layer with default layout');
|
|
7379
|
+
}
|
|
7380
|
+
const layer = new XRQuadLayer(init);
|
|
7381
|
+
layer.initialize(this.session, this.context);
|
|
7382
|
+
return layer;
|
|
7383
|
+
}
|
|
7384
|
+
createCylinderLayer(init = defaultCylinderLayerInit) {
|
|
7385
|
+
if (this.session.ended) {
|
|
7386
|
+
throw new Error('Session has ended');
|
|
7387
|
+
}
|
|
7388
|
+
if (this.context.isContextLost()) {
|
|
7389
|
+
throw new Error('context is lost');
|
|
7390
|
+
}
|
|
7391
|
+
if (init.layout === XRLayerLayout.default) {
|
|
7392
|
+
throw new TypeError('Cylinder Layer cannot have a default layout');
|
|
7393
|
+
}
|
|
7394
|
+
const layer = new XRCylinderLayer(init);
|
|
7395
|
+
layer.initialize(this.session, this.context);
|
|
7396
|
+
return layer;
|
|
7397
|
+
}
|
|
7398
|
+
createEquirectLayer(init = defaultEquirectLayerInit) {
|
|
7399
|
+
if (this.session.ended) {
|
|
7400
|
+
throw new Error('Session has ended');
|
|
7401
|
+
}
|
|
7402
|
+
if (this.context.isContextLost()) {
|
|
7403
|
+
throw new Error('context is lost');
|
|
7404
|
+
}
|
|
7405
|
+
if (init.layout === XRLayerLayout.default) {
|
|
7406
|
+
throw new TypeError('Equirect Layer cannot have a default layout');
|
|
7407
|
+
}
|
|
7408
|
+
if (!isReferenceSpace(init.space)) {
|
|
7409
|
+
throw new TypeError('Equirect layer requires an XRReferenceSpace');
|
|
7410
|
+
}
|
|
7411
|
+
let layer = new XREquirectLayer(init);
|
|
7412
|
+
layer.initialize(this.session, this.context);
|
|
7413
|
+
return layer;
|
|
7414
|
+
}
|
|
7415
|
+
createCubeLayer(init) {
|
|
7416
|
+
if (this.session.ended) {
|
|
7417
|
+
throw new Error('Session has ended');
|
|
7418
|
+
}
|
|
7419
|
+
if (this.context.isContextLost()) {
|
|
7420
|
+
throw new Error('context is lost');
|
|
7421
|
+
}
|
|
7422
|
+
if (!(this.context instanceof WebGL2RenderingContext)) {
|
|
7423
|
+
throw new Error('XRCubeLayer only work on WebGL2');
|
|
7424
|
+
}
|
|
7425
|
+
if (!isReferenceSpace(init.space)) {
|
|
7426
|
+
throw new TypeError('XRCubeLayer requires a space of type XRReferenceSpace');
|
|
7427
|
+
}
|
|
7428
|
+
let layer = new XRCubeLayer(init);
|
|
7429
|
+
layer.initialize(this.session, this.context);
|
|
7430
|
+
return layer;
|
|
7431
|
+
}
|
|
7432
|
+
getSubImage(layer, frame, eye = 'none') {
|
|
7433
|
+
if (layer.isStatic && (layer.needsRedraw === false)) {
|
|
7434
|
+
throw new Error('Invalid state for subimage creation');
|
|
7435
|
+
}
|
|
7436
|
+
let existingSubImage = this.subImageCache.tryGetCachedSubImage(this.context, layer, eye);
|
|
7437
|
+
if (existingSubImage) {
|
|
7438
|
+
return existingSubImage;
|
|
7439
|
+
}
|
|
7440
|
+
let subimage = new XRWebGLSubImagePolyfill();
|
|
7441
|
+
if (layer instanceof XRProjectionLayer) {
|
|
7442
|
+
throw new TypeError();
|
|
7443
|
+
}
|
|
7444
|
+
if (layer.layout === XRLayerLayout.default) {
|
|
7445
|
+
throw new TypeError();
|
|
7446
|
+
}
|
|
7447
|
+
if (!this.validateStateofSubImageCreation(layer, frame)) {
|
|
7448
|
+
throw new Error('Invalid state for subimage creation');
|
|
7449
|
+
}
|
|
7450
|
+
let index = 0;
|
|
7451
|
+
if (layer.layout === XRLayerLayout.stereo) {
|
|
7452
|
+
if (eye === 'none') {
|
|
7453
|
+
throw new TypeError();
|
|
7454
|
+
}
|
|
7455
|
+
if (eye === 'right') {
|
|
7456
|
+
index = 1;
|
|
7457
|
+
}
|
|
7458
|
+
}
|
|
7459
|
+
if (layer.getTextureType() === XRTextureType['texture-array']) {
|
|
7460
|
+
subimage.imageIndex = index;
|
|
7461
|
+
}
|
|
7462
|
+
else {
|
|
7463
|
+
subimage.imageIndex = 0;
|
|
7464
|
+
}
|
|
7465
|
+
let _textureIndex = 0;
|
|
7466
|
+
if (layer.getTextureType() === XRTextureType.texture) {
|
|
7467
|
+
subimage.colorTexture = layer.colorTextures[index];
|
|
7468
|
+
_textureIndex = index;
|
|
7469
|
+
}
|
|
7470
|
+
else {
|
|
7471
|
+
subimage.colorTexture = layer.colorTextures[0];
|
|
7472
|
+
_textureIndex = 0;
|
|
7473
|
+
}
|
|
7474
|
+
if (!layer.depthStencilTextures || !layer.depthStencilTextures.length) {
|
|
7475
|
+
subimage.depthStencilTexture = null;
|
|
7476
|
+
}
|
|
7477
|
+
else if (layer.getTextureType() === XRTextureType.texture) {
|
|
7478
|
+
subimage.depthStencilTexture = layer.depthStencilTextures[index];
|
|
7479
|
+
}
|
|
7480
|
+
else {
|
|
7481
|
+
subimage.depthStencilTexture = layer.depthStencilTextures[0];
|
|
7482
|
+
}
|
|
7483
|
+
const layerMeta = layer.colorTexturesMeta[_textureIndex];
|
|
7484
|
+
subimage.textureWidth = layerMeta.width;
|
|
7485
|
+
subimage.textureHeight = layerMeta.height;
|
|
7486
|
+
let viewsPerTexture = 1;
|
|
7487
|
+
if (layer.layout === XRLayerLayout['stereo-left-right'] ||
|
|
7488
|
+
layer.layout === XRLayerLayout['stereo-top-bottom']) {
|
|
7489
|
+
viewsPerTexture = 2;
|
|
7490
|
+
}
|
|
7491
|
+
initializeViewport(subimage.viewport, layerMeta, layer.layout, index, viewsPerTexture);
|
|
7492
|
+
this.session.queueTask(() => {
|
|
7493
|
+
layer.needsRedraw = false;
|
|
7494
|
+
});
|
|
7495
|
+
this.subImageCache.cacheSubImage(subimage, this.context, layer, eye);
|
|
7496
|
+
return subimage;
|
|
7497
|
+
}
|
|
7498
|
+
getViewSubImage(layer, view) {
|
|
7499
|
+
let existingSubImage = this.subImageCache.tryGetCachedViewSubImage(this.context, layer, view);
|
|
7500
|
+
if (existingSubImage) {
|
|
7501
|
+
return existingSubImage;
|
|
7502
|
+
}
|
|
7503
|
+
let subimage = new XRWebGLSubImagePolyfill();
|
|
7504
|
+
let session = this.session;
|
|
7505
|
+
if (!session.internalViews || !session.internalViews.length) {
|
|
7506
|
+
console.warn('Tried to get view sub image before we have any views');
|
|
7507
|
+
return subimage;
|
|
7508
|
+
}
|
|
7509
|
+
let index = session.getViewIndex(view);
|
|
7510
|
+
let _textureIndex = 0;
|
|
7511
|
+
if (layer.getTextureType() === XRTextureType['texture-array']) {
|
|
7512
|
+
subimage.imageIndex = index;
|
|
7513
|
+
}
|
|
7514
|
+
else {
|
|
7515
|
+
subimage.imageIndex = 0;
|
|
7516
|
+
}
|
|
7517
|
+
if (layer.layout === XRLayerLayout.default &&
|
|
7518
|
+
layer.getTextureType() === XRTextureType.texture) {
|
|
7519
|
+
subimage.colorTexture = layer.colorTextures[index];
|
|
7520
|
+
_textureIndex = index;
|
|
7521
|
+
}
|
|
7522
|
+
else {
|
|
7523
|
+
subimage.colorTexture = layer.colorTextures[0];
|
|
7524
|
+
_textureIndex = 0;
|
|
7525
|
+
}
|
|
7526
|
+
if (layer.depthStencilTextures.length === 0) {
|
|
7527
|
+
subimage.depthStencilTexture = null;
|
|
7528
|
+
}
|
|
7529
|
+
else if (layer.layout === XRLayerLayout.default &&
|
|
7530
|
+
layer.getTextureType() === XRTextureType.texture) {
|
|
7531
|
+
subimage.depthStencilTexture = layer.depthStencilTextures[index];
|
|
7532
|
+
}
|
|
7533
|
+
else {
|
|
7534
|
+
subimage.depthStencilTexture = layer.depthStencilTextures[0];
|
|
7535
|
+
}
|
|
7536
|
+
subimage.textureWidth = layer.colorTexturesMeta[_textureIndex].width;
|
|
7537
|
+
subimage.textureHeight = layer.colorTexturesMeta[_textureIndex].height;
|
|
7538
|
+
initializeViewport(subimage.viewport, layer.colorTexturesMeta[_textureIndex], layer.layout, index, session.internalViews.length);
|
|
7539
|
+
layer.needsRedraw = false;
|
|
7540
|
+
this.subImageCache.cacheViewSubImage(subimage, this.context, layer, view);
|
|
7541
|
+
return subimage;
|
|
7542
|
+
}
|
|
7543
|
+
validateStateofSubImageCreation(layer, frame) {
|
|
7544
|
+
if (frame.session !== layer.session) {
|
|
7545
|
+
return false;
|
|
7546
|
+
}
|
|
7547
|
+
if (this.session !== layer.session) {
|
|
7548
|
+
return false;
|
|
7549
|
+
}
|
|
7550
|
+
if (this.context !== layer.context) {
|
|
7551
|
+
return false;
|
|
7552
|
+
}
|
|
7553
|
+
if (!layer.colorTextures || !layer.colorTextures.length) {
|
|
7554
|
+
return false;
|
|
7555
|
+
}
|
|
7556
|
+
if (layer.isStatic && layer.needsRedraw === false) {
|
|
7557
|
+
return false;
|
|
7558
|
+
}
|
|
7559
|
+
return true;
|
|
7560
|
+
}
|
|
7561
|
+
}
|
|
7562
|
+
class SubImageCache {
|
|
7563
|
+
constructor() {
|
|
7564
|
+
this.cache = new Map();
|
|
7565
|
+
this.viewCache = new Map();
|
|
7566
|
+
}
|
|
7567
|
+
cacheSubImage(subimage, context, layer, eye) {
|
|
7568
|
+
let eyeMap = new Map();
|
|
7569
|
+
eyeMap.set(eye, subimage);
|
|
7570
|
+
let layerMap = new Map();
|
|
7571
|
+
layerMap.set(layer, eyeMap);
|
|
7572
|
+
this.cache.set(context, layerMap);
|
|
7573
|
+
}
|
|
7574
|
+
tryGetCachedSubImage(context, layer, eye) {
|
|
7575
|
+
var _a, _b;
|
|
7576
|
+
return (_b = (_a = this.cache.get(context)) === null || _a === void 0 ? void 0 : _a.get(layer)) === null || _b === void 0 ? void 0 : _b.get(eye);
|
|
7577
|
+
}
|
|
7578
|
+
cacheViewSubImage(subimage, context, layer, view) {
|
|
7579
|
+
let viewMap = new Map();
|
|
7580
|
+
viewMap.set(view, subimage);
|
|
7581
|
+
let layerMap = new Map();
|
|
7582
|
+
layerMap.set(layer, viewMap);
|
|
7583
|
+
this.viewCache.set(context, layerMap);
|
|
7584
|
+
}
|
|
7585
|
+
tryGetCachedViewSubImage(context, layer, view) {
|
|
7586
|
+
var _a, _b;
|
|
7587
|
+
return (_b = (_a = this.viewCache.get(context)) === null || _a === void 0 ? void 0 : _a.get(layer)) === null || _b === void 0 ? void 0 : _b.get(view);
|
|
7588
|
+
}
|
|
7589
|
+
}
|
|
7590
|
+
|
|
7591
|
+
const isLayersNativelySupported = (global) => {
|
|
7592
|
+
if (!global.navigator.xr) {
|
|
7593
|
+
return false;
|
|
7594
|
+
}
|
|
7595
|
+
if (global.XRMediaBinding && global.XRWebGLBinding) {
|
|
7596
|
+
return true;
|
|
7597
|
+
}
|
|
7598
|
+
return false;
|
|
7599
|
+
};
|
|
7600
|
+
|
|
7601
|
+
class WebXRLayersPolyfill {
|
|
7602
|
+
constructor() {
|
|
7603
|
+
this.injected = false;
|
|
7604
|
+
const _global = getGlobal();
|
|
7605
|
+
this._injectPolyfill(_global);
|
|
7606
|
+
}
|
|
7607
|
+
_injectPolyfill(global) {
|
|
7608
|
+
if (!('xr' in global.navigator)) {
|
|
7609
|
+
throw new Error('WebXR Layers polyfill requires WebXR support.');
|
|
7610
|
+
}
|
|
7611
|
+
if (this.injected === true) {
|
|
7612
|
+
console.warn('Polyfill has already been injected...');
|
|
7613
|
+
}
|
|
7614
|
+
if (isLayersNativelySupported(global)) {
|
|
7615
|
+
return;
|
|
7616
|
+
}
|
|
7617
|
+
this._polyfillRequiredLayersFeature(global);
|
|
7618
|
+
this._polyfillXRSession(global);
|
|
7619
|
+
global.XRWebGLBinding = XRWebGLBindingPolyfill;
|
|
7620
|
+
global.XRMediaBinding = XRMediaBindingPolyfill;
|
|
7621
|
+
this.injected = true;
|
|
7622
|
+
console.log('Injected Layers Polyfill');
|
|
7623
|
+
}
|
|
7624
|
+
_polyfillXRSession(global) {
|
|
7625
|
+
global.XRSession.prototype._updateRenderState = global.XRSession.prototype.updateRenderState;
|
|
7626
|
+
global.XRSession.prototype._requestAnimationFrame =
|
|
7627
|
+
global.XRSession.prototype.requestAnimationFrame;
|
|
7628
|
+
let renderStateGetter = Object.getOwnPropertyDescriptor(global.XRSession.prototype, 'renderState');
|
|
7629
|
+
Object.defineProperty(global.XRSession.prototype, '_renderState', renderStateGetter);
|
|
7630
|
+
let polyfillRenderStateGetter = Object.getOwnPropertyDescriptor(XRSessionWithLayer.prototype, 'renderState');
|
|
7631
|
+
Object.defineProperty(global.XRSession.prototype, 'renderState', polyfillRenderStateGetter);
|
|
7632
|
+
let prototypeNames = Object.getOwnPropertyNames(XRSessionWithLayer.prototype);
|
|
7633
|
+
for (let item of prototypeNames) {
|
|
7634
|
+
let propertyDescriptor = Object.getOwnPropertyDescriptor(XRSessionWithLayer.prototype, item);
|
|
7635
|
+
Object.defineProperty(global.XRSession.prototype, item, propertyDescriptor);
|
|
7636
|
+
}
|
|
7637
|
+
}
|
|
7638
|
+
_polyfillRequiredLayersFeature(global) {
|
|
7639
|
+
const existingRequestSession = global.navigator.xr.requestSession;
|
|
7640
|
+
Object.defineProperty(global.navigator.xr, 'requestSessionInternal', { writable: true });
|
|
7641
|
+
global.navigator.xr.requestSessionInternal = existingRequestSession;
|
|
7642
|
+
const newRequestSession = (sessionMode, sessionInit) => {
|
|
7643
|
+
const modifiedSessionPromise = (mode, init) => {
|
|
7644
|
+
return global.navigator.xr.requestSessionInternal(mode, init).then((session) => {
|
|
7645
|
+
Object.assign(session, new XRSessionWithLayer());
|
|
7646
|
+
let polyfilledSession = session;
|
|
7647
|
+
polyfilledSession.initializeSession(sessionMode);
|
|
7648
|
+
return Promise.resolve(polyfilledSession);
|
|
7649
|
+
});
|
|
7650
|
+
};
|
|
7651
|
+
if (sessionMode !== 'immersive-vr') {
|
|
7652
|
+
return modifiedSessionPromise(sessionMode, sessionInit);
|
|
7653
|
+
}
|
|
7654
|
+
if (!sessionInit) {
|
|
7655
|
+
return modifiedSessionPromise(sessionMode, sessionInit);
|
|
7656
|
+
}
|
|
7657
|
+
if (sessionInit.requiredFeatures && sessionInit.requiredFeatures.indexOf('layers') > -1) {
|
|
7658
|
+
const sessionInitClone = Object.assign({}, sessionInit);
|
|
7659
|
+
const reqFeatures = [...sessionInit.requiredFeatures];
|
|
7660
|
+
const layersIndex = reqFeatures.indexOf('layers');
|
|
7661
|
+
reqFeatures.splice(layersIndex, 1);
|
|
7662
|
+
sessionInitClone.requiredFeatures = reqFeatures;
|
|
7663
|
+
return modifiedSessionPromise(sessionMode, sessionInitClone);
|
|
7664
|
+
}
|
|
7665
|
+
return modifiedSessionPromise(sessionMode, sessionInit);
|
|
7666
|
+
};
|
|
7667
|
+
Object.defineProperty(global.navigator.xr, 'requestSession', { writable: true });
|
|
7668
|
+
global.navigator.xr.requestSession = newRequestSession;
|
|
7669
|
+
}
|
|
7670
|
+
}
|
|
7671
|
+
|
|
7672
|
+
/**
|
|
7673
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
7674
|
+
*
|
|
7675
|
+
* This source code is licensed under the MIT license found in the
|
|
7676
|
+
* LICENSE file in the root directory of this source tree.
|
|
7677
|
+
*/
|
|
7678
|
+
const DEFAULTS = {
|
|
7679
|
+
ipd: 0.063,
|
|
7680
|
+
fovy: Math.PI / 2,
|
|
7681
|
+
headsetPosition: new Vector3(0, 1.6, 0),
|
|
7682
|
+
headsetQuaternion: new Quaternion(),
|
|
7683
|
+
stereoEnabled: false,
|
|
7684
|
+
};
|
|
7685
|
+
const Z_INDEX_SEM_CANVAS = 1;
|
|
7686
|
+
const Z_INDEX_APP_CANVAS = 2;
|
|
7687
|
+
const Z_INDEX_DEVUI_CANVAS = 3;
|
|
7688
|
+
const Z_INDEX_DEVUI_CONTAINER = 4;
|
|
7689
|
+
/**
|
|
7690
|
+
* XRDevice is not a standard API class outlined in the WebXR Device API Specifications
|
|
7691
|
+
* Instead, it serves as an user-facing interface to control the emulated XR Device
|
|
7692
|
+
*/
|
|
7693
|
+
class XRDevice {
|
|
7694
|
+
constructor(deviceConfig, deviceOptions = {}) {
|
|
7695
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7696
|
+
this.version = VERSION;
|
|
7697
|
+
const globalSpace = new GlobalSpace();
|
|
7698
|
+
const viewerSpace = new XRReferenceSpace(XRReferenceSpaceType.Viewer, globalSpace);
|
|
7699
|
+
const viewSpaces = {
|
|
7700
|
+
[XREye.Left]: new XRSpace(viewerSpace),
|
|
7701
|
+
[XREye.Right]: new XRSpace(viewerSpace),
|
|
7702
|
+
[XREye.None]: new XRSpace(viewerSpace),
|
|
7703
|
+
};
|
|
7704
|
+
const controllerConfig = deviceConfig.controllerConfig;
|
|
7705
|
+
const controllers = {};
|
|
4791
7706
|
if (controllerConfig) {
|
|
4792
7707
|
Object.values(XRHandedness).forEach((handedness) => {
|
|
4793
7708
|
if (controllerConfig.layout[handedness]) {
|
|
@@ -4833,7 +7748,7 @@ class XRDevice {
|
|
|
4833
7748
|
visibilityState: 'visible',
|
|
4834
7749
|
pendingVisibilityState: null,
|
|
4835
7750
|
xrSystem: null,
|
|
4836
|
-
matrix: create$
|
|
7751
|
+
matrix: create$5(),
|
|
4837
7752
|
globalSpace,
|
|
4838
7753
|
viewerSpace,
|
|
4839
7754
|
viewSpaces,
|
|
@@ -4955,7 +7870,10 @@ class XRDevice {
|
|
|
4955
7870
|
};
|
|
4956
7871
|
this[P_DEVICE].updateViews();
|
|
4957
7872
|
}
|
|
4958
|
-
installRuntime(
|
|
7873
|
+
installRuntime(options) {
|
|
7874
|
+
var _a;
|
|
7875
|
+
const globalObject = (_a = options === null || options === void 0 ? void 0 : options.globalObject) !== null && _a !== void 0 ? _a : globalThis;
|
|
7876
|
+
const polyfillLayers = options === null || options === void 0 ? void 0 : options.polyfillLayers;
|
|
4959
7877
|
Object.defineProperty(WebGL2RenderingContext.prototype, 'makeXRCompatible', {
|
|
4960
7878
|
value: function () {
|
|
4961
7879
|
return new Promise((resolve, _reject) => {
|
|
@@ -4997,6 +7915,13 @@ class XRDevice {
|
|
|
4997
7915
|
globalObject['XRInputSourceEvent'] = XRInputSourceEvent;
|
|
4998
7916
|
globalObject['XRInputSourcesChangeEvent'] = XRInputSourcesChangeEvent;
|
|
4999
7917
|
globalObject['XRReferenceSpaceEvent'] = XRReferenceSpaceEvent;
|
|
7918
|
+
if (polyfillLayers) {
|
|
7919
|
+
new WebXRLayersPolyfill();
|
|
7920
|
+
}
|
|
7921
|
+
else {
|
|
7922
|
+
globalObject['XRMediaBinding'] = undefined;
|
|
7923
|
+
globalObject['XRWebGLBinding'] = undefined;
|
|
7924
|
+
}
|
|
5000
7925
|
}
|
|
5001
7926
|
installDevUI(devUIConstructor) {
|
|
5002
7927
|
this[P_DEVICE].devui = new devUIConstructor(this);
|
|
@@ -5117,11 +8042,16 @@ class XRDevice {
|
|
|
5117
8042
|
return this[P_DEVICE].name;
|
|
5118
8043
|
}
|
|
5119
8044
|
grantOfferedSession() {
|
|
5120
|
-
|
|
5121
|
-
const pSystem =
|
|
8045
|
+
const xrSystem = this[P_DEVICE].xrSystem;
|
|
8046
|
+
const pSystem = xrSystem === null || xrSystem === void 0 ? void 0 : xrSystem[P_SYSTEM];
|
|
5122
8047
|
if (pSystem && pSystem.offeredSessionConfig) {
|
|
5123
|
-
pSystem.
|
|
8048
|
+
const { resolve, reject, mode, options } = pSystem.offeredSessionConfig;
|
|
8049
|
+
// Clear the offered session config first
|
|
5124
8050
|
pSystem.offeredSessionConfig = undefined;
|
|
8051
|
+
// Use the same requestSession flow to ensure identical behavior
|
|
8052
|
+
xrSystem.requestSession(mode, options)
|
|
8053
|
+
.then(resolve)
|
|
8054
|
+
.catch(reject);
|
|
5125
8055
|
}
|
|
5126
8056
|
}
|
|
5127
8057
|
recenter() {
|
|
@@ -5440,7 +8370,7 @@ const metaQuest3 = {
|
|
|
5440
8370
|
*/
|
|
5441
8371
|
const compress = (arr) => {
|
|
5442
8372
|
const out = [];
|
|
5443
|
-
arr.forEach((num) => {
|
|
8373
|
+
Array.from(arr).forEach((num) => {
|
|
5444
8374
|
out.push(parseFloat(num.toFixed(3)));
|
|
5445
8375
|
});
|
|
5446
8376
|
return out;
|
|
@@ -5463,8 +8393,8 @@ class ActionRecorder {
|
|
|
5463
8393
|
const viewerMatrix = (_a = frame.getViewerPose(this[P_ACTION_RECORDER].refSpace)) === null || _a === void 0 ? void 0 : _a.transform.matrix;
|
|
5464
8394
|
if (!viewerMatrix)
|
|
5465
8395
|
return;
|
|
5466
|
-
const position = getTranslation(create$
|
|
5467
|
-
const quaternion = getRotation(create(), viewerMatrix);
|
|
8396
|
+
const position = getTranslation(create$4(), viewerMatrix);
|
|
8397
|
+
const quaternion = getRotation(create$2(), viewerMatrix);
|
|
5468
8398
|
const actionFrame = {
|
|
5469
8399
|
timeStamp,
|
|
5470
8400
|
position,
|
|
@@ -5498,8 +8428,8 @@ class ActionRecorder {
|
|
|
5498
8428
|
const schema = this[P_ACTION_RECORDER].schemaMap.get(index);
|
|
5499
8429
|
const targetRayMatrix = (_a = frame.getPose(inputSource.targetRaySpace, this[P_ACTION_RECORDER].refSpace)) === null || _a === void 0 ? void 0 : _a.transform.matrix;
|
|
5500
8430
|
if (targetRayMatrix) {
|
|
5501
|
-
const targetRayPosition = getTranslation(create$
|
|
5502
|
-
const targetRayQuaternion = getRotation(create(), targetRayMatrix);
|
|
8431
|
+
const targetRayPosition = getTranslation(create$4(), targetRayMatrix);
|
|
8432
|
+
const targetRayQuaternion = getRotation(create$2(), targetRayMatrix);
|
|
5503
8433
|
const inputFrame = {
|
|
5504
8434
|
index,
|
|
5505
8435
|
targetRayTransform: {
|
|
@@ -5510,8 +8440,8 @@ class ActionRecorder {
|
|
|
5510
8440
|
if (schema.hasGrip) {
|
|
5511
8441
|
const gripMatrix = (_b = frame.getPose(inputSource.gripSpace, this[P_ACTION_RECORDER].refSpace)) === null || _b === void 0 ? void 0 : _b.transform.matrix;
|
|
5512
8442
|
if (gripMatrix) {
|
|
5513
|
-
const position = getTranslation(create$
|
|
5514
|
-
const quaternion = getRotation(create(), gripMatrix);
|
|
8443
|
+
const position = getTranslation(create$4(), gripMatrix);
|
|
8444
|
+
const quaternion = getRotation(create$2(), gripMatrix);
|
|
5515
8445
|
inputFrame.gripTransform = {
|
|
5516
8446
|
position,
|
|
5517
8447
|
quaternion,
|
|
@@ -5530,8 +8460,8 @@ class ActionRecorder {
|
|
|
5530
8460
|
for (let offset = 0; offset < 25; offset++) {
|
|
5531
8461
|
const jointMatrix = this[P_ACTION_RECORDER].jointTransforms.slice(offset * 16, (offset + 1) * 16);
|
|
5532
8462
|
const radius = this[P_ACTION_RECORDER].jointRadii[offset];
|
|
5533
|
-
const position = getTranslation(create$
|
|
5534
|
-
const quaternion = getRotation(create(), jointMatrix);
|
|
8463
|
+
const position = getTranslation(create$4(), jointMatrix);
|
|
8464
|
+
const quaternion = getRotation(create$2(), jointMatrix);
|
|
5535
8465
|
const jointName = jointSpaces[offset].jointName;
|
|
5536
8466
|
hand[jointName] = { position, quaternion, radius };
|
|
5537
8467
|
}
|