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.
Files changed (130) hide show
  1. package/build/iwer.js +1396 -754
  2. package/build/iwer.min.js +1 -1
  3. package/build/iwer.module.js +1361 -755
  4. package/build/iwer.module.min.js +1 -1
  5. package/lib/action/ActionPlayer.d.ts +3 -3
  6. package/lib/action/ActionPlayer.d.ts.map +1 -1
  7. package/lib/action/ActionPlayer.js +43 -41
  8. package/lib/action/ActionPlayer.js.map +1 -1
  9. package/lib/action/ActionRecorder.d.ts +2 -2
  10. package/lib/action/ActionRecorder.d.ts.map +1 -1
  11. package/lib/action/ActionRecorder.js +20 -20
  12. package/lib/action/ActionRecorder.js.map +1 -1
  13. package/lib/anchors/XRAnchor.d.ts +27 -0
  14. package/lib/anchors/XRAnchor.d.ts.map +1 -0
  15. package/lib/anchors/XRAnchor.js +73 -0
  16. package/lib/anchors/XRAnchor.js.map +1 -0
  17. package/lib/device/XRController.d.ts +2 -2
  18. package/lib/device/XRController.d.ts.map +1 -1
  19. package/lib/device/XRController.js +12 -16
  20. package/lib/device/XRController.js.map +1 -1
  21. package/lib/device/XRDevice.d.ts +16 -18
  22. package/lib/device/XRDevice.d.ts.map +1 -1
  23. package/lib/device/XRDevice.js +81 -93
  24. package/lib/device/XRDevice.js.map +1 -1
  25. package/lib/device/XRHandInput.d.ts +3 -3
  26. package/lib/device/XRHandInput.d.ts.map +1 -1
  27. package/lib/device/XRHandInput.js +18 -20
  28. package/lib/device/XRHandInput.js.map +1 -1
  29. package/lib/device/XRTrackedInput.d.ts +2 -2
  30. package/lib/device/XRTrackedInput.d.ts.map +1 -1
  31. package/lib/device/XRTrackedInput.js +30 -31
  32. package/lib/device/XRTrackedInput.js.map +1 -1
  33. package/lib/device/configs/headset/meta.d.ts.map +1 -1
  34. package/lib/device/configs/headset/meta.js +52 -69
  35. package/lib/device/configs/headset/meta.js.map +1 -1
  36. package/lib/frameloop/XRFrame.d.ts +18 -4
  37. package/lib/frameloop/XRFrame.d.ts.map +1 -1
  38. package/lib/frameloop/XRFrame.js +77 -24
  39. package/lib/frameloop/XRFrame.js.map +1 -1
  40. package/lib/gamepad/Gamepad.d.ts +3 -3
  41. package/lib/gamepad/Gamepad.d.ts.map +1 -1
  42. package/lib/gamepad/Gamepad.js +27 -27
  43. package/lib/gamepad/Gamepad.js.map +1 -1
  44. package/lib/hittest/XRHitTest.d.ts +35 -0
  45. package/lib/hittest/XRHitTest.d.ts.map +1 -0
  46. package/lib/hittest/XRHitTest.js +34 -0
  47. package/lib/hittest/XRHitTest.js.map +1 -0
  48. package/lib/hittest/XRRay.d.ts +22 -0
  49. package/lib/hittest/XRRay.d.ts.map +1 -0
  50. package/lib/hittest/XRRay.js +93 -0
  51. package/lib/hittest/XRRay.js.map +1 -0
  52. package/lib/index.d.ts +6 -0
  53. package/lib/index.d.ts.map +1 -1
  54. package/lib/index.js +11 -0
  55. package/lib/index.js.map +1 -1
  56. package/lib/initialization/XRSystem.d.ts +3 -3
  57. package/lib/initialization/XRSystem.d.ts.map +1 -1
  58. package/lib/initialization/XRSystem.js +12 -13
  59. package/lib/initialization/XRSystem.js.map +1 -1
  60. package/lib/input/XRInputSource.d.ts +2 -2
  61. package/lib/input/XRInputSource.d.ts.map +1 -1
  62. package/lib/input/XRInputSource.js +9 -9
  63. package/lib/input/XRInputSource.js.map +1 -1
  64. package/lib/labels/labels.d.ts +29 -0
  65. package/lib/labels/labels.d.ts.map +1 -0
  66. package/lib/labels/labels.js +31 -0
  67. package/lib/labels/labels.js.map +1 -0
  68. package/lib/layers/XRWebGLLayer.d.ts +2 -2
  69. package/lib/layers/XRWebGLLayer.d.ts.map +1 -1
  70. package/lib/layers/XRWebGLLayer.js +11 -13
  71. package/lib/layers/XRWebGLLayer.js.map +1 -1
  72. package/lib/meshes/XRMesh.d.ts +38 -0
  73. package/lib/meshes/XRMesh.d.ts.map +1 -0
  74. package/lib/meshes/XRMesh.js +46 -0
  75. package/lib/meshes/XRMesh.js.map +1 -0
  76. package/lib/planes/XRPlane.d.ts +46 -0
  77. package/lib/planes/XRPlane.d.ts.map +1 -0
  78. package/lib/planes/XRPlane.js +73 -0
  79. package/lib/planes/XRPlane.js.map +1 -0
  80. package/lib/pose/XRJointPose.d.ts +2 -2
  81. package/lib/pose/XRJointPose.d.ts.map +1 -1
  82. package/lib/pose/XRJointPose.js +3 -3
  83. package/lib/pose/XRJointPose.js.map +1 -1
  84. package/lib/pose/XRPose.d.ts +2 -2
  85. package/lib/pose/XRPose.d.ts.map +1 -1
  86. package/lib/pose/XRPose.js +6 -6
  87. package/lib/pose/XRPose.js.map +1 -1
  88. package/lib/pose/XRViewerPose.d.ts +2 -2
  89. package/lib/pose/XRViewerPose.d.ts.map +1 -1
  90. package/lib/pose/XRViewerPose.js +3 -3
  91. package/lib/pose/XRViewerPose.js.map +1 -1
  92. package/lib/primitives/XRRigidTransform.d.ts +2 -2
  93. package/lib/primitives/XRRigidTransform.d.ts.map +1 -1
  94. package/lib/primitives/XRRigidTransform.js +11 -11
  95. package/lib/primitives/XRRigidTransform.js.map +1 -1
  96. package/lib/private.d.ts +34 -0
  97. package/lib/private.d.ts.map +1 -0
  98. package/lib/private.js +34 -0
  99. package/lib/private.js.map +1 -0
  100. package/lib/session/XRRenderState.d.ts +2 -2
  101. package/lib/session/XRRenderState.d.ts.map +1 -1
  102. package/lib/session/XRRenderState.js +6 -6
  103. package/lib/session/XRRenderState.js.map +1 -1
  104. package/lib/session/XRSession.d.ts +30 -16
  105. package/lib/session/XRSession.d.ts.map +1 -1
  106. package/lib/session/XRSession.js +268 -127
  107. package/lib/session/XRSession.js.map +1 -1
  108. package/lib/spaces/XRJointSpace.d.ts +2 -2
  109. package/lib/spaces/XRJointSpace.d.ts.map +1 -1
  110. package/lib/spaces/XRJointSpace.js +3 -3
  111. package/lib/spaces/XRJointSpace.js.map +1 -1
  112. package/lib/spaces/XRReferenceSpace.d.ts +2 -2
  113. package/lib/spaces/XRReferenceSpace.d.ts.map +1 -1
  114. package/lib/spaces/XRReferenceSpace.js +8 -8
  115. package/lib/spaces/XRReferenceSpace.js.map +1 -1
  116. package/lib/spaces/XRSpace.d.ts +2 -2
  117. package/lib/spaces/XRSpace.d.ts.map +1 -1
  118. package/lib/spaces/XRSpace.js +8 -8
  119. package/lib/spaces/XRSpace.js.map +1 -1
  120. package/lib/version.d.ts +1 -1
  121. package/lib/version.js +1 -1
  122. package/lib/views/XRView.d.ts +2 -2
  123. package/lib/views/XRView.d.ts.map +1 -1
  124. package/lib/views/XRView.js +7 -7
  125. package/lib/views/XRView.js.map +1 -1
  126. package/lib/views/XRViewport.d.ts +2 -2
  127. package/lib/views/XRViewport.d.ts.map +1 -1
  128. package/lib/views/XRViewport.js +6 -6
  129. package/lib/views/XRViewport.js.map +1 -1
  130. 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 PRIVATE$l = Symbol('@immersive-web-emulation-runtime/xr-space');
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[PRIVATE$l] = {
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[PRIVATE$l].offsetMatrix;
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[PRIVATE$l].offsetMatrix;
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[PRIVATE$l].offsetMatrix;
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[PRIVATE$l].parentSpace
1327
- ? XRSpaceUtils.calculateGlobalOffsetMatrix(space[PRIVATE$l].parentSpace)
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[PRIVATE$l].offsetMatrix);
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[PRIVATE$k] = {
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[PRIVATE$k].type === 'manual') {
1494
- return this[PRIVATE$k].pressed;
1621
+ if (this[P_GAMEPAD].type === 'manual') {
1622
+ return this[P_GAMEPAD].pressed;
1495
1623
  }
1496
1624
  else {
1497
- return this[PRIVATE$k].value > 0;
1625
+ return this[P_GAMEPAD].value > 0;
1498
1626
  }
1499
1627
  }
