iwer 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/iwer.js +1396 -754
- package/build/iwer.min.js +1 -1
- package/build/iwer.module.js +1361 -755
- package/build/iwer.module.min.js +1 -1
- package/lib/action/ActionPlayer.d.ts +3 -3
- package/lib/action/ActionPlayer.d.ts.map +1 -1
- package/lib/action/ActionPlayer.js +43 -41
- package/lib/action/ActionPlayer.js.map +1 -1
- package/lib/action/ActionRecorder.d.ts +2 -2
- package/lib/action/ActionRecorder.d.ts.map +1 -1
- package/lib/action/ActionRecorder.js +20 -20
- package/lib/action/ActionRecorder.js.map +1 -1
- package/lib/anchors/XRAnchor.d.ts +27 -0
- package/lib/anchors/XRAnchor.d.ts.map +1 -0
- package/lib/anchors/XRAnchor.js +73 -0
- package/lib/anchors/XRAnchor.js.map +1 -0
- package/lib/device/XRController.d.ts +2 -2
- package/lib/device/XRController.d.ts.map +1 -1
- package/lib/device/XRController.js +12 -16
- package/lib/device/XRController.js.map +1 -1
- package/lib/device/XRDevice.d.ts +16 -18
- package/lib/device/XRDevice.d.ts.map +1 -1
- package/lib/device/XRDevice.js +81 -93
- package/lib/device/XRDevice.js.map +1 -1
- package/lib/device/XRHandInput.d.ts +3 -3
- package/lib/device/XRHandInput.d.ts.map +1 -1
- package/lib/device/XRHandInput.js +18 -20
- package/lib/device/XRHandInput.js.map +1 -1
- package/lib/device/XRTrackedInput.d.ts +2 -2
- package/lib/device/XRTrackedInput.d.ts.map +1 -1
- package/lib/device/XRTrackedInput.js +30 -31
- package/lib/device/XRTrackedInput.js.map +1 -1
- package/lib/device/configs/headset/meta.d.ts.map +1 -1
- package/lib/device/configs/headset/meta.js +52 -69
- package/lib/device/configs/headset/meta.js.map +1 -1
- package/lib/frameloop/XRFrame.d.ts +18 -4
- package/lib/frameloop/XRFrame.d.ts.map +1 -1
- package/lib/frameloop/XRFrame.js +77 -24
- package/lib/frameloop/XRFrame.js.map +1 -1
- package/lib/gamepad/Gamepad.d.ts +3 -3
- package/lib/gamepad/Gamepad.d.ts.map +1 -1
- package/lib/gamepad/Gamepad.js +27 -27
- package/lib/gamepad/Gamepad.js.map +1 -1
- package/lib/hittest/XRHitTest.d.ts +35 -0
- package/lib/hittest/XRHitTest.d.ts.map +1 -0
- package/lib/hittest/XRHitTest.js +34 -0
- package/lib/hittest/XRHitTest.js.map +1 -0
- package/lib/hittest/XRRay.d.ts +22 -0
- package/lib/hittest/XRRay.d.ts.map +1 -0
- package/lib/hittest/XRRay.js +93 -0
- package/lib/hittest/XRRay.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -1
- package/lib/initialization/XRSystem.d.ts +3 -3
- package/lib/initialization/XRSystem.d.ts.map +1 -1
- package/lib/initialization/XRSystem.js +12 -13
- package/lib/initialization/XRSystem.js.map +1 -1
- package/lib/input/XRInputSource.d.ts +2 -2
- package/lib/input/XRInputSource.d.ts.map +1 -1
- package/lib/input/XRInputSource.js +9 -9
- package/lib/input/XRInputSource.js.map +1 -1
- package/lib/labels/labels.d.ts +29 -0
- package/lib/labels/labels.d.ts.map +1 -0
- package/lib/labels/labels.js +31 -0
- package/lib/labels/labels.js.map +1 -0
- package/lib/layers/XRWebGLLayer.d.ts +2 -2
- package/lib/layers/XRWebGLLayer.d.ts.map +1 -1
- package/lib/layers/XRWebGLLayer.js +11 -13
- package/lib/layers/XRWebGLLayer.js.map +1 -1
- package/lib/meshes/XRMesh.d.ts +38 -0
- package/lib/meshes/XRMesh.d.ts.map +1 -0
- package/lib/meshes/XRMesh.js +46 -0
- package/lib/meshes/XRMesh.js.map +1 -0
- package/lib/planes/XRPlane.d.ts +46 -0
- package/lib/planes/XRPlane.d.ts.map +1 -0
- package/lib/planes/XRPlane.js +73 -0
- package/lib/planes/XRPlane.js.map +1 -0
- package/lib/pose/XRJointPose.d.ts +2 -2
- package/lib/pose/XRJointPose.d.ts.map +1 -1
- package/lib/pose/XRJointPose.js +3 -3
- package/lib/pose/XRJointPose.js.map +1 -1
- package/lib/pose/XRPose.d.ts +2 -2
- package/lib/pose/XRPose.d.ts.map +1 -1
- package/lib/pose/XRPose.js +6 -6
- package/lib/pose/XRPose.js.map +1 -1
- package/lib/pose/XRViewerPose.d.ts +2 -2
- package/lib/pose/XRViewerPose.d.ts.map +1 -1
- package/lib/pose/XRViewerPose.js +3 -3
- package/lib/pose/XRViewerPose.js.map +1 -1
- package/lib/primitives/XRRigidTransform.d.ts +2 -2
- package/lib/primitives/XRRigidTransform.d.ts.map +1 -1
- package/lib/primitives/XRRigidTransform.js +11 -11
- package/lib/primitives/XRRigidTransform.js.map +1 -1
- package/lib/private.d.ts +34 -0
- package/lib/private.d.ts.map +1 -0
- package/lib/private.js +34 -0
- package/lib/private.js.map +1 -0
- package/lib/session/XRRenderState.d.ts +2 -2
- package/lib/session/XRRenderState.d.ts.map +1 -1
- package/lib/session/XRRenderState.js +6 -6
- package/lib/session/XRRenderState.js.map +1 -1
- package/lib/session/XRSession.d.ts +30 -16
- package/lib/session/XRSession.d.ts.map +1 -1
- package/lib/session/XRSession.js +268 -127
- package/lib/session/XRSession.js.map +1 -1
- package/lib/spaces/XRJointSpace.d.ts +2 -2
- package/lib/spaces/XRJointSpace.d.ts.map +1 -1
- package/lib/spaces/XRJointSpace.js +3 -3
- package/lib/spaces/XRJointSpace.js.map +1 -1
- package/lib/spaces/XRReferenceSpace.d.ts +2 -2
- package/lib/spaces/XRReferenceSpace.d.ts.map +1 -1
- package/lib/spaces/XRReferenceSpace.js +8 -8
- package/lib/spaces/XRReferenceSpace.js.map +1 -1
- package/lib/spaces/XRSpace.d.ts +2 -2
- package/lib/spaces/XRSpace.d.ts.map +1 -1
- package/lib/spaces/XRSpace.js +8 -8
- package/lib/spaces/XRSpace.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/views/XRView.d.ts +2 -2
- package/lib/views/XRView.d.ts.map +1 -1
- package/lib/views/XRView.js +7 -7
- package/lib/views/XRView.js.map +1 -1
- package/lib/views/XRViewport.d.ts +2 -2
- package/lib/views/XRViewport.d.ts.map +1 -1
- package/lib/views/XRViewport.js +6 -6
- package/lib/views/XRViewport.js.map +1 -1
- package/package.json +1 -1
package/build/iwer.js
CHANGED
|
@@ -140,6 +140,32 @@
|
|
|
140
140
|
out[15] = a[15];
|
|
141
141
|
return out;
|
|
142
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Set a mat4 to the identity matrix
|
|
145
|
+
*
|
|
146
|
+
* @param {mat4} out the receiving matrix
|
|
147
|
+
* @returns {mat4} out
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
function identity(out) {
|
|
151
|
+
out[0] = 1;
|
|
152
|
+
out[1] = 0;
|
|
153
|
+
out[2] = 0;
|
|
154
|
+
out[3] = 0;
|
|
155
|
+
out[4] = 0;
|
|
156
|
+
out[5] = 1;
|
|
157
|
+
out[6] = 0;
|
|
158
|
+
out[7] = 0;
|
|
159
|
+
out[8] = 0;
|
|
160
|
+
out[9] = 0;
|
|
161
|
+
out[10] = 1;
|
|
162
|
+
out[11] = 0;
|
|
163
|
+
out[12] = 0;
|
|
164
|
+
out[13] = 0;
|
|
165
|
+
out[14] = 0;
|
|
166
|
+
out[15] = 1;
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
143
169
|
/**
|
|
144
170
|
* Inverts a mat4
|
|
145
171
|
*
|
|
@@ -295,6 +321,56 @@
|
|
|
295
321
|
out[15] = 1;
|
|
296
322
|
return out;
|
|
297
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* Creates a matrix from a given angle around a given axis
|
|
326
|
+
* This is equivalent to (but much faster than):
|
|
327
|
+
*
|
|
328
|
+
* mat4.identity(dest);
|
|
329
|
+
* mat4.rotate(dest, dest, rad, axis);
|
|
330
|
+
*
|
|
331
|
+
* @param {mat4} out mat4 receiving operation result
|
|
332
|
+
* @param {Number} rad the angle to rotate the matrix by
|
|
333
|
+
* @param {ReadonlyVec3} axis the axis to rotate around
|
|
334
|
+
* @returns {mat4} out
|
|
335
|
+
*/
|
|
336
|
+
|
|
337
|
+
function fromRotation(out, rad, axis) {
|
|
338
|
+
var x = axis[0],
|
|
339
|
+
y = axis[1],
|
|
340
|
+
z = axis[2];
|
|
341
|
+
var len = Math.hypot(x, y, z);
|
|
342
|
+
var s, c, t;
|
|
343
|
+
|
|
344
|
+
if (len < EPSILON) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
len = 1 / len;
|
|
349
|
+
x *= len;
|
|
350
|
+
y *= len;
|
|
351
|
+
z *= len;
|
|
352
|
+
s = Math.sin(rad);
|
|
353
|
+
c = Math.cos(rad);
|
|
354
|
+
t = 1 - c; // Perform rotation-specific matrix multiplication
|
|
355
|
+
|
|
356
|
+
out[0] = x * x * t + c;
|
|
357
|
+
out[1] = y * x * t + z * s;
|
|
358
|
+
out[2] = z * x * t - y * s;
|
|
359
|
+
out[3] = 0;
|
|
360
|
+
out[4] = x * y * t - z * s;
|
|
361
|
+
out[5] = y * y * t + c;
|
|
362
|
+
out[6] = z * y * t + x * s;
|
|
363
|
+
out[7] = 0;
|
|
364
|
+
out[8] = x * z * t + y * s;
|
|
365
|
+
out[9] = y * z * t - x * s;
|
|
366
|
+
out[10] = z * z * t + c;
|
|
367
|
+
out[11] = 0;
|
|
368
|
+
out[12] = 0;
|
|
369
|
+
out[13] = 0;
|
|
370
|
+
out[14] = 0;
|
|
371
|
+
out[15] = 1;
|
|
372
|
+
return out;
|
|
373
|
+
}
|
|
298
374
|
/**
|
|
299
375
|
* Creates a matrix from a quaternion rotation and vector translation
|
|
300
376
|
* This is equivalent to (but much faster than):
|
|
@@ -917,6 +993,26 @@
|
|
|
917
993
|
out[3] = w * len;
|
|
918
994
|
return out;
|
|
919
995
|
}
|
|
996
|
+
/**
|
|
997
|
+
* Transforms the vec4 with a mat4.
|
|
998
|
+
*
|
|
999
|
+
* @param {vec4} out the receiving vector
|
|
1000
|
+
* @param {ReadonlyVec4} a the vector to transform
|
|
1001
|
+
* @param {ReadonlyMat4} m matrix to transform with
|
|
1002
|
+
* @returns {vec4} out
|
|
1003
|
+
*/
|
|
1004
|
+
|
|
1005
|
+
function transformMat4(out, a, m) {
|
|
1006
|
+
var x = a[0],
|
|
1007
|
+
y = a[1],
|
|
1008
|
+
z = a[2],
|
|
1009
|
+
w = a[3];
|
|
1010
|
+
out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
|
|
1011
|
+
out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
|
|
1012
|
+
out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
|
|
1013
|
+
out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
|
|
1014
|
+
return out;
|
|
1015
|
+
}
|
|
920
1016
|
/**
|
|
921
1017
|
* Perform some operation over an array of vec4s.
|
|
922
1018
|
*
|
|
@@ -1287,11 +1383,44 @@
|
|
|
1287
1383
|
* This source code is licensed under the MIT license found in the
|
|
1288
1384
|
* LICENSE file in the root directory of this source tree.
|
|
1289
1385
|
*/
|
|
1290
|
-
const
|
|
1386
|
+
const P_ACTION_PLAYER = Symbol('@iwer/action-player');
|
|
1387
|
+
const P_ACTION_RECORDER = Symbol('@iwer/action-recorder');
|
|
1388
|
+
const P_ANCHOR = Symbol('@iwer/xr-anchor');
|
|
1389
|
+
const P_CONTROLLER = Symbol('@iwer/xr-controller');
|
|
1390
|
+
const P_DEVICE = Symbol('@iwer/xr-device');
|
|
1391
|
+
const P_HAND_INPUT = Symbol('@iwer/xr-hand-input');
|
|
1392
|
+
const P_TRACKED_INPUT = Symbol('@iwer/xr-tracked-input');
|
|
1393
|
+
const P_FRAME = Symbol('@iwer/xr-frame');
|
|
1394
|
+
const P_GAMEPAD = Symbol('@iwer/gamepad');
|
|
1395
|
+
const P_SYSTEM = Symbol('@iwer/xr-system');
|
|
1396
|
+
const P_INPUT_SOURCE = Symbol('@iwer/xr-input-source');
|
|
1397
|
+
const P_WEBGL_LAYER = Symbol('@iwer/xr-webgl-layer');
|
|
1398
|
+
const P_MESH = Symbol('@iwer/xr-mesh');
|
|
1399
|
+
const P_PLANE = Symbol('@iwer/xr-plane');
|
|
1400
|
+
const P_JOINT_POSE = Symbol('@iwer/xr-joint-pose');
|
|
1401
|
+
const P_POSE = Symbol('@iwer/xr-pose');
|
|
1402
|
+
const P_VIEWER_POSE = Symbol('@iwer/xr-viewer-pose');
|
|
1403
|
+
const P_RIGID_TRANSFORM = Symbol('@iwer/xr-rigid-transform');
|
|
1404
|
+
const P_RENDER_STATE = Symbol('@iwer/xr-render-state');
|
|
1405
|
+
const P_SESSION = Symbol('@iwer/xr-session');
|
|
1406
|
+
const P_JOINT_SPACE = Symbol('@iwer/xr-joint-space');
|
|
1407
|
+
const P_REF_SPACE = Symbol('@iwer/xr-reference-space');
|
|
1408
|
+
const P_SPACE = Symbol('@iwer/xr-space');
|
|
1409
|
+
const P_VIEW = Symbol('@iwer/xr-view');
|
|
1410
|
+
const P_VIEWPORT = Symbol('@iwer/xr-viewport');
|
|
1411
|
+
const P_RAY = Symbol('@iwer/xr-ray');
|
|
1412
|
+
const P_HIT_TEST = Symbol('@iwer/xr-hit-test');
|
|
1413
|
+
|
|
1414
|
+
/**
|
|
1415
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
1416
|
+
*
|
|
1417
|
+
* This source code is licensed under the MIT license found in the
|
|
1418
|
+
* LICENSE file in the root directory of this source tree.
|
|
1419
|
+
*/
|
|
1291
1420
|
class XRSpace extends EventTarget {
|
|
1292
1421
|
constructor(parentSpace, offsetMatrix) {
|
|
1293
1422
|
super();
|
|
1294
|
-
this[
|
|
1423
|
+
this[P_SPACE] = {
|
|
1295
1424
|
parentSpace,
|
|
1296
1425
|
offsetMatrix: offsetMatrix ? clone(offsetMatrix) : create$3(),
|
|
1297
1426
|
emulated: true,
|
|
@@ -1306,27 +1435,27 @@
|
|
|
1306
1435
|
class XRSpaceUtils {
|
|
1307
1436
|
// Update the position component of the offsetMatrix of a given XRSpace
|
|
1308
1437
|
static updateOffsetPosition(space, position) {
|
|
1309
|
-
const offsetMatrix = space[
|
|
1438
|
+
const offsetMatrix = space[P_SPACE].offsetMatrix;
|
|
1310
1439
|
fromTranslation(offsetMatrix, position);
|
|
1311
1440
|
}
|
|
1312
1441
|
// Update the rotation component of the offsetMatrix of a given XRSpace using a quaternion
|
|
1313
1442
|
static updateOffsetQuaternion(space, quaternion) {
|
|
1314
|
-
const offsetMatrix = space[
|
|
1443
|
+
const offsetMatrix = space[P_SPACE].offsetMatrix;
|
|
1315
1444
|
const translation = create$2();
|
|
1316
1445
|
getTranslation(translation, offsetMatrix);
|
|
1317
1446
|
fromRotationTranslation(offsetMatrix, quaternion, translation);
|
|
1318
1447
|
}
|
|
1319
1448
|
// Update the offsetMatrix of a given XRSpace directly
|
|
1320
1449
|
static updateOffsetMatrix(space, matrix) {
|
|
1321
|
-
const offsetMatrix = space[
|
|
1450
|
+
const offsetMatrix = space[P_SPACE].offsetMatrix;
|
|
1322
1451
|
copy$3(offsetMatrix, matrix);
|
|
1323
1452
|
}
|
|
1324
1453
|
// Calculate the global offset matrix for a given XRSpace
|
|
1325
1454
|
static calculateGlobalOffsetMatrix(space, globalOffset = create$3()) {
|
|
1326
|
-
const parentOffset = space[
|
|
1327
|
-
? XRSpaceUtils.calculateGlobalOffsetMatrix(space[
|
|
1455
|
+
const parentOffset = space[P_SPACE].parentSpace
|
|
1456
|
+
? XRSpaceUtils.calculateGlobalOffsetMatrix(space[P_SPACE].parentSpace)
|
|
1328
1457
|
: create$3(); // Identity matrix for GlobalSpace
|
|
1329
|
-
multiply$1(globalOffset, parentOffset, space[
|
|
1458
|
+
multiply$1(globalOffset, parentOffset, space[P_SPACE].offsetMatrix);
|
|
1330
1459
|
return globalOffset;
|
|
1331
1460
|
}
|
|
1332
1461
|
}
|
|
@@ -1470,7 +1599,6 @@
|
|
|
1470
1599
|
* This source code is licensed under the MIT license found in the
|
|
1471
1600
|
* LICENSE file in the root directory of this source tree.
|
|
1472
1601
|
*/
|
|
1473
|
-
const PRIVATE$k = Symbol('@immersive-web-emulation-runtime/gamepad');
|
|
1474
1602
|
var GamepadMappingType;
|
|
1475
1603
|
(function (GamepadMappingType) {
|
|
1476
1604
|
GamepadMappingType["None"] = "";
|
|
@@ -1479,7 +1607,7 @@
|
|
|
1479
1607
|
})(GamepadMappingType || (GamepadMappingType = {}));
|
|
1480
1608
|
class GamepadButton {
|
|
1481
1609
|
constructor(type, eventTrigger) {
|
|
1482
|
-
this[
|
|
1610
|
+
this[P_GAMEPAD] = {
|
|
1483
1611
|
type,
|
|
1484
1612
|
eventTrigger,
|
|
1485
1613
|
pressed: false,
|
|
@@ -1490,23 +1618,23 @@
|
|
|
1490
1618
|
};
|
|
1491
1619
|
}
|
|
1492
1620
|
get pressed() {
|
|
1493
|
-
if (this[
|
|
1494
|
-
return this[
|
|
1621
|
+
if (this[P_GAMEPAD].type === 'manual') {
|
|
1622
|
+
return this[P_GAMEPAD].pressed;
|
|
1495
1623
|
}
|
|
1496
1624
|
else {
|
|
1497
|
-
return this[
|
|
1625
|
+
return this[P_GAMEPAD].value > 0;
|
|
1498
1626
|
}
|
|
1499
1627
|
}
|
|
1500
1628
|
get touched() {
|
|
1501
|
-
if (this[
|
|
1502
|
-
return this[
|
|
1629
|
+
if (this[P_GAMEPAD].type === 'manual') {
|
|
1630
|
+
return this[P_GAMEPAD].touched;
|
|
1503
1631
|
}
|
|
1504
1632
|
else {
|
|
1505
|
-
return this[
|
|
1633
|
+
return this[P_GAMEPAD].touched || this.pressed;
|
|
1506
1634
|
}
|
|
1507
1635
|
}
|
|
1508
1636
|
get value() {
|
|
1509
|
-
return this[
|
|
1637
|
+
return this[P_GAMEPAD].value;
|
|
1510
1638
|
}
|
|
1511
1639
|
}
|
|
1512
1640
|
class EmptyGamepadButton {
|
|
@@ -1518,7 +1646,7 @@
|
|
|
1518
1646
|
}
|
|
1519
1647
|
class Gamepad {
|
|
1520
1648
|
constructor(gamepadConfig, id = '', index = -1) {
|
|
1521
|
-
this[
|
|
1649
|
+
this[P_GAMEPAD] = {
|
|
1522
1650
|
id,
|
|
1523
1651
|
index,
|
|
1524
1652
|
connected: false,
|
|
@@ -1533,43 +1661,43 @@
|
|
|
1533
1661
|
gamepadConfig.buttons.forEach((buttonConfig) => {
|
|
1534
1662
|
var _a;
|
|
1535
1663
|
if (buttonConfig === null) {
|
|
1536
|
-
this[
|
|
1664
|
+
this[P_GAMEPAD].buttonsSequence.push(null);
|
|
1537
1665
|
}
|
|
1538
1666
|
else {
|
|
1539
|
-
this[
|
|
1540
|
-
this[
|
|
1667
|
+
this[P_GAMEPAD].buttonsSequence.push(buttonConfig.id);
|
|
1668
|
+
this[P_GAMEPAD].buttonsMap[buttonConfig.id] = new GamepadButton(buttonConfig.type, (_a = buttonConfig.eventTrigger) !== null && _a !== void 0 ? _a : null);
|
|
1541
1669
|
}
|
|
1542
1670
|
});
|
|
1543
1671
|
gamepadConfig.axes.forEach((axisConfig) => {
|
|
1544
1672
|
if (axisConfig === null) {
|
|
1545
|
-
this[
|
|
1673
|
+
this[P_GAMEPAD].axesSequence.push(null);
|
|
1546
1674
|
}
|
|
1547
1675
|
else {
|
|
1548
|
-
this[
|
|
1549
|
-
if (!this[
|
|
1550
|
-
this[
|
|
1676
|
+
this[P_GAMEPAD].axesSequence.push(axisConfig.id + axisConfig.type);
|
|
1677
|
+
if (!this[P_GAMEPAD].axesMap[axisConfig.id]) {
|
|
1678
|
+
this[P_GAMEPAD].axesMap[axisConfig.id] = { x: 0, y: 0 };
|
|
1551
1679
|
}
|
|
1552
1680
|
}
|
|
1553
1681
|
});
|
|
1554
1682
|
}
|
|
1555
1683
|
get id() {
|
|
1556
|
-
return this[
|
|
1684
|
+
return this[P_GAMEPAD].id;
|
|
1557
1685
|
}
|
|
1558
1686
|
get index() {
|
|
1559
|
-
return this[
|
|
1687
|
+
return this[P_GAMEPAD].index;
|
|
1560
1688
|
}
|
|
1561
1689
|
get connected() {
|
|
1562
|
-
return this[
|
|
1690
|
+
return this[P_GAMEPAD].connected;
|
|
1563
1691
|
}
|
|
1564
1692
|
get timestamp() {
|
|
1565
|
-
return this[
|
|
1693
|
+
return this[P_GAMEPAD].timestamp;
|
|
1566
1694
|
}
|
|
1567
1695
|
get mapping() {
|
|
1568
|
-
return this[
|
|
1696
|
+
return this[P_GAMEPAD].mapping;
|
|
1569
1697
|
}
|
|
1570
1698
|
get axes() {
|
|
1571
1699
|
const axes = [];
|
|
1572
|
-
this[
|
|
1700
|
+
this[P_GAMEPAD].axesSequence.forEach((id) => {
|
|
1573
1701
|
if (id === null) {
|
|
1574
1702
|
axes.push(null);
|
|
1575
1703
|
}
|
|
@@ -1579,17 +1707,17 @@
|
|
|
1579
1707
|
axes.push(
|
|
1580
1708
|
// if axis type is manual, then return the x value
|
|
1581
1709
|
axisType === 'y-axis'
|
|
1582
|
-
? this[
|
|
1583
|
-
: this[
|
|
1710
|
+
? this[P_GAMEPAD].axesMap[axisId].y
|
|
1711
|
+
: this[P_GAMEPAD].axesMap[axisId].x);
|
|
1584
1712
|
}
|
|
1585
1713
|
});
|
|
1586
1714
|
return axes;
|
|
1587
1715
|
}
|
|
1588
1716
|
get buttons() {
|
|
1589
|
-
return this[
|
|
1717
|
+
return this[P_GAMEPAD].buttonsSequence.map((id) => id === null ? new EmptyGamepadButton() : this[P_GAMEPAD].buttonsMap[id]);
|
|
1590
1718
|
}
|
|
1591
1719
|
get hapticActuators() {
|
|
1592
|
-
return this[
|
|
1720
|
+
return this[P_GAMEPAD].hapticActuators;
|
|
1593
1721
|
}
|
|
1594
1722
|
get vibrationActuator() {
|
|
1595
1723
|
return null;
|
|
@@ -1617,10 +1745,9 @@
|
|
|
1617
1745
|
})(XRTargetRayMode || (XRTargetRayMode = {}));
|
|
1618
1746
|
class XRInputSourceArray extends Array {
|
|
1619
1747
|
}
|
|
1620
|
-
const PRIVATE$j = Symbol('@immersive-web-emulation-runtime/xr-input-source');
|
|
1621
1748
|
class XRInputSource {
|
|
1622
1749
|
constructor(handedness, targetRayMode, profiles, targetRaySpace, gamepad, gripSpace, hand) {
|
|
1623
|
-
this[
|
|
1750
|
+
this[P_INPUT_SOURCE] = {
|
|
1624
1751
|
handedness,
|
|
1625
1752
|
targetRayMode,
|
|
1626
1753
|
targetRaySpace,
|
|
@@ -1631,25 +1758,25 @@
|
|
|
1631
1758
|
};
|
|
1632
1759
|
}
|
|
1633
1760
|
get handedness() {
|
|
1634
|
-
return this[
|
|
1761
|
+
return this[P_INPUT_SOURCE].handedness;
|
|
1635
1762
|
}
|
|
1636
1763
|
get targetRayMode() {
|
|
1637
|
-
return this[
|
|
1764
|
+
return this[P_INPUT_SOURCE].targetRayMode;
|
|
1638
1765
|
}
|
|
1639
1766
|
get targetRaySpace() {
|
|
1640
|
-
return this[
|
|
1767
|
+
return this[P_INPUT_SOURCE].targetRaySpace;
|
|
1641
1768
|
}
|
|
1642
1769
|
get gripSpace() {
|
|
1643
|
-
return this[
|
|
1770
|
+
return this[P_INPUT_SOURCE].gripSpace;
|
|
1644
1771
|
}
|
|
1645
1772
|
get profiles() {
|
|
1646
|
-
return this[
|
|
1773
|
+
return this[P_INPUT_SOURCE].profiles;
|
|
1647
1774
|
}
|
|
1648
1775
|
get gamepad() {
|
|
1649
|
-
return this[
|
|
1776
|
+
return this[P_INPUT_SOURCE].gamepad;
|
|
1650
1777
|
}
|
|
1651
1778
|
get hand() {
|
|
1652
|
-
return this[
|
|
1779
|
+
return this[P_INPUT_SOURCE].hand;
|
|
1653
1780
|
}
|
|
1654
1781
|
}
|
|
1655
1782
|
|
|
@@ -1679,7 +1806,6 @@
|
|
|
1679
1806
|
* This source code is licensed under the MIT license found in the
|
|
1680
1807
|
* LICENSE file in the root directory of this source tree.
|
|
1681
1808
|
*/
|
|
1682
|
-
const PRIVATE$i = Symbol('@immersive-web-emulation-runtime/xr-tracked-input');
|
|
1683
1809
|
const DEFAULT_TRANSFORM = {
|
|
1684
1810
|
[XRHandedness.Left]: {
|
|
1685
1811
|
position: new Vector3(-0.25, 1.5, -0.4),
|
|
@@ -1696,7 +1822,7 @@
|
|
|
1696
1822
|
};
|
|
1697
1823
|
class XRTrackedInput {
|
|
1698
1824
|
constructor(inputSource) {
|
|
1699
|
-
this[
|
|
1825
|
+
this[P_TRACKED_INPUT] = {
|
|
1700
1826
|
inputSource,
|
|
1701
1827
|
position: DEFAULT_TRANSFORM[inputSource.handedness].position.clone(),
|
|
1702
1828
|
quaternion: DEFAULT_TRANSFORM[inputSource.handedness].quaternion.clone(),
|
|
@@ -1706,59 +1832,59 @@
|
|
|
1706
1832
|
};
|
|
1707
1833
|
}
|
|
1708
1834
|
get position() {
|
|
1709
|
-
return this[
|
|
1835
|
+
return this[P_TRACKED_INPUT].position;
|
|
1710
1836
|
}
|
|
1711
1837
|
get quaternion() {
|
|
1712
|
-
return this[
|
|
1838
|
+
return this[P_TRACKED_INPUT].quaternion;
|
|
1713
1839
|
}
|
|
1714
1840
|
get inputSource() {
|
|
1715
|
-
return this[
|
|
1841
|
+
return this[P_TRACKED_INPUT].inputSource;
|
|
1716
1842
|
}
|
|
1717
1843
|
get connected() {
|
|
1718
|
-
return this[
|
|
1844
|
+
return this[P_TRACKED_INPUT].connected;
|
|
1719
1845
|
}
|
|
1720
1846
|
set connected(value) {
|
|
1721
|
-
this[
|
|
1722
|
-
this[
|
|
1847
|
+
this[P_TRACKED_INPUT].connected = value;
|
|
1848
|
+
this[P_TRACKED_INPUT].inputSource.gamepad[P_GAMEPAD].connected = value;
|
|
1723
1849
|
}
|
|
1724
1850
|
onFrameStart(frame) {
|
|
1725
|
-
const targetRaySpace = this[
|
|
1726
|
-
fromRotationTranslation(targetRaySpace[
|
|
1851
|
+
const targetRaySpace = this[P_TRACKED_INPUT].inputSource.targetRaySpace;
|
|
1852
|
+
fromRotationTranslation(targetRaySpace[P_SPACE].offsetMatrix, this[P_TRACKED_INPUT].quaternion.quat, this[P_TRACKED_INPUT].position.vec3);
|
|
1727
1853
|
const session = frame.session;
|
|
1728
|
-
this[
|
|
1854
|
+
this[P_TRACKED_INPUT].inputSource.gamepad.buttons.forEach((button) => {
|
|
1729
1855
|
if (button instanceof GamepadButton) {
|
|
1730
1856
|
// apply pending values and record last frame values
|
|
1731
|
-
button[
|
|
1732
|
-
if (button[
|
|
1733
|
-
button[
|
|
1734
|
-
button[
|
|
1857
|
+
button[P_GAMEPAD].lastFrameValue = button[P_GAMEPAD].value;
|
|
1858
|
+
if (button[P_GAMEPAD].pendingValue != null) {
|
|
1859
|
+
button[P_GAMEPAD].value = button[P_GAMEPAD].pendingValue;
|
|
1860
|
+
button[P_GAMEPAD].pendingValue = null;
|
|
1735
1861
|
}
|
|
1736
1862
|
// trigger input source events
|
|
1737
|
-
if (button[
|
|
1738
|
-
if (button[
|
|
1739
|
-
button[
|
|
1740
|
-
session.dispatchEvent(new XRInputSourceEvent(button[
|
|
1863
|
+
if (button[P_GAMEPAD].eventTrigger != null) {
|
|
1864
|
+
if (button[P_GAMEPAD].lastFrameValue === 0 &&
|
|
1865
|
+
button[P_GAMEPAD].value > 0) {
|
|
1866
|
+
session.dispatchEvent(new XRInputSourceEvent(button[P_GAMEPAD].eventTrigger, {
|
|
1741
1867
|
frame,
|
|
1742
|
-
inputSource: this[
|
|
1868
|
+
inputSource: this[P_TRACKED_INPUT].inputSource,
|
|
1743
1869
|
}));
|
|
1744
|
-
session.dispatchEvent(new XRInputSourceEvent(button[
|
|
1870
|
+
session.dispatchEvent(new XRInputSourceEvent(button[P_GAMEPAD].eventTrigger + 'start', {
|
|
1745
1871
|
frame,
|
|
1746
|
-
inputSource: this[
|
|
1872
|
+
inputSource: this[P_TRACKED_INPUT].inputSource,
|
|
1747
1873
|
}));
|
|
1748
1874
|
}
|
|
1749
|
-
else if (button[
|
|
1750
|
-
button[
|
|
1751
|
-
session.dispatchEvent(new XRInputSourceEvent(button[
|
|
1875
|
+
else if (button[P_GAMEPAD].lastFrameValue > 0 &&
|
|
1876
|
+
button[P_GAMEPAD].value === 0) {
|
|
1877
|
+
session.dispatchEvent(new XRInputSourceEvent(button[P_GAMEPAD].eventTrigger + 'end', {
|
|
1752
1878
|
frame,
|
|
1753
|
-
inputSource: this[
|
|
1879
|
+
inputSource: this[P_TRACKED_INPUT].inputSource,
|
|
1754
1880
|
}));
|
|
1755
1881
|
}
|
|
1756
1882
|
}
|
|
1757
1883
|
}
|
|
1758
1884
|
});
|
|
1759
|
-
this[
|
|
1760
|
-
this.connected !== this[
|
|
1761
|
-
this[
|
|
1885
|
+
this[P_TRACKED_INPUT].inputSourceChanged =
|
|
1886
|
+
this.connected !== this[P_TRACKED_INPUT].lastFrameConnected;
|
|
1887
|
+
this[P_TRACKED_INPUT].lastFrameConnected = this.connected;
|
|
1762
1888
|
}
|
|
1763
1889
|
}
|
|
1764
1890
|
|
|
@@ -1768,7 +1894,6 @@
|
|
|
1768
1894
|
* This source code is licensed under the MIT license found in the
|
|
1769
1895
|
* LICENSE file in the root directory of this source tree.
|
|
1770
1896
|
*/
|
|
1771
|
-
const PRIVATE$h = Symbol('@immersive-web-emulation-runtime/xr-controller');
|
|
1772
1897
|
class XRController extends XRTrackedInput {
|
|
1773
1898
|
constructor(controllerConfig, handedness, globalSpace) {
|
|
1774
1899
|
if (!controllerConfig.layout[handedness]) {
|
|
@@ -1784,38 +1909,36 @@
|
|
|
1784
1909
|
];
|
|
1785
1910
|
const inputSource = new XRInputSource(handedness, XRTargetRayMode.TrackedPointer, profiles, targetRaySpace, new Gamepad(controllerConfig.layout[handedness].gamepad), gripSpace);
|
|
1786
1911
|
super(inputSource);
|
|
1787
|
-
this[
|
|
1912
|
+
this[P_CONTROLLER] = {
|
|
1788
1913
|
gamepadConfig: controllerConfig.layout[handedness].gamepad,
|
|
1789
1914
|
};
|
|
1790
1915
|
}
|
|
1791
1916
|
get gamepadConfig() {
|
|
1792
|
-
return this[
|
|
1917
|
+
return this[P_CONTROLLER].gamepadConfig;
|
|
1793
1918
|
}
|
|
1794
1919
|
updateButtonValue(id, value) {
|
|
1795
1920
|
if (value > 1 || value < 0) {
|
|
1796
1921
|
console.warn(`Out-of-range value ${value} provided for button ${id}.`);
|
|
1797
1922
|
return;
|
|
1798
1923
|
}
|
|
1799
|
-
const gamepadButton = this[
|
|
1800
|
-
.buttonsMap[id];
|
|
1924
|
+
const gamepadButton = this[P_TRACKED_INPUT].inputSource.gamepad[P_GAMEPAD].buttonsMap[id];
|
|
1801
1925
|
if (gamepadButton) {
|
|
1802
|
-
if (gamepadButton[
|
|
1926
|
+
if (gamepadButton[P_GAMEPAD].type === 'binary' &&
|
|
1803
1927
|
value != 1 &&
|
|
1804
1928
|
value != 0) {
|
|
1805
1929
|
console.warn(`Non-binary value ${value} provided for binary button ${id}.`);
|
|
1806
1930
|
return;
|
|
1807
1931
|
}
|
|
1808
|
-
gamepadButton[
|
|
1932
|
+
gamepadButton[P_GAMEPAD].pendingValue = value;
|
|
1809
1933
|
}
|
|
1810
1934
|
else {
|
|
1811
1935
|
console.warn(`Current controller does not have button ${id}.`);
|
|
1812
1936
|
}
|
|
1813
1937
|
}
|
|
1814
1938
|
updateButtonTouch(id, touched) {
|
|
1815
|
-
const gamepadButton = this[
|
|
1816
|
-
.buttonsMap[id];
|
|
1939
|
+
const gamepadButton = this[P_TRACKED_INPUT].inputSource.gamepad[P_GAMEPAD].buttonsMap[id];
|
|
1817
1940
|
if (gamepadButton) {
|
|
1818
|
-
gamepadButton[
|
|
1941
|
+
gamepadButton[P_GAMEPAD].touched = touched;
|
|
1819
1942
|
}
|
|
1820
1943
|
else {
|
|
1821
1944
|
console.warn(`Current controller does not have button ${id}.`);
|
|
@@ -1826,8 +1949,7 @@
|
|
|
1826
1949
|
console.warn(`Out-of-range value ${value} provided for ${id} axes.`);
|
|
1827
1950
|
return;
|
|
1828
1951
|
}
|
|
1829
|
-
const axesById = this[
|
|
1830
|
-
.axesMap[id];
|
|
1952
|
+
const axesById = this[P_TRACKED_INPUT].inputSource.gamepad[P_GAMEPAD].axesMap[id];
|
|
1831
1953
|
if (axesById) {
|
|
1832
1954
|
if (type === 'x-axis') {
|
|
1833
1955
|
axesById.x = value;
|
|
@@ -1845,8 +1967,7 @@
|
|
|
1845
1967
|
console.warn(`Out-of-range value x:${x}, y:${y} provided for ${id} axes.`);
|
|
1846
1968
|
return;
|
|
1847
1969
|
}
|
|
1848
|
-
const axesById = this[
|
|
1849
|
-
.axesMap[id];
|
|
1970
|
+
const axesById = this[P_TRACKED_INPUT].inputSource.gamepad[P_GAMEPAD].axesMap[id];
|
|
1850
1971
|
if (axesById) {
|
|
1851
1972
|
axesById.x = x;
|
|
1852
1973
|
axesById.y = y;
|
|
@@ -1863,42 +1984,42 @@
|
|
|
1863
1984
|
* This source code is licensed under the MIT license found in the
|
|
1864
1985
|
* LICENSE file in the root directory of this source tree.
|
|
1865
1986
|
*/
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
eye,
|
|
1877
|
-
projectionMatrix,
|
|
1878
|
-
transform,
|
|
1879
|
-
recommendedViewportScale: null,
|
|
1880
|
-
requestedViewportScale: 1.0,
|
|
1881
|
-
session,
|
|
1987
|
+
class XRMesh {
|
|
1988
|
+
constructor(nativeMesh, meshSpace, vertices, indices, semanticLabel) {
|
|
1989
|
+
this[P_MESH] = {
|
|
1990
|
+
nativeMesh,
|
|
1991
|
+
frame: undefined,
|
|
1992
|
+
meshSpace,
|
|
1993
|
+
vertices,
|
|
1994
|
+
indices,
|
|
1995
|
+
lastChangedTime: performance.now(),
|
|
1996
|
+
semanticLabel,
|
|
1882
1997
|
};
|
|
1883
1998
|
}
|
|
1884
|
-
get
|
|
1885
|
-
return this[
|
|
1999
|
+
get meshSpace() {
|
|
2000
|
+
return this[P_MESH].meshSpace;
|
|
1886
2001
|
}
|
|
1887
|
-
get
|
|
1888
|
-
return this[
|
|
2002
|
+
get vertices() {
|
|
2003
|
+
return this[P_MESH].vertices;
|
|
1889
2004
|
}
|
|
1890
|
-
get
|
|
1891
|
-
return this[
|
|
2005
|
+
get indices() {
|
|
2006
|
+
return this[P_MESH].indices;
|
|
1892
2007
|
}
|
|
1893
|
-
get
|
|
1894
|
-
return this[
|
|
2008
|
+
get lastChangedTime() {
|
|
2009
|
+
return this[P_MESH].lastChangedTime;
|
|
1895
2010
|
}
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
2011
|
+
get semanticLabel() {
|
|
2012
|
+
return this[P_MESH].semanticLabel;
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
class XRMeshSet extends Set {
|
|
2016
|
+
}
|
|
2017
|
+
class NativeMesh {
|
|
2018
|
+
constructor(transform, vertices, indices, semanticLabel) {
|
|
2019
|
+
this.transform = transform;
|
|
2020
|
+
this.vertices = vertices;
|
|
2021
|
+
this.indices = indices;
|
|
2022
|
+
this.semanticLabel = semanticLabel;
|
|
1902
2023
|
}
|
|
1903
2024
|
}
|
|
1904
2025
|
|
|
@@ -1908,16 +2029,30 @@
|
|
|
1908
2029
|
* This source code is licensed under the MIT license found in the
|
|
1909
2030
|
* LICENSE file in the root directory of this source tree.
|
|
1910
2031
|
*/
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
2032
|
+
// Source: https://github.com/immersive-web/semantic-labels/blob/master/labels.json
|
|
2033
|
+
/**
|
|
2034
|
+
* Enum for semantic labels.
|
|
2035
|
+
* For more details, see the {@link https://github.com/immersive-web/semantic-labels | Semantic Labels Documentation}.
|
|
2036
|
+
*/
|
|
2037
|
+
exports.XRSemanticLabels = void 0;
|
|
2038
|
+
(function (XRSemanticLabels) {
|
|
2039
|
+
XRSemanticLabels["Desk"] = "desk";
|
|
2040
|
+
XRSemanticLabels["Couch"] = "couch";
|
|
2041
|
+
XRSemanticLabels["Floor"] = "floor";
|
|
2042
|
+
XRSemanticLabels["Ceiling"] = "ceiling";
|
|
2043
|
+
XRSemanticLabels["Wall"] = "wall";
|
|
2044
|
+
XRSemanticLabels["Door"] = "door";
|
|
2045
|
+
XRSemanticLabels["Window"] = "window";
|
|
2046
|
+
XRSemanticLabels["Table"] = "table";
|
|
2047
|
+
XRSemanticLabels["Shelf"] = "shelf";
|
|
2048
|
+
XRSemanticLabels["Bed"] = "bed";
|
|
2049
|
+
XRSemanticLabels["Screen"] = "screen";
|
|
2050
|
+
XRSemanticLabels["Lamp"] = "lamp";
|
|
2051
|
+
XRSemanticLabels["Plant"] = "plant";
|
|
2052
|
+
XRSemanticLabels["WallArt"] = "wall art";
|
|
2053
|
+
XRSemanticLabels["GlobalMesh"] = "global mesh";
|
|
2054
|
+
XRSemanticLabels["Other"] = "other";
|
|
2055
|
+
})(exports.XRSemanticLabels || (exports.XRSemanticLabels = {}));
|
|
1921
2056
|
|
|
1922
2057
|
/**
|
|
1923
2058
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -1925,27 +2060,68 @@
|
|
|
1925
2060
|
* This source code is licensed under the MIT license found in the
|
|
1926
2061
|
* LICENSE file in the root directory of this source tree.
|
|
1927
2062
|
*/
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
2063
|
+
var XRPlaneOrientation;
|
|
2064
|
+
(function (XRPlaneOrientation) {
|
|
2065
|
+
XRPlaneOrientation["Horizontal"] = "horizontal";
|
|
2066
|
+
XRPlaneOrientation["Vertical"] = "vertical";
|
|
2067
|
+
})(XRPlaneOrientation || (XRPlaneOrientation = {}));
|
|
2068
|
+
/**
|
|
2069
|
+
* XRPlane orientation mapping from semantic labels.
|
|
2070
|
+
* For more details, see the {@link https://github.com/immersive-web/semantic-labels | Semantic Labels Documentation}.
|
|
2071
|
+
*/
|
|
2072
|
+
const XREntityOrientation = {
|
|
2073
|
+
[exports.XRSemanticLabels.Desk]: XRPlaneOrientation.Horizontal,
|
|
2074
|
+
[exports.XRSemanticLabels.Couch]: XRPlaneOrientation.Horizontal,
|
|
2075
|
+
[exports.XRSemanticLabels.Floor]: XRPlaneOrientation.Horizontal,
|
|
2076
|
+
[exports.XRSemanticLabels.Ceiling]: XRPlaneOrientation.Horizontal,
|
|
2077
|
+
[exports.XRSemanticLabels.Wall]: XRPlaneOrientation.Vertical,
|
|
2078
|
+
[exports.XRSemanticLabels.Door]: XRPlaneOrientation.Vertical,
|
|
2079
|
+
[exports.XRSemanticLabels.Window]: XRPlaneOrientation.Vertical,
|
|
2080
|
+
[exports.XRSemanticLabels.Table]: XRPlaneOrientation.Horizontal,
|
|
2081
|
+
[exports.XRSemanticLabels.Shelf]: XRPlaneOrientation.Horizontal,
|
|
2082
|
+
[exports.XRSemanticLabels.Bed]: XRPlaneOrientation.Horizontal,
|
|
2083
|
+
[exports.XRSemanticLabels.Screen]: XRPlaneOrientation.Horizontal,
|
|
2084
|
+
[exports.XRSemanticLabels.Lamp]: XRPlaneOrientation.Horizontal,
|
|
2085
|
+
[exports.XRSemanticLabels.Plant]: XRPlaneOrientation.Horizontal,
|
|
2086
|
+
[exports.XRSemanticLabels.WallArt]: XRPlaneOrientation.Vertical,
|
|
2087
|
+
};
|
|
2088
|
+
class XRPlane {
|
|
2089
|
+
constructor(nativePlane, planeSpace, polygon, semanticLabel) {
|
|
2090
|
+
this[P_PLANE] = {
|
|
2091
|
+
nativePlane,
|
|
2092
|
+
frame: undefined,
|
|
2093
|
+
planeSpace,
|
|
2094
|
+
polygon,
|
|
2095
|
+
lastChangedTime: performance.now(),
|
|
2096
|
+
semanticLabel,
|
|
2097
|
+
orientation: semanticLabel
|
|
2098
|
+
? XREntityOrientation[semanticLabel]
|
|
2099
|
+
: undefined,
|
|
1936
2100
|
};
|
|
1937
2101
|
}
|
|
1938
|
-
get
|
|
1939
|
-
return this[
|
|
2102
|
+
get planeSpace() {
|
|
2103
|
+
return this[P_PLANE].planeSpace;
|
|
1940
2104
|
}
|
|
1941
|
-
get
|
|
1942
|
-
return this[
|
|
2105
|
+
get polygon() {
|
|
2106
|
+
return this[P_PLANE].polygon;
|
|
1943
2107
|
}
|
|
1944
|
-
get
|
|
1945
|
-
return this[
|
|
2108
|
+
get orientation() {
|
|
2109
|
+
return this[P_PLANE].orientation;
|
|
1946
2110
|
}
|
|
1947
|
-
get
|
|
1948
|
-
return this[
|
|
2111
|
+
get lastChangedTime() {
|
|
2112
|
+
return this[P_PLANE].lastChangedTime;
|
|
2113
|
+
}
|
|
2114
|
+
get semanticLabel() {
|
|
2115
|
+
return this[P_PLANE].semanticLabel;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
class XRPlaneSet extends Set {
|
|
2119
|
+
}
|
|
2120
|
+
class NativePlane {
|
|
2121
|
+
constructor(transform, polygon, semanticLabel) {
|
|
2122
|
+
this.transform = transform;
|
|
2123
|
+
this.polygon = polygon;
|
|
2124
|
+
this.semanticLabel = semanticLabel;
|
|
1949
2125
|
}
|
|
1950
2126
|
}
|
|
1951
2127
|
|
|
@@ -1955,14 +2131,68 @@
|
|
|
1955
2131
|
* This source code is licensed under the MIT license found in the
|
|
1956
2132
|
* LICENSE file in the root directory of this source tree.
|
|
1957
2133
|
*/
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
2134
|
+
class XRAnchor {
|
|
2135
|
+
constructor(anchorSpace, session) {
|
|
2136
|
+
this[P_ANCHOR] = {
|
|
2137
|
+
anchorSpace,
|
|
2138
|
+
session,
|
|
2139
|
+
deleted: false,
|
|
2140
|
+
};
|
|
2141
|
+
session[P_SESSION].trackedAnchors.add(this);
|
|
1963
2142
|
}
|
|
1964
|
-
get
|
|
1965
|
-
|
|
2143
|
+
get anchorSpace() {
|
|
2144
|
+
if (this[P_ANCHOR].deleted) {
|
|
2145
|
+
throw new DOMException('XRAnchor has already been deleted.', 'InvalidStateError');
|
|
2146
|
+
}
|
|
2147
|
+
return this[P_ANCHOR].anchorSpace;
|
|
2148
|
+
}
|
|
2149
|
+
requestPersistentHandle() {
|
|
2150
|
+
return new Promise((resolve, reject) => {
|
|
2151
|
+
if (this[P_ANCHOR].deleted) {
|
|
2152
|
+
reject(new DOMException('XRAnchor has already been deleted.', 'InvalidStateError'));
|
|
2153
|
+
}
|
|
2154
|
+
else {
|
|
2155
|
+
const persistentAnchors = this[P_ANCHOR].session[P_SESSION].persistentAnchors;
|
|
2156
|
+
for (const [uuid, anchor] of persistentAnchors.entries()) {
|
|
2157
|
+
if (anchor === this) {
|
|
2158
|
+
resolve(uuid);
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
const uuid = crypto.randomUUID();
|
|
2163
|
+
XRAnchorUtils.createPersistentAnchor(this[P_ANCHOR].session, this, uuid);
|
|
2164
|
+
resolve(uuid);
|
|
2165
|
+
}
|
|
2166
|
+
});
|
|
2167
|
+
}
|
|
2168
|
+
delete() {
|
|
2169
|
+
if (this[P_ANCHOR].deleted) {
|
|
2170
|
+
return;
|
|
2171
|
+
}
|
|
2172
|
+
this[P_ANCHOR].anchorSpace = null;
|
|
2173
|
+
this[P_ANCHOR].deleted = true;
|
|
2174
|
+
this[P_ANCHOR].session[P_SESSION].trackedAnchors.delete(this);
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
class XRAnchorSet extends Set {
|
|
2178
|
+
}
|
|
2179
|
+
const PersistentAnchorsStorageKey = '@immersive-web-emulation-runtime/persistent-anchors';
|
|
2180
|
+
class XRAnchorUtils {
|
|
2181
|
+
static recoverPersistentAnchorsFromStorage(session) {
|
|
2182
|
+
const persistentAnchors = JSON.parse(localStorage.getItem(PersistentAnchorsStorageKey) || '{}');
|
|
2183
|
+
Object.entries(persistentAnchors).forEach(([uuid, offsetMatrix]) => {
|
|
2184
|
+
const globalSpace = session[P_SESSION].device[P_DEVICE].globalSpace;
|
|
2185
|
+
const anchorSpace = new XRSpace(globalSpace, offsetMatrix);
|
|
2186
|
+
const anchor = new XRAnchor(anchorSpace, session);
|
|
2187
|
+
session[P_SESSION].persistentAnchors.set(uuid, anchor);
|
|
2188
|
+
});
|
|
2189
|
+
}
|
|
2190
|
+
static createPersistentAnchor(session, anchor, uuid) {
|
|
2191
|
+
session[P_SESSION].trackedAnchors.add(anchor);
|
|
2192
|
+
session[P_SESSION].persistentAnchors.set(uuid, anchor);
|
|
2193
|
+
const persistentAnchors = JSON.parse(localStorage.getItem(PersistentAnchorsStorageKey) || '{}');
|
|
2194
|
+
persistentAnchors[uuid] = Array.from(anchor[P_ANCHOR].anchorSpace[P_SPACE].offsetMatrix);
|
|
2195
|
+
localStorage.setItem(PersistentAnchorsStorageKey, JSON.stringify(persistentAnchors));
|
|
1966
2196
|
}
|
|
1967
2197
|
}
|
|
1968
2198
|
|
|
@@ -1994,7 +2224,7 @@
|
|
|
1994
2224
|
return { x: this.x, y: this.y, z: this.z, w: this.w };
|
|
1995
2225
|
}
|
|
1996
2226
|
}
|
|
1997
|
-
const DOMPointReadOnly = typeof globalThis.DOMPointReadOnly !== 'undefined'
|
|
2227
|
+
const DOMPointReadOnly$1 = typeof globalThis.DOMPointReadOnly !== 'undefined'
|
|
1998
2228
|
? globalThis.DOMPointReadOnly
|
|
1999
2229
|
: PolyfillDOMPointReadOnly;
|
|
2000
2230
|
|
|
@@ -2004,13 +2234,12 @@
|
|
|
2004
2234
|
* This source code is licensed under the MIT license found in the
|
|
2005
2235
|
* LICENSE file in the root directory of this source tree.
|
|
2006
2236
|
*/
|
|
2007
|
-
const PRIVATE$c = Symbol('@immersive-web-emulation-runtime/xr-rigid-transform');
|
|
2008
2237
|
class XRRigidTransform {
|
|
2009
2238
|
constructor(position, orientation) {
|
|
2010
2239
|
// Default values
|
|
2011
2240
|
const defaultPosition = fromValues$2(0, 0, 0);
|
|
2012
2241
|
const defaultOrientation = create();
|
|
2013
|
-
this[
|
|
2242
|
+
this[P_RIGID_TRANSFORM] = {
|
|
2014
2243
|
matrix: create$3(),
|
|
2015
2244
|
position: position
|
|
2016
2245
|
? fromValues$2(position.x, position.y, position.z)
|
|
@@ -2023,23 +2252,23 @@
|
|
|
2023
2252
|
this.updateMatrix();
|
|
2024
2253
|
}
|
|
2025
2254
|
updateMatrix() {
|
|
2026
|
-
fromRotationTranslation(this[
|
|
2255
|
+
fromRotationTranslation(this[P_RIGID_TRANSFORM].matrix, this[P_RIGID_TRANSFORM].orientation, this[P_RIGID_TRANSFORM].position);
|
|
2027
2256
|
}
|
|
2028
2257
|
get matrix() {
|
|
2029
|
-
return this[
|
|
2258
|
+
return this[P_RIGID_TRANSFORM].matrix;
|
|
2030
2259
|
}
|
|
2031
2260
|
get position() {
|
|
2032
|
-
const pos = this[
|
|
2033
|
-
return new DOMPointReadOnly(pos[0], pos[1], pos[2], 1);
|
|
2261
|
+
const pos = this[P_RIGID_TRANSFORM].position;
|
|
2262
|
+
return new DOMPointReadOnly$1(pos[0], pos[1], pos[2], 1);
|
|
2034
2263
|
}
|
|
2035
2264
|
get orientation() {
|
|
2036
|
-
const ori = this[
|
|
2037
|
-
return new DOMPointReadOnly(ori[0], ori[1], ori[2], ori[3]);
|
|
2265
|
+
const ori = this[P_RIGID_TRANSFORM].orientation;
|
|
2266
|
+
return new DOMPointReadOnly$1(ori[0], ori[1], ori[2], ori[3]);
|
|
2038
2267
|
}
|
|
2039
2268
|
get inverse() {
|
|
2040
|
-
if (!this[
|
|
2269
|
+
if (!this[P_RIGID_TRANSFORM].inverse) {
|
|
2041
2270
|
const invMatrix = create$3();
|
|
2042
|
-
if (!invert(invMatrix, this[
|
|
2271
|
+
if (!invert(invMatrix, this[P_RIGID_TRANSFORM].matrix)) {
|
|
2043
2272
|
throw new Error('Matrix is not invertible.');
|
|
2044
2273
|
}
|
|
2045
2274
|
// Decomposing the inverse matrix into position and orientation
|
|
@@ -2048,30 +2277,101 @@
|
|
|
2048
2277
|
let invOrientation = create();
|
|
2049
2278
|
getRotation(invOrientation, invMatrix);
|
|
2050
2279
|
// Creating a new XRRigidTransform for the inverse
|
|
2051
|
-
this[
|
|
2280
|
+
this[P_RIGID_TRANSFORM].inverse = new XRRigidTransform(new DOMPointReadOnly$1(invPosition[0], invPosition[1], invPosition[2], 1), new DOMPointReadOnly$1(invOrientation[0], invOrientation[1], invOrientation[2], invOrientation[3]));
|
|
2052
2281
|
// Setting the inverse of the inverse to be this transform
|
|
2053
|
-
this[
|
|
2282
|
+
this[P_RIGID_TRANSFORM].inverse[P_RIGID_TRANSFORM].inverse = this;
|
|
2054
2283
|
}
|
|
2055
|
-
return this[
|
|
2284
|
+
return this[P_RIGID_TRANSFORM].inverse;
|
|
2056
2285
|
}
|
|
2057
2286
|
}
|
|
2058
2287
|
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2288
|
+
class DOMPointReadOnly {
|
|
2289
|
+
constructor(x = 0, y = 0, z = 0, w = 1) {
|
|
2290
|
+
this.x = x;
|
|
2291
|
+
this.y = y;
|
|
2292
|
+
this.z = z;
|
|
2293
|
+
this.w = w;
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
class XRRay {
|
|
2297
|
+
constructor(origin, direction) {
|
|
2298
|
+
const _origin = { x: 0, y: 0, z: 0, w: 1 };
|
|
2299
|
+
const _direction = { x: 0, y: 0, z: -1, w: 0 };
|
|
2300
|
+
if (origin instanceof XRRigidTransform) {
|
|
2301
|
+
const transform = origin;
|
|
2302
|
+
const matrix = transform.matrix;
|
|
2303
|
+
const originVec4 = set$1(create$1(), _origin.x, _origin.y, _origin.z, _origin.w);
|
|
2304
|
+
const directionVec4 = set$1(create$1(), _direction.x, _direction.y, _direction.z, _direction.w);
|
|
2305
|
+
transformMat4(originVec4, originVec4, matrix);
|
|
2306
|
+
transformMat4(directionVec4, directionVec4, matrix);
|
|
2307
|
+
_origin.x = originVec4[0];
|
|
2308
|
+
_origin.y = originVec4[1];
|
|
2309
|
+
_origin.z = originVec4[2];
|
|
2310
|
+
_origin.w = originVec4[3];
|
|
2311
|
+
_direction.x = directionVec4[0];
|
|
2312
|
+
_direction.y = directionVec4[1];
|
|
2313
|
+
_direction.z = directionVec4[2];
|
|
2314
|
+
_direction.w = directionVec4[3];
|
|
2315
|
+
}
|
|
2316
|
+
else {
|
|
2317
|
+
if (origin) {
|
|
2318
|
+
_origin.x = origin.x;
|
|
2319
|
+
_origin.y = origin.y;
|
|
2320
|
+
_origin.z = origin.z;
|
|
2321
|
+
_origin.w = origin.w;
|
|
2322
|
+
}
|
|
2323
|
+
if (direction) {
|
|
2324
|
+
if ((direction.x === 0 && direction.y === 0 && direction.z === 0) ||
|
|
2325
|
+
direction.w !== 1) {
|
|
2326
|
+
throw new DOMException('Invalid direction value to construct XRRay', 'TypeError');
|
|
2327
|
+
}
|
|
2328
|
+
_direction.x = direction.x;
|
|
2329
|
+
_direction.y = direction.y;
|
|
2330
|
+
_direction.z = direction.z;
|
|
2331
|
+
_direction.w = direction.w;
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
const length = Math.sqrt(_direction.x * _direction.x +
|
|
2335
|
+
_direction.y * _direction.y +
|
|
2336
|
+
_direction.z * _direction.z) || 1;
|
|
2337
|
+
_direction.x = _direction.x / length;
|
|
2338
|
+
_direction.y = _direction.y / length;
|
|
2339
|
+
_direction.z = _direction.z / length;
|
|
2340
|
+
this[P_RAY] = {
|
|
2341
|
+
origin: new DOMPointReadOnly(_origin.x, _origin.y, _origin.z, _origin.w),
|
|
2342
|
+
direction: new DOMPointReadOnly(_direction.x, _direction.y, _direction.z, _direction.w),
|
|
2343
|
+
matrix: null,
|
|
2071
2344
|
};
|
|
2072
2345
|
}
|
|
2073
|
-
get
|
|
2074
|
-
return this[
|
|
2346
|
+
get origin() {
|
|
2347
|
+
return this[P_RAY].origin;
|
|
2348
|
+
}
|
|
2349
|
+
get direction() {
|
|
2350
|
+
return this[P_RAY].direction;
|
|
2351
|
+
}
|
|
2352
|
+
get matrix() {
|
|
2353
|
+
if (this[P_RAY].matrix) {
|
|
2354
|
+
return this[P_RAY].matrix;
|
|
2355
|
+
}
|
|
2356
|
+
const z = set$2(create$2(), 0, 0, -1);
|
|
2357
|
+
const origin = set$2(create$2(), this[P_RAY].origin.x, this[P_RAY].origin.y, this[P_RAY].origin.z);
|
|
2358
|
+
const direction = set$2(create$2(), this[P_RAY].direction.x, this[P_RAY].direction.y, this[P_RAY].direction.z);
|
|
2359
|
+
const axis = cross(create$2(), direction, z);
|
|
2360
|
+
const cosAngle = dot(direction, z);
|
|
2361
|
+
const rotation = create$3();
|
|
2362
|
+
if (cosAngle > -1 && cosAngle < 1) {
|
|
2363
|
+
fromRotation(rotation, Math.acos(cosAngle), axis);
|
|
2364
|
+
}
|
|
2365
|
+
else if (cosAngle === -1) {
|
|
2366
|
+
fromRotation(rotation, Math.acos(cosAngle), set$2(create$2(), 1, 0, 0));
|
|
2367
|
+
}
|
|
2368
|
+
else {
|
|
2369
|
+
identity(rotation);
|
|
2370
|
+
}
|
|
2371
|
+
const translation = fromTranslation(create$3(), origin);
|
|
2372
|
+
const matrix = multiply$1(create$3(), translation, rotation);
|
|
2373
|
+
this[P_RAY].matrix = new Float32Array(matrix);
|
|
2374
|
+
return this[P_RAY].matrix;
|
|
2075
2375
|
}
|
|
2076
2376
|
}
|
|
2077
2377
|
|
|
@@ -2081,111 +2381,28 @@
|
|
|
2081
2381
|
* This source code is licensed under the MIT license found in the
|
|
2082
2382
|
* LICENSE file in the root directory of this source tree.
|
|
2083
2383
|
*/
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
const getOffsetMatrix = (offsetMatrix, space, baseSpace) => {
|
|
2089
|
-
XRSpaceUtils.calculateGlobalOffsetMatrix(space, spaceGlobalMatrix);
|
|
2090
|
-
XRSpaceUtils.calculateGlobalOffsetMatrix(baseSpace, baseSpaceGlobalMatrix);
|
|
2091
|
-
invert(baseSpaceGlobalMatrixInverse, baseSpaceGlobalMatrix);
|
|
2092
|
-
multiply$1(offsetMatrix, baseSpaceGlobalMatrixInverse, spaceGlobalMatrix);
|
|
2093
|
-
};
|
|
2094
|
-
class XRFrame {
|
|
2095
|
-
constructor(session, id, active, animationFrame, predictedDisplayTime) {
|
|
2096
|
-
this[PRIVATE$a] = {
|
|
2384
|
+
class XRHitTestSource {
|
|
2385
|
+
constructor(session, options) {
|
|
2386
|
+
var _a;
|
|
2387
|
+
this[P_HIT_TEST] = {
|
|
2097
2388
|
session,
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
animationFrame,
|
|
2101
|
-
predictedDisplayTime,
|
|
2102
|
-
tempMat4: create$3(),
|
|
2389
|
+
space: options.space,
|
|
2390
|
+
offsetRay: (_a = options.offsetRay) !== null && _a !== void 0 ? _a : new XRRay(),
|
|
2103
2391
|
};
|
|
2104
2392
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
}
|
|
2108
|
-
get predictedDisplayTime() {
|
|
2109
|
-
return this[PRIVATE$a].predictedDisplayTime;
|
|
2110
|
-
}
|
|
2111
|
-
getPose(space, baseSpace) {
|
|
2112
|
-
if (!this[PRIVATE$a].active) {
|
|
2113
|
-
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2114
|
-
}
|
|
2115
|
-
getOffsetMatrix(this[PRIVATE$a].tempMat4, space, baseSpace);
|
|
2116
|
-
const position = create$2();
|
|
2117
|
-
getTranslation(position, this[PRIVATE$a].tempMat4);
|
|
2118
|
-
const orientation = create();
|
|
2119
|
-
getRotation(orientation, this[PRIVATE$a].tempMat4);
|
|
2120
|
-
return new XRPose(new XRRigidTransform({ x: position[0], y: position[1], z: position[2], w: 1.0 }, {
|
|
2121
|
-
x: orientation[0],
|
|
2122
|
-
y: orientation[1],
|
|
2123
|
-
z: orientation[2],
|
|
2124
|
-
w: orientation[3],
|
|
2125
|
-
}), space[PRIVATE$l].emulated);
|
|
2393
|
+
cancel() {
|
|
2394
|
+
this[P_HIT_TEST].session[P_SESSION].hitTestSources.delete(this);
|
|
2126
2395
|
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
}
|
|
2131
|
-
const session = this[PRIVATE$a].session;
|
|
2132
|
-
const device = session[PRIVATE$6].device;
|
|
2133
|
-
const pose = this.getPose(device.viewerSpace, referenceSpace);
|
|
2134
|
-
const eyes = session[PRIVATE$6].mode === XRSessionMode.Inline
|
|
2135
|
-
? [XREye.None]
|
|
2136
|
-
: [XREye.Left, XREye.Right];
|
|
2137
|
-
const views = [];
|
|
2138
|
-
eyes.forEach((eye) => {
|
|
2139
|
-
const viewSpace = device.viewSpaces[eye];
|
|
2140
|
-
const viewPose = this.getPose(viewSpace, referenceSpace);
|
|
2141
|
-
const projectionMatrix = session[PRIVATE$6].getProjectionMatrix(eye);
|
|
2142
|
-
const view = new XRView(eye, new Float32Array(projectionMatrix), viewPose.transform, session);
|
|
2143
|
-
views.push(view);
|
|
2144
|
-
});
|
|
2145
|
-
return new XRViewerPose(pose.transform, views, false);
|
|
2146
|
-
}
|
|
2147
|
-
getJointPose(joint, baseSpace) {
|
|
2148
|
-
const xrPose = this.getPose(joint, baseSpace);
|
|
2149
|
-
const radius = joint[PRIVATE$f].radius;
|
|
2150
|
-
return new XRJointPose(xrPose.transform, radius, false);
|
|
2396
|
+
}
|
|
2397
|
+
class XRHitTestResult {
|
|
2398
|
+
constructor(frame, offsetSpace) {
|
|
2399
|
+
this[P_HIT_TEST] = { frame, offsetSpace };
|
|
2151
2400
|
}
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
jointSpaces = Array.from(jointSpaces);
|
|
2155
|
-
if (!this[PRIVATE$a].active) {
|
|
2156
|
-
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2157
|
-
}
|
|
2158
|
-
if (jointSpaces.length > radii.length) {
|
|
2159
|
-
throw new DOMException('The length of jointSpaces is larger than the number of elements in radii', 'TypeError');
|
|
2160
|
-
}
|
|
2161
|
-
let allValid = true;
|
|
2162
|
-
for (let offset = 0; offset < jointSpaces.length; offset++) {
|
|
2163
|
-
if (!jointSpaces[offset][PRIVATE$f].radius) {
|
|
2164
|
-
radii[offset] = NaN;
|
|
2165
|
-
allValid = false;
|
|
2166
|
-
}
|
|
2167
|
-
else {
|
|
2168
|
-
radii[offset] = jointSpaces[offset][PRIVATE$f].radius;
|
|
2169
|
-
}
|
|
2170
|
-
}
|
|
2171
|
-
return allValid;
|
|
2401
|
+
getPose(baseSpace) {
|
|
2402
|
+
return this[P_HIT_TEST].frame.getPose(this[P_HIT_TEST].offsetSpace, baseSpace);
|
|
2172
2403
|
}
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
spaces = Array.from(spaces);
|
|
2176
|
-
if (!this[PRIVATE$a].active) {
|
|
2177
|
-
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2178
|
-
}
|
|
2179
|
-
if (spaces.length * 16 > transforms.length) {
|
|
2180
|
-
throw new DOMException('The length of spaces multiplied by 16 is larger than the number of elements in transforms', 'TypeError');
|
|
2181
|
-
}
|
|
2182
|
-
spaces.forEach((space, i) => {
|
|
2183
|
-
getOffsetMatrix(this[PRIVATE$a].tempMat4, space, baseSpace);
|
|
2184
|
-
for (let j = 0; j < 16; j++) {
|
|
2185
|
-
transforms[i * 16 + j] = this[PRIVATE$a].tempMat4[j];
|
|
2186
|
-
}
|
|
2187
|
-
});
|
|
2188
|
-
return true;
|
|
2404
|
+
createAnchor() {
|
|
2405
|
+
return this[P_HIT_TEST].frame.createAnchor(new XRRigidTransform(), this[P_HIT_TEST].offsetSpace);
|
|
2189
2406
|
}
|
|
2190
2407
|
}
|
|
2191
2408
|
|
|
@@ -2220,7 +2437,6 @@
|
|
|
2220
2437
|
* LICENSE file in the root directory of this source tree.
|
|
2221
2438
|
*/
|
|
2222
2439
|
var _a;
|
|
2223
|
-
const PRIVATE$9 = Symbol('@immersive-web-emulation-runtime/xr-reference-space');
|
|
2224
2440
|
var XRReferenceSpaceType;
|
|
2225
2441
|
(function (XRReferenceSpaceType) {
|
|
2226
2442
|
XRReferenceSpaceType["Viewer"] = "viewer";
|
|
@@ -2236,17 +2452,17 @@
|
|
|
2236
2452
|
type: null,
|
|
2237
2453
|
onreset: () => { },
|
|
2238
2454
|
};
|
|
2239
|
-
this[
|
|
2455
|
+
this[P_REF_SPACE].type = type;
|
|
2240
2456
|
}
|
|
2241
2457
|
get onreset() {
|
|
2242
2458
|
var _b;
|
|
2243
|
-
return (_b = this[
|
|
2459
|
+
return (_b = this[P_REF_SPACE].onreset) !== null && _b !== void 0 ? _b : (() => { });
|
|
2244
2460
|
}
|
|
2245
2461
|
set onreset(callback) {
|
|
2246
|
-
if (this[
|
|
2247
|
-
this.removeEventListener('reset', this[
|
|
2462
|
+
if (this[P_REF_SPACE].onreset) {
|
|
2463
|
+
this.removeEventListener('reset', this[P_REF_SPACE].onreset);
|
|
2248
2464
|
}
|
|
2249
|
-
this[
|
|
2465
|
+
this[P_REF_SPACE].onreset = callback;
|
|
2250
2466
|
if (callback) {
|
|
2251
2467
|
this.addEventListener('reset', callback);
|
|
2252
2468
|
}
|
|
@@ -2255,10 +2471,10 @@
|
|
|
2255
2471
|
getOffsetReferenceSpace(originOffset) {
|
|
2256
2472
|
// Create a new XRReferenceSpace with the originOffset as its offsetMatrix
|
|
2257
2473
|
// The new space's parent is set to 'this' (the current XRReferenceSpace)
|
|
2258
|
-
return new XRReferenceSpace(this[
|
|
2474
|
+
return new XRReferenceSpace(this[P_REF_SPACE].type, this, originOffset);
|
|
2259
2475
|
}
|
|
2260
2476
|
}
|
|
2261
|
-
_a =
|
|
2477
|
+
_a = P_REF_SPACE;
|
|
2262
2478
|
|
|
2263
2479
|
/**
|
|
2264
2480
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -2266,10 +2482,9 @@
|
|
|
2266
2482
|
* This source code is licensed under the MIT license found in the
|
|
2267
2483
|
* LICENSE file in the root directory of this source tree.
|
|
2268
2484
|
*/
|
|
2269
|
-
const PRIVATE$8 = Symbol('@immersive-web-emulation-runtime/xr-render-state');
|
|
2270
2485
|
class XRRenderState {
|
|
2271
2486
|
constructor(init = {}, oldState) {
|
|
2272
|
-
this[
|
|
2487
|
+
this[P_RENDER_STATE] = {
|
|
2273
2488
|
depthNear: init.depthNear || (oldState === null || oldState === void 0 ? void 0 : oldState.depthNear) || 0.1,
|
|
2274
2489
|
depthFar: init.depthFar || (oldState === null || oldState === void 0 ? void 0 : oldState.depthFar) || 1000.0,
|
|
2275
2490
|
inlineVerticalFieldOfView: init.inlineVerticalFieldOfView ||
|
|
@@ -2279,16 +2494,16 @@
|
|
|
2279
2494
|
};
|
|
2280
2495
|
}
|
|
2281
2496
|
get depthNear() {
|
|
2282
|
-
return this[
|
|
2497
|
+
return this[P_RENDER_STATE].depthNear;
|
|
2283
2498
|
}
|
|
2284
2499
|
get depthFar() {
|
|
2285
|
-
return this[
|
|
2500
|
+
return this[P_RENDER_STATE].depthFar;
|
|
2286
2501
|
}
|
|
2287
2502
|
get inlineVerticalFieldOfView() {
|
|
2288
|
-
return this[
|
|
2503
|
+
return this[P_RENDER_STATE].inlineVerticalFieldOfView;
|
|
2289
2504
|
}
|
|
2290
2505
|
get baseLayer() {
|
|
2291
|
-
return this[
|
|
2506
|
+
return this[P_RENDER_STATE].baseLayer;
|
|
2292
2507
|
}
|
|
2293
2508
|
}
|
|
2294
2509
|
|
|
@@ -2314,67 +2529,269 @@
|
|
|
2314
2529
|
* This source code is licensed under the MIT license found in the
|
|
2315
2530
|
* LICENSE file in the root directory of this source tree.
|
|
2316
2531
|
*/
|
|
2317
|
-
|
|
2532
|
+
var XREye;
|
|
2533
|
+
(function (XREye) {
|
|
2534
|
+
XREye["None"] = "none";
|
|
2535
|
+
XREye["Left"] = "left";
|
|
2536
|
+
XREye["Right"] = "right";
|
|
2537
|
+
})(XREye || (XREye = {}));
|
|
2538
|
+
class XRView {
|
|
2539
|
+
constructor(eye, projectionMatrix, transform, session) {
|
|
2540
|
+
this[P_VIEW] = {
|
|
2541
|
+
eye,
|
|
2542
|
+
projectionMatrix,
|
|
2543
|
+
transform,
|
|
2544
|
+
recommendedViewportScale: null,
|
|
2545
|
+
requestedViewportScale: 1.0,
|
|
2546
|
+
session,
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
get eye() {
|
|
2550
|
+
return this[P_VIEW].eye;
|
|
2551
|
+
}
|
|
2552
|
+
get projectionMatrix() {
|
|
2553
|
+
return this[P_VIEW].projectionMatrix;
|
|
2554
|
+
}
|
|
2555
|
+
get transform() {
|
|
2556
|
+
return this[P_VIEW].transform;
|
|
2557
|
+
}
|
|
2558
|
+
get recommendedViewportScale() {
|
|
2559
|
+
return this[P_VIEW].recommendedViewportScale;
|
|
2560
|
+
}
|
|
2561
|
+
requestViewportScale(scale) {
|
|
2562
|
+
if (scale === null || scale <= 0 || scale > 1) {
|
|
2563
|
+
console.warn('Invalid scale value. Scale must be > 0 and <= 1.');
|
|
2564
|
+
return;
|
|
2565
|
+
}
|
|
2566
|
+
this[P_VIEW].requestedViewportScale = scale;
|
|
2567
|
+
}
|
|
2318
2568
|
}
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2569
|
+
|
|
2570
|
+
/**
|
|
2571
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2572
|
+
*
|
|
2573
|
+
* This source code is licensed under the MIT license found in the
|
|
2574
|
+
* LICENSE file in the root directory of this source tree.
|
|
2575
|
+
*/
|
|
2576
|
+
class XRPose {
|
|
2577
|
+
constructor(transform, emulatedPosition = false, linearVelocity = undefined, angularVelocity = undefined) {
|
|
2578
|
+
this[P_POSE] = {
|
|
2579
|
+
transform,
|
|
2580
|
+
emulatedPosition,
|
|
2581
|
+
linearVelocity,
|
|
2582
|
+
angularVelocity,
|
|
2583
|
+
};
|
|
2584
|
+
}
|
|
2585
|
+
get transform() {
|
|
2586
|
+
return this[P_POSE].transform;
|
|
2587
|
+
}
|
|
2588
|
+
get emulatedPosition() {
|
|
2589
|
+
return this[P_POSE].emulatedPosition;
|
|
2590
|
+
}
|
|
2591
|
+
get linearVelocity() {
|
|
2592
|
+
return this[P_POSE].linearVelocity;
|
|
2593
|
+
}
|
|
2594
|
+
get angularVelocity() {
|
|
2595
|
+
return this[P_POSE].angularVelocity;
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
/**
|
|
2600
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2601
|
+
*
|
|
2602
|
+
* This source code is licensed under the MIT license found in the
|
|
2603
|
+
* LICENSE file in the root directory of this source tree.
|
|
2604
|
+
*/
|
|
2605
|
+
class XRJointPose extends XRPose {
|
|
2606
|
+
constructor(transform, radius, emulatedPosition = false, linearVelocity = undefined, angularVelocity = undefined) {
|
|
2607
|
+
super(transform, emulatedPosition, linearVelocity, angularVelocity);
|
|
2608
|
+
this[P_JOINT_POSE] = { radius };
|
|
2609
|
+
}
|
|
2610
|
+
get radius() {
|
|
2611
|
+
return this[P_JOINT_POSE].radius;
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
/**
|
|
2616
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2617
|
+
*
|
|
2618
|
+
* This source code is licensed under the MIT license found in the
|
|
2619
|
+
* LICENSE file in the root directory of this source tree.
|
|
2620
|
+
*/
|
|
2621
|
+
class XRViewerPose extends XRPose {
|
|
2622
|
+
constructor(transform, views, emulatedPosition = false, linearVelocity = undefined, angularVelocity = undefined) {
|
|
2623
|
+
super(transform, emulatedPosition, linearVelocity, angularVelocity);
|
|
2624
|
+
this[P_VIEWER_POSE] = {
|
|
2625
|
+
views: Object.freeze(views),
|
|
2626
|
+
};
|
|
2627
|
+
}
|
|
2628
|
+
get views() {
|
|
2629
|
+
return this[P_VIEWER_POSE].views;
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
|
|
2633
|
+
/**
|
|
2634
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2635
|
+
*
|
|
2636
|
+
* This source code is licensed under the MIT license found in the
|
|
2637
|
+
* LICENSE file in the root directory of this source tree.
|
|
2638
|
+
*/
|
|
2639
|
+
const spaceGlobalMatrix = create$3();
|
|
2640
|
+
const baseSpaceGlobalMatrix = create$3();
|
|
2641
|
+
const baseSpaceGlobalMatrixInverse = create$3();
|
|
2642
|
+
const getOffsetMatrix = (offsetMatrix, space, baseSpace) => {
|
|
2643
|
+
XRSpaceUtils.calculateGlobalOffsetMatrix(space, spaceGlobalMatrix);
|
|
2644
|
+
XRSpaceUtils.calculateGlobalOffsetMatrix(baseSpace, baseSpaceGlobalMatrix);
|
|
2645
|
+
invert(baseSpaceGlobalMatrixInverse, baseSpaceGlobalMatrix);
|
|
2646
|
+
multiply$1(offsetMatrix, baseSpaceGlobalMatrixInverse, spaceGlobalMatrix);
|
|
2327
2647
|
};
|
|
2328
|
-
class
|
|
2329
|
-
constructor(session,
|
|
2330
|
-
|
|
2331
|
-
if (session[PRIVATE$6].ended) {
|
|
2332
|
-
throw new DOMException('Session has ended', 'InvalidStateError');
|
|
2333
|
-
}
|
|
2334
|
-
// TO-DO: Check that the context attribute has xrCompatible set to true
|
|
2335
|
-
// may require polyfilling the context and perhaps canvas.getContext
|
|
2336
|
-
// Default values for XRWebGLLayerInit, can be overridden by layerInit
|
|
2337
|
-
const config = { ...defaultLayerInit, ...layerInit };
|
|
2338
|
-
this[PRIVATE$7] = {
|
|
2648
|
+
class XRFrame {
|
|
2649
|
+
constructor(session, id, active, animationFrame, predictedDisplayTime) {
|
|
2650
|
+
this[P_FRAME] = {
|
|
2339
2651
|
session,
|
|
2340
|
-
|
|
2341
|
-
|
|
2652
|
+
id,
|
|
2653
|
+
active,
|
|
2654
|
+
animationFrame,
|
|
2655
|
+
predictedDisplayTime,
|
|
2656
|
+
tempMat4: create$3(),
|
|
2657
|
+
detectedPlanes: new XRPlaneSet(),
|
|
2658
|
+
detectedMeshes: new XRMeshSet(),
|
|
2659
|
+
trackedAnchors: session[P_SESSION].frameTrackedAnchors,
|
|
2660
|
+
hitTestResultsMap: new Map(),
|
|
2342
2661
|
};
|
|
2343
2662
|
}
|
|
2344
|
-
get
|
|
2345
|
-
return this[
|
|
2663
|
+
get session() {
|
|
2664
|
+
return this[P_FRAME].session;
|
|
2346
2665
|
}
|
|
2347
|
-
get
|
|
2348
|
-
return this[
|
|
2666
|
+
get predictedDisplayTime() {
|
|
2667
|
+
return this[P_FRAME].predictedDisplayTime;
|
|
2349
2668
|
}
|
|
2350
|
-
|
|
2669
|
+
getPose(space, baseSpace) {
|
|
2670
|
+
if (!this[P_FRAME].active) {
|
|
2671
|
+
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2672
|
+
}
|
|
2673
|
+
getOffsetMatrix(this[P_FRAME].tempMat4, space, baseSpace);
|
|
2674
|
+
const position = create$2();
|
|
2675
|
+
getTranslation(position, this[P_FRAME].tempMat4);
|
|
2676
|
+
const orientation = create();
|
|
2677
|
+
getRotation(orientation, this[P_FRAME].tempMat4);
|
|
2678
|
+
return new XRPose(new XRRigidTransform({ x: position[0], y: position[1], z: position[2], w: 1.0 }, {
|
|
2679
|
+
x: orientation[0],
|
|
2680
|
+
y: orientation[1],
|
|
2681
|
+
z: orientation[2],
|
|
2682
|
+
w: orientation[3],
|
|
2683
|
+
}), space[P_SPACE].emulated);
|
|
2684
|
+
}
|
|
2685
|
+
getViewerPose(referenceSpace) {
|
|
2686
|
+
if (!this[P_FRAME].animationFrame) {
|
|
2687
|
+
throw new DOMException('getViewerPose can only be called on XRFrame objects passed to XRSession.requestAnimationFrame callbacks.', 'InvalidStateError');
|
|
2688
|
+
}
|
|
2689
|
+
const session = this[P_FRAME].session;
|
|
2690
|
+
const device = session[P_SESSION].device;
|
|
2691
|
+
const pose = this.getPose(device.viewerSpace, referenceSpace);
|
|
2692
|
+
const eyes = session[P_SESSION].mode === 'inline'
|
|
2693
|
+
? [XREye.None]
|
|
2694
|
+
: [XREye.Left, XREye.Right];
|
|
2695
|
+
const views = [];
|
|
2696
|
+
eyes.forEach((eye) => {
|
|
2697
|
+
const viewSpace = device.viewSpaces[eye];
|
|
2698
|
+
const viewPose = this.getPose(viewSpace, referenceSpace);
|
|
2699
|
+
const projectionMatrix = session[P_SESSION].getProjectionMatrix(eye);
|
|
2700
|
+
const view = new XRView(eye, new Float32Array(projectionMatrix), viewPose.transform, session);
|
|
2701
|
+
views.push(view);
|
|
2702
|
+
});
|
|
2703
|
+
return new XRViewerPose(pose.transform, views, false);
|
|
2704
|
+
}
|
|
2705
|
+
getJointPose(joint, baseSpace) {
|
|
2706
|
+
const xrPose = this.getPose(joint, baseSpace);
|
|
2707
|
+
const radius = joint[P_JOINT_SPACE].radius;
|
|
2708
|
+
return new XRJointPose(xrPose.transform, radius, false);
|
|
2709
|
+
}
|
|
2710
|
+
fillJointRadii(jointSpaces, radii) {
|
|
2711
|
+
// converting from sequence type to array
|
|
2712
|
+
jointSpaces = Array.from(jointSpaces);
|
|
2713
|
+
if (!this[P_FRAME].active) {
|
|
2714
|
+
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2715
|
+
}
|
|
2716
|
+
if (jointSpaces.length > radii.length) {
|
|
2717
|
+
throw new DOMException('The length of jointSpaces is larger than the number of elements in radii', 'TypeError');
|
|
2718
|
+
}
|
|
2719
|
+
let allValid = true;
|
|
2720
|
+
for (let offset = 0; offset < jointSpaces.length; offset++) {
|
|
2721
|
+
if (!jointSpaces[offset][P_JOINT_SPACE].radius) {
|
|
2722
|
+
radii[offset] = NaN;
|
|
2723
|
+
allValid = false;
|
|
2724
|
+
}
|
|
2725
|
+
else {
|
|
2726
|
+
radii[offset] = jointSpaces[offset][P_JOINT_SPACE].radius;
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
return allValid;
|
|
2730
|
+
}
|
|
2731
|
+
fillPoses(spaces, baseSpace, transforms) {
|
|
2732
|
+
// converting from sequence type to array
|
|
2733
|
+
spaces = Array.from(spaces);
|
|
2734
|
+
if (!this[P_FRAME].active) {
|
|
2735
|
+
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2736
|
+
}
|
|
2737
|
+
if (spaces.length * 16 > transforms.length) {
|
|
2738
|
+
throw new DOMException('The length of spaces multiplied by 16 is larger than the number of elements in transforms', 'TypeError');
|
|
2739
|
+
}
|
|
2740
|
+
spaces.forEach((space, i) => {
|
|
2741
|
+
getOffsetMatrix(this[P_FRAME].tempMat4, space, baseSpace);
|
|
2742
|
+
for (let j = 0; j < 16; j++) {
|
|
2743
|
+
transforms[i * 16 + j] = this[P_FRAME].tempMat4[j];
|
|
2744
|
+
}
|
|
2745
|
+
});
|
|
2351
2746
|
return true;
|
|
2352
2747
|
}
|
|
2353
|
-
get
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
return this[
|
|
2748
|
+
get detectedPlanes() {
|
|
2749
|
+
if (!this[P_FRAME].active) {
|
|
2750
|
+
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2751
|
+
}
|
|
2752
|
+
return this[P_FRAME].detectedPlanes;
|
|
2358
2753
|
}
|
|
2359
|
-
get
|
|
2360
|
-
|
|
2754
|
+
get detectedMeshes() {
|
|
2755
|
+
if (!this[P_FRAME].active) {
|
|
2756
|
+
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2757
|
+
}
|
|
2758
|
+
return this[P_FRAME].detectedMeshes;
|
|
2361
2759
|
}
|
|
2362
|
-
|
|
2363
|
-
if (
|
|
2364
|
-
throw new DOMException(
|
|
2760
|
+
get trackedAnchors() {
|
|
2761
|
+
if (!this[P_FRAME].active) {
|
|
2762
|
+
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2365
2763
|
}
|
|
2366
|
-
|
|
2367
|
-
return this[PRIVATE$7].session[PRIVATE$6].device[PRIVATE$1].getViewport(this, view);
|
|
2764
|
+
return this[P_FRAME].trackedAnchors;
|
|
2368
2765
|
}
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2766
|
+
createAnchor(pose, space) {
|
|
2767
|
+
return new Promise((resolve, reject) => {
|
|
2768
|
+
if (!this[P_FRAME].active) {
|
|
2769
|
+
reject(new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError'));
|
|
2770
|
+
}
|
|
2771
|
+
else {
|
|
2772
|
+
const globalSpace = this[P_FRAME].session[P_SESSION].device[P_DEVICE].globalSpace;
|
|
2773
|
+
const tempSpace = new XRSpace(space, pose.matrix);
|
|
2774
|
+
const globalOffsetMatrix = XRSpaceUtils.calculateGlobalOffsetMatrix(tempSpace);
|
|
2775
|
+
const anchorSpace = new XRSpace(globalSpace, globalOffsetMatrix);
|
|
2776
|
+
const anchor = new XRAnchor(anchorSpace, this[P_FRAME].session);
|
|
2777
|
+
this[P_FRAME].session[P_SESSION].trackedAnchors.add(anchor);
|
|
2778
|
+
this[P_FRAME].session[P_SESSION].newAnchors.set(anchor, {
|
|
2779
|
+
resolve,
|
|
2780
|
+
reject,
|
|
2781
|
+
});
|
|
2782
|
+
}
|
|
2783
|
+
});
|
|
2784
|
+
}
|
|
2785
|
+
getHitTestResults(hitTestSource) {
|
|
2786
|
+
if (!this[P_FRAME].active) {
|
|
2787
|
+
throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
|
|
2372
2788
|
}
|
|
2373
|
-
if (
|
|
2374
|
-
|
|
2789
|
+
else if (!this[P_FRAME].hitTestResultsMap.has(hitTestSource)) {
|
|
2790
|
+
throw new DOMException('Requested hit test results are not available for current frame.', 'InvalidStateError');
|
|
2791
|
+
}
|
|
2792
|
+
else {
|
|
2793
|
+
return [...this[P_FRAME].hitTestResultsMap.get(hitTestSource)];
|
|
2375
2794
|
}
|
|
2376
|
-
// Return 1.0 for simplicity, actual implementation might vary based on the device capabilities
|
|
2377
|
-
return 1.0;
|
|
2378
2795
|
}
|
|
2379
2796
|
}
|
|
2380
2797
|
|
|
@@ -2384,18 +2801,6 @@
|
|
|
2384
2801
|
* This source code is licensed under the MIT license found in the
|
|
2385
2802
|
* LICENSE file in the root directory of this source tree.
|
|
2386
2803
|
*/
|
|
2387
|
-
var XRVisibilityState;
|
|
2388
|
-
(function (XRVisibilityState) {
|
|
2389
|
-
XRVisibilityState["Visible"] = "visible";
|
|
2390
|
-
XRVisibilityState["VisibleBlurred"] = "visible-blurred";
|
|
2391
|
-
XRVisibilityState["Hidden"] = "hidden";
|
|
2392
|
-
})(XRVisibilityState || (XRVisibilityState = {}));
|
|
2393
|
-
var XRSessionMode;
|
|
2394
|
-
(function (XRSessionMode) {
|
|
2395
|
-
XRSessionMode["Inline"] = "inline";
|
|
2396
|
-
XRSessionMode["ImmersiveVR"] = "immersive-vr";
|
|
2397
|
-
XRSessionMode["ImmersiveAR"] = "immersive-ar";
|
|
2398
|
-
})(XRSessionMode || (XRSessionMode = {}));
|
|
2399
2804
|
var XREnvironmentBlendMode;
|
|
2400
2805
|
(function (XREnvironmentBlendMode) {
|
|
2401
2806
|
XREnvironmentBlendMode["Opaque"] = "opaque";
|
|
@@ -2407,11 +2812,10 @@
|
|
|
2407
2812
|
XRInteractionMode["ScreenSpace"] = "screen-space";
|
|
2408
2813
|
XRInteractionMode["WorldSpace"] = "world-space";
|
|
2409
2814
|
})(XRInteractionMode || (XRInteractionMode = {}));
|
|
2410
|
-
const PRIVATE$6 = Symbol('@immersive-web-emulation-runtime/xr-session');
|
|
2411
2815
|
class XRSession extends EventTarget {
|
|
2412
2816
|
constructor(device, mode, enabledFeatures) {
|
|
2413
2817
|
super();
|
|
2414
|
-
this[
|
|
2818
|
+
this[P_SESSION] = {
|
|
2415
2819
|
device,
|
|
2416
2820
|
mode,
|
|
2417
2821
|
renderState: new XRRenderState(),
|
|
@@ -2425,10 +2829,10 @@
|
|
|
2425
2829
|
[XREye.None]: create$3(),
|
|
2426
2830
|
},
|
|
2427
2831
|
getProjectionMatrix: (eye) => {
|
|
2428
|
-
return this[
|
|
2832
|
+
return this[P_SESSION].projectionMatrices[eye];
|
|
2429
2833
|
},
|
|
2430
2834
|
referenceSpaceIsSupported: (referenceSpaceType) => {
|
|
2431
|
-
if (!this[
|
|
2835
|
+
if (!this[P_SESSION].enabledFeatures.includes(referenceSpaceType)) {
|
|
2432
2836
|
return false;
|
|
2433
2837
|
}
|
|
2434
2838
|
switch (referenceSpaceType) {
|
|
@@ -2438,23 +2842,23 @@
|
|
|
2438
2842
|
case XRReferenceSpaceType.LocalFloor:
|
|
2439
2843
|
case XRReferenceSpaceType.BoundedFloor:
|
|
2440
2844
|
case XRReferenceSpaceType.Unbounded:
|
|
2441
|
-
return this[
|
|
2845
|
+
return this[P_SESSION].mode != 'inline';
|
|
2442
2846
|
}
|
|
2443
2847
|
},
|
|
2444
2848
|
frameHandle: 0,
|
|
2445
2849
|
frameCallbacks: [],
|
|
2446
2850
|
currentFrameCallbacks: null,
|
|
2447
2851
|
onDeviceFrame: () => {
|
|
2448
|
-
if (this[
|
|
2852
|
+
if (this[P_SESSION].ended) {
|
|
2449
2853
|
return;
|
|
2450
2854
|
}
|
|
2451
|
-
this[
|
|
2452
|
-
if (this[
|
|
2453
|
-
this[
|
|
2454
|
-
this[
|
|
2455
|
-
this[
|
|
2855
|
+
this[P_SESSION].deviceFrameHandle = globalThis.requestAnimationFrame(this[P_SESSION].onDeviceFrame);
|
|
2856
|
+
if (this[P_SESSION].pendingRenderState != null) {
|
|
2857
|
+
this[P_SESSION].renderState = this[P_SESSION].pendingRenderState;
|
|
2858
|
+
this[P_SESSION].pendingRenderState = null;
|
|
2859
|
+
this[P_SESSION].device[P_DEVICE].onBaseLayerSet(this[P_SESSION].renderState.baseLayer);
|
|
2456
2860
|
}
|
|
2457
|
-
const baseLayer = this[
|
|
2861
|
+
const baseLayer = this[P_SESSION].renderState.baseLayer;
|
|
2458
2862
|
if (baseLayer === null) {
|
|
2459
2863
|
return;
|
|
2460
2864
|
}
|
|
@@ -2488,7 +2892,7 @@
|
|
|
2488
2892
|
* prevent rendering artifacts from past frames. It ensures that each new frame starts
|
|
2489
2893
|
* with a clean slate.
|
|
2490
2894
|
*/
|
|
2491
|
-
if (this[
|
|
2895
|
+
if (this[P_SESSION].mode != 'inline') {
|
|
2492
2896
|
const currentClearColor = context.getParameter(context.COLOR_CLEAR_VALUE);
|
|
2493
2897
|
const currentClearDepth = context.getParameter(context.DEPTH_CLEAR_VALUE);
|
|
2494
2898
|
const currentClearStencil = context.getParameter(context.STENCIL_CLEAR_VALUE);
|
|
@@ -2503,20 +2907,33 @@
|
|
|
2503
2907
|
context.clearStencil(currentClearStencil);
|
|
2504
2908
|
}
|
|
2505
2909
|
// Calculate projection matrices
|
|
2506
|
-
const { depthNear, depthFar } = this[
|
|
2910
|
+
const { depthNear, depthFar } = this[P_SESSION].renderState;
|
|
2507
2911
|
const { width, height } = canvas;
|
|
2508
|
-
if (this[
|
|
2509
|
-
const aspect = (width * (this[
|
|
2510
|
-
|
|
2511
|
-
|
|
2912
|
+
if (this[P_SESSION].mode !== 'inline') {
|
|
2913
|
+
const aspect = (width * (this[P_SESSION].device.stereoEnabled ? 0.5 : 1.0)) /
|
|
2914
|
+
height;
|
|
2915
|
+
perspective(this[P_SESSION].projectionMatrices[XREye.Left], this[P_SESSION].device.fovy, aspect, depthNear, depthFar);
|
|
2916
|
+
copy$3(this[P_SESSION].projectionMatrices[XREye.Right], this[P_SESSION].projectionMatrices[XREye.Left]);
|
|
2512
2917
|
}
|
|
2513
2918
|
else {
|
|
2514
2919
|
const aspect = width / height;
|
|
2515
|
-
perspective(this[
|
|
2920
|
+
perspective(this[P_SESSION].projectionMatrices[XREye.None], this[P_SESSION].renderState.inlineVerticalFieldOfView, aspect, depthNear, depthFar);
|
|
2921
|
+
}
|
|
2922
|
+
const frame = new XRFrame(this, this[P_SESSION].frameHandle, true, true, performance.now());
|
|
2923
|
+
if (this[P_SESSION].enabledFeatures.includes('anchors')) {
|
|
2924
|
+
this[P_SESSION].updateTrackedAnchors();
|
|
2516
2925
|
}
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2926
|
+
if (this[P_SESSION].enabledFeatures.includes('plane-detection')) {
|
|
2927
|
+
this[P_SESSION].updateTrackedPlanes(frame);
|
|
2928
|
+
}
|
|
2929
|
+
if (this[P_SESSION].enabledFeatures.includes('mesh-detection')) {
|
|
2930
|
+
this[P_SESSION].updateTrackedMeshes(frame);
|
|
2931
|
+
}
|
|
2932
|
+
if (this[P_SESSION].enabledFeatures.includes('hit-test')) {
|
|
2933
|
+
this[P_SESSION].computeHitTestResults(frame);
|
|
2934
|
+
}
|
|
2935
|
+
this[P_SESSION].device[P_DEVICE].onFrameStart(frame);
|
|
2936
|
+
this[P_SESSION].updateActiveInputSources();
|
|
2520
2937
|
/*
|
|
2521
2938
|
* For each entry in callbacks, in order:
|
|
2522
2939
|
* - If the entry’s cancelled boolean is true, continue to the next entry.
|
|
@@ -2525,10 +2942,10 @@
|
|
|
2525
2942
|
*/
|
|
2526
2943
|
// - Let callbacks be a list of the entries in session’s list of animation frame
|
|
2527
2944
|
// callback, in the order in which they were added to the list.
|
|
2528
|
-
const callbacks = (this[
|
|
2529
|
-
this[
|
|
2945
|
+
const callbacks = (this[P_SESSION].currentFrameCallbacks =
|
|
2946
|
+
this[P_SESSION].frameCallbacks);
|
|
2530
2947
|
// - Set session’s list of animation frame callbacks to the empty list.
|
|
2531
|
-
this[
|
|
2948
|
+
this[P_SESSION].frameCallbacks = [];
|
|
2532
2949
|
const rightNow = performance.now();
|
|
2533
2950
|
for (let i = 0; i < callbacks.length; i++) {
|
|
2534
2951
|
try {
|
|
@@ -2540,21 +2957,21 @@
|
|
|
2540
2957
|
console.error(err);
|
|
2541
2958
|
}
|
|
2542
2959
|
}
|
|
2543
|
-
this[
|
|
2960
|
+
this[P_SESSION].currentFrameCallbacks = null;
|
|
2544
2961
|
// - Set frame’s active boolean to false.
|
|
2545
|
-
frame[
|
|
2962
|
+
frame[P_FRAME].active = false;
|
|
2546
2963
|
},
|
|
2547
2964
|
nominalFrameRate: device.internalNominalFrameRate,
|
|
2548
2965
|
referenceSpaces: [],
|
|
2549
2966
|
inputSourceArray: [],
|
|
2550
2967
|
activeInputSources: [],
|
|
2551
2968
|
updateActiveInputSources: () => {
|
|
2552
|
-
const handTrackingOn = this[
|
|
2553
|
-
const prevInputs = this[
|
|
2554
|
-
const currInputs = this[
|
|
2969
|
+
const handTrackingOn = this[P_SESSION].enabledFeatures.includes('hand-tracking');
|
|
2970
|
+
const prevInputs = this[P_SESSION].activeInputSources;
|
|
2971
|
+
const currInputs = this[P_SESSION].device.inputSources.filter((inputSource) => !inputSource.hand || handTrackingOn);
|
|
2555
2972
|
const added = currInputs.filter((item) => !prevInputs.includes(item));
|
|
2556
2973
|
const removed = prevInputs.filter((item) => !currInputs.includes(item));
|
|
2557
|
-
this[
|
|
2974
|
+
this[P_SESSION].activeInputSources = currInputs;
|
|
2558
2975
|
if (added.length > 0 || removed.length > 0) {
|
|
2559
2976
|
this.dispatchEvent(new XRInputSourcesChangeEvent('inputsourceschange', {
|
|
2560
2977
|
session: this,
|
|
@@ -2563,6 +2980,89 @@
|
|
|
2563
2980
|
}));
|
|
2564
2981
|
}
|
|
2565
2982
|
},
|
|
2983
|
+
trackedAnchors: new XRAnchorSet(),
|
|
2984
|
+
persistentAnchors: new Map(),
|
|
2985
|
+
newAnchors: new Map(),
|
|
2986
|
+
frameTrackedAnchors: new XRAnchorSet(),
|
|
2987
|
+
updateTrackedAnchors: () => {
|
|
2988
|
+
if (this[P_SESSION].enabledFeatures.includes('anchors')) {
|
|
2989
|
+
this[P_SESSION].frameTrackedAnchors.clear();
|
|
2990
|
+
Array.from(this[P_SESSION].trackedAnchors).forEach((anchor) => {
|
|
2991
|
+
if (anchor[P_ANCHOR].deleted) {
|
|
2992
|
+
this[P_SESSION].trackedAnchors.delete(anchor);
|
|
2993
|
+
if (this[P_SESSION].newAnchors.has(anchor)) {
|
|
2994
|
+
const { reject } = this[P_SESSION].newAnchors.get(anchor);
|
|
2995
|
+
reject(new DOMException('Anchor is no longer tracked', 'InvalidStateError'));
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
else {
|
|
2999
|
+
this[P_SESSION].frameTrackedAnchors.add(anchor);
|
|
3000
|
+
if (this[P_SESSION].newAnchors.has(anchor)) {
|
|
3001
|
+
const { resolve } = this[P_SESSION].newAnchors.get(anchor);
|
|
3002
|
+
resolve(anchor);
|
|
3003
|
+
this[P_SESSION].newAnchors.delete(anchor);
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
});
|
|
3007
|
+
}
|
|
3008
|
+
},
|
|
3009
|
+
trackedPlanes: new Map(),
|
|
3010
|
+
updateTrackedPlanes: (frame) => {
|
|
3011
|
+
const sem = this[P_SESSION].device[P_DEVICE].syntheticEnvironmentModule;
|
|
3012
|
+
if (!sem) {
|
|
3013
|
+
return;
|
|
3014
|
+
}
|
|
3015
|
+
sem.trackedPlanes.forEach((plane) => {
|
|
3016
|
+
let xrPlane = this[P_SESSION].trackedPlanes.get(plane);
|
|
3017
|
+
if (!xrPlane) {
|
|
3018
|
+
const planeSpace = new XRSpace(this[P_SESSION].device[P_DEVICE].globalSpace, plane.transform.matrix);
|
|
3019
|
+
xrPlane = new XRPlane(plane, planeSpace, plane.polygon);
|
|
3020
|
+
this[P_SESSION].trackedPlanes.set(plane, xrPlane);
|
|
3021
|
+
}
|
|
3022
|
+
xrPlane[P_PLANE].lastChangedTime = frame.predictedDisplayTime;
|
|
3023
|
+
xrPlane[P_PLANE].frame = frame;
|
|
3024
|
+
frame[P_FRAME].detectedPlanes.add(xrPlane);
|
|
3025
|
+
});
|
|
3026
|
+
},
|
|
3027
|
+
trackedMeshes: new Map(),
|
|
3028
|
+
updateTrackedMeshes: (frame) => {
|
|
3029
|
+
const sem = this[P_SESSION].device[P_DEVICE].syntheticEnvironmentModule;
|
|
3030
|
+
if (!sem) {
|
|
3031
|
+
return;
|
|
3032
|
+
}
|
|
3033
|
+
sem.trackedMeshes.forEach((mesh) => {
|
|
3034
|
+
let xrMesh = this[P_SESSION].trackedMeshes.get(mesh);
|
|
3035
|
+
if (!xrMesh) {
|
|
3036
|
+
const meshSpace = new XRSpace(this[P_SESSION].device[P_DEVICE].globalSpace, mesh.transform.matrix);
|
|
3037
|
+
xrMesh = new XRMesh(mesh, meshSpace, mesh.vertices, mesh.indices);
|
|
3038
|
+
this[P_SESSION].trackedMeshes.set(mesh, xrMesh);
|
|
3039
|
+
}
|
|
3040
|
+
xrMesh[P_MESH].lastChangedTime = frame.predictedDisplayTime;
|
|
3041
|
+
xrMesh[P_MESH].frame = frame;
|
|
3042
|
+
frame[P_FRAME].detectedMeshes.add(xrMesh);
|
|
3043
|
+
});
|
|
3044
|
+
},
|
|
3045
|
+
hitTestSources: new Set(),
|
|
3046
|
+
computeHitTestResults: (frame) => {
|
|
3047
|
+
const sem = this[P_SESSION].device[P_DEVICE].syntheticEnvironmentModule;
|
|
3048
|
+
if (!sem)
|
|
3049
|
+
return;
|
|
3050
|
+
const globalSpace = this[P_SESSION].device[P_DEVICE].globalSpace;
|
|
3051
|
+
this[P_SESSION].hitTestSources.forEach((hitTestSource) => {
|
|
3052
|
+
const sourceSpace = hitTestSource[P_HIT_TEST].space;
|
|
3053
|
+
const sourceGlobalOffset = XRSpaceUtils.calculateGlobalOffsetMatrix(sourceSpace);
|
|
3054
|
+
const rayLocalOffset = hitTestSource[P_HIT_TEST].offsetRay.matrix;
|
|
3055
|
+
const rayGlobalOffset = create$3();
|
|
3056
|
+
multiply$1(rayGlobalOffset, sourceGlobalOffset, rayLocalOffset);
|
|
3057
|
+
const hitTestResults = [];
|
|
3058
|
+
sem.computeHitTestResults(rayGlobalOffset).forEach((matrix) => {
|
|
3059
|
+
const offsetSpace = new XRSpace(globalSpace, matrix);
|
|
3060
|
+
const hitTestResult = new XRHitTestResult(frame, offsetSpace);
|
|
3061
|
+
hitTestResults.push(hitTestResult);
|
|
3062
|
+
});
|
|
3063
|
+
frame[P_FRAME].hitTestResultsMap.set(hitTestSource, hitTestResults);
|
|
3064
|
+
});
|
|
3065
|
+
},
|
|
2566
3066
|
onend: null,
|
|
2567
3067
|
oninputsourceschange: null,
|
|
2568
3068
|
onselect: null,
|
|
@@ -2574,87 +3074,87 @@
|
|
|
2574
3074
|
onvisibilitychange: null,
|
|
2575
3075
|
onframeratechange: null,
|
|
2576
3076
|
};
|
|
3077
|
+
XRAnchorUtils.recoverPersistentAnchorsFromStorage(this);
|
|
2577
3078
|
// start the frameloop
|
|
2578
|
-
this[
|
|
3079
|
+
this[P_SESSION].onDeviceFrame();
|
|
2579
3080
|
}
|
|
2580
3081
|
get visibilityState() {
|
|
2581
|
-
return this[
|
|
3082
|
+
return this[P_SESSION].device.visibilityState;
|
|
2582
3083
|
}
|
|
2583
3084
|
get frameRate() {
|
|
2584
|
-
return this[
|
|
3085
|
+
return this[P_SESSION].nominalFrameRate;
|
|
2585
3086
|
}
|
|
2586
3087
|
get supportedFrameRates() {
|
|
2587
|
-
return new Float32Array(this[
|
|
3088
|
+
return new Float32Array(this[P_SESSION].device.supportedFrameRates);
|
|
2588
3089
|
}
|
|
2589
3090
|
get renderState() {
|
|
2590
|
-
return this[
|
|
3091
|
+
return this[P_SESSION].renderState;
|
|
2591
3092
|
}
|
|
2592
3093
|
get inputSources() {
|
|
2593
3094
|
// use the same array object
|
|
2594
|
-
this[
|
|
2595
|
-
if (!this[
|
|
2596
|
-
this[
|
|
3095
|
+
this[P_SESSION].inputSourceArray.length = 0;
|
|
3096
|
+
if (!this[P_SESSION].ended && this[P_SESSION].mode !== 'inline') {
|
|
3097
|
+
this[P_SESSION].inputSourceArray.push(...this[P_SESSION].activeInputSources);
|
|
2597
3098
|
}
|
|
2598
|
-
return this[
|
|
3099
|
+
return this[P_SESSION].inputSourceArray;
|
|
2599
3100
|
}
|
|
2600
3101
|
get enabledFeatures() {
|
|
2601
|
-
return this[
|
|
3102
|
+
return this[P_SESSION].enabledFeatures;
|
|
2602
3103
|
}
|
|
2603
3104
|
get isSystemKeyboardSupported() {
|
|
2604
|
-
return this[
|
|
3105
|
+
return this[P_SESSION].isSystemKeyboardSupported;
|
|
2605
3106
|
}
|
|
2606
3107
|
get environmentBlendMode() {
|
|
2607
3108
|
var _a;
|
|
2608
|
-
return ((_a = this[
|
|
3109
|
+
return ((_a = this[P_SESSION].device[P_DEVICE].environmentBlendModes[this[P_SESSION].mode]) !== null && _a !== void 0 ? _a : XREnvironmentBlendMode.Opaque);
|
|
2609
3110
|
}
|
|
2610
3111
|
get interactionMode() {
|
|
2611
|
-
return this[
|
|
3112
|
+
return this[P_SESSION].device[P_DEVICE].interactionMode;
|
|
2612
3113
|
}
|
|
2613
3114
|
updateRenderState(state = {}) {
|
|
2614
3115
|
var _a, _b, _c, _d;
|
|
2615
|
-
if (this[
|
|
3116
|
+
if (this[P_SESSION].ended) {
|
|
2616
3117
|
throw new DOMException('XRSession has already ended.', 'InvalidStateError');
|
|
2617
3118
|
}
|
|
2618
|
-
if (state.baseLayer &&
|
|
2619
|
-
state.baseLayer[PRIVATE$7].session !== this) {
|
|
3119
|
+
if (state.baseLayer && state.baseLayer[P_WEBGL_LAYER].session !== this) {
|
|
2620
3120
|
throw new DOMException('Base layer was created by a different XRSession', 'InvalidStateError');
|
|
2621
3121
|
}
|
|
2622
3122
|
if (state.inlineVerticalFieldOfView != null &&
|
|
2623
|
-
this[
|
|
3123
|
+
this[P_SESSION].mode !== 'inline') {
|
|
2624
3124
|
throw new DOMException('InlineVerticalFieldOfView must not be set for an immersive session', 'InvalidStateError');
|
|
2625
3125
|
}
|
|
2626
3126
|
const compoundStateInit = {
|
|
2627
3127
|
baseLayer: state.baseLayer ||
|
|
2628
|
-
((_a = this[
|
|
3128
|
+
((_a = this[P_SESSION].pendingRenderState) === null || _a === void 0 ? void 0 : _a.baseLayer) ||
|
|
2629
3129
|
undefined,
|
|
2630
3130
|
depthFar: state.depthFar ||
|
|
2631
|
-
((_b = this[
|
|
3131
|
+
((_b = this[P_SESSION].pendingRenderState) === null || _b === void 0 ? void 0 : _b.depthFar) ||
|
|
2632
3132
|
undefined,
|
|
2633
3133
|
depthNear: state.depthNear ||
|
|
2634
|
-
((_c = this[
|
|
3134
|
+
((_c = this[P_SESSION].pendingRenderState) === null || _c === void 0 ? void 0 : _c.depthNear) ||
|
|
2635
3135
|
undefined,
|
|
2636
3136
|
inlineVerticalFieldOfView: state.inlineVerticalFieldOfView ||
|
|
2637
|
-
((_d = this[
|
|
3137
|
+
((_d = this[P_SESSION].pendingRenderState) === null || _d === void 0 ? void 0 : _d.inlineVerticalFieldOfView) ||
|
|
2638
3138
|
undefined,
|
|
2639
3139
|
};
|
|
2640
|
-
this[
|
|
3140
|
+
this[P_SESSION].pendingRenderState = new XRRenderState(compoundStateInit, this[P_SESSION].renderState);
|
|
2641
3141
|
}
|
|
2642
3142
|
// the nominal frame rate updates are emulated, no actual update to the
|
|
2643
3143
|
// display frame rate of the device will be executed
|
|
2644
3144
|
async updateTargetFrameRate(rate) {
|
|
2645
3145
|
return new Promise((resolve, reject) => {
|
|
2646
|
-
if (this[
|
|
3146
|
+
if (this[P_SESSION].ended) {
|
|
2647
3147
|
reject(new DOMException('XRSession has already ended.', 'InvalidStateError'));
|
|
2648
3148
|
}
|
|
2649
|
-
else if (!this[
|
|
3149
|
+
else if (!this[P_SESSION].device.supportedFrameRates.includes(rate)) {
|
|
2650
3150
|
reject(new DOMException('Requested frame rate not supported.', 'InvalidStateError'));
|
|
2651
3151
|
}
|
|
2652
3152
|
else {
|
|
2653
|
-
if (this[
|
|
3153
|
+
if (this[P_SESSION].nominalFrameRate === rate) {
|
|
2654
3154
|
console.log(`Requested frame rate is the same as the current nominal frame rate, no update made`);
|
|
2655
3155
|
}
|
|
2656
3156
|
else {
|
|
2657
|
-
this[
|
|
3157
|
+
this[P_SESSION].nominalFrameRate = rate;
|
|
2658
3158
|
this.dispatchEvent(new XRSessionEvent('frameratechange', { session: this }));
|
|
2659
3159
|
console.log(`Nominal frame rate updated to ${rate}`);
|
|
2660
3160
|
}
|
|
@@ -2664,37 +3164,37 @@
|
|
|
2664
3164
|
}
|
|
2665
3165
|
async requestReferenceSpace(type) {
|
|
2666
3166
|
return new Promise((resolve, reject) => {
|
|
2667
|
-
if (this[
|
|
2668
|
-
!this[
|
|
3167
|
+
if (this[P_SESSION].ended ||
|
|
3168
|
+
!this[P_SESSION].referenceSpaceIsSupported(type)) {
|
|
2669
3169
|
reject(new DOMException('The requested reference space type is not supported.', 'NotSupportedError'));
|
|
2670
3170
|
return;
|
|
2671
3171
|
}
|
|
2672
3172
|
let referenceSpace;
|
|
2673
3173
|
switch (type) {
|
|
2674
3174
|
case XRReferenceSpaceType.Viewer:
|
|
2675
|
-
referenceSpace = this[
|
|
3175
|
+
referenceSpace = this[P_SESSION].device.viewerSpace;
|
|
2676
3176
|
break;
|
|
2677
3177
|
case XRReferenceSpaceType.Local:
|
|
2678
3178
|
// creating an XRReferenceSpace with the current headset transform in global space
|
|
2679
|
-
referenceSpace = new XRReferenceSpace(type, this[
|
|
3179
|
+
referenceSpace = new XRReferenceSpace(type, this[P_SESSION].device[P_DEVICE].globalSpace, this[P_SESSION].device.viewerSpace[P_SPACE].offsetMatrix);
|
|
2680
3180
|
break;
|
|
2681
3181
|
case XRReferenceSpaceType.LocalFloor:
|
|
2682
3182
|
case XRReferenceSpaceType.BoundedFloor:
|
|
2683
3183
|
case XRReferenceSpaceType.Unbounded:
|
|
2684
3184
|
// TO-DO: add boundary geometry for bounded-floor
|
|
2685
|
-
referenceSpace = new XRReferenceSpace(type, this[
|
|
3185
|
+
referenceSpace = new XRReferenceSpace(type, this[P_SESSION].device[P_DEVICE].globalSpace);
|
|
2686
3186
|
break;
|
|
2687
3187
|
}
|
|
2688
|
-
this[
|
|
3188
|
+
this[P_SESSION].referenceSpaces.push(referenceSpace);
|
|
2689
3189
|
resolve(referenceSpace);
|
|
2690
3190
|
});
|
|
2691
3191
|
}
|
|
2692
3192
|
requestAnimationFrame(callback) {
|
|
2693
|
-
if (this[
|
|
3193
|
+
if (this[P_SESSION].ended) {
|
|
2694
3194
|
return 0;
|
|
2695
3195
|
}
|
|
2696
|
-
const frameHandle = ++this[
|
|
2697
|
-
this[
|
|
3196
|
+
const frameHandle = ++this[P_SESSION].frameHandle;
|
|
3197
|
+
this[P_SESSION].frameCallbacks.push({
|
|
2698
3198
|
handle: frameHandle,
|
|
2699
3199
|
callback,
|
|
2700
3200
|
cancelled: false,
|
|
@@ -2703,7 +3203,7 @@
|
|
|
2703
3203
|
}
|
|
2704
3204
|
cancelAnimationFrame(handle) {
|
|
2705
3205
|
// Remove the callback with that handle from the queue
|
|
2706
|
-
let callbacks = this[
|
|
3206
|
+
let callbacks = this[P_SESSION].frameCallbacks;
|
|
2707
3207
|
let index = callbacks.findIndex((d) => d && d.handle === handle);
|
|
2708
3208
|
if (index > -1) {
|
|
2709
3209
|
callbacks[index].cancelled = true;
|
|
@@ -2711,7 +3211,7 @@
|
|
|
2711
3211
|
}
|
|
2712
3212
|
// If cancelAnimationFrame is called from within a frame callback, also check
|
|
2713
3213
|
// the remaining callbacks for the current frame:
|
|
2714
|
-
callbacks = this[
|
|
3214
|
+
callbacks = this[P_SESSION].currentFrameCallbacks;
|
|
2715
3215
|
if (callbacks) {
|
|
2716
3216
|
index = callbacks.findIndex((d) => d && d.handle === handle);
|
|
2717
3217
|
if (index > -1) {
|
|
@@ -2722,144 +3222,199 @@
|
|
|
2722
3222
|
}
|
|
2723
3223
|
async end() {
|
|
2724
3224
|
return new Promise((resolve, reject) => {
|
|
2725
|
-
if (this[
|
|
3225
|
+
if (this[P_SESSION].ended || this[P_SESSION].deviceFrameHandle === null) {
|
|
2726
3226
|
reject(new DOMException('XRSession has already ended.', 'InvalidStateError'));
|
|
2727
3227
|
}
|
|
2728
3228
|
else {
|
|
2729
|
-
globalThis.cancelAnimationFrame(this[
|
|
2730
|
-
this[
|
|
3229
|
+
globalThis.cancelAnimationFrame(this[P_SESSION].deviceFrameHandle);
|
|
3230
|
+
this[P_SESSION].device[P_DEVICE].onSessionEnd();
|
|
2731
3231
|
this.dispatchEvent(new XRSessionEvent('end', { session: this }));
|
|
2732
3232
|
resolve();
|
|
2733
3233
|
}
|
|
2734
3234
|
});
|
|
2735
3235
|
}
|
|
3236
|
+
// anchors
|
|
3237
|
+
get persistentAnchors() {
|
|
3238
|
+
return Array.from(this[P_SESSION].persistentAnchors.keys());
|
|
3239
|
+
}
|
|
3240
|
+
restorePersistentAnchor(uuid) {
|
|
3241
|
+
return new Promise((resolve, reject) => {
|
|
3242
|
+
if (!this[P_SESSION].persistentAnchors.has(uuid)) {
|
|
3243
|
+
reject(new DOMException(`Persistent anchor with uuid ${uuid} not found.`, 'InvalidStateError'));
|
|
3244
|
+
}
|
|
3245
|
+
else if (this[P_SESSION].ended) {
|
|
3246
|
+
reject(new DOMException('XRSession has already ended.', 'InvalidStateError'));
|
|
3247
|
+
}
|
|
3248
|
+
else {
|
|
3249
|
+
const anchor = this[P_SESSION].persistentAnchors.get(uuid);
|
|
3250
|
+
if (this[P_SESSION].newAnchors.has(anchor)) {
|
|
3251
|
+
reject(new DOMException(`Multiple concurrent attempts detected to restore the anchor with UUID: ${uuid}.`, 'InvalidStateError'));
|
|
3252
|
+
}
|
|
3253
|
+
else {
|
|
3254
|
+
this[P_SESSION].trackedAnchors.add(anchor);
|
|
3255
|
+
this[P_SESSION].newAnchors.set(anchor, { resolve, reject });
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3258
|
+
});
|
|
3259
|
+
}
|
|
3260
|
+
deletePersistentAnchor(uuid) {
|
|
3261
|
+
return new Promise((resolve, reject) => {
|
|
3262
|
+
if (!this[P_SESSION].persistentAnchors.has(uuid)) {
|
|
3263
|
+
reject(new DOMException(`Persistent anchor with uuid ${uuid} not found.`, 'InvalidStateError'));
|
|
3264
|
+
}
|
|
3265
|
+
else {
|
|
3266
|
+
const anchor = this[P_SESSION].persistentAnchors.get(uuid);
|
|
3267
|
+
this[P_SESSION].persistentAnchors.delete(uuid);
|
|
3268
|
+
anchor.delete();
|
|
3269
|
+
resolve(undefined);
|
|
3270
|
+
}
|
|
3271
|
+
});
|
|
3272
|
+
}
|
|
3273
|
+
requestHitTestSource(options) {
|
|
3274
|
+
return new Promise((resolve, reject) => {
|
|
3275
|
+
if (!this[P_SESSION].enabledFeatures.includes('hit-test')) {
|
|
3276
|
+
reject(new DOMException(`WebXR feature "hit-test" is not supported by current session`, 'NotSupportedError'));
|
|
3277
|
+
}
|
|
3278
|
+
else if (this[P_SESSION].ended) {
|
|
3279
|
+
reject(new DOMException('XRSession has already ended.', 'InvalidStateError'));
|
|
3280
|
+
}
|
|
3281
|
+
else if (!this[P_SESSION].device[P_DEVICE].syntheticEnvironmentModule) {
|
|
3282
|
+
reject(new DOMException('Synthethic Environment Module required for emulating hit-test', 'OperationError'));
|
|
3283
|
+
}
|
|
3284
|
+
else {
|
|
3285
|
+
const xrHitTestSource = new XRHitTestSource(this, options);
|
|
3286
|
+
this[P_SESSION].hitTestSources.add(xrHitTestSource);
|
|
3287
|
+
resolve(xrHitTestSource);
|
|
3288
|
+
}
|
|
3289
|
+
});
|
|
3290
|
+
}
|
|
2736
3291
|
// events
|
|
2737
3292
|
get onend() {
|
|
2738
3293
|
var _a;
|
|
2739
|
-
return (_a = this[
|
|
3294
|
+
return (_a = this[P_SESSION].onend) !== null && _a !== void 0 ? _a : (() => { });
|
|
2740
3295
|
}
|
|
2741
3296
|
set onend(callback) {
|
|
2742
|
-
if (this[
|
|
2743
|
-
this.removeEventListener('end', this[
|
|
3297
|
+
if (this[P_SESSION].onend) {
|
|
3298
|
+
this.removeEventListener('end', this[P_SESSION].onend);
|
|
2744
3299
|
}
|
|
2745
|
-
this[
|
|
3300
|
+
this[P_SESSION].onend = callback;
|
|
2746
3301
|
if (callback) {
|
|
2747
3302
|
this.addEventListener('end', callback);
|
|
2748
3303
|
}
|
|
2749
3304
|
}
|
|
2750
3305
|
get oninputsourceschange() {
|
|
2751
3306
|
var _a;
|
|
2752
|
-
return (_a = this[
|
|
3307
|
+
return (_a = this[P_SESSION].oninputsourceschange) !== null && _a !== void 0 ? _a : (() => { });
|
|
2753
3308
|
}
|
|
2754
3309
|
set oninputsourceschange(callback) {
|
|
2755
|
-
if (this[
|
|
2756
|
-
this.removeEventListener('inputsourceschange', this[
|
|
3310
|
+
if (this[P_SESSION].oninputsourceschange) {
|
|
3311
|
+
this.removeEventListener('inputsourceschange', this[P_SESSION].oninputsourceschange);
|
|
2757
3312
|
}
|
|
2758
|
-
this[
|
|
3313
|
+
this[P_SESSION].oninputsourceschange = callback;
|
|
2759
3314
|
if (callback) {
|
|
2760
3315
|
this.addEventListener('inputsourceschange', callback);
|
|
2761
3316
|
}
|
|
2762
3317
|
}
|
|
2763
3318
|
get onselect() {
|
|
2764
3319
|
var _a;
|
|
2765
|
-
return (_a = this[
|
|
3320
|
+
return (_a = this[P_SESSION].onselect) !== null && _a !== void 0 ? _a : (() => { });
|
|
2766
3321
|
}
|
|
2767
3322
|
set onselect(callback) {
|
|
2768
|
-
if (this[
|
|
2769
|
-
this.removeEventListener('select', this[
|
|
3323
|
+
if (this[P_SESSION].onselect) {
|
|
3324
|
+
this.removeEventListener('select', this[P_SESSION].onselect);
|
|
2770
3325
|
}
|
|
2771
|
-
this[
|
|
3326
|
+
this[P_SESSION].onselect = callback;
|
|
2772
3327
|
if (callback) {
|
|
2773
3328
|
this.addEventListener('select', callback);
|
|
2774
3329
|
}
|
|
2775
3330
|
}
|
|
2776
3331
|
get onselectstart() {
|
|
2777
3332
|
var _a;
|
|
2778
|
-
return (_a = this[
|
|
3333
|
+
return (_a = this[P_SESSION].onselectstart) !== null && _a !== void 0 ? _a : (() => { });
|
|
2779
3334
|
}
|
|
2780
3335
|
set onselectstart(callback) {
|
|
2781
|
-
if (this[
|
|
2782
|
-
this.removeEventListener('selectstart', this[
|
|
3336
|
+
if (this[P_SESSION].onselectstart) {
|
|
3337
|
+
this.removeEventListener('selectstart', this[P_SESSION].onselectstart);
|
|
2783
3338
|
}
|
|
2784
|
-
this[
|
|
3339
|
+
this[P_SESSION].onselectstart = callback;
|
|
2785
3340
|
if (callback) {
|
|
2786
3341
|
this.addEventListener('selectstart', callback);
|
|
2787
3342
|
}
|
|
2788
3343
|
}
|
|
2789
3344
|
get onselectend() {
|
|
2790
3345
|
var _a;
|
|
2791
|
-
return (_a = this[
|
|
3346
|
+
return (_a = this[P_SESSION].onselectend) !== null && _a !== void 0 ? _a : (() => { });
|
|
2792
3347
|
}
|
|
2793
3348
|
set onselectend(callback) {
|
|
2794
|
-
if (this[
|
|
2795
|
-
this.removeEventListener('selectend', this[
|
|
3349
|
+
if (this[P_SESSION].onselectend) {
|
|
3350
|
+
this.removeEventListener('selectend', this[P_SESSION].onselectend);
|
|
2796
3351
|
}
|
|
2797
|
-
this[
|
|
3352
|
+
this[P_SESSION].onselectend = callback;
|
|
2798
3353
|
if (callback) {
|
|
2799
3354
|
this.addEventListener('selectend', callback);
|
|
2800
3355
|
}
|
|
2801
3356
|
}
|
|
2802
3357
|
get onsqueeze() {
|
|
2803
3358
|
var _a;
|
|
2804
|
-
return (_a = this[
|
|
3359
|
+
return (_a = this[P_SESSION].onsqueeze) !== null && _a !== void 0 ? _a : (() => { });
|
|
2805
3360
|
}
|
|
2806
3361
|
set onsqueeze(callback) {
|
|
2807
|
-
if (this[
|
|
2808
|
-
this.removeEventListener('squeeze', this[
|
|
3362
|
+
if (this[P_SESSION].onsqueeze) {
|
|
3363
|
+
this.removeEventListener('squeeze', this[P_SESSION].onsqueeze);
|
|
2809
3364
|
}
|
|
2810
|
-
this[
|
|
3365
|
+
this[P_SESSION].onsqueeze = callback;
|
|
2811
3366
|
if (callback) {
|
|
2812
3367
|
this.addEventListener('squeeze', callback);
|
|
2813
3368
|
}
|
|
2814
3369
|
}
|
|
2815
3370
|
get onsqueezestart() {
|
|
2816
3371
|
var _a;
|
|
2817
|
-
return (_a = this[
|
|
3372
|
+
return (_a = this[P_SESSION].onsqueezestart) !== null && _a !== void 0 ? _a : (() => { });
|
|
2818
3373
|
}
|
|
2819
3374
|
set onsqueezestart(callback) {
|
|
2820
|
-
if (this[
|
|
2821
|
-
this.removeEventListener('squeezestart', this[
|
|
3375
|
+
if (this[P_SESSION].onsqueezestart) {
|
|
3376
|
+
this.removeEventListener('squeezestart', this[P_SESSION].onsqueezestart);
|
|
2822
3377
|
}
|
|
2823
|
-
this[
|
|
3378
|
+
this[P_SESSION].onsqueezestart = callback;
|
|
2824
3379
|
if (callback) {
|
|
2825
3380
|
this.addEventListener('squeezestart', callback);
|
|
2826
3381
|
}
|
|
2827
3382
|
}
|
|
2828
3383
|
get onsqueezeend() {
|
|
2829
3384
|
var _a;
|
|
2830
|
-
return (_a = this[
|
|
3385
|
+
return (_a = this[P_SESSION].onsqueezeend) !== null && _a !== void 0 ? _a : (() => { });
|
|
2831
3386
|
}
|
|
2832
3387
|
set onsqueezeend(callback) {
|
|
2833
|
-
if (this[
|
|
2834
|
-
this.removeEventListener('squeezeend', this[
|
|
3388
|
+
if (this[P_SESSION].onsqueezeend) {
|
|
3389
|
+
this.removeEventListener('squeezeend', this[P_SESSION].onsqueezeend);
|
|
2835
3390
|
}
|
|
2836
|
-
this[
|
|
3391
|
+
this[P_SESSION].onsqueezeend = callback;
|
|
2837
3392
|
if (callback) {
|
|
2838
3393
|
this.addEventListener('squeezeend', callback);
|
|
2839
3394
|
}
|
|
2840
3395
|
}
|
|
2841
3396
|
get onvisibilitychange() {
|
|
2842
3397
|
var _a;
|
|
2843
|
-
return (_a = this[
|
|
3398
|
+
return (_a = this[P_SESSION].onvisibilitychange) !== null && _a !== void 0 ? _a : (() => { });
|
|
2844
3399
|
}
|
|
2845
3400
|
set onvisibilitychange(callback) {
|
|
2846
|
-
if (this[
|
|
2847
|
-
this.removeEventListener('visibilitychange', this[
|
|
3401
|
+
if (this[P_SESSION].onvisibilitychange) {
|
|
3402
|
+
this.removeEventListener('visibilitychange', this[P_SESSION].onvisibilitychange);
|
|
2848
3403
|
}
|
|
2849
|
-
this[
|
|
3404
|
+
this[P_SESSION].onvisibilitychange = callback;
|
|
2850
3405
|
if (callback) {
|
|
2851
3406
|
this.addEventListener('visibilitychange', callback);
|
|
2852
3407
|
}
|
|
2853
3408
|
}
|
|
2854
3409
|
get onframeratechange() {
|
|
2855
3410
|
var _a;
|
|
2856
|
-
return (_a = this[
|
|
3411
|
+
return (_a = this[P_SESSION].onframeratechange) !== null && _a !== void 0 ? _a : (() => { });
|
|
2857
3412
|
}
|
|
2858
3413
|
set onframeratechange(callback) {
|
|
2859
|
-
if (this[
|
|
2860
|
-
this.removeEventListener('frameratechange', this[
|
|
3414
|
+
if (this[P_SESSION].onframeratechange) {
|
|
3415
|
+
this.removeEventListener('frameratechange', this[P_SESSION].onframeratechange);
|
|
2861
3416
|
}
|
|
2862
|
-
this[
|
|
3417
|
+
this[P_SESSION].onframeratechange = callback;
|
|
2863
3418
|
if (callback) {
|
|
2864
3419
|
this.addEventListener('frameratechange', callback);
|
|
2865
3420
|
}
|
|
@@ -2903,6 +3458,22 @@
|
|
|
2903
3458
|
class XRHand extends Map {
|
|
2904
3459
|
}
|
|
2905
3460
|
|
|
3461
|
+
/**
|
|
3462
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3463
|
+
*
|
|
3464
|
+
* This source code is licensed under the MIT license found in the
|
|
3465
|
+
* LICENSE file in the root directory of this source tree.
|
|
3466
|
+
*/
|
|
3467
|
+
class XRJointSpace extends XRSpace {
|
|
3468
|
+
constructor(jointName, parentSpace, offsetMatrix) {
|
|
3469
|
+
super(parentSpace, offsetMatrix);
|
|
3470
|
+
this[P_JOINT_SPACE] = { jointName, radius: 0 };
|
|
3471
|
+
}
|
|
3472
|
+
get jointName() {
|
|
3473
|
+
return this[P_JOINT_SPACE].jointName;
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3476
|
+
|
|
2906
3477
|
/**
|
|
2907
3478
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2908
3479
|
*
|
|
@@ -3684,7 +4255,6 @@
|
|
|
3684
4255
|
matrixLeft[i] *= mirrorMultiplierMatrix[i];
|
|
3685
4256
|
}
|
|
3686
4257
|
};
|
|
3687
|
-
const PRIVATE$5 = Symbol('@immersive-web-emulation-runtime/xr-hand-input');
|
|
3688
4258
|
class XRHandInput extends XRTrackedInput {
|
|
3689
4259
|
constructor(handInputConfig, handedness, globalSpace) {
|
|
3690
4260
|
if (handedness !== XRHandedness.Left && handedness !== XRHandedness.Right) {
|
|
@@ -3705,53 +4275,51 @@
|
|
|
3705
4275
|
});
|
|
3706
4276
|
const inputSource = new XRInputSource(handedness, XRTargetRayMode.TrackedPointer, profiles, targetRaySpace, new Gamepad(XRHandGamepadConfig), gripSpace, hand);
|
|
3707
4277
|
super(inputSource);
|
|
3708
|
-
this[
|
|
4278
|
+
this[P_HAND_INPUT] = {
|
|
3709
4279
|
poseId: 'default',
|
|
3710
4280
|
poses: handInputConfig.poses,
|
|
3711
4281
|
};
|
|
3712
4282
|
this.updateHandPose();
|
|
3713
4283
|
}
|
|
3714
4284
|
get poseId() {
|
|
3715
|
-
return this[
|
|
4285
|
+
return this[P_HAND_INPUT].poseId;
|
|
3716
4286
|
}
|
|
3717
4287
|
set poseId(poseId) {
|
|
3718
|
-
if (!this[
|
|
4288
|
+
if (!this[P_HAND_INPUT].poses[poseId]) {
|
|
3719
4289
|
console.warn(`Pose config ${poseId} not found`);
|
|
3720
4290
|
return;
|
|
3721
4291
|
}
|
|
3722
|
-
this[
|
|
4292
|
+
this[P_HAND_INPUT].poseId = poseId;
|
|
3723
4293
|
}
|
|
3724
4294
|
updateHandPose() {
|
|
3725
|
-
const targetPose = this[
|
|
3726
|
-
const pinchPose = this[
|
|
4295
|
+
const targetPose = this[P_HAND_INPUT].poses[this[P_HAND_INPUT].poseId];
|
|
4296
|
+
const pinchPose = this[P_HAND_INPUT].poses.pinch;
|
|
3727
4297
|
Object.values(XRHandJoint).forEach((jointName) => {
|
|
3728
4298
|
const targetJointMatrix = targetPose.jointTransforms[jointName].offsetMatrix;
|
|
3729
4299
|
const pinchJointMatrix = pinchPose.jointTransforms[jointName].offsetMatrix;
|
|
3730
4300
|
const jointSpace = this.inputSource.hand.get(jointName);
|
|
3731
|
-
interpolateMatrix(jointSpace[
|
|
4301
|
+
interpolateMatrix(jointSpace[P_SPACE].offsetMatrix, targetJointMatrix, pinchJointMatrix, this.pinchValue);
|
|
3732
4302
|
if (this.inputSource.handedness === XRHandedness.Right) {
|
|
3733
|
-
mirrorMatrixToRight(jointSpace[
|
|
4303
|
+
mirrorMatrixToRight(jointSpace[P_SPACE].offsetMatrix);
|
|
3734
4304
|
}
|
|
3735
|
-
jointSpace[
|
|
4305
|
+
jointSpace[P_JOINT_SPACE].radius =
|
|
3736
4306
|
(1 - this.pinchValue) * targetPose.jointTransforms[jointName].radius +
|
|
3737
4307
|
this.pinchValue * pinchPose.jointTransforms[jointName].radius;
|
|
3738
4308
|
});
|
|
3739
4309
|
if (targetPose.gripOffsetMatrix && pinchPose.gripOffsetMatrix) {
|
|
3740
|
-
interpolateMatrix(this.inputSource.gripSpace[
|
|
4310
|
+
interpolateMatrix(this.inputSource.gripSpace[P_SPACE].offsetMatrix, targetPose.gripOffsetMatrix, pinchPose.gripOffsetMatrix, this.pinchValue);
|
|
3741
4311
|
}
|
|
3742
4312
|
}
|
|
3743
4313
|
get pinchValue() {
|
|
3744
|
-
return this[
|
|
3745
|
-
.buttonsMap['pinch'].value;
|
|
4314
|
+
return this[P_TRACKED_INPUT].inputSource.gamepad[P_GAMEPAD].buttonsMap['pinch'].value;
|
|
3746
4315
|
}
|
|
3747
4316
|
updatePinchValue(value) {
|
|
3748
4317
|
if (value > 1 || value < 0) {
|
|
3749
4318
|
console.warn(`Out-of-range value ${value} provided for pinch`);
|
|
3750
4319
|
return;
|
|
3751
4320
|
}
|
|
3752
|
-
const gamepadButton = this[
|
|
3753
|
-
|
|
3754
|
-
gamepadButton[PRIVATE$k].pendingValue = value;
|
|
4321
|
+
const gamepadButton = this[P_TRACKED_INPUT].inputSource.gamepad[P_GAMEPAD].buttonsMap['pinch'];
|
|
4322
|
+
gamepadButton[P_GAMEPAD].pendingValue = value;
|
|
3755
4323
|
}
|
|
3756
4324
|
onFrameStart(frame) {
|
|
3757
4325
|
super.onFrameStart(frame);
|
|
@@ -3765,66 +4333,66 @@
|
|
|
3765
4333
|
* This source code is licensed under the MIT license found in the
|
|
3766
4334
|
* LICENSE file in the root directory of this source tree.
|
|
3767
4335
|
*/
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
4336
|
+
class XRLayer extends EventTarget {
|
|
4337
|
+
}
|
|
4338
|
+
const defaultLayerInit = {
|
|
4339
|
+
antialias: true,
|
|
4340
|
+
depth: true,
|
|
4341
|
+
stencil: false,
|
|
4342
|
+
alpha: true,
|
|
4343
|
+
ignoreDepthValues: false,
|
|
4344
|
+
framebufferScaleFactor: 1.0,
|
|
4345
|
+
};
|
|
4346
|
+
class XRWebGLLayer extends XRLayer {
|
|
4347
|
+
constructor(session, context, layerInit = {}) {
|
|
3771
4348
|
super();
|
|
3772
|
-
|
|
3773
|
-
|
|
4349
|
+
if (session[P_SESSION].ended) {
|
|
4350
|
+
throw new DOMException('Session has ended', 'InvalidStateError');
|
|
4351
|
+
}
|
|
4352
|
+
// TO-DO: Check that the context attribute has xrCompatible set to true
|
|
4353
|
+
// may require polyfilling the context and perhaps canvas.getContext
|
|
4354
|
+
// Default values for XRWebGLLayerInit, can be overridden by layerInit
|
|
4355
|
+
const config = { ...defaultLayerInit, ...layerInit };
|
|
4356
|
+
this[P_WEBGL_LAYER] = {
|
|
4357
|
+
session,
|
|
4358
|
+
context,
|
|
4359
|
+
antialias: config.antialias,
|
|
4360
|
+
};
|
|
3774
4361
|
}
|
|
3775
|
-
|
|
3776
|
-
return
|
|
3777
|
-
if (mode === XRSessionMode.Inline) {
|
|
3778
|
-
resolve(true);
|
|
3779
|
-
}
|
|
3780
|
-
else {
|
|
3781
|
-
// Check for spatial tracking permission if necessary
|
|
3782
|
-
resolve(this[PRIVATE$4].device.supportedSessionModes.includes(mode));
|
|
3783
|
-
}
|
|
3784
|
-
});
|
|
4362
|
+
get context() {
|
|
4363
|
+
return this[P_WEBGL_LAYER].context;
|
|
3785
4364
|
}
|
|
3786
|
-
|
|
3787
|
-
return
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
// Proceed with session creation
|
|
3818
|
-
const session = new XRSession(this[PRIVATE$4].device, mode, enabledFeatures);
|
|
3819
|
-
this[PRIVATE$4].activeSession = session;
|
|
3820
|
-
// Listen for session end to clear the active session
|
|
3821
|
-
session.addEventListener('end', () => {
|
|
3822
|
-
this[PRIVATE$4].activeSession = undefined;
|
|
3823
|
-
});
|
|
3824
|
-
resolve(session);
|
|
3825
|
-
})
|
|
3826
|
-
.catch(reject);
|
|
3827
|
-
});
|
|
4365
|
+
get antialias() {
|
|
4366
|
+
return this[P_WEBGL_LAYER].antialias;
|
|
4367
|
+
}
|
|
4368
|
+
get ignoreDepthValues() {
|
|
4369
|
+
return true;
|
|
4370
|
+
}
|
|
4371
|
+
get framebuffer() {
|
|
4372
|
+
return null;
|
|
4373
|
+
}
|
|
4374
|
+
get framebufferWidth() {
|
|
4375
|
+
return this[P_WEBGL_LAYER].context.drawingBufferWidth;
|
|
4376
|
+
}
|
|
4377
|
+
get framebufferHeight() {
|
|
4378
|
+
return this[P_WEBGL_LAYER].context.drawingBufferHeight;
|
|
4379
|
+
}
|
|
4380
|
+
getViewport(view) {
|
|
4381
|
+
if (view[P_VIEW].session !== this[P_WEBGL_LAYER].session) {
|
|
4382
|
+
throw new DOMException("View's session differs from Layer's session", 'InvalidStateError');
|
|
4383
|
+
}
|
|
4384
|
+
// TO-DO: check frame
|
|
4385
|
+
return this[P_WEBGL_LAYER].session[P_SESSION].device[P_DEVICE].getViewport(this, view);
|
|
4386
|
+
}
|
|
4387
|
+
static getNativeFramebufferScaleFactor(session) {
|
|
4388
|
+
if (!(session instanceof XRSession)) {
|
|
4389
|
+
throw new TypeError('getNativeFramebufferScaleFactor must be passed a session.');
|
|
4390
|
+
}
|
|
4391
|
+
if (session[P_SESSION].ended) {
|
|
4392
|
+
return 0.0;
|
|
4393
|
+
}
|
|
4394
|
+
// Return 1.0 for simplicity, actual implementation might vary based on the device capabilities
|
|
4395
|
+
return 1.0;
|
|
3828
4396
|
}
|
|
3829
4397
|
}
|
|
3830
4398
|
|
|
@@ -3834,7 +4402,6 @@
|
|
|
3834
4402
|
* This source code is licensed under the MIT license found in the
|
|
3835
4403
|
* LICENSE file in the root directory of this source tree.
|
|
3836
4404
|
*/
|
|
3837
|
-
const PRIVATE$3 = Symbol('@immersive-web-emulation-runtime/action-player');
|
|
3838
4405
|
class ActionPlayer {
|
|
3839
4406
|
constructor(refSpace, recording, ipd) {
|
|
3840
4407
|
const { schema, frames } = recording;
|
|
@@ -3847,7 +4414,7 @@
|
|
|
3847
4414
|
[XREye.Right]: new XRSpace(viewerSpace),
|
|
3848
4415
|
[XREye.None]: new XRSpace(viewerSpace),
|
|
3849
4416
|
};
|
|
3850
|
-
this[
|
|
4417
|
+
this[P_ACTION_PLAYER] = {
|
|
3851
4418
|
refSpace,
|
|
3852
4419
|
inputSources: new Map(),
|
|
3853
4420
|
inputSchemas: new Map(),
|
|
@@ -3862,8 +4429,8 @@
|
|
|
3862
4429
|
vec3: create$2(),
|
|
3863
4430
|
quat: create(),
|
|
3864
4431
|
};
|
|
3865
|
-
fromTranslation(this[
|
|
3866
|
-
fromTranslation(this[
|
|
4432
|
+
fromTranslation(this[P_ACTION_PLAYER].viewSpaces[XREye.Left][P_SPACE].offsetMatrix, fromValues$2(-ipd / 2, 0, 0));
|
|
4433
|
+
fromTranslation(this[P_ACTION_PLAYER].viewSpaces[XREye.Right][P_SPACE].offsetMatrix, fromValues$2(ipd / 2, 0, 0));
|
|
3867
4434
|
schema.forEach((schemaEntry) => {
|
|
3868
4435
|
const index = schemaEntry[0];
|
|
3869
4436
|
const schema = schemaEntry[1];
|
|
@@ -3892,53 +4459,55 @@
|
|
|
3892
4459
|
});
|
|
3893
4460
|
}
|
|
3894
4461
|
const inputSource = new XRInputSource(schema.handedness, schema.targetRayMode, schema.profiles, targetRaySpace, gamepad, schema.hasGrip ? new XRSpace(refSpace) : undefined, schema.hasHand ? hand : undefined);
|
|
3895
|
-
this[
|
|
4462
|
+
this[P_ACTION_PLAYER].inputSources.set(index, {
|
|
3896
4463
|
active: false,
|
|
3897
4464
|
source: inputSource,
|
|
3898
4465
|
});
|
|
3899
|
-
this[
|
|
4466
|
+
this[P_ACTION_PLAYER].inputSchemas.set(index, schema);
|
|
3900
4467
|
});
|
|
3901
4468
|
}
|
|
3902
4469
|
play() {
|
|
3903
|
-
this[
|
|
3904
|
-
this[
|
|
3905
|
-
|
|
3906
|
-
this[
|
|
4470
|
+
this[P_ACTION_PLAYER].recordedFramePointer = 0;
|
|
4471
|
+
this[P_ACTION_PLAYER].playbackTime =
|
|
4472
|
+
this[P_ACTION_PLAYER].startingTimeStamp;
|
|
4473
|
+
this[P_ACTION_PLAYER].playing = true;
|
|
4474
|
+
this[P_ACTION_PLAYER].actualTimeStamp = performance.now();
|
|
3907
4475
|
}
|
|
3908
4476
|
stop() {
|
|
3909
|
-
this[
|
|
4477
|
+
this[P_ACTION_PLAYER].playing = false;
|
|
3910
4478
|
}
|
|
3911
4479
|
get playing() {
|
|
3912
|
-
return this[
|
|
4480
|
+
return this[P_ACTION_PLAYER].playing;
|
|
3913
4481
|
}
|
|
3914
4482
|
get viewerSpace() {
|
|
3915
|
-
return this[
|
|
4483
|
+
return this[P_ACTION_PLAYER].viewerSpace;
|
|
3916
4484
|
}
|
|
3917
4485
|
get viewSpaces() {
|
|
3918
|
-
return this[
|
|
4486
|
+
return this[P_ACTION_PLAYER].viewSpaces;
|
|
3919
4487
|
}
|
|
3920
4488
|
get inputSources() {
|
|
3921
|
-
return Array.from(this[
|
|
4489
|
+
return Array.from(this[P_ACTION_PLAYER].inputSources.values())
|
|
3922
4490
|
.filter((wrapper) => wrapper.active)
|
|
3923
4491
|
.map((wrapper) => wrapper.source);
|
|
3924
4492
|
}
|
|
3925
4493
|
playFrame() {
|
|
3926
4494
|
const now = performance.now();
|
|
3927
|
-
const delta = now - this[
|
|
3928
|
-
this[
|
|
3929
|
-
this[
|
|
3930
|
-
if (this[
|
|
4495
|
+
const delta = now - this[P_ACTION_PLAYER].actualTimeStamp;
|
|
4496
|
+
this[P_ACTION_PLAYER].actualTimeStamp = now;
|
|
4497
|
+
this[P_ACTION_PLAYER].playbackTime += delta;
|
|
4498
|
+
if (this[P_ACTION_PLAYER].playbackTime >
|
|
4499
|
+
this[P_ACTION_PLAYER].endingTimeStamp) {
|
|
3931
4500
|
this.stop();
|
|
3932
4501
|
return;
|
|
3933
4502
|
}
|
|
3934
|
-
while (this[
|
|
3935
|
-
this[
|
|
4503
|
+
while (this[P_ACTION_PLAYER].frames[this[P_ACTION_PLAYER].recordedFramePointer + 1][0] < this[P_ACTION_PLAYER].playbackTime) {
|
|
4504
|
+
this[P_ACTION_PLAYER].recordedFramePointer++;
|
|
3936
4505
|
}
|
|
3937
|
-
const lastFrameData = this[
|
|
3938
|
-
const nextFrameData = this[
|
|
3939
|
-
const alpha = (this[
|
|
4506
|
+
const lastFrameData = this[P_ACTION_PLAYER].frames[this[P_ACTION_PLAYER].recordedFramePointer];
|
|
4507
|
+
const nextFrameData = this[P_ACTION_PLAYER].frames[this[P_ACTION_PLAYER].recordedFramePointer + 1];
|
|
4508
|
+
const alpha = (this[P_ACTION_PLAYER].playbackTime - lastFrameData[0]) /
|
|
3940
4509
|
(nextFrameData[0] - lastFrameData[0]);
|
|
3941
|
-
this.updateXRSpaceFromMergedFrames(this[
|
|
4510
|
+
this.updateXRSpaceFromMergedFrames(this[P_ACTION_PLAYER].viewerSpace, lastFrameData.slice(1, 8), nextFrameData.slice(1, 8), alpha);
|
|
3942
4511
|
const lastFrameInputs = new Map();
|
|
3943
4512
|
for (let i = 8; i < lastFrameData.length; i++) {
|
|
3944
4513
|
const { index, inputData } = this.processRawInputData(lastFrameData[i]);
|
|
@@ -3949,13 +4518,13 @@
|
|
|
3949
4518
|
const { index, inputData } = this.processRawInputData(nextFrameData[i]);
|
|
3950
4519
|
nextFrameInputs.set(index, inputData);
|
|
3951
4520
|
}
|
|
3952
|
-
this[
|
|
4521
|
+
this[P_ACTION_PLAYER].inputSources.forEach((sourceWrapper) => {
|
|
3953
4522
|
sourceWrapper.active = false;
|
|
3954
4523
|
});
|
|
3955
4524
|
nextFrameInputs.forEach((inputData, index) => {
|
|
3956
|
-
this[
|
|
3957
|
-
const inputSource = this[
|
|
3958
|
-
const schema = this[
|
|
4525
|
+
this[P_ACTION_PLAYER].inputSources.get(index).active = true;
|
|
4526
|
+
const inputSource = this[P_ACTION_PLAYER].inputSources.get(index).source;
|
|
4527
|
+
const schema = this[P_ACTION_PLAYER].inputSchemas.get(index);
|
|
3959
4528
|
this.updateInputSource(inputSource, schema, lastFrameInputs.has(index) ? lastFrameInputs.get(index) : inputData, inputData, alpha);
|
|
3960
4529
|
});
|
|
3961
4530
|
}
|
|
@@ -3972,7 +4541,7 @@
|
|
|
3972
4541
|
const nextRadius = nextInputData.handTransforms[i * 8 + 7];
|
|
3973
4542
|
const jointSpace = inputSource.hand.get(schema.jointSequence[i]);
|
|
3974
4543
|
this.updateXRSpaceFromMergedFrames(jointSpace, lastTransformArray, nextTransformArray, alpha);
|
|
3975
|
-
jointSpace[
|
|
4544
|
+
jointSpace[P_JOINT_SPACE].radius =
|
|
3976
4545
|
(nextRadius - lastRadius) * alpha + lastRadius;
|
|
3977
4546
|
}
|
|
3978
4547
|
}
|
|
@@ -3980,16 +4549,16 @@
|
|
|
3980
4549
|
const gamepad = inputSource.gamepad;
|
|
3981
4550
|
nextInputData.buttons.forEach((states, index) => {
|
|
3982
4551
|
const gamepadButton = gamepad.buttons[index];
|
|
3983
|
-
gamepadButton[
|
|
3984
|
-
gamepadButton[
|
|
4552
|
+
gamepadButton[P_GAMEPAD].pressed = states[0] === 1 ? true : false;
|
|
4553
|
+
gamepadButton[P_GAMEPAD].touched = states[1] === 1 ? true : false;
|
|
3985
4554
|
const lastValue = lastInputData.buttons[index][2];
|
|
3986
4555
|
const nextValue = states[2];
|
|
3987
|
-
gamepadButton[
|
|
4556
|
+
gamepadButton[P_GAMEPAD].value =
|
|
3988
4557
|
(nextValue - lastValue) * alpha + lastValue;
|
|
3989
4558
|
});
|
|
3990
4559
|
nextInputData.axes.forEach((nextValue, index) => {
|
|
3991
4560
|
const lastValue = lastInputData.axes[index];
|
|
3992
|
-
gamepad[
|
|
4561
|
+
gamepad[P_GAMEPAD].axesMap[index.toString()].x =
|
|
3993
4562
|
(nextValue - lastValue) * alpha + lastValue;
|
|
3994
4563
|
});
|
|
3995
4564
|
}
|
|
@@ -3999,13 +4568,13 @@
|
|
|
3999
4568
|
const f1q = fromValues(lastTransform[3], lastTransform[4], lastTransform[5], lastTransform[6]);
|
|
4000
4569
|
const f2p = fromValues$2(nextTransform[0], nextTransform[1], nextTransform[2]);
|
|
4001
4570
|
const f2q = fromValues(nextTransform[3], nextTransform[4], nextTransform[5], nextTransform[6]);
|
|
4002
|
-
lerp(this[
|
|
4003
|
-
slerp(this[
|
|
4004
|
-
fromRotationTranslation(space[
|
|
4571
|
+
lerp(this[P_ACTION_PLAYER].vec3, f1p, f2p, alpha);
|
|
4572
|
+
slerp(this[P_ACTION_PLAYER].quat, f1q, f2q, alpha);
|
|
4573
|
+
fromRotationTranslation(space[P_SPACE].offsetMatrix, this[P_ACTION_PLAYER].quat, this[P_ACTION_PLAYER].vec3);
|
|
4005
4574
|
}
|
|
4006
4575
|
processRawInputData(inputDataRaw) {
|
|
4007
4576
|
const index = inputDataRaw[0];
|
|
4008
|
-
const schema = this[
|
|
4577
|
+
const schema = this[P_ACTION_PLAYER].inputSchemas.get(index);
|
|
4009
4578
|
const targetRayTransform = inputDataRaw.slice(1, 8);
|
|
4010
4579
|
const inputData = { targetRayTransform };
|
|
4011
4580
|
let dataCounter = 8;
|
|
@@ -4024,7 +4593,7 @@
|
|
|
4024
4593
|
}
|
|
4025
4594
|
}
|
|
4026
4595
|
|
|
4027
|
-
const VERSION = "1.0
|
|
4596
|
+
const VERSION = "1.1.0";
|
|
4028
4597
|
|
|
4029
4598
|
/**
|
|
4030
4599
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -4049,22 +4618,89 @@
|
|
|
4049
4618
|
* This source code is licensed under the MIT license found in the
|
|
4050
4619
|
* LICENSE file in the root directory of this source tree.
|
|
4051
4620
|
*/
|
|
4052
|
-
|
|
4621
|
+
class XRSystem extends EventTarget {
|
|
4622
|
+
constructor(device) {
|
|
4623
|
+
super();
|
|
4624
|
+
this[P_SYSTEM] = { device };
|
|
4625
|
+
// Initialize device change monitoring here if applicable
|
|
4626
|
+
}
|
|
4627
|
+
isSessionSupported(mode) {
|
|
4628
|
+
return new Promise((resolve, _reject) => {
|
|
4629
|
+
if (mode === 'inline') {
|
|
4630
|
+
resolve(true);
|
|
4631
|
+
}
|
|
4632
|
+
else {
|
|
4633
|
+
// Check for spatial tracking permission if necessary
|
|
4634
|
+
resolve(this[P_SYSTEM].device.supportedSessionModes.includes(mode));
|
|
4635
|
+
}
|
|
4636
|
+
});
|
|
4637
|
+
}
|
|
4638
|
+
requestSession(mode, options = {}) {
|
|
4639
|
+
return new Promise((resolve, reject) => {
|
|
4640
|
+
this.isSessionSupported(mode)
|
|
4641
|
+
.then((isSupported) => {
|
|
4642
|
+
if (!isSupported) {
|
|
4643
|
+
reject(new DOMException('The requested XRSession mode is not supported.', 'NotSupportedError'));
|
|
4644
|
+
return;
|
|
4645
|
+
}
|
|
4646
|
+
// Check for active sessions and other constraints here
|
|
4647
|
+
if (this[P_SYSTEM].activeSession) {
|
|
4648
|
+
reject(new DOMException('An active XRSession already exists.', 'InvalidStateError'));
|
|
4649
|
+
return;
|
|
4650
|
+
}
|
|
4651
|
+
// Handle required and optional features
|
|
4652
|
+
const { requiredFeatures = [], optionalFeatures = [] } = options;
|
|
4653
|
+
const { supportedFeatures } = this[P_SYSTEM].device;
|
|
4654
|
+
// Check if all required features are supported
|
|
4655
|
+
const allRequiredSupported = requiredFeatures.every((feature) => supportedFeatures.includes(feature));
|
|
4656
|
+
if (!allRequiredSupported) {
|
|
4657
|
+
reject(new Error('One or more required features are not supported by the device.'));
|
|
4658
|
+
return;
|
|
4659
|
+
}
|
|
4660
|
+
// Filter out unsupported optional features
|
|
4661
|
+
const supportedOptionalFeatures = optionalFeatures.filter((feature) => supportedFeatures.includes(feature));
|
|
4662
|
+
// Combine required and supported optional features into enabled features
|
|
4663
|
+
const enabledFeatures = Array.from(new Set([
|
|
4664
|
+
...requiredFeatures,
|
|
4665
|
+
...supportedOptionalFeatures,
|
|
4666
|
+
'viewer',
|
|
4667
|
+
'local',
|
|
4668
|
+
]));
|
|
4669
|
+
// Proceed with session creation
|
|
4670
|
+
const session = new XRSession(this[P_SYSTEM].device, mode, enabledFeatures);
|
|
4671
|
+
this[P_SYSTEM].activeSession = session;
|
|
4672
|
+
// Listen for session end to clear the active session
|
|
4673
|
+
session.addEventListener('end', () => {
|
|
4674
|
+
this[P_SYSTEM].activeSession = undefined;
|
|
4675
|
+
});
|
|
4676
|
+
resolve(session);
|
|
4677
|
+
})
|
|
4678
|
+
.catch(reject);
|
|
4679
|
+
});
|
|
4680
|
+
}
|
|
4681
|
+
}
|
|
4682
|
+
|
|
4683
|
+
/**
|
|
4684
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4685
|
+
*
|
|
4686
|
+
* This source code is licensed under the MIT license found in the
|
|
4687
|
+
* LICENSE file in the root directory of this source tree.
|
|
4688
|
+
*/
|
|
4053
4689
|
class XRViewport {
|
|
4054
4690
|
constructor(x, y, width, height) {
|
|
4055
|
-
this[
|
|
4691
|
+
this[P_VIEWPORT] = { x, y, width, height };
|
|
4056
4692
|
}
|
|
4057
4693
|
get x() {
|
|
4058
|
-
return this[
|
|
4694
|
+
return this[P_VIEWPORT].x;
|
|
4059
4695
|
}
|
|
4060
4696
|
get y() {
|
|
4061
|
-
return this[
|
|
4697
|
+
return this[P_VIEWPORT].y;
|
|
4062
4698
|
}
|
|
4063
4699
|
get width() {
|
|
4064
|
-
return this[
|
|
4700
|
+
return this[P_VIEWPORT].width;
|
|
4065
4701
|
}
|
|
4066
4702
|
get height() {
|
|
4067
|
-
return this[
|
|
4703
|
+
return this[P_VIEWPORT].height;
|
|
4068
4704
|
}
|
|
4069
4705
|
}
|
|
4070
4706
|
|
|
@@ -4074,22 +4710,6 @@
|
|
|
4074
4710
|
* This source code is licensed under the MIT license found in the
|
|
4075
4711
|
* LICENSE file in the root directory of this source tree.
|
|
4076
4712
|
*/
|
|
4077
|
-
var WebXRFeatures;
|
|
4078
|
-
(function (WebXRFeatures) {
|
|
4079
|
-
WebXRFeatures["Viewer"] = "viewer";
|
|
4080
|
-
WebXRFeatures["Local"] = "local";
|
|
4081
|
-
WebXRFeatures["LocalFloor"] = "local-floor";
|
|
4082
|
-
WebXRFeatures["BoundedFloor"] = "bounded-floor";
|
|
4083
|
-
WebXRFeatures["Unbounded"] = "unbounded";
|
|
4084
|
-
WebXRFeatures["DomOverlay"] = "dom-overlay";
|
|
4085
|
-
WebXRFeatures["Anchors"] = "anchors";
|
|
4086
|
-
WebXRFeatures["PlaneDetection"] = "plane-detection";
|
|
4087
|
-
WebXRFeatures["MeshDetection"] = "mesh-detection";
|
|
4088
|
-
WebXRFeatures["HitTest"] = "hit-test";
|
|
4089
|
-
WebXRFeatures["HandTracking"] = "hand-tracking";
|
|
4090
|
-
WebXRFeatures["DepthSensing"] = "depth-sensing";
|
|
4091
|
-
})(WebXRFeatures || (WebXRFeatures = {}));
|
|
4092
|
-
const PRIVATE$1 = Symbol('@immersive-web-emulation-runtime/xr-device');
|
|
4093
4713
|
const DEFAULTS = {
|
|
4094
4714
|
ipd: 0.063,
|
|
4095
4715
|
fovy: Math.PI / 2,
|
|
@@ -4136,7 +4756,7 @@
|
|
|
4136
4756
|
canvasContainer.style.alignItems = 'center';
|
|
4137
4757
|
canvasContainer.style.overflow = 'hidden';
|
|
4138
4758
|
canvasContainer.style.zIndex = '999';
|
|
4139
|
-
this[
|
|
4759
|
+
this[P_DEVICE] = {
|
|
4140
4760
|
name: deviceConfig.name,
|
|
4141
4761
|
supportedSessionModes: deviceConfig.supportedSessionModes,
|
|
4142
4762
|
supportedFeatures: deviceConfig.supportedFeatures,
|
|
@@ -4155,7 +4775,7 @@
|
|
|
4155
4775
|
hands,
|
|
4156
4776
|
primaryInputMode: 'controller',
|
|
4157
4777
|
pendingReferenceSpaceReset: false,
|
|
4158
|
-
visibilityState:
|
|
4778
|
+
visibilityState: 'visible',
|
|
4159
4779
|
pendingVisibilityState: null,
|
|
4160
4780
|
xrSystem: null,
|
|
4161
4781
|
matrix: create$3(),
|
|
@@ -4170,74 +4790,74 @@
|
|
|
4170
4790
|
case XREye.None:
|
|
4171
4791
|
return new XRViewport(0, 0, width, height);
|
|
4172
4792
|
case XREye.Left:
|
|
4173
|
-
return new XRViewport(0, 0, this[
|
|
4793
|
+
return new XRViewport(0, 0, this[P_DEVICE].stereoEnabled ? width / 2 : width, height);
|
|
4174
4794
|
case XREye.Right:
|
|
4175
|
-
return new XRViewport(width / 2, 0, this[
|
|
4795
|
+
return new XRViewport(width / 2, 0, this[P_DEVICE].stereoEnabled ? width / 2 : 0, height);
|
|
4176
4796
|
}
|
|
4177
4797
|
},
|
|
4178
4798
|
updateViews: () => {
|
|
4179
4799
|
// update viewerSpace
|
|
4180
|
-
const viewerSpace = this[
|
|
4181
|
-
fromRotationTranslation(viewerSpace[
|
|
4800
|
+
const viewerSpace = this[P_DEVICE].viewerSpace;
|
|
4801
|
+
fromRotationTranslation(viewerSpace[P_SPACE].offsetMatrix, this[P_DEVICE].quaternion.quat, this[P_DEVICE].position.vec3);
|
|
4182
4802
|
// update viewSpaces
|
|
4183
|
-
fromTranslation(this[
|
|
4184
|
-
fromTranslation(this[
|
|
4803
|
+
fromTranslation(this[P_DEVICE].viewSpaces[XREye.Left][P_SPACE].offsetMatrix, fromValues$2(-this[P_DEVICE].ipd / 2, 0, 0));
|
|
4804
|
+
fromTranslation(this[P_DEVICE].viewSpaces[XREye.Right][P_SPACE].offsetMatrix, fromValues$2(this[P_DEVICE].ipd / 2, 0, 0));
|
|
4185
4805
|
},
|
|
4186
4806
|
onBaseLayerSet: (baseLayer) => {
|
|
4187
4807
|
if (!baseLayer)
|
|
4188
4808
|
return;
|
|
4189
4809
|
// backup canvas data
|
|
4190
4810
|
const canvas = baseLayer.context.canvas;
|
|
4191
|
-
if (canvas.parentElement !== this[
|
|
4192
|
-
this[
|
|
4811
|
+
if (canvas.parentElement !== this[P_DEVICE].canvasContainer) {
|
|
4812
|
+
this[P_DEVICE].canvasData = {
|
|
4193
4813
|
canvas,
|
|
4194
4814
|
parent: canvas.parentElement,
|
|
4195
4815
|
width: canvas.width,
|
|
4196
4816
|
height: canvas.height,
|
|
4197
4817
|
};
|
|
4198
|
-
this[
|
|
4199
|
-
document.body.appendChild(this[
|
|
4818
|
+
this[P_DEVICE].canvasContainer.appendChild(canvas);
|
|
4819
|
+
document.body.appendChild(this[P_DEVICE].canvasContainer);
|
|
4200
4820
|
}
|
|
4201
4821
|
canvas.width = window.innerWidth;
|
|
4202
4822
|
canvas.height = window.innerHeight;
|
|
4203
4823
|
},
|
|
4204
4824
|
onSessionEnd: () => {
|
|
4205
|
-
if (this[
|
|
4206
|
-
const { canvas, parent, width, height } = this[
|
|
4825
|
+
if (this[P_DEVICE].canvasData) {
|
|
4826
|
+
const { canvas, parent, width, height } = this[P_DEVICE].canvasData;
|
|
4207
4827
|
canvas.width = width;
|
|
4208
4828
|
canvas.height = height;
|
|
4209
4829
|
if (parent) {
|
|
4210
4830
|
parent.appendChild(canvas);
|
|
4211
4831
|
}
|
|
4212
4832
|
else {
|
|
4213
|
-
this[
|
|
4833
|
+
this[P_DEVICE].canvasContainer.removeChild(canvas);
|
|
4214
4834
|
}
|
|
4215
|
-
document.body.removeChild(this[
|
|
4835
|
+
document.body.removeChild(this[P_DEVICE].canvasContainer);
|
|
4216
4836
|
window.dispatchEvent(new Event('resize'));
|
|
4217
4837
|
}
|
|
4218
4838
|
},
|
|
4219
4839
|
onFrameStart: (frame) => {
|
|
4220
4840
|
var _a;
|
|
4221
|
-
if ((_a = this[
|
|
4222
|
-
this[
|
|
4841
|
+
if ((_a = this[P_DEVICE].actionPlayer) === null || _a === void 0 ? void 0 : _a.playing) {
|
|
4842
|
+
this[P_DEVICE].actionPlayer.playFrame();
|
|
4223
4843
|
}
|
|
4224
4844
|
else {
|
|
4225
4845
|
const session = frame.session;
|
|
4226
|
-
this[
|
|
4227
|
-
if (this[
|
|
4228
|
-
this[
|
|
4229
|
-
this[
|
|
4230
|
-
this[
|
|
4846
|
+
this[P_DEVICE].updateViews();
|
|
4847
|
+
if (this[P_DEVICE].pendingVisibilityState) {
|
|
4848
|
+
this[P_DEVICE].visibilityState =
|
|
4849
|
+
this[P_DEVICE].pendingVisibilityState;
|
|
4850
|
+
this[P_DEVICE].pendingVisibilityState = null;
|
|
4231
4851
|
session.dispatchEvent(new XRSessionEvent('visibilitychange', { session }));
|
|
4232
4852
|
}
|
|
4233
|
-
if (this[
|
|
4853
|
+
if (this[P_DEVICE].visibilityState === 'visible') {
|
|
4234
4854
|
this.activeInputs.forEach((activeInput) => {
|
|
4235
4855
|
activeInput.onFrameStart(frame);
|
|
4236
4856
|
});
|
|
4237
4857
|
}
|
|
4238
|
-
if (this[
|
|
4239
|
-
session[
|
|
4240
|
-
switch (referenceSpace[
|
|
4858
|
+
if (this[P_DEVICE].pendingReferenceSpaceReset) {
|
|
4859
|
+
session[P_SESSION].referenceSpaces.forEach((referenceSpace) => {
|
|
4860
|
+
switch (referenceSpace[P_REF_SPACE].type) {
|
|
4241
4861
|
case XRReferenceSpaceType.Local:
|
|
4242
4862
|
case XRReferenceSpaceType.LocalFloor:
|
|
4243
4863
|
case XRReferenceSpaceType.BoundedFloor:
|
|
@@ -4246,13 +4866,13 @@
|
|
|
4246
4866
|
break;
|
|
4247
4867
|
}
|
|
4248
4868
|
});
|
|
4249
|
-
this[
|
|
4869
|
+
this[P_DEVICE].pendingReferenceSpaceReset = false;
|
|
4250
4870
|
}
|
|
4251
4871
|
}
|
|
4252
|
-
this[
|
|
4872
|
+
this[P_DEVICE].updateViews();
|
|
4253
4873
|
},
|
|
4254
4874
|
};
|
|
4255
|
-
this[
|
|
4875
|
+
this[P_DEVICE].updateViews();
|
|
4256
4876
|
}
|
|
4257
4877
|
installRuntime(globalObject = globalThis) {
|
|
4258
4878
|
Object.defineProperty(WebGL2RenderingContext.prototype, 'makeXRCompatible', {
|
|
@@ -4263,13 +4883,13 @@
|
|
|
4263
4883
|
},
|
|
4264
4884
|
configurable: true,
|
|
4265
4885
|
});
|
|
4266
|
-
this[
|
|
4886
|
+
this[P_DEVICE].xrSystem = new XRSystem(this);
|
|
4267
4887
|
Object.defineProperty(globalThis.navigator, 'xr', {
|
|
4268
|
-
value: this[
|
|
4888
|
+
value: this[P_DEVICE].xrSystem,
|
|
4269
4889
|
configurable: true,
|
|
4270
4890
|
});
|
|
4271
4891
|
Object.defineProperty(navigator, 'userAgent', {
|
|
4272
|
-
value: this[
|
|
4892
|
+
value: this[P_DEVICE].userAgent,
|
|
4273
4893
|
writable: false,
|
|
4274
4894
|
configurable: false,
|
|
4275
4895
|
enumerable: true,
|
|
@@ -4297,103 +4917,106 @@
|
|
|
4297
4917
|
globalObject['XRInputSourcesChangeEvent'] = XRInputSourcesChangeEvent;
|
|
4298
4918
|
globalObject['XRReferenceSpaceEvent'] = XRReferenceSpaceEvent;
|
|
4299
4919
|
}
|
|
4920
|
+
installSyntheticEnvironmentModule(sem) {
|
|
4921
|
+
this[P_DEVICE].syntheticEnvironmentModule = sem;
|
|
4922
|
+
}
|
|
4300
4923
|
get supportedSessionModes() {
|
|
4301
|
-
return this[
|
|
4924
|
+
return this[P_DEVICE].supportedSessionModes;
|
|
4302
4925
|
}
|
|
4303
4926
|
get supportedFeatures() {
|
|
4304
|
-
return this[
|
|
4927
|
+
return this[P_DEVICE].supportedFeatures;
|
|
4305
4928
|
}
|
|
4306
4929
|
get supportedFrameRates() {
|
|
4307
|
-
return this[
|
|
4930
|
+
return this[P_DEVICE].supportedFrameRates;
|
|
4308
4931
|
}
|
|
4309
4932
|
get isSystemKeyboardSupported() {
|
|
4310
|
-
return this[
|
|
4933
|
+
return this[P_DEVICE].isSystemKeyboardSupported;
|
|
4311
4934
|
}
|
|
4312
4935
|
get internalNominalFrameRate() {
|
|
4313
|
-
return this[
|
|
4936
|
+
return this[P_DEVICE].internalNominalFrameRate;
|
|
4314
4937
|
}
|
|
4315
4938
|
get stereoEnabled() {
|
|
4316
|
-
return this[
|
|
4939
|
+
return this[P_DEVICE].stereoEnabled;
|
|
4317
4940
|
}
|
|
4318
4941
|
set stereoEnabled(value) {
|
|
4319
|
-
this[
|
|
4942
|
+
this[P_DEVICE].stereoEnabled = value;
|
|
4320
4943
|
}
|
|
4321
4944
|
get ipd() {
|
|
4322
|
-
return this[
|
|
4945
|
+
return this[P_DEVICE].ipd;
|
|
4323
4946
|
}
|
|
4324
4947
|
set ipd(value) {
|
|
4325
|
-
this[
|
|
4948
|
+
this[P_DEVICE].ipd = value;
|
|
4326
4949
|
}
|
|
4327
4950
|
get fovy() {
|
|
4328
|
-
return this[
|
|
4951
|
+
return this[P_DEVICE].fovy;
|
|
4329
4952
|
}
|
|
4330
4953
|
set fovy(value) {
|
|
4331
|
-
this[
|
|
4954
|
+
this[P_DEVICE].fovy = value;
|
|
4332
4955
|
}
|
|
4333
4956
|
get position() {
|
|
4334
|
-
return this[
|
|
4957
|
+
return this[P_DEVICE].position;
|
|
4335
4958
|
}
|
|
4336
4959
|
get quaternion() {
|
|
4337
|
-
return this[
|
|
4960
|
+
return this[P_DEVICE].quaternion;
|
|
4338
4961
|
}
|
|
4339
4962
|
get viewerSpace() {
|
|
4340
4963
|
var _a;
|
|
4341
|
-
if ((_a = this[
|
|
4342
|
-
return this[
|
|
4964
|
+
if ((_a = this[P_DEVICE].actionPlayer) === null || _a === void 0 ? void 0 : _a.playing) {
|
|
4965
|
+
return this[P_DEVICE].actionPlayer.viewerSpace;
|
|
4343
4966
|
}
|
|
4344
4967
|
else {
|
|
4345
|
-
return this[
|
|
4968
|
+
return this[P_DEVICE].viewerSpace;
|
|
4346
4969
|
}
|
|
4347
4970
|
}
|
|
4348
4971
|
get viewSpaces() {
|
|
4349
4972
|
var _a;
|
|
4350
|
-
if ((_a = this[
|
|
4351
|
-
return this[
|
|
4973
|
+
if ((_a = this[P_DEVICE].actionPlayer) === null || _a === void 0 ? void 0 : _a.playing) {
|
|
4974
|
+
return this[P_DEVICE].actionPlayer.viewSpaces;
|
|
4352
4975
|
}
|
|
4353
4976
|
else {
|
|
4354
|
-
return this[
|
|
4977
|
+
return this[P_DEVICE].viewSpaces;
|
|
4355
4978
|
}
|
|
4356
4979
|
}
|
|
4357
4980
|
get controllers() {
|
|
4358
|
-
return this[
|
|
4981
|
+
return this[P_DEVICE].controllers;
|
|
4359
4982
|
}
|
|
4360
4983
|
get hands() {
|
|
4361
|
-
return this[
|
|
4984
|
+
return this[P_DEVICE].hands;
|
|
4362
4985
|
}
|
|
4363
4986
|
get primaryInputMode() {
|
|
4364
|
-
return this[
|
|
4987
|
+
return this[P_DEVICE].primaryInputMode;
|
|
4365
4988
|
}
|
|
4366
4989
|
set primaryInputMode(mode) {
|
|
4367
4990
|
if (mode !== 'controller' && mode !== 'hand') {
|
|
4368
4991
|
console.warn('primary input mode can only be "controller" or "hand"');
|
|
4369
4992
|
return;
|
|
4370
4993
|
}
|
|
4371
|
-
this[
|
|
4994
|
+
this[P_DEVICE].primaryInputMode = mode;
|
|
4372
4995
|
}
|
|
4373
4996
|
get activeInputs() {
|
|
4374
|
-
if (this[
|
|
4997
|
+
if (this[P_DEVICE].visibilityState !== 'visible') {
|
|
4375
4998
|
return [];
|
|
4376
4999
|
}
|
|
4377
|
-
const activeInputs = this[
|
|
4378
|
-
? Object.values(this[
|
|
4379
|
-
: Object.values(this[
|
|
5000
|
+
const activeInputs = this[P_DEVICE].primaryInputMode === 'controller'
|
|
5001
|
+
? Object.values(this[P_DEVICE].controllers)
|
|
5002
|
+
: Object.values(this[P_DEVICE].hands);
|
|
4380
5003
|
return activeInputs.filter((input) => input.connected);
|
|
4381
5004
|
}
|
|
4382
5005
|
get inputSources() {
|
|
4383
5006
|
var _a;
|
|
4384
|
-
if ((_a = this[
|
|
4385
|
-
return this[
|
|
5007
|
+
if ((_a = this[P_DEVICE].actionPlayer) === null || _a === void 0 ? void 0 : _a.playing) {
|
|
5008
|
+
return this[P_DEVICE].actionPlayer.inputSources;
|
|
4386
5009
|
}
|
|
4387
5010
|
else {
|
|
4388
5011
|
return this.activeInputs.map((input) => input.inputSource);
|
|
4389
5012
|
}
|
|
4390
5013
|
}
|
|
4391
5014
|
get canvasContainer() {
|
|
4392
|
-
return this[
|
|
5015
|
+
return this[P_DEVICE].canvasContainer;
|
|
4393
5016
|
}
|
|
4394
5017
|
get activeSession() {
|
|
4395
5018
|
var _a;
|
|
4396
|
-
return (_a = this[
|
|
5019
|
+
return (_a = this[P_DEVICE].xrSystem) === null || _a === void 0 ? void 0 : _a[P_SYSTEM].activeSession;
|
|
4397
5020
|
}
|
|
4398
5021
|
recenter() {
|
|
4399
5022
|
const deltaVec = new Vector3(-this.position.x, 0, -this.position.z);
|
|
@@ -4405,30 +5028,30 @@
|
|
|
4405
5028
|
this.position.add(deltaVec);
|
|
4406
5029
|
this.quaternion.multiply(deltaQuat);
|
|
4407
5030
|
[
|
|
4408
|
-
...Object.values(this[
|
|
4409
|
-
...Object.values(this[
|
|
5031
|
+
...Object.values(this[P_DEVICE].controllers),
|
|
5032
|
+
...Object.values(this[P_DEVICE].hands),
|
|
4410
5033
|
].forEach((activeInput) => {
|
|
4411
5034
|
activeInput.position.add(deltaVec);
|
|
4412
5035
|
activeInput.quaternion.multiply(deltaQuat);
|
|
4413
5036
|
activeInput.position.applyQuaternion(deltaQuat);
|
|
4414
5037
|
});
|
|
4415
|
-
this[
|
|
5038
|
+
this[P_DEVICE].pendingReferenceSpaceReset = true;
|
|
4416
5039
|
}
|
|
4417
5040
|
get visibilityState() {
|
|
4418
|
-
return this[
|
|
5041
|
+
return this[P_DEVICE].visibilityState;
|
|
4419
5042
|
}
|
|
4420
5043
|
// visibility state updates are queued until the XRSession produces frames
|
|
4421
5044
|
updateVisibilityState(state) {
|
|
4422
|
-
if (!Object.values(
|
|
5045
|
+
if (!Object.values(['visible', 'visible-blurred', 'hidden']).includes(state)) {
|
|
4423
5046
|
throw new DOMException('Invalid XRVisibilityState value', 'NotSupportedError');
|
|
4424
5047
|
}
|
|
4425
|
-
if (state !== this[
|
|
4426
|
-
this[
|
|
5048
|
+
if (state !== this[P_DEVICE].visibilityState) {
|
|
5049
|
+
this[P_DEVICE].pendingVisibilityState = state;
|
|
4427
5050
|
}
|
|
4428
5051
|
}
|
|
4429
5052
|
createActionPlayer(refSpace, recording) {
|
|
4430
|
-
this[
|
|
4431
|
-
return this[
|
|
5053
|
+
this[P_DEVICE].actionPlayer = new ActionPlayer(refSpace, recording, this[P_DEVICE].ipd);
|
|
5054
|
+
return this[P_DEVICE].actionPlayer;
|
|
4432
5055
|
}
|
|
4433
5056
|
}
|
|
4434
5057
|
|
|
@@ -4596,27 +5219,23 @@
|
|
|
4596
5219
|
const oculusQuest1 = {
|
|
4597
5220
|
name: 'Oculus Quest 1',
|
|
4598
5221
|
controllerConfig: oculusTouchV2,
|
|
4599
|
-
supportedSessionModes: [
|
|
4600
|
-
XRSessionMode.Inline,
|
|
4601
|
-
XRSessionMode.ImmersiveVR,
|
|
4602
|
-
XRSessionMode.ImmersiveAR,
|
|
4603
|
-
],
|
|
5222
|
+
supportedSessionModes: ['inline', 'immersive-vr', 'immersive-ar'],
|
|
4604
5223
|
supportedFeatures: [
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
5224
|
+
'viewer',
|
|
5225
|
+
'local',
|
|
5226
|
+
'local-floor',
|
|
5227
|
+
'bounded-floor',
|
|
5228
|
+
'unbounded',
|
|
5229
|
+
'anchors',
|
|
5230
|
+
'plane-detection',
|
|
5231
|
+
'hand-tracking',
|
|
4613
5232
|
],
|
|
4614
5233
|
supportedFrameRates: [72, 80, 90],
|
|
4615
5234
|
isSystemKeyboardSupported: true,
|
|
4616
5235
|
internalNominalFrameRate: 72,
|
|
4617
5236
|
environmentBlendModes: {
|
|
4618
|
-
[
|
|
4619
|
-
[
|
|
5237
|
+
['immersive-vr']: XREnvironmentBlendMode.Opaque,
|
|
5238
|
+
['immersive-ar']: XREnvironmentBlendMode.AlphaBlend,
|
|
4620
5239
|
},
|
|
4621
5240
|
interactionMode: XRInteractionMode.WorldSpace,
|
|
4622
5241
|
userAgent: 'Mozilla/5.0 (X11; Linux x86_64; Quest 1) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/33.0.0.x.x.x Chrome/126.0.6478.122 VR Safari/537.36',
|
|
@@ -4624,29 +5243,25 @@
|
|
|
4624
5243
|
const metaQuest2 = {
|
|
4625
5244
|
name: 'Meta Quest 2',
|
|
4626
5245
|
controllerConfig: oculusTouchV3,
|
|
4627
|
-
supportedSessionModes: [
|
|
4628
|
-
XRSessionMode.Inline,
|
|
4629
|
-
XRSessionMode.ImmersiveVR,
|
|
4630
|
-
XRSessionMode.ImmersiveAR,
|
|
4631
|
-
],
|
|
5246
|
+
supportedSessionModes: ['inline', 'immersive-vr', 'immersive-ar'],
|
|
4632
5247
|
supportedFeatures: [
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
5248
|
+
'viewer',
|
|
5249
|
+
'local',
|
|
5250
|
+
'local-floor',
|
|
5251
|
+
'bounded-floor',
|
|
5252
|
+
'unbounded',
|
|
5253
|
+
'anchors',
|
|
5254
|
+
'plane-detection',
|
|
5255
|
+
'mesh-detection',
|
|
5256
|
+
'hit-test',
|
|
5257
|
+
'hand-tracking',
|
|
4643
5258
|
],
|
|
4644
5259
|
supportedFrameRates: [72, 80, 90, 120],
|
|
4645
5260
|
isSystemKeyboardSupported: true,
|
|
4646
5261
|
internalNominalFrameRate: 72,
|
|
4647
5262
|
environmentBlendModes: {
|
|
4648
|
-
[
|
|
4649
|
-
[
|
|
5263
|
+
['immersive-vr']: XREnvironmentBlendMode.Opaque,
|
|
5264
|
+
['immersive-ar']: XREnvironmentBlendMode.AlphaBlend,
|
|
4650
5265
|
},
|
|
4651
5266
|
interactionMode: XRInteractionMode.WorldSpace,
|
|
4652
5267
|
userAgent: 'Mozilla/5.0 (X11; Linux x86_64; Quest 2) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/33.0.0.x.x.x Chrome/126.0.6478.122 VR Safari/537.36',
|
|
@@ -4654,29 +5269,25 @@
|
|
|
4654
5269
|
const metaQuestPro = {
|
|
4655
5270
|
name: 'Meta Quest Pro',
|
|
4656
5271
|
controllerConfig: metaQuestTouchPro,
|
|
4657
|
-
supportedSessionModes: [
|
|
4658
|
-
XRSessionMode.Inline,
|
|
4659
|
-
XRSessionMode.ImmersiveVR,
|
|
4660
|
-
XRSessionMode.ImmersiveAR,
|
|
4661
|
-
],
|
|
5272
|
+
supportedSessionModes: ['inline', 'immersive-vr', 'immersive-ar'],
|
|
4662
5273
|
supportedFeatures: [
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
5274
|
+
'viewer',
|
|
5275
|
+
'local',
|
|
5276
|
+
'local-floor',
|
|
5277
|
+
'bounded-floor',
|
|
5278
|
+
'unbounded',
|
|
5279
|
+
'anchors',
|
|
5280
|
+
'plane-detection',
|
|
5281
|
+
'mesh-detection',
|
|
5282
|
+
'hit-test',
|
|
5283
|
+
'hand-tracking',
|
|
4673
5284
|
],
|
|
4674
5285
|
supportedFrameRates: [72, 80, 90, 120],
|
|
4675
5286
|
isSystemKeyboardSupported: true,
|
|
4676
5287
|
internalNominalFrameRate: 90,
|
|
4677
5288
|
environmentBlendModes: {
|
|
4678
|
-
[
|
|
4679
|
-
[
|
|
5289
|
+
['immersive-vr']: XREnvironmentBlendMode.Opaque,
|
|
5290
|
+
['immersive-ar']: XREnvironmentBlendMode.AlphaBlend,
|
|
4680
5291
|
},
|
|
4681
5292
|
interactionMode: XRInteractionMode.WorldSpace,
|
|
4682
5293
|
userAgent: 'Mozilla/5.0 (X11; Linux x86_64; Quest Pro) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/33.0.0.x.x.x Chrome/126.0.6478.122 VR Safari/537.36',
|
|
@@ -4684,30 +5295,26 @@
|
|
|
4684
5295
|
const metaQuest3 = {
|
|
4685
5296
|
name: 'Meta Quest 3',
|
|
4686
5297
|
controllerConfig: metaQuestTouchPlus,
|
|
4687
|
-
supportedSessionModes: [
|
|
4688
|
-
XRSessionMode.Inline,
|
|
4689
|
-
XRSessionMode.ImmersiveVR,
|
|
4690
|
-
XRSessionMode.ImmersiveAR,
|
|
4691
|
-
],
|
|
5298
|
+
supportedSessionModes: ['inline', 'immersive-vr', 'immersive-ar'],
|
|
4692
5299
|
supportedFeatures: [
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
5300
|
+
'viewer',
|
|
5301
|
+
'local',
|
|
5302
|
+
'local-floor',
|
|
5303
|
+
'bounded-floor',
|
|
5304
|
+
'unbounded',
|
|
5305
|
+
'anchors',
|
|
5306
|
+
'plane-detection',
|
|
5307
|
+
'mesh-detection',
|
|
5308
|
+
'hit-test',
|
|
5309
|
+
'hand-tracking',
|
|
5310
|
+
'depth-sensing',
|
|
4704
5311
|
],
|
|
4705
5312
|
supportedFrameRates: [72, 80, 90, 120],
|
|
4706
5313
|
isSystemKeyboardSupported: true,
|
|
4707
5314
|
internalNominalFrameRate: 90,
|
|
4708
5315
|
environmentBlendModes: {
|
|
4709
|
-
[
|
|
4710
|
-
[
|
|
5316
|
+
['immersive-vr']: XREnvironmentBlendMode.Opaque,
|
|
5317
|
+
['immersive-ar']: XREnvironmentBlendMode.AlphaBlend,
|
|
4711
5318
|
},
|
|
4712
5319
|
interactionMode: XRInteractionMode.WorldSpace,
|
|
4713
5320
|
userAgent: 'Mozilla/5.0 (X11; Linux x86_64; Quest 3) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/33.0.0.x.x.x Chrome/126.0.6478.122 VR Safari/537.36',
|
|
@@ -4719,7 +5326,6 @@
|
|
|
4719
5326
|
* This source code is licensed under the MIT license found in the
|
|
4720
5327
|
* LICENSE file in the root directory of this source tree.
|
|
4721
5328
|
*/
|
|
4722
|
-
const PRIVATE = Symbol('@immersive-web-emulation-runtime/action-recorder');
|
|
4723
5329
|
const compress = (arr) => {
|
|
4724
5330
|
const out = [];
|
|
4725
5331
|
arr.forEach((num) => {
|
|
@@ -4729,7 +5335,7 @@
|
|
|
4729
5335
|
};
|
|
4730
5336
|
class ActionRecorder {
|
|
4731
5337
|
constructor(session, refSpace) {
|
|
4732
|
-
this[
|
|
5338
|
+
this[P_ACTION_RECORDER] = {
|
|
4733
5339
|
session,
|
|
4734
5340
|
refSpace,
|
|
4735
5341
|
inputMap: new Map(),
|
|
@@ -4742,7 +5348,7 @@
|
|
|
4742
5348
|
recordFrame(frame) {
|
|
4743
5349
|
var _a;
|
|
4744
5350
|
const timeStamp = performance.now();
|
|
4745
|
-
const viewerMatrix = (_a = frame.getViewerPose(this[
|
|
5351
|
+
const viewerMatrix = (_a = frame.getViewerPose(this[P_ACTION_RECORDER].refSpace)) === null || _a === void 0 ? void 0 : _a.transform.matrix;
|
|
4746
5352
|
if (!viewerMatrix)
|
|
4747
5353
|
return;
|
|
4748
5354
|
const position = getTranslation(create$2(), viewerMatrix);
|
|
@@ -4753,9 +5359,9 @@
|
|
|
4753
5359
|
quaternion,
|
|
4754
5360
|
inputFrames: [],
|
|
4755
5361
|
};
|
|
4756
|
-
this[
|
|
5362
|
+
this[P_ACTION_RECORDER].session.inputSources.forEach((inputSource) => {
|
|
4757
5363
|
var _a, _b;
|
|
4758
|
-
if (!this[
|
|
5364
|
+
if (!this[P_ACTION_RECORDER].inputMap.has(inputSource)) {
|
|
4759
5365
|
const schema = {
|
|
4760
5366
|
handedness: inputSource.handedness,
|
|
4761
5367
|
targetRayMode: inputSource.targetRayMode,
|
|
@@ -4772,13 +5378,13 @@
|
|
|
4772
5378
|
schema.numButtons = inputSource.gamepad.buttons.length;
|
|
4773
5379
|
schema.numAxes = inputSource.gamepad.axes.length;
|
|
4774
5380
|
}
|
|
4775
|
-
const index = this[
|
|
4776
|
-
this[
|
|
4777
|
-
this[
|
|
5381
|
+
const index = this[P_ACTION_RECORDER].inputMap.size;
|
|
5382
|
+
this[P_ACTION_RECORDER].inputMap.set(inputSource, index);
|
|
5383
|
+
this[P_ACTION_RECORDER].schemaMap.set(index, schema);
|
|
4778
5384
|
}
|
|
4779
|
-
const index = this[
|
|
4780
|
-
const schema = this[
|
|
4781
|
-
const targetRayMatrix = (_a = frame.getPose(inputSource.targetRaySpace, this[
|
|
5385
|
+
const index = this[P_ACTION_RECORDER].inputMap.get(inputSource);
|
|
5386
|
+
const schema = this[P_ACTION_RECORDER].schemaMap.get(index);
|
|
5387
|
+
const targetRayMatrix = (_a = frame.getPose(inputSource.targetRaySpace, this[P_ACTION_RECORDER].refSpace)) === null || _a === void 0 ? void 0 : _a.transform.matrix;
|
|
4782
5388
|
if (targetRayMatrix) {
|
|
4783
5389
|
const targetRayPosition = getTranslation(create$2(), targetRayMatrix);
|
|
4784
5390
|
const targetRayQuaternion = getRotation(create(), targetRayMatrix);
|
|
@@ -4790,7 +5396,7 @@
|
|
|
4790
5396
|
},
|
|
4791
5397
|
};
|
|
4792
5398
|
if (schema.hasGrip) {
|
|
4793
|
-
const gripMatrix = (_b = frame.getPose(inputSource.gripSpace, this[
|
|
5399
|
+
const gripMatrix = (_b = frame.getPose(inputSource.gripSpace, this[P_ACTION_RECORDER].refSpace)) === null || _b === void 0 ? void 0 : _b.transform.matrix;
|
|
4794
5400
|
if (gripMatrix) {
|
|
4795
5401
|
const position = getTranslation(create$2(), gripMatrix);
|
|
4796
5402
|
const quaternion = getRotation(create(), gripMatrix);
|
|
@@ -4804,14 +5410,14 @@
|
|
|
4804
5410
|
const jointSpaces = Array.from(inputSource.hand.values());
|
|
4805
5411
|
let allValid = true;
|
|
4806
5412
|
// @ts-ignore
|
|
4807
|
-
allValid && (allValid = frame.fillPoses(jointSpaces, inputSource.targetRaySpace, this[
|
|
5413
|
+
allValid && (allValid = frame.fillPoses(jointSpaces, inputSource.targetRaySpace, this[P_ACTION_RECORDER].jointTransforms));
|
|
4808
5414
|
// @ts-ignore
|
|
4809
|
-
allValid && (allValid = frame.fillJointRadii(jointSpaces, this[
|
|
5415
|
+
allValid && (allValid = frame.fillJointRadii(jointSpaces, this[P_ACTION_RECORDER].jointRadii));
|
|
4810
5416
|
if (allValid) {
|
|
4811
5417
|
const hand = {};
|
|
4812
5418
|
for (let offset = 0; offset < 25; offset++) {
|
|
4813
|
-
const jointMatrix = this[
|
|
4814
|
-
const radius = this[
|
|
5419
|
+
const jointMatrix = this[P_ACTION_RECORDER].jointTransforms.slice(offset * 16, (offset + 1) * 16);
|
|
5420
|
+
const radius = this[P_ACTION_RECORDER].jointRadii[offset];
|
|
4815
5421
|
const position = getTranslation(create$2(), jointMatrix);
|
|
4816
5422
|
const quaternion = getRotation(create(), jointMatrix);
|
|
4817
5423
|
const jointName = jointSpaces[offset].jointName;
|
|
@@ -4832,7 +5438,7 @@
|
|
|
4832
5438
|
actionFrame.inputFrames.push(inputFrame);
|
|
4833
5439
|
}
|
|
4834
5440
|
});
|
|
4835
|
-
this[
|
|
5441
|
+
this[P_ACTION_RECORDER].compressedFrames.push(this.compressActionFrame(actionFrame));
|
|
4836
5442
|
}
|
|
4837
5443
|
compressActionFrame(af) {
|
|
4838
5444
|
const out = [
|
|
@@ -4842,7 +5448,7 @@
|
|
|
4842
5448
|
];
|
|
4843
5449
|
af.inputFrames.forEach((inputFrame) => {
|
|
4844
5450
|
const index = inputFrame.index;
|
|
4845
|
-
const schema = this[
|
|
5451
|
+
const schema = this[P_ACTION_RECORDER].schemaMap.get(index);
|
|
4846
5452
|
const inputOut = [
|
|
4847
5453
|
index,
|
|
4848
5454
|
...compress(inputFrame.targetRayTransform.position),
|
|
@@ -4873,14 +5479,45 @@
|
|
|
4873
5479
|
}
|
|
4874
5480
|
log() {
|
|
4875
5481
|
const out = {
|
|
4876
|
-
schema: Array.from(this[
|
|
4877
|
-
frames: this[
|
|
5482
|
+
schema: Array.from(this[P_ACTION_RECORDER].schemaMap.entries()),
|
|
5483
|
+
frames: this[P_ACTION_RECORDER].compressedFrames,
|
|
4878
5484
|
};
|
|
4879
5485
|
console.log(JSON.stringify(out));
|
|
4880
5486
|
}
|
|
4881
5487
|
}
|
|
4882
5488
|
|
|
4883
5489
|
exports.ActionRecorder = ActionRecorder;
|
|
5490
|
+
exports.NativeMesh = NativeMesh;
|
|
5491
|
+
exports.NativePlane = NativePlane;
|
|
5492
|
+
exports.P_ACTION_PLAYER = P_ACTION_PLAYER;
|
|
5493
|
+
exports.P_ACTION_RECORDER = P_ACTION_RECORDER;
|
|
5494
|
+
exports.P_ANCHOR = P_ANCHOR;
|
|
5495
|
+
exports.P_CONTROLLER = P_CONTROLLER;
|
|
5496
|
+
exports.P_DEVICE = P_DEVICE;
|
|
5497
|
+
exports.P_FRAME = P_FRAME;
|
|
5498
|
+
exports.P_GAMEPAD = P_GAMEPAD;
|
|
5499
|
+
exports.P_HAND_INPUT = P_HAND_INPUT;
|
|
5500
|
+
exports.P_HIT_TEST = P_HIT_TEST;
|
|
5501
|
+
exports.P_INPUT_SOURCE = P_INPUT_SOURCE;
|
|
5502
|
+
exports.P_JOINT_POSE = P_JOINT_POSE;
|
|
5503
|
+
exports.P_JOINT_SPACE = P_JOINT_SPACE;
|
|
5504
|
+
exports.P_MESH = P_MESH;
|
|
5505
|
+
exports.P_PLANE = P_PLANE;
|
|
5506
|
+
exports.P_POSE = P_POSE;
|
|
5507
|
+
exports.P_RAY = P_RAY;
|
|
5508
|
+
exports.P_REF_SPACE = P_REF_SPACE;
|
|
5509
|
+
exports.P_RENDER_STATE = P_RENDER_STATE;
|
|
5510
|
+
exports.P_RIGID_TRANSFORM = P_RIGID_TRANSFORM;
|
|
5511
|
+
exports.P_SESSION = P_SESSION;
|
|
5512
|
+
exports.P_SPACE = P_SPACE;
|
|
5513
|
+
exports.P_SYSTEM = P_SYSTEM;
|
|
5514
|
+
exports.P_TRACKED_INPUT = P_TRACKED_INPUT;
|
|
5515
|
+
exports.P_VIEW = P_VIEW;
|
|
5516
|
+
exports.P_VIEWER_POSE = P_VIEWER_POSE;
|
|
5517
|
+
exports.P_VIEWPORT = P_VIEWPORT;
|
|
5518
|
+
exports.P_WEBGL_LAYER = P_WEBGL_LAYER;
|
|
5519
|
+
exports.XRAnchor = XRAnchor;
|
|
5520
|
+
exports.XRAnchorSet = XRAnchorSet;
|
|
4884
5521
|
exports.XRDevice = XRDevice;
|
|
4885
5522
|
exports.XRFrame = XRFrame;
|
|
4886
5523
|
exports.XRHand = XRHand;
|
|
@@ -4891,7 +5528,12 @@
|
|
|
4891
5528
|
exports.XRJointPose = XRJointPose;
|
|
4892
5529
|
exports.XRJointSpace = XRJointSpace;
|
|
4893
5530
|
exports.XRLayer = XRLayer;
|
|
5531
|
+
exports.XRMesh = XRMesh;
|
|
5532
|
+
exports.XRMeshSet = XRMeshSet;
|
|
5533
|
+
exports.XRPlane = XRPlane;
|
|
5534
|
+
exports.XRPlaneSet = XRPlaneSet;
|
|
4894
5535
|
exports.XRPose = XRPose;
|
|
5536
|
+
exports.XRRay = XRRay;
|
|
4895
5537
|
exports.XRReferenceSpace = XRReferenceSpace;
|
|
4896
5538
|
exports.XRReferenceSpaceEvent = XRReferenceSpaceEvent;
|
|
4897
5539
|
exports.XRRenderState = XRRenderState;
|