iwer 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/iwer.js CHANGED
@@ -1375,6 +1375,7 @@
1375
1375
  const P_VIEW = Symbol('@iwer/xr-view');
1376
1376
  const P_VIEWPORT = Symbol('@iwer/xr-viewport');
1377
1377
  const P_RAY = Symbol('@iwer/xr-ray');
1378
+ const P_DEPTH_INFO = Symbol('@iwer/xr-depth-info');
1378
1379
  const P_HIT_TEST = Symbol('@iwer/xr-hit-test');
1379
1380
 
1380
1381
  /**
@@ -1883,6 +1884,34 @@
1883
1884
  w: s0 * a.w + s1 * bw,
1884
1885
  };
1885
1886
  }
1887
+ /**
1888
+ * Map of common device name aliases to canonical DeviceId values.
1889
+ * Enables callers to use natural variants like "right", "left-controller",
1890
+ * "controllers.right", etc. in addition to the canonical names.
1891
+ */
1892
+ const DEVICE_ID_ALIASES = {
1893
+ right: 'controller-right',
1894
+ left: 'controller-left',
1895
+ 'right-controller': 'controller-right',
1896
+ 'left-controller': 'controller-left',
1897
+ 'controllers.right': 'controller-right',
1898
+ 'controllers.left': 'controller-left',
1899
+ rightController: 'controller-right',
1900
+ leftController: 'controller-left',
1901
+ 'right-hand': 'hand-right',
1902
+ 'left-hand': 'hand-left',
1903
+ 'hands.right': 'hand-right',
1904
+ 'hands.left': 'hand-left',
1905
+ rightHand: 'hand-right',
1906
+ leftHand: 'hand-left',
1907
+ };
1908
+ /**
1909
+ * Resolve a device identifier, accepting both canonical names and common aliases.
1910
+ */
1911
+ function resolveDeviceId(id) {
1912
+ var _a;
1913
+ return (_a = DEVICE_ID_ALIASES[id]) !== null && _a !== void 0 ? _a : id;
1914
+ }
1886
1915
  /**
1887
1916
  * RemoteControlInterface provides frame-synchronized programmatic control of an XRDevice.
1888
1917
  *
@@ -2017,15 +2046,27 @@
2017
2046
  action.elapsedMs += deltaTimeMs;
2018
2047
  if (action.elapsedMs >= action.durationMs) {
2019
2048
  // Complete - apply final state
2020
- this.applyDurationFinalState(action);
2021
- action.resolve(this.getDurationResult(action));
2049
+ try {
2050
+ this.applyDurationFinalState(action);
2051
+ action.resolve(this.getDurationResult(action));
2052
+ }
2053
+ catch (error) {
2054
+ action.reject(error);
2055
+ }
2022
2056
  this.commandQueue.shift();
2023
2057
  // Continue to next action
2024
2058
  }
2025
2059
  else {
2026
2060
  // In progress - lerp
2027
- const t = action.elapsedMs / action.durationMs;
2028
- this.applyDurationLerpState(action, t);
2061
+ try {
2062
+ const t = action.elapsedMs / action.durationMs;
2063
+ this.applyDurationLerpState(action, t);
2064
+ }
2065
+ catch (error) {
2066
+ action.reject(error);
2067
+ this.commandQueue.shift();
2068
+ continue;
2069
+ }
2029
2070
  // Stop processing - wait for next frame
2030
2071
  break;
2031
2072
  }
@@ -2783,6 +2824,10 @@
2783
2824
  */
