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