1500
1628
  get touched() {
1501
- if (this[PRIVATE$k].type === 'manual') {
1502
- return this[PRIVATE$k].touched;
1629
+ if (this[P_GAMEPAD].type === 'manual') {
1630
+ return this[P_GAMEPAD].touched;
1503
1631
  }
1504
1632
  else {
1505
- return this[PRIVATE$k].touched || this.pressed;
1633
+ return this[P_GAMEPAD].touched || this.pressed;
1506
1634
  }
1507
1635
  }
1508
1636
  get value() {
1509
- return this[PRIVATE$k].value;
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[PRIVATE$k] = {
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[PRIVATE$k].buttonsSequence.push(null);
1664
+ this[P_GAMEPAD].buttonsSequence.push(null);
1537
1665
  }
1538
1666
  else {
1539
- this[PRIVATE$k].buttonsSequence.push(buttonConfig.id);
1540
- this[PRIVATE$k].buttonsMap[buttonConfig.id] = new GamepadButton(buttonConfig.type, (_a = buttonConfig.eventTrigger) !== null && _a !== void 0 ? _a : null);
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[PRIVATE$k].axesSequence.push(null);
1673
+ this[P_GAMEPAD].axesSequence.push(null);
1546
1674
  }
1547
1675
  else {
1548
- this[PRIVATE$k].axesSequence.push(axisConfig.id + axisConfig.type);
1549
- if (!this[PRIVATE$k].axesMap[axisConfig.id]) {
1550
- this[PRIVATE$k].axesMap[axisConfig.id] = { x: 0, y: 0 };
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[PRIVATE$k].id;
1684
+ return this[P_GAMEPAD].id;
1557
1685
  }
1558
1686
  get index() {
1559
- return this[PRIVATE$k].index;
1687
+ return this[P_GAMEPAD].index;
1560
1688
  }
1561
1689
  get connected() {
1562
- return this[PRIVATE$k].connected;
1690
+ return this[P_GAMEPAD].connected;
1563
1691
  }
1564
1692
  get timestamp() {
1565
- return this[PRIVATE$k].timestamp;
1693
+ return this[P_GAMEPAD].timestamp;
1566
1694
  }
1567
1695
  get mapping() {
1568
- return this[PRIVATE$k].mapping;
1696
+ return this[P_GAMEPAD].mapping;
1569
1697
  }
1570
1698
  get axes() {
1571
1699
  const axes = [];
1572
- this[PRIVATE$k].axesSequence.forEach((id) => {
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[PRIVATE$k].axesMap[axisId].y
1583
- : this[PRIVATE$k].axesMap[axisId].x);
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[PRIVATE$k].buttonsSequence.map((id) => id === null ? new EmptyGamepadButton() : this[PRIVATE$k].buttonsMap[id]);
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[PRIVATE$k].hapticActuators;
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[PRIVATE$j] = {
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[PRIVATE$j].handedness;
1761
+ return this[P_INPUT_SOURCE].handedness;
1635
1762
  }
1636
1763
  get targetRayMode() {
1637
- return this[PRIVATE$j].targetRayMode;
1764
+ return this[P_INPUT_SOURCE].targetRayMode;
1638
1765
  }
1639
1766
  get targetRaySpace() {
1640
- return this[PRIVATE$j].targetRaySpace;
1767
+ return this[P_INPUT_SOURCE].targetRaySpace;
1641
1768
  }
1642
1769
  get gripSpace() {
1643
- return this[PRIVATE$j].gripSpace;
1770
+ return this[P_INPUT_SOURCE].gripSpace;
1644
1771
  }
1645
1772
  get profiles() {
1646
- return this[PRIVATE$j].profiles;
1773
+ return this[P_INPUT_SOURCE].profiles;
1647
1774
  }
1648
1775
  get gamepad() {
1649
- return this[PRIVATE$j].gamepad;
1776
+ return this[P_INPUT_SOURCE].gamepad;
1650
1777
  }
1651
1778
  get hand() {
1652
- return this[PRIVATE$j].hand;
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[PRIVATE$i] = {
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[PRIVATE$i].position;
1835
+ return this[P_TRACKED_INPUT].position;
1710
1836
  }
1711
1837
  get quaternion() {
1712
- return this[PRIVATE$i].quaternion;
1838
+ return this[P_TRACKED_INPUT].quaternion;
1713
1839
  }
1714
1840
  get inputSource() {
1715
- return this[PRIVATE$i].inputSource;
1841
+ return this[P_TRACKED_INPUT].inputSource;
1716
1842
  }
1717
1843
  get connected() {
1718
- return this[PRIVATE$i].connected;
1844
+ return this[P_TRACKED_INPUT].connected;
1719
1845
  }
1720
1846
  set connected(value) {
1721
- this[PRIVATE$i].connected = value;
1722
- this[PRIVATE$i].inputSource.gamepad[PRIVATE$k].connected = value;
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[PRIVATE$i].inputSource.targetRaySpace;
1726
- fromRotationTranslation(targetRaySpace[PRIVATE$l].offsetMatrix, this[PRIVATE$i].quaternion.quat, this[PRIVATE$i].position.vec3);
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[PRIVATE$i].inputSource.gamepad.buttons.forEach((button) => {
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[PRIVATE$k].lastFrameValue = button[PRIVATE$k].value;
1732
- if (button[PRIVATE$k].pendingValue != null) {
1733
- button[PRIVATE$k].value = button[PRIVATE$k].pendingValue;
1734
- button[PRIVATE$k].pendingValue = null;
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[PRIVATE$k].eventTrigger != null) {
1738
- if (button[PRIVATE$k].lastFrameValue === 0 &&
1739
- button[PRIVATE$k].value > 0) {
1740
- session.dispatchEvent(new XRInputSourceEvent(button[PRIVATE$k].eventTrigger, {
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[PRIVATE$i].inputSource,
1868
+ inputSource: this[P_TRACKED_INPUT].inputSource,
1743
1869
  }));
1744
- session.dispatchEvent(new XRInputSourceEvent(button[PRIVATE$k].eventTrigger + 'start', {
1870
+ session.dispatchEvent(new XRInputSourceEvent(button[P_GAMEPAD].eventTrigger + 'start', {
1745
1871
  frame,
1746
- inputSource: this[PRIVATE$i].inputSource,
1872
+ inputSource: this[P_TRACKED_INPUT].inputSource,
1747
1873
  }));
1748
1874
  }
1749
- else if (button[PRIVATE$k].lastFrameValue > 0 &&
1750
- button[PRIVATE$k].value === 0) {
1751
- session.dispatchEvent(new XRInputSourceEvent(button[PRIVATE$k].eventTrigger + 'end', {
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[PRIVATE$i].inputSource,
1879
+ inputSource: this[P_TRACKED_INPUT].inputSource,
1754
1880
  }));
1755
1881
  }
1756
1882
  }
1757
1883
  }
1758
1884
  });
1759
- this[PRIVATE$i].inputSourceChanged =
1760
- this.connected !== this[PRIVATE$i].lastFrameConnected;
1761
- this[PRIVATE$i].lastFrameConnected = this.connected;
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[PRIVATE$h] = {
1912
+ this[P_CONTROLLER] = {
1788
1913
  gamepadConfig: controllerConfig.layout[handedness].gamepad,
1789
1914
  };
1790
1915
  }
1791
1916
  get gamepadConfig() {
1792
- return this[PRIVATE$h].gamepadConfig;
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[PRIVATE$i].inputSource.gamepad[PRIVATE$k]
1800
- .buttonsMap[id];
1924
+ const gamepadButton = this[P_TRACKED_INPUT].inputSource.gamepad[P_GAMEPAD].buttonsMap[id];
1801
1925
  if (gamepadButton) {
1802
- if (gamepadButton[PRIVATE$k].type === 'binary' &&
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[PRIVATE$k].pendingValue = value;
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[PRIVATE$i].inputSource.gamepad[PRIVATE$k]
1816
- .buttonsMap[id];
1939
+ const gamepadButton = this[P_TRACKED_INPUT].inputSource.gamepad[P_GAMEPAD].buttonsMap[id];
1817
1940
  if (gamepadButton) {
1818
- gamepadButton[PRIVATE$k].touched = touched;
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[PRIVATE$i].inputSource.gamepad[PRIVATE$k]
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[PRIVATE$i].inputSource.gamepad[PRIVATE$k]
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
- const PRIVATE$g = Symbol('@immersive-web-emulation-runtime/xr-view');
1867
- var XREye;
1868
- (function (XREye) {
1869
- XREye["None"] = "none";
1870
- XREye["Left"] = "left";
1871
- XREye["Right"] = "right";
1872
- })(XREye || (XREye = {}));
1873
- class XRView {
1874
- constructor(eye, projectionMatrix, transform, session) {
1875
- this[PRIVATE$g] = {
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 eye() {
1885
- return this[PRIVATE$g].eye;
1999
+ get meshSpace() {
2000
+ return this[P_MESH].meshSpace;
1886
2001
  }
1887
- get projectionMatrix() {
1888
- return this[PRIVATE$g].projectionMatrix;
2002
+ get vertices() {
2003
+ return this[P_MESH].vertices;
1889
2004
  }
1890
- get transform() {
1891
- return this[PRIVATE$g].transform;
2005
+ get indices() {
2006
+ return this[P_MESH].indices;
1892
2007
  }
1893
- get recommendedViewportScale() {
1894
- return this[PRIVATE$g].recommendedViewportScale;
2008
+ get lastChangedTime() {
2009
+ return this[P_MESH].lastChangedTime;
1895
2010
  }
1896
- requestViewportScale(scale) {
1897
- if (scale === null || scale <= 0 || scale > 1) {
1898
- console.warn('Invalid scale value. Scale must be > 0 and <= 1.');
1899
- return;
1900
- }
1901
- this[PRIVATE$g].requestedViewportScale = scale;
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
- const PRIVATE$f = Symbol('@immersive-web-emulation-runtime/xr-joint-space');
1912
- class XRJointSpace extends XRSpace {
1913
- constructor(jointName, parentSpace, offsetMatrix) {
1914
- super(parentSpace, offsetMatrix);
1915
- this[PRIVATE$f] = { jointName, radius: 0 };
1916
- }
1917
- get jointName() {
1918
- return this[PRIVATE$f].jointName;
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
- const PRIVATE$e = Symbol('@immersive-web-emulation-runtime/xr-pose');
1929
- class XRPose {
1930
- constructor(transform, emulatedPosition = false, linearVelocity = undefined, angularVelocity = undefined) {
1931
- this[PRIVATE$e] = {
1932
- transform,
1933
- emulatedPosition,
1934
- linearVelocity,
1935
- angularVelocity,
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 transform() {
1939
- return this[PRIVATE$e].transform;
2102
+ get planeSpace() {
2103
+ return this[P_PLANE].planeSpace;
1940
2104
  }
1941
- get emulatedPosition() {
1942
- return this[PRIVATE$e].emulatedPosition;
2105
+ get polygon() {
2106
+ return this[P_PLANE].polygon;
1943
2107
  }
1944
- get linearVelocity() {
1945
- return this[PRIVATE$e].linearVelocity;
2108
+ get orientation() {
2109
+ return this[P_PLANE].orientation;
1946
2110
  }
1947
- get angularVelocity() {
1948
- return this[PRIVATE$e].angularVelocity;
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
- const PRIVATE$d = Symbol('@immersive-web-emulation-runtime/xr-joint-pose');
1959
- class XRJointPose extends XRPose {
1960
- constructor(transform, radius, emulatedPosition = false, linearVelocity = undefined, angularVelocity = undefined) {
1961
- super(transform, emulatedPosition, linearVelocity, angularVelocity);
1962
- this[PRIVATE$d] = { radius };
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 radius() {
1965
- return this[PRIVATE$d].radius;
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[PRIVATE$c] = {
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[PRIVATE$c].matrix, this[PRIVATE$c].orientation, this[PRIVATE$c].position);
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[PRIVATE$c].matrix;
2258
+ return this[P_RIGID_TRANSFORM].matrix;
2030
2259
  }
2031
2260
  get position() {
2032
- const pos = this[PRIVATE$c].position;
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[PRIVATE$c].orientation;
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[PRIVATE$c].inverse) {
2269
+ if (!this[P_RIGID_TRANSFORM].inverse) {
2041
2270
  const invMatrix = create$3();
2042
- if (!invert(invMatrix, this[PRIVATE$c].matrix)) {
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[PRIVATE$c].inverse = new XRRigidTransform(new DOMPointReadOnly(invPosition[0], invPosition[1], invPosition[2], 1), new DOMPointReadOnly(invOrientation[0], invOrientation[1], invOrientation[2], invOrientation[3]));
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[PRIVATE$c].inverse[PRIVATE$c].inverse = this;
2282
+ this[P_RIGID_TRANSFORM].inverse[P_RIGID_TRANSFORM].inverse = this;
2054
2283
  }
2055
- return this[PRIVATE$c].inverse;
2284
+ return this[P_RIGID_TRANSFORM].inverse;
2056
2285
  }
2057
2286
  }
2058
2287
 
2059
- /**
2060
- * Copyright (c) Meta Platforms, Inc. and affiliates.
2061
- *
2062
- * This source code is licensed under the MIT license found in the
2063
- * LICENSE file in the root directory of this source tree.
2064
- */
2065
- const PRIVATE$b = Symbol('@immersive-web-emulation-runtime/xr-viewer-pose');
2066
- class XRViewerPose extends XRPose {
2067
- constructor(transform, views, emulatedPosition = false, linearVelocity = undefined, angularVelocity = undefined) {
2068
- super(transform, emulatedPosition, linearVelocity, angularVelocity);
2069
- this[PRIVATE$b] = {
2070
- views: Object.freeze(views),
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 views() {
2074
- return this[PRIVATE$b].views;
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
- const PRIVATE$a = Symbol('@immersive-web-emulation-runtime/xr-frame');
2085
- const spaceGlobalMatrix = create$3();
2086
- const baseSpaceGlobalMatrix = create$3();
2087
- const baseSpaceGlobalMatrixInverse = create$3();
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
- id,
2099
- active,
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
- get session() {
2106
- return this[PRIVATE$a].session;
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
- getViewerPose(referenceSpace) {
2128
- if (!this[PRIVATE$a].animationFrame) {
2129
- throw new DOMException('getViewerPose can only be called on XRFrame objects passed to XRSession.requestAnimationFrame callbacks.', 'InvalidStateError');
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
- fillJointRadii(jointSpaces, radii) {
2153
- // converting from sequence type to array
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
- fillPoses(spaces, baseSpace, transforms) {
2174
- // converting from sequence type to array
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[PRIVATE$9].type = type;
2455
+ this[P_REF_SPACE].type = type;
2240
2456
  }
2241
2457
  get onreset() {
2242
2458
  var _b;
2243
- return (_b = this[PRIVATE$9].onreset) !== null && _b !== void 0 ? _b : (() => { });
2459
+ return (_b = this[P_REF_SPACE].onreset) !== null && _b !== void 0 ? _b : (() => { });
2244
2460
  }
2245
2461
  set onreset(callback) {
2246
- if (this[PRIVATE$9].onreset) {
2247
- this.removeEventListener('reset', this[PRIVATE$9].onreset);
2462
+ if (this[P_REF_SPACE].onreset) {
2463
+ this.removeEventListener('reset', this[P_REF_SPACE].onreset);
2248
2464
  }
2249
- this[PRIVATE$9].onreset = callback;
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[PRIVATE$9].type, this, originOffset);
2474
+ return new XRReferenceSpace(this[P_REF_SPACE].type, this, originOffset);
2259
2475
  }
2260
2476
  }
2261
- _a = PRIVATE$9;
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[PRIVATE$8] = {
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[PRIVATE$8].depthNear;
2497
+ return this[P_RENDER_STATE].depthNear;
2283
2498
  }
2284
2499
  get depthFar() {
2285
- return this[PRIVATE$8].depthFar;
2500
+ return this[P_RENDER_STATE].depthFar;
2286
2501
  }
2287
2502
  get inlineVerticalFieldOfView() {
2288
- return this[PRIVATE$8].inlineVerticalFieldOfView;
2503
+ return this[P_RENDER_STATE].inlineVerticalFieldOfView;
2289
2504
  }
2290
2505
  get baseLayer() {
2291
- return this[PRIVATE$8].baseLayer;
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
- class XRLayer extends EventTarget {
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
- const PRIVATE$7 = Symbol('@immersive-web-emulation-runtime/XRWebGLLayer');
2320
- const defaultLayerInit = {
2321
- antialias: true,
2322
- depth: true,
2323
- stencil: false,
2324
- alpha: true,
2325
- ignoreDepthValues: false,
2326
- framebufferScaleFactor: 1.0,
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 XRWebGLLayer extends XRLayer {
2329
- constructor(session, context, layerInit = {}) {
2330
- super();
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
- context,
2341
- antialias: config.antialias,
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 context() {
2345
- return this[PRIVATE$7].context;
2663
+ get session() {
2664
+ return this[P_FRAME].session;
2346
2665
  }
2347
- get antialias() {
2348
- return this[PRIVATE$7].antialias;
2666
+ get predictedDisplayTime() {
2667
+ return this[P_FRAME].predictedDisplayTime;
2349
2668
  }
2350
- get ignoreDepthValues() {
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 framebuffer() {
2354
- return null;
2355
- }
2356
- get framebufferWidth() {
2357
- return this[PRIVATE$7].context.drawingBufferWidth;
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 framebufferHeight() {
2360
- return this[PRIVATE$7].context.drawingBufferHeight;
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
- getViewport(view) {
2363
- if (view[PRIVATE$g].session !== this[PRIVATE$7].session) {
2364
- throw new DOMException("View's session differs from Layer's session", 'InvalidStateError');
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
- // TO-DO: check frame
2367
- return this[PRIVATE$7].session[PRIVATE$6].device[PRIVATE$1].getViewport(this, view);
2764
+ return this[P_FRAME].trackedAnchors;
2368
2765
  }
2369
- static getNativeFramebufferScaleFactor(session) {
2370
- if (!(session instanceof XRSession)) {
2371
- throw new TypeError('getNativeFramebufferScaleFactor must be passed a session.');
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 (session[PRIVATE$6].ended) {
2374
- return 0.0;
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[PRIVATE$6] = {
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[PRIVATE$6].projectionMatrices[eye];
2832
+ return this[P_SESSION].projectionMatrices[eye];
2429
2833
  },
2430
2834
  referenceSpaceIsSupported: (referenceSpaceType) => {
2431
- if (!this[PRIVATE$6].enabledFeatures.includes(referenceSpaceType)) {
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[PRIVATE$6].mode != XRSessionMode.Inline;
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[PRIVATE$6].ended) {
2852
+ if (this[P_SESSION].ended) {
2449
2853
  return;
2450
2854
  }
2451
- this[PRIVATE$6].deviceFrameHandle = globalThis.requestAnimationFrame(this[PRIVATE$6].onDeviceFrame);
2452
- if (this[PRIVATE$6].pendingRenderState != null) {
2453
- this[PRIVATE$6].renderState = this[PRIVATE$6].pendingRenderState;
2454
- this[PRIVATE$6].pendingRenderState = null;
2455
- this[PRIVATE$6].device[PRIVATE$1].onBaseLayerSet(this[PRIVATE$6].renderState.baseLayer);
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[PRIVATE$6].renderState.baseLayer;
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[PRIVATE$6].mode != XRSessionMode.Inline) {
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[PRIVATE$6].renderState;
2910
+ const { depthNear, depthFar } = this[P_SESSION].renderState;
2507
2911
  const { width, height } = canvas;
2508
- if (this[PRIVATE$6].mode !== XRSessionMode.Inline) {
2509
- const aspect = (width * (this[PRIVATE$6].device.stereoEnabled ? 0.5 : 1.0)) / height;
2510
- perspective(this[PRIVATE$6].projectionMatrices[XREye.Left], this[PRIVATE$6].device.fovy, aspect, depthNear, depthFar);
2511
- copy$3(this[PRIVATE$6].projectionMatrices[XREye.Right], this[PRIVATE$6].projectionMatrices[XREye.Left]);
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[PRIVATE$6].projectionMatrices[XREye.None], this[PRIVATE$6].renderState.inlineVerticalFieldOfView, aspect, depthNear, depthFar);
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
- const frame = new XRFrame(this, this[PRIVATE$6].frameHandle, true, true, performance.now());
2518
- this[PRIVATE$6].device[PRIVATE$1].onFrameStart(frame);
2519
- this[PRIVATE$6].updateActiveInputSources();
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[PRIVATE$6].currentFrameCallbacks =
2529
- this[PRIVATE$6].frameCallbacks);
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[PRIVATE$6].frameCallbacks = [];
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[PRIVATE$6].currentFrameCallbacks = null;
2960
+ this[P_SESSION].currentFrameCallbacks = null;
2544
2961
  // - Set frame’s active boolean to false.
2545
- frame[PRIVATE$a].active = false;
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[PRIVATE$6].enabledFeatures.includes(WebXRFeatures.HandTracking);
2553
- const prevInputs = this[PRIVATE$6].activeInputSources;
2554
- const currInputs = this[PRIVATE$6].device.inputSources.filter((inputSource) => !inputSource.hand || handTrackingOn);
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[PRIVATE$6].activeInputSources = currInputs;
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[PRIVATE$6].onDeviceFrame();
3079
+ this[P_SESSION].onDeviceFrame();
2579
3080
  }
2580
3081
  get visibilityState() {
2581
- return this[PRIVATE$6].device.visibilityState;
3082
+ return this[P_SESSION].device.visibilityState;
2582
3083
  }
2583
3084
  get frameRate() {
2584
- return this[PRIVATE$6].nominalFrameRate;
3085
+ return this[P_SESSION].nominalFrameRate;
2585
3086
  }
2586
3087
  get supportedFrameRates() {
2587
- return new Float32Array(this[PRIVATE$6].device.supportedFrameRates);
3088
+ return new Float32Array(this[P_SESSION].device.supportedFrameRates);
2588
3089
  }
2589
3090
  get renderState() {
2590
- return this[PRIVATE$6].renderState;
3091
+ return this[P_SESSION].renderState;
2591
3092
  }
2592
3093
  get inputSources() {
2593
3094
  // use the same array object
2594
- this[PRIVATE$6].inputSourceArray.length = 0;
2595
- if (!this[PRIVATE$6].ended && this[PRIVATE$6].mode !== XRSessionMode.Inline) {
2596
- this[PRIVATE$6].inputSourceArray.push(...this[PRIVATE$6].activeInputSources);
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[PRIVATE$6].inputSourceArray;
3099
+ return this[P_SESSION].inputSourceArray;
2599
3100
  }
2600
3101
  get enabledFeatures() {
2601
- return this[PRIVATE$6].enabledFeatures;
3102
+ return this[P_SESSION].enabledFeatures;
2602
3103
  }
2603
3104
  get isSystemKeyboardSupported() {
2604
- return this[PRIVATE$6].isSystemKeyboardSupported;
3105
+ return this[P_SESSION].isSystemKeyboardSupported;
2605
3106
  }
2606
3107
  get environmentBlendMode() {
2607
3108
  var _a;
2608
- return ((_a = this[PRIVATE$6].device[PRIVATE$1].environmentBlendModes[this[PRIVATE$6].mode]) !== null && _a !== void 0 ? _a : XREnvironmentBlendMode.Opaque);
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[PRIVATE$6].device[PRIVATE$1].interactionMode;
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[PRIVATE$6].ended) {
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[PRIVATE$6].mode !== XRSessionMode.Inline) {
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[PRIVATE$6].pendingRenderState) === null || _a === void 0 ? void 0 : _a.baseLayer) ||
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[PRIVATE$6].pendingRenderState) === null || _b === void 0 ? void 0 : _b.depthFar) ||
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[PRIVATE$6].pendingRenderState) === null || _c === void 0 ? void 0 : _c.depthNear) ||
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[PRIVATE$6].pendingRenderState) === null || _d === void 0 ? void 0 : _d.inlineVerticalFieldOfView) ||
3137
+ ((_d = this[P_SESSION].pendingRenderState) === null || _d === void 0 ? void 0 : _d.inlineVerticalFieldOfView) ||
2638
3138
  undefined,
2639
3139
  };
2640
- this[PRIVATE$6].pendingRenderState = new XRRenderState(compoundStateInit, this[PRIVATE$6].renderState);
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[PRIVATE$6].ended) {
3146
+ if (this[P_SESSION].ended) {
2647
3147
  reject(new DOMException('XRSession has already ended.', 'InvalidStateError'));
2648
3148
  }
2649
- else if (!this[PRIVATE$6].device.supportedFrameRates.includes(rate)) {
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[PRIVATE$6].nominalFrameRate === rate) {
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[PRIVATE$6].nominalFrameRate = rate;
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[PRIVATE$6].ended ||
2668
- !this[PRIVATE$6].referenceSpaceIsSupported(type)) {
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[PRIVATE$6].device.viewerSpace;
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[PRIVATE$6].device[PRIVATE$1].globalSpace, this[PRIVATE$6].device.viewerSpace[PRIVATE$l].offsetMatrix);
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[PRIVATE$6].device[PRIVATE$1].globalSpace);
3185
+ referenceSpace = new XRReferenceSpace(type, this[P_SESSION].device[P_DEVICE].globalSpace);
2686
3186
  break;
2687
3187
  }
2688
- this[PRIVATE$6].referenceSpaces.push(referenceSpace);
3188
+ this[P_SESSION].referenceSpaces.push(referenceSpace);
2689
3189
  resolve(referenceSpace);
2690
3190
  });
2691
3191
  }
2692
3192
  requestAnimationFrame(callback) {
2693
- if (this[PRIVATE$6].ended) {
3193
+ if (this[P_SESSION].ended) {
2694
3194
  return 0;
2695
3195
  }
2696
- const frameHandle = ++this[PRIVATE$6].frameHandle;
2697
- this[PRIVATE$6].frameCallbacks.push({
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[PRIVATE$6].frameCallbacks;
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[PRIVATE$6].currentFrameCallbacks;
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[PRIVATE$6].ended || this[PRIVATE$6].deviceFrameHandle === null) {
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[PRIVATE$6].deviceFrameHandle);
2730
- this[PRIVATE$6].device[PRIVATE$1].onSessionEnd();
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[PRIVATE$6].onend) !== null && _a !== void 0 ? _a : (() => { });
3294
+ return (_a = this[P_SESSION].onend) !== null && _a !== void 0 ? _a : (() => { });
2740
3295
  }
2741
3296
  set onend(callback) {
2742
- if (this[PRIVATE$6].onend) {
2743
- this.removeEventListener('end', this[PRIVATE$6].onend);
3297
+ if (this[P_SESSION].onend) {
3298
+ this.removeEventListener('end', this[P_SESSION].onend);
2744
3299
  }
2745
- this[PRIVATE$6].onend = callback;
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[PRIVATE$6].oninputsourceschange) !== null && _a !== void 0 ? _a : (() => { });
3307
+ return (_a = this[P_SESSION].oninputsourceschange) !== null && _a !== void 0 ? _a : (() => { });
2753
3308
  }
2754
3309
  set oninputsourceschange(callback) {
2755
- if (this[PRIVATE$6].oninputsourceschange) {
2756
- this.removeEventListener('inputsourceschange', this[PRIVATE$6].oninputsourceschange);
3310
+ if (this[P_SESSION].oninputsourceschange) {
3311
+ this.removeEventListener('inputsourceschange', this[P_SESSION].oninputsourceschange);
2757
3312
  }
2758
- this[PRIVATE$6].oninputsourceschange = callback;
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[PRIVATE$6].onselect) !== null && _a !== void 0 ? _a : (() => { });
3320
+ return (_a = this[P_SESSION].onselect) !== null && _a !== void 0 ? _a : (() => { });
2766
3321
  }
2767
3322
  set onselect(callback) {
2768
- if (this[PRIVATE$6].onselect) {
2769
- this.removeEventListener('select', this[PRIVATE$6].onselect);
3323
+ if (this[P_SESSION].onselect) {
3324
+ this.removeEventListener('select', this[P_SESSION].onselect);
2770
3325
  }
2771
- this[PRIVATE$6].onselect = callback;
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[PRIVATE$6].onselectstart) !== null && _a !== void 0 ? _a : (() => { });
3333
+ return (_a = this[P_SESSION].onselectstart) !== null && _a !== void 0 ? _a : (() => { });
2779
3334
  }
2780
3335
  set onselectstart(callback) {
2781
- if (this[PRIVATE$6].onselectstart) {
2782
- this.removeEventListener('selectstart', this[PRIVATE$6].onselectstart);
3336
+ if (this[P_SESSION].onselectstart) {
3337
+ this.removeEventListener('selectstart', this[P_SESSION].onselectstart);
2783
3338
  }
2784
- this[PRIVATE$6].onselectstart = callback;
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[PRIVATE$6].onselectend) !== null && _a !== void 0 ? _a : (() => { });
3346
+ return (_a = this[P_SESSION].onselectend) !== null && _a !== void 0 ? _a : (() => { });
2792
3347
  }
2793
3348
  set onselectend(callback) {
2794
- if (this[PRIVATE$6].onselectend) {
2795
- this.removeEventListener('selectend', this[PRIVATE$6].onselectend);
3349
+ if (this[P_SESSION].onselectend) {
3350
+ this.removeEventListener('selectend', this[P_SESSION].onselectend);
2796
3351
  }
2797
- this[PRIVATE$6].onselectend = callback;
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[PRIVATE$6].onsqueeze) !== null && _a !== void 0 ? _a : (() => { });
3359
+ return (_a = this[P_SESSION].onsqueeze) !== null && _a !== void 0 ? _a : (() => { });
2805
3360
  }
2806
3361
  set onsqueeze(callback) {
2807
- if (this[PRIVATE$6].onsqueeze) {
2808
- this.removeEventListener('squeeze', this[PRIVATE$6].onsqueeze);
3362
+ if (this[P_SESSION].onsqueeze) {
3363
+ this.removeEventListener('squeeze', this[P_SESSION].onsqueeze);
2809
3364
  }
2810
- this[PRIVATE$6].onsqueeze = callback;
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[PRIVATE$6].onsqueezestart) !== null && _a !== void 0 ? _a : (() => { });
3372
+ return (_a = this[P_SESSION].onsqueezestart) !== null && _a !== void 0 ? _a : (() => { });
2818
3373
  }
2819
3374
  set onsqueezestart(callback) {
2820
- if (this[PRIVATE$6].onsqueezestart) {
2821
- this.removeEventListener('squeezestart', this[PRIVATE$6].onsqueezestart);
3375
+ if (this[P_SESSION].onsqueezestart) {
3376
+ this.removeEventListener('squeezestart', this[P_SESSION].onsqueezestart);
2822
3377
  }
2823
- this[PRIVATE$6].onsqueezestart = callback;
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[PRIVATE$6].onsqueezeend) !== null && _a !== void 0 ? _a : (() => { });
3385
+ return (_a = this[P_SESSION].onsqueezeend) !== null && _a !== void 0 ? _a : (() => { });
2831
3386
  }
2832
3387
  set onsqueezeend(callback) {
2833
- if (this[PRIVATE$6].onsqueezeend) {
2834
- this.removeEventListener('squeezeend', this[PRIVATE$6].onsqueezeend);
3388
+ if (this[P_SESSION].onsqueezeend) {
3389
+ this.removeEventListener('squeezeend', this[P_SESSION].onsqueezeend);
2835
3390
  }
2836
- this[PRIVATE$6].onsqueezeend = callback;
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[PRIVATE$6].onvisibilitychange) !== null && _a !== void 0 ? _a : (() => { });
3398
+ return (_a = this[P_SESSION].onvisibilitychange) !== null && _a !== void 0 ? _a : (() => { });
2844
3399
  }
2845
3400
  set onvisibilitychange(callback) {
2846
- if (this[PRIVATE$6].onvisibilitychange) {
2847
- this.removeEventListener('visibilitychange', this[PRIVATE$6].onvisibilitychange);
3401
+ if (this[P_SESSION].onvisibilitychange) {
3402
+ this.removeEventListener('visibilitychange', this[P_SESSION].onvisibilitychange);
2848
3403
  }
2849
- this[PRIVATE$6].onvisibilitychange = callback;
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[PRIVATE$6].onframeratechange) !== null && _a !== void 0 ? _a : (() => { });
3411
+ return (_a = this[P_SESSION].onframeratechange) !== null && _a !== void 0 ? _a : (() => { });
2857
3412
  }
2858
3413
  set onframeratechange(callback) {
2859
- if (this[PRIVATE$6].onframeratechange) {
2860
- this.removeEventListener('frameratechange', this[PRIVATE$6].onframeratechange);
3414
+ if (this[P_SESSION].onframeratechange) {
3415
+ this.removeEventListener('frameratechange', this[P_SESSION].onframeratechange);
2861
3416
  }
2862
- this[PRIVATE$6].onframeratechange = callback;
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[PRIVATE$5] = {
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[PRIVATE$5].poseId;
4285
+ return this[P_HAND_INPUT].poseId;
3716
4286
  }
3717
4287
  set poseId(poseId) {
3718
- if (!this[PRIVATE$5].poses[poseId]) {
4288
+ if (!this[P_HAND_INPUT].poses[poseId]) {
3719
4289
  console.warn(`Pose config ${poseId} not found`);
3720
4290
  return;
3721
4291
  }
3722
- this[PRIVATE$5].poseId = poseId;
4292
+ this[P_HAND_INPUT].poseId = poseId;
3723
4293
  }
3724
4294
  updateHandPose() {
3725
- const targetPose = this[PRIVATE$5].poses[this[PRIVATE$5].poseId];
3726
- const pinchPose = this[PRIVATE$5].poses.pinch;
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[PRIVATE$l].offsetMatrix, targetJointMatrix, pinchJointMatrix, this.pinchValue);
4301
+ interpolateMatrix(jointSpace[P_SPACE].offsetMatrix, targetJointMatrix, pinchJointMatrix, this.pinchValue);
3732
4302
  if (this.inputSource.handedness === XRHandedness.Right) {
3733
- mirrorMatrixToRight(jointSpace[PRIVATE$l].offsetMatrix);
4303
+ mirrorMatrixToRight(jointSpace[P_SPACE].offsetMatrix);
3734
4304
  }
3735
- jointSpace[PRIVATE$f].radius =
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[PRIVATE$l].offsetMatrix, targetPose.gripOffsetMatrix, pinchPose.gripOffsetMatrix, this.pinchValue);
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[PRIVATE$i].inputSource.gamepad[PRIVATE$k]
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[PRIVATE$i].inputSource.gamepad[PRIVATE$k]
3753
- .buttonsMap['pinch'];
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
- const PRIVATE$4 = Symbol('@immersive-web-emulation-runtime/xr-system');
3769
- class XRSystem extends EventTarget {
3770
- constructor(device) {
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
- this[PRIVATE$4] = { device };
3773
- // Initialize device change monitoring here if applicable
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
- isSessionSupported(mode) {
3776
- return new Promise((resolve, _reject) => {
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
- requestSession(mode, options = {}) {
3787
- return new Promise((resolve, reject) => {
3788
- this.isSessionSupported(mode)
3789
- .then((isSupported) => {
3790
- if (!isSupported) {
3791
- reject(new DOMException('The requested XRSession mode is not supported.', 'NotSupportedError'));
3792
- return;
3793
- }
3794
- // Check for active sessions and other constraints here
3795
- if (this[PRIVATE$4].activeSession) {
3796
- reject(new DOMException('An active XRSession already exists.', 'InvalidStateError'));
3797
- return;
3798
- }
3799
- // Handle required and optional features
3800
- const { requiredFeatures = [], optionalFeatures = [] } = options;
3801
- const { supportedFeatures } = this[PRIVATE$4].device;
3802
- // Check if all required features are supported
3803
- const allRequiredSupported = requiredFeatures.every((feature) => supportedFeatures.includes(feature));
3804
- if (!allRequiredSupported) {
3805
- reject(new Error('One or more required features are not supported by the device.'));
3806
- return;
3807
- }
3808
- // Filter out unsupported optional features
3809
- const supportedOptionalFeatures = optionalFeatures.filter((feature) => supportedFeatures.includes(feature));
3810
- // Combine required and supported optional features into enabled features
3811
- const enabledFeatures = Array.from(new Set([
3812
- ...requiredFeatures,
3813
- ...supportedOptionalFeatures,
3814
- WebXRFeatures.Viewer,
3815
- WebXRFeatures.Local,
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[PRIVATE$3] = {
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[PRIVATE$3].viewSpaces[XREye.Left][PRIVATE$l].offsetMatrix, fromValues$2(-ipd / 2, 0, 0));
3866
- fromTranslation(this[PRIVATE$3].viewSpaces[XREye.Right][PRIVATE$l].offsetMatrix, fromValues$2(ipd / 2, 0, 0));
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[PRIVATE$3].inputSources.set(index, {
4462
+ this[P_ACTION_PLAYER].inputSources.set(index, {
3896
4463
  active: false,
3897
4464
  source: inputSource,
3898
4465
  });
3899
- this[PRIVATE$3].inputSchemas.set(index, schema);
4466
+ this[P_ACTION_PLAYER].inputSchemas.set(index, schema);
3900
4467
  });
3901
4468
  }
3902
4469
  play() {
3903
- this[PRIVATE$3].recordedFramePointer = 0;
3904
- this[PRIVATE$3].playbackTime = this[PRIVATE$3].startingTimeStamp;
3905
- this[PRIVATE$3].playing = true;
3906
- this[PRIVATE$3].actualTimeStamp = performance.now();
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[PRIVATE$3].playing = false;
4477
+ this[P_ACTION_PLAYER].playing = false;
3910
4478
  }
3911
4479
  get playing() {
3912
- return this[PRIVATE$3].playing;
4480
+ return this[P_ACTION_PLAYER].playing;
3913
4481
  }
3914
4482
  get viewerSpace() {
3915
- return this[PRIVATE$3].viewerSpace;
4483
+ return this[P_ACTION_PLAYER].viewerSpace;
3916
4484
  }
3917
4485
  get viewSpaces() {
3918
- return this[PRIVATE$3].viewSpaces;
4486
+ return this[P_ACTION_PLAYER].viewSpaces;
3919
4487
  }
3920
4488
  get inputSources() {
3921
- return Array.from(this[PRIVATE$3].inputSources.values())
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[PRIVATE$3].actualTimeStamp;
3928
- this[PRIVATE$3].actualTimeStamp = now;
3929
- this[PRIVATE$3].playbackTime += delta;
3930
- if (this[PRIVATE$3].playbackTime > this[PRIVATE$3].endingTimeStamp) {
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[PRIVATE$3].frames[this[PRIVATE$3].recordedFramePointer + 1][0] < this[PRIVATE$3].playbackTime) {
3935
- this[PRIVATE$3].recordedFramePointer++;
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[PRIVATE$3].frames[this[PRIVATE$3].recordedFramePointer];
3938
- const nextFrameData = this[PRIVATE$3].frames[this[PRIVATE$3].recordedFramePointer + 1];
3939
- const alpha = (this[PRIVATE$3].playbackTime - lastFrameData[0]) /
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[PRIVATE$3].viewerSpace, lastFrameData.slice(1, 8), nextFrameData.slice(1, 8), alpha);
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[PRIVATE$3].inputSources.forEach((sourceWrapper) => {
4521
+ this[P_ACTION_PLAYER].inputSources.forEach((sourceWrapper) => {
3953
4522
  sourceWrapper.active = false;
3954
4523
  });
3955
4524
  nextFrameInputs.forEach((inputData, index) => {
3956
- this[PRIVATE$3].inputSources.get(index).active = true;
3957
- const inputSource = this[PRIVATE$3].inputSources.get(index).source;
3958
- const schema = this[PRIVATE$3].inputSchemas.get(index);
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[PRIVATE$f].radius =
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[PRIVATE$k].pressed = states[0] === 1 ? true : false;
3984
- gamepadButton[PRIVATE$k].touched = states[1] === 1 ? true : false;
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[PRIVATE$k].value =
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[PRIVATE$k].axesMap[index.toString()].x =
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[PRIVATE$3].vec3, f1p, f2p, alpha);
4003
- slerp(this[PRIVATE$3].quat, f1q, f2q, alpha);
4004
- fromRotationTranslation(space[PRIVATE$l].offsetMatrix, this[PRIVATE$3].quat, this[PRIVATE$3].vec3);
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[PRIVATE$3].inputSchemas.get(index);
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.4";
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
- const PRIVATE$2 = Symbol('@immersive-web-emulation-runtime/xr-viewport');
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[PRIVATE$2] = { x, y, width, height };
4691
+ this[P_VIEWPORT] = { x, y, width, height };
4056
4692
  }
4057
4693
  get x() {
4058
- return this[PRIVATE$2].x;
4694
+ return this[P_VIEWPORT].x;
4059
4695
  }
4060
4696
  get y() {
4061
- return this[PRIVATE$2].y;
4697
+ return this[P_VIEWPORT].y;
4062
4698
  }
4063
4699
  get width() {
4064
- return this[PRIVATE$2].width;
4700
+ return this[P_VIEWPORT].width;
4065
4701
  }
4066
4702
  get height() {
4067
- return this[PRIVATE$2].height;
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[PRIVATE$1] = {
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: XRVisibilityState.Visible,
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[PRIVATE$1].stereoEnabled ? width / 2 : width, height);
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[PRIVATE$1].stereoEnabled ? width / 2 : 0, height);
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[PRIVATE$1].viewerSpace;
4181
- fromRotationTranslation(viewerSpace[PRIVATE$l].offsetMatrix, this[PRIVATE$1].quaternion.quat, this[PRIVATE$1].position.vec3);
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[PRIVATE$1].viewSpaces[XREye.Left][PRIVATE$l].offsetMatrix, fromValues$2(-this[PRIVATE$1].ipd / 2, 0, 0));
4184
- fromTranslation(this[PRIVATE$1].viewSpaces[XREye.Right][PRIVATE$l].offsetMatrix, fromValues$2(this[PRIVATE$1].ipd / 2, 0, 0));
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[PRIVATE$1].canvasContainer) {
4192
- this[PRIVATE$1].canvasData = {
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[PRIVATE$1].canvasContainer.appendChild(canvas);
4199
- document.body.appendChild(this[PRIVATE$1].canvasContainer);
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[PRIVATE$1].canvasData) {
4206
- const { canvas, parent, width, height } = this[PRIVATE$1].canvasData;
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[PRIVATE$1].canvasContainer.removeChild(canvas);
4833
+ this[P_DEVICE].canvasContainer.removeChild(canvas);
4214
4834
  }
4215
- document.body.removeChild(this[PRIVATE$1].canvasContainer);
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[PRIVATE$1].actionPlayer) === null || _a === void 0 ? void 0 : _a.playing) {
4222
- this[PRIVATE$1].actionPlayer.playFrame();
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[PRIVATE$1].updateViews();
4227
- if (this[PRIVATE$1].pendingVisibilityState) {
4228
- this[PRIVATE$1].visibilityState =
4229
- this[PRIVATE$1].pendingVisibilityState;
4230
- this[PRIVATE$1].pendingVisibilityState = null;
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[PRIVATE$1].visibilityState === XRVisibilityState.Visible) {
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[PRIVATE$1].pendingReferenceSpaceReset) {
4239
- session[PRIVATE$6].referenceSpaces.forEach((referenceSpace) => {
4240
- switch (referenceSpace[PRIVATE$9].type) {
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[PRIVATE$1].pendingReferenceSpaceReset = false;
4869
+ this[P_DEVICE].pendingReferenceSpaceReset = false;
4250
4870
  }
4251
4871
  }
4252
- this[PRIVATE$1].updateViews();
4872
+ this[P_DEVICE].updateViews();
4253
4873
  },
4254
4874
  };
4255
- this[PRIVATE$1].updateViews();
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[PRIVATE$1].xrSystem = new XRSystem(this);
4886
+ this[P_DEVICE].xrSystem = new XRSystem(this);
4267
4887
  Object.defineProperty(globalThis.navigator, 'xr', {
4268
- value: this[PRIVATE$1].xrSystem,
4888
+ value: this[P_DEVICE].xrSystem,
4269
4889
  configurable: true,
4270
4890
  });
4271
4891
  Object.defineProperty(navigator, 'userAgent', {
4272
- value: this[PRIVATE$1].userAgent,
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[PRIVATE$1].supportedSessionModes;
4924
+ return this[P_DEVICE].supportedSessionModes;
4302
4925
  }
4303
4926
  get supportedFeatures() {
4304
- return this[PRIVATE$1].supportedFeatures;
4927
+ return this[P_DEVICE].supportedFeatures;
4305
4928
  }
4306
4929
  get supportedFrameRates() {
4307
- return this[PRIVATE$1].supportedFrameRates;
4930
+ return this[P_DEVICE].supportedFrameRates;
4308
4931
  }
4309
4932
  get isSystemKeyboardSupported() {
4310
- return this[PRIVATE$1].isSystemKeyboardSupported;
4933
+ return this[P_DEVICE].isSystemKeyboardSupported;
4311
4934
  }
4312
4935
  get internalNominalFrameRate() {
4313
- return this[PRIVATE$1].internalNominalFrameRate;
4936
+ return this[P_DEVICE].internalNominalFrameRate;
4314
4937
  }
4315
4938
  get stereoEnabled() {
4316
- return this[PRIVATE$1].stereoEnabled;
4939
+ return this[P_DEVICE].stereoEnabled;
4317
4940
  }
4318
4941
  set stereoEnabled(value) {
4319
- this[PRIVATE$1].stereoEnabled = value;
4942
+ this[P_DEVICE].stereoEnabled = value;
4320
4943
  }
4321
4944
  get ipd() {
4322
- return this[PRIVATE$1].ipd;
4945
+ return this[P_DEVICE].ipd;
4323
4946
  }
4324
4947
  set ipd(value) {
4325
- this[PRIVATE$1].ipd = value;
4948
+ this[P_DEVICE].ipd = value;
4326
4949
  }
4327
4950
  get fovy() {
4328
- return this[PRIVATE$1].fovy;
4951
+ return this[P_DEVICE].fovy;
4329
4952
  }
4330
4953
  set fovy(value) {
4331
- this[PRIVATE$1].fovy = value;
4954
+ this[P_DEVICE].fovy = value;
4332
4955
  }
4333
4956
  get position() {
4334
- return this[PRIVATE$1].position;
4957
+ return this[P_DEVICE].position;
4335
4958
  }
4336
4959
  get quaternion() {
4337
- return this[PRIVATE$1].quaternion;
4960
+ return this[P_DEVICE].quaternion;
4338
4961
  }
4339
4962
  get viewerSpace() {
4340
4963
  var _a;
4341
- if ((_a = this[PRIVATE$1].actionPlayer) === null || _a === void 0 ? void 0 : _a.playing) {
4342
- return this[PRIVATE$1].actionPlayer.viewerSpace;
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[PRIVATE$1].viewerSpace;
4968
+ return this[P_DEVICE].viewerSpace;
4346
4969
  }
4347
4970
  }
4348
4971
  get viewSpaces() {
4349
4972
  var _a;
4350
- if ((_a = this[PRIVATE$1].actionPlayer) === null || _a === void 0 ? void 0 : _a.playing) {
4351
- return this[PRIVATE$1].actionPlayer.viewSpaces;
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[PRIVATE$1].viewSpaces;
4977
+ return this[P_DEVICE].viewSpaces;
4355
4978
  }
4356
4979
  }
4357
4980
  get controllers() {
4358
- return this[PRIVATE$1].controllers;
4981
+ return this[P_DEVICE].controllers;
4359
4982
  }
4360
4983
  get hands() {
4361
- return this[PRIVATE$1].hands;
4984
+ return this[P_DEVICE].hands;
4362
4985
  }
4363
4986
  get primaryInputMode() {
4364
- return this[PRIVATE$1].primaryInputMode;
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[PRIVATE$1].primaryInputMode = mode;
4994
+ this[P_DEVICE].primaryInputMode = mode;
4372
4995
  }
4373
4996
  get activeInputs() {
4374
- if (this[PRIVATE$1].visibilityState !== XRVisibilityState.Visible) {
4997
+ if (this[P_DEVICE].visibilityState !== 'visible') {
4375
4998
  return [];
4376
4999
  }
4377
- const activeInputs = this[PRIVATE$1].primaryInputMode === 'controller'
4378
- ? Object.values(this[PRIVATE$1].controllers)
4379
- : Object.values(this[PRIVATE$1].hands);
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[PRIVATE$1].actionPlayer) === null || _a === void 0 ? void 0 : _a.playing) {
4385
- return this[PRIVATE$1].actionPlayer.inputSources;
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[PRIVATE$1].canvasContainer;
5015
+ return this[P_DEVICE].canvasContainer;
4393
5016
  }
4394
5017
  get activeSession() {
4395
5018
  var _a;
4396
- return (_a = this[PRIVATE$1].xrSystem) === null || _a === void 0 ? void 0 : _a[PRIVATE$4].activeSession;
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[PRIVATE$1].controllers),
4409
- ...Object.values(this[PRIVATE$1].hands),
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[PRIVATE$1].pendingReferenceSpaceReset = true;
5038
+ this[P_DEVICE].pendingReferenceSpaceReset = true;
4416
5039
  }
4417
5040
  get visibilityState() {
4418
- return this[PRIVATE$1].visibilityState;
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(XRVisibilityState).includes(state)) {
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[PRIVATE$1].visibilityState) {
4426
- this[PRIVATE$1].pendingVisibilityState = state;
5048
+ if (state !== this[P_DEVICE].visibilityState) {
5049
+ this[P_DEVICE].pendingVisibilityState = state;
4427
5050
  }
4428
5051
  }
4429
5052
  createActionPlayer(refSpace, recording) {
4430
- this[PRIVATE$1].actionPlayer = new ActionPlayer(refSpace, recording, this[PRIVATE$1].ipd);
4431
- return this[PRIVATE$1].actionPlayer;
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
- WebXRFeatures.Viewer,
4606
- WebXRFeatures.Local,
4607
- WebXRFeatures.LocalFloor,
4608
- WebXRFeatures.BoundedFloor,
4609
- WebXRFeatures.Unbounded,
4610
- WebXRFeatures.Anchors,
4611
- WebXRFeatures.PlaneDetection,
4612
- WebXRFeatures.HandTracking,
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
- [XRSessionMode.ImmersiveVR]: XREnvironmentBlendMode.Opaque,
4619
- [XRSessionMode.ImmersiveAR]: XREnvironmentBlendMode.AlphaBlend,
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
- WebXRFeatures.Viewer,
4634
- WebXRFeatures.Local,
4635
- WebXRFeatures.LocalFloor,
4636
- WebXRFeatures.BoundedFloor,
4637
- WebXRFeatures.Unbounded,
4638
- WebXRFeatures.Anchors,
4639
- WebXRFeatures.PlaneDetection,
4640
- WebXRFeatures.MeshDetection,
4641
- WebXRFeatures.HitTest,
4642
- WebXRFeatures.HandTracking,
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
- [XRSessionMode.ImmersiveVR]: XREnvironmentBlendMode.Opaque,
4649
- [XRSessionMode.ImmersiveAR]: XREnvironmentBlendMode.AlphaBlend,
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
- WebXRFeatures.Viewer,
4664
- WebXRFeatures.Local,
4665
- WebXRFeatures.LocalFloor,
4666
- WebXRFeatures.BoundedFloor,
4667
- WebXRFeatures.Unbounded,
4668
- WebXRFeatures.Anchors,
4669
- WebXRFeatures.PlaneDetection,
4670
- WebXRFeatures.MeshDetection,
4671
- WebXRFeatures.HitTest,
4672
- WebXRFeatures.HandTracking,
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
- [XRSessionMode.ImmersiveVR]: XREnvironmentBlendMode.Opaque,
4679
- [XRSessionMode.ImmersiveAR]: XREnvironmentBlendMode.AlphaBlend,
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
- WebXRFeatures.Viewer,
4694
- WebXRFeatures.Local,
4695
- WebXRFeatures.LocalFloor,
4696
- WebXRFeatures.BoundedFloor,
4697
- WebXRFeatures.Unbounded,
4698
- WebXRFeatures.Anchors,
4699
- WebXRFeatures.PlaneDetection,
4700
- WebXRFeatures.MeshDetection,
4701
- WebXRFeatures.HitTest,
4702
- WebXRFeatures.HandTracking,
4703
- WebXRFeatures.DepthSensing,
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
- [XRSessionMode.ImmersiveVR]: XREnvironmentBlendMode.Opaque,
4710
- [XRSessionMode.ImmersiveAR]: XREnvironmentBlendMode.AlphaBlend,
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[PRIVATE] = {
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[PRIVATE].refSpace)) === null || _a === void 0 ? void 0 : _a.transform.matrix;
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[PRIVATE].session.inputSources.forEach((inputSource) => {
5362
+ this[P_ACTION_RECORDER].session.inputSources.forEach((inputSource) => {
4757
5363
  var _a, _b;
4758
- if (!this[PRIVATE].inputMap.has(inputSource)) {
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[PRIVATE].inputMap.size;
4776
- this[PRIVATE].inputMap.set(inputSource, index);
4777
- this[PRIVATE].schemaMap.set(index, schema);
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[PRIVATE].inputMap.get(inputSource);
4780
- const schema = this[PRIVATE].schemaMap.get(index);
4781
- const targetRayMatrix = (_a = frame.getPose(inputSource.targetRaySpace, this[PRIVATE].refSpace)) === null || _a === void 0 ? void 0 : _a.transform.matrix;
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[PRIVATE].refSpace)) === null || _b === void 0 ? void 0 : _b.transform.matrix;
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[PRIVATE].jointTransforms));
5413
+ allValid && (allValid = frame.fillPoses(jointSpaces, inputSource.targetRaySpace, this[P_ACTION_RECORDER].jointTransforms));
4808
5414
  // @ts-ignore
4809
- allValid && (allValid = frame.fillJointRadii(jointSpaces, this[PRIVATE].jointRadii));
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[PRIVATE].jointTransforms.slice(offset * 16, (offset + 1) * 16);
4814
- const radius = this[PRIVATE].jointRadii[offset];
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[PRIVATE].compressedFrames.push(this.compressActionFrame(actionFrame));
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[PRIVATE].schemaMap.get(index);
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[PRIVATE].schemaMap.entries()),
4877
- frames: this[PRIVATE].compressedFrames,
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;