2784
2825
  async dispatch(method, params = {}) {
2785
2826
  var _a;
2827
+ // Normalize device identifier aliases (e.g. "right" -> "controller-right")
2828
+ if (typeof params.device === 'string') {
2829
+ params.device = resolveDeviceId(params.device);
2830
+ }
2786
2831
  // Immediate methods execute synchronously without queue
2787
2832
  if (RemoteControlInterface.IMMEDIATE_METHODS.has(method)) {
2788
2833
  // Active immediate methods trigger capture mode
@@ -2862,6 +2907,8 @@
2862
2907
  */
2863
2908
  executeSelectSequence(params) {
2864
2909
  const { device: deviceId, duration = 0.15 } = params;
2910
+ // Validate device upfront to prevent sub-actions from failing in the frame loop
2911
+ this.getDeviceSelectValue(deviceId);
2865
2912
  return new Promise((resolve, reject) => {
2866
2913
  // Track completion of all three actions
2867
2914
  let actionsCompleted = 0;
@@ -3580,6 +3627,60 @@
3580
3627
  }
3581
3628
  }
3582
3629
 
3630
+ /**
3631
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3632
+ *
3633
+ * This source code is licensed under the MIT license found in the
3634
+ * LICENSE file in the root directory of this source tree.
3635
+ */
3636
+ class XRCPUDepthInformation {
3637
+ constructor(data, width, height, normDepthBufferFromNormView, rawValueToMeters, dataFormat) {
3638
+ this[P_DEPTH_INFO] = {
3639
+ data,
3640
+ width,
3641
+ height,
3642
+ normDepthBufferFromNormView,
3643
+ rawValueToMeters,
3644
+ dataFormat,
3645
+ };
3646
+ }
3647
+ get data() {
3648
+ return this[P_DEPTH_INFO].data;
3649
+ }
3650
+ get width() {
3651
+ return this[P_DEPTH_INFO].width;
3652
+ }
3653
+ get height() {
3654
+ return this[P_DEPTH_INFO].height;
3655
+ }
3656
+ get normDepthBufferFromNormView() {
3657
+ return this[P_DEPTH_INFO].normDepthBufferFromNormView;
3658
+ }
3659
+ get rawValueToMeters() {
3660
+ return this[P_DEPTH_INFO].rawValueToMeters;
3661
+ }
3662
+ getDepthInMeters(x, y) {
3663
+ const { width, height, rawValueToMeters, data, dataFormat } = this[P_DEPTH_INFO];
3664
+ if (x < 0 || x >= 1 || y < 0 || y >= 1) {
3665
+ throw new RangeError('Normalized coordinates must be in [0, 1) range.');
3666
+ }
3667
+ const col = Math.floor(x * width);
3668
+ const row = Math.floor(y * height);
3669
+ if (dataFormat === 'float32') {
3670
+ const floatView = new Float32Array(data);
3671
+ const index = row * width + col;
3672
+ return floatView[index] * rawValueToMeters;
3673
+ }
3674
+ else {
3675
+ // luminance-alpha: 16-bit unsigned int packed as two bytes
3676
+ const byteView = new Uint8Array(data);
3677
+ const index = (row * width + col) * 2;
3678
+ const rawValue = byteView[index] + byteView[index + 1] * 256;
3679
+ return rawValue * rawValueToMeters;
3680
+ }
3681
+ }
3682
+ }
3683
+
3583
3684
  /**
3584
3685
  * Copyright (c) Meta Platforms, Inc. and affiliates.
3585
3686
  *
@@ -4081,6 +4182,7 @@
4081
4182
  detectedMeshes: new XRMeshSet(),
4082
4183
  trackedAnchors: session[P_SESSION].frameTrackedAnchors,
4083
4184
  hitTestResultsMap: new Map(),
4185
+ depthDataMap: new Map(),
4084
4186
  };
4085
4187
  }
4086
4188
  get session() {
@@ -4216,6 +4318,16 @@
4216
4318
  return [...this[P_FRAME].hitTestResultsMap.get(hitTestSource)];
4217
4319
  }
4218
4320
  }
4321
+ getDepthInformation(view) {
4322
+ var _a;
4323
+ if (!this[P_FRAME].active) {
4324
+ throw new DOMException('XRFrame access outside the callback that produced it is invalid.', 'InvalidStateError');
4325
+ }
4326
+ if (!this[P_FRAME].session[P_SESSION].enabledFeatures.includes('depth-sensing')) {
4327
+ throw new DOMException('depth-sensing feature is not enabled on this session.', 'InvalidStateError');
4328
+ }
4329
+ return (_a = this[P_FRAME].depthDataMap.get(view[P_VIEW].eye)) !== null && _a !== void 0 ? _a : null;
4330
+ }
4219
4331
  }
4220
4332
 
4221
4333
  /**
@@ -4363,6 +4475,9 @@
4363
4475
  if (this[P_SESSION].enabledFeatures.includes('mesh-detection')) {
4364
4476
  this[P_SESSION].updateTrackedMeshes(frame);
4365
4477
  }
4478
+ if (this[P_SESSION].enabledFeatures.includes('depth-sensing')) {
4479
+ this[P_SESSION].computeDepthSensing(frame);
4480
+ }
4366
4481
  if (this[P_SESSION].enabledFeatures.includes('hit-test')) {
4367
4482
  this[P_SESSION].computeHitTestResults(frame);
4368
4483
  }
@@ -4488,6 +4603,37 @@
4488
4603
  frame[P_FRAME].detectedMeshes.add(xrMesh);
4489
4604
  });
4490
4605
  },
4606
+ depthSensingUsage: 'cpu-optimized',
4607
+ depthSensingDataFormat: 'float32',
4608
+ computeDepthSensing: (frame) => {
4609
+ const sem = this[P_SESSION].device[P_DEVICE].sem;
4610
+ if (!sem)
4611
+ return;
4612
+ const { depthNear, depthFar } = this[P_SESSION].renderState;
4613
+ const baseLayer = this[P_SESSION].renderState.baseLayer;
4614
+ if (!baseLayer)
4615
+ return;
4616
+ const canvas = baseLayer.context.canvas;
4617
+ // Use a reduced resolution for depth buffer (1/4 of canvas)
4618
+ const depthWidth = Math.max(1, Math.floor(canvas.width / 4));
4619
+ const depthHeight = Math.max(1, Math.floor(canvas.height / 4));
4620
+ const eyes = this[P_SESSION].mode === 'inline'
4621
+ ? [XREye.None]
4622
+ : [XREye.Left, XREye.Right];
4623
+ for (const eye of eyes) {
4624
+ const projectionMatrix = this[P_SESSION].getProjectionMatrix(eye);
4625
+ const viewSpace = this[P_SESSION].device.viewSpaces[eye];
4626
+ const viewGlobalMatrix = XRSpaceUtils.calculateGlobalOffsetMatrix(viewSpace);
4627
+ const viewMatrix = create$5();
4628
+ invert(viewMatrix, viewGlobalMatrix);
4629
+ const result = sem.computeDepthBuffer(viewMatrix, projectionMatrix, depthWidth, depthHeight, depthNear, depthFar);
4630
+ if (result) {
4631
+ const depthInfo = new XRCPUDepthInformation(result.data, result.width, result.height, new XRRigidTransform(), // identity: depth buffer is aligned with view
4632
+ result.rawValueToMeters, this[P_SESSION].depthSensingDataFormat);
4633
+ frame[P_FRAME].depthDataMap.set(eye, depthInfo);
4634
+ }
4635
+ }
4636
+ },
4491
4637
  hitTestSources: new Set(),
4492
4638
  computeHitTestResults: (frame) => {
4493
4639
  const sem = this[P_SESSION].device[P_DEVICE].sem;
@@ -4557,6 +4703,12 @@
4557
4703
  get interactionMode() {
4558
4704
  return this[P_SESSION].device[P_DEVICE].interactionMode;
4559
4705
  }
4706
+ get depthUsage() {
4707
+ return this[P_SESSION].depthSensingUsage;
4708
+ }
4709
+ get depthDataFormat() {
4710
+ return this[P_SESSION].depthSensingDataFormat;
4711
+ }
4560
4712
  updateRenderState(state = {}) {
4561
4713
  var _a, _b, _c, _d;
4562
4714
  if (this[P_SESSION].ended) {
@@ -6039,7 +6191,7 @@
6039
6191
  }
6040
6192
  }
6041
6193
 
6042
- const VERSION = "2.2.0";
6194
+ const VERSION = "2.2.1";
6043
6195
 
6044
6196
  /**
6045
6197
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -10134,6 +10286,7 @@ void main() {
10134
10286
  exports.P_ACTION_RECORDER = P_ACTION_RECORDER;
10135
10287
  exports.P_ANCHOR = P_ANCHOR;
10136
10288
  exports.P_CONTROLLER = P_CONTROLLER;
10289
+ exports.P_DEPTH_INFO = P_DEPTH_INFO;
10137
10290
  exports.P_DEVICE = P_DEVICE;
10138
10291
  exports.P_FRAME = P_FRAME;
10139
10292
  exports.P_GAMEPAD = P_GAMEPAD;
@@ -10160,6 +10313,7 @@ void main() {
10160
10313
  exports.RemoteControlInterface = RemoteControlInterface;
10161
10314
  exports.XRAnchor = XRAnchor;
10162
10315
  exports.XRAnchorSet = XRAnchorSet;
10316
+ exports.XRCPUDepthInformation = XRCPUDepthInformation;
10163
10317
  exports.XRDevice = XRDevice;
10164
10318
  exports.XRFrame = XRFrame;
10165
10319
  exports.XRHand = XRHand;