@woosh/meep-engine 3.34.0 → 3.36.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 (161) hide show
  1. package/package.json +1 -1
  2. package/src/engine/Engine.d.ts +2 -0
  3. package/src/engine/Engine.d.ts.map +1 -1
  4. package/src/engine/Engine.js +5 -1
  5. package/src/engine/input/devices/XRInputDevice.d.ts +63 -0
  6. package/src/engine/input/devices/XRInputDevice.d.ts.map +1 -0
  7. package/src/engine/input/devices/XRInputDevice.js +386 -0
  8. package/src/engine/input/devices/xr/XRInputAction.d.ts +37 -0
  9. package/src/engine/input/devices/xr/XRInputAction.d.ts.map +1 -0
  10. package/src/engine/input/devices/xr/XRInputAction.js +85 -0
  11. package/src/engine/input/devices/xr/XRInputButton.d.ts +28 -0
  12. package/src/engine/input/devices/xr/XRInputButton.d.ts.map +1 -0
  13. package/src/engine/input/devices/xr/XRInputButton.js +43 -0
  14. package/src/engine/input/devices/xr/XRInputCoordinates.d.ts +15 -0
  15. package/src/engine/input/devices/xr/XRInputCoordinates.d.ts.map +1 -0
  16. package/src/engine/input/devices/xr/XRInputCoordinates.js +21 -0
  17. package/src/engine/input/devices/xr/XRInputHandle.d.ts +63 -0
  18. package/src/engine/input/devices/xr/XRInputHandle.d.ts.map +1 -0
  19. package/src/engine/input/devices/xr/XRInputHandle.js +171 -0
  20. package/src/engine/input/devices/xr/XRInputPose.d.ts +23 -0
  21. package/src/engine/input/devices/xr/XRInputPose.d.ts.map +1 -0
  22. package/src/engine/input/devices/xr/XRInputPose.js +36 -0
  23. package/src/engine/input/devices/xr/XRInputTypes.d.ts +76 -0
  24. package/src/engine/input/devices/xr/XRInputTypes.d.ts.map +1 -0
  25. package/src/engine/input/devices/xr/XRInputTypes.js +31 -0
  26. package/src/engine/input/devices/xr/XRInputValueSource.d.ts +11 -0
  27. package/src/engine/input/devices/xr/XRInputValueSource.d.ts.map +1 -0
  28. package/src/engine/input/devices/xr/XRInputValueSource.js +11 -0
  29. package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.d.ts +15 -1
  30. package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.d.ts.map +1 -1
  31. package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.js +9 -0
  32. package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.d.ts +15 -4
  33. package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.d.ts.map +1 -1
  34. package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.js +22 -0
  35. package/src/engine/input/ecs/ism/coordinate/InputCoordinateSwitches.d.ts +17 -2
  36. package/src/engine/input/ecs/ism/coordinate/InputCoordinateSwitches.d.ts.map +1 -1
  37. package/src/engine/input/ecs/ism/device/GamepadInputDeviceAdapter.d.ts +5 -0
  38. package/src/engine/input/ecs/ism/device/GamepadInputDeviceAdapter.d.ts.map +1 -1
  39. package/src/engine/input/ecs/ism/device/InputDeviceAdapter.d.ts +2 -0
  40. package/src/engine/input/ecs/ism/device/InputDeviceAdapter.d.ts.map +1 -1
  41. package/src/engine/input/ecs/ism/device/InputDeviceAdapter.js +2 -0
  42. package/src/engine/input/ecs/ism/device/KeyboardInputDeviceAdapter.d.ts +7 -0
  43. package/src/engine/input/ecs/ism/device/KeyboardInputDeviceAdapter.d.ts.map +1 -1
  44. package/src/engine/input/ecs/ism/device/ManualInputDeviceAdapter.d.ts +5 -0
  45. package/src/engine/input/ecs/ism/device/ManualInputDeviceAdapter.d.ts.map +1 -1
  46. package/src/engine/input/ecs/ism/device/PointerInputDeviceAdapter.d.ts +5 -0
  47. package/src/engine/input/ecs/ism/device/PointerInputDeviceAdapter.d.ts.map +1 -1
  48. package/src/engine/input/ecs/ism/device/XRInputDeviceAdapter.d.ts +16 -0
  49. package/src/engine/input/ecs/ism/device/XRInputDeviceAdapter.d.ts.map +1 -0
  50. package/src/engine/input/ecs/ism/device/XRInputDeviceAdapter.js +54 -0
  51. package/src/engine/input/ecs/ism/device/XR_INPUT_DEVICE_IDS.d.ts +9 -0
  52. package/src/engine/input/ecs/ism/device/XR_INPUT_DEVICE_IDS.d.ts.map +1 -0
  53. package/src/engine/input/ecs/ism/device/XR_INPUT_DEVICE_IDS.js +12 -0
  54. package/src/engine/input/ecs/ism/trigger/InputTrigger.d.ts +11 -1
  55. package/src/engine/input/ecs/ism/trigger/InputTrigger.d.ts.map +1 -1
  56. package/src/engine/input/ecs/ism/trigger/InputTrigger.js +7 -0
  57. package/src/engine/input/ecs/ism/trigger/InputTriggerChord.d.ts +16 -2
  58. package/src/engine/input/ecs/ism/trigger/InputTriggerChord.d.ts.map +1 -1
  59. package/src/engine/input/ecs/ism/trigger/InputTriggerHold.d.ts +22 -2
  60. package/src/engine/input/ecs/ism/trigger/InputTriggerHold.d.ts.map +1 -1
  61. package/src/engine/input/ecs/ism/trigger/InputTriggerRelease.d.ts +16 -2
  62. package/src/engine/input/ecs/ism/trigger/InputTriggerRelease.d.ts.map +1 -1
  63. package/src/engine/input/ecs/ism/trigger/InputTriggerSequence.d.ts +24 -4
  64. package/src/engine/input/ecs/ism/trigger/InputTriggerSequence.d.ts.map +1 -1
  65. package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.d.ts +6 -8
  66. package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.d.ts.map +1 -1
  67. package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.js +5 -0
  68. package/src/engine/input/ecs/ism/trigger/InputTriggerXRButton.d.ts +7 -0
  69. package/src/engine/input/ecs/ism/trigger/InputTriggerXRButton.d.ts.map +1 -0
  70. package/src/engine/input/ecs/ism/trigger/InputTriggerXRButton.js +15 -0
  71. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  72. package/src/shade/device/timing/profile/GPUProfileSession.d.ts +25 -11
  73. package/src/shade/device/timing/profile/GPUProfileSession.d.ts.map +1 -1
  74. package/src/shade/device/timing/profile/GPUProfileSession.js +553 -474
  75. package/src/shade/playground/avboit/main.d.ts.map +1 -1
  76. package/src/shade/playground/avboit/main.js +888 -916
  77. package/src/shade/playground/particle_ecs/README.md +13 -7
  78. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +5 -5
  79. package/src/shade/playground/particle_ecs/bonfire_effects.js +5 -5
  80. package/src/shade/playground/particle_ecs/effects/smoke.json +1859 -1859
  81. package/src/shade/playground/particle_ecs/effects/soot.json +1605 -1605
  82. package/src/shade/playground/particle_system/README.md +1 -2
  83. package/src/shade/playground/profile_hotkey.d.ts.map +1 -1
  84. package/src/shade/playground/profile_hotkey.js +4 -40
  85. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  86. package/src/shade/playground/skinned_blas_refit/main.js +4 -39
  87. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  88. package/src/shade/playground/volumetrics_froxel/main.js +4 -39
  89. package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -1
  90. package/src/shade/playground/volumetrics_froxel/measure.js +2 -4
  91. package/src/shade/renderer/Renderer.d.ts +1 -1
  92. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  93. package/src/shade/renderer/Renderer.js +3 -1
  94. package/src/shade/renderer/light/GPULightCollection.d.ts +9 -1
  95. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  96. package/src/shade/renderer/light/GPULightCollection.js +41 -0
  97. package/src/shade/renderer/light/environment/shader_project_environment_sh.d.ts +37 -0
  98. package/src/shade/renderer/light/environment/shader_project_environment_sh.d.ts.map +1 -0
  99. package/src/shade/renderer/light/environment/shader_project_environment_sh.js +105 -0
  100. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  101. package/src/shade/renderer/particles/DESIGN.md +65 -8
  102. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +7 -1
  103. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  104. package/src/shade/renderer/particles/GPUParticleSystem.js +1247 -1244
  105. package/src/shade/renderer/particles/graph_particles_avboit.d.ts +7 -1
  106. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  107. package/src/shade/renderer/particles/graph_particles_avboit.js +9 -0
  108. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts.map +1 -1
  109. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +4 -2
  110. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +15 -9
  111. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts.map +1 -1
  112. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +29 -11
  113. package/src/shade/renderer/particles/shaders/chunk_particle_lighting_model.d.ts +24 -0
  114. package/src/shade/renderer/particles/shaders/chunk_particle_lighting_model.d.ts.map +1 -0
  115. package/src/shade/renderer/particles/shaders/chunk_particle_lighting_model.js +45 -0
  116. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +3 -0
  117. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts.map +1 -1
  118. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +38 -0
  119. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
  120. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +190 -185
  121. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +8 -0
  122. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  123. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +5 -0
  124. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +8 -1
  125. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  126. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +9 -0
  127. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +13 -3
  128. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  129. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +9 -1
  130. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts +39 -0
  131. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts.map +1 -0
  132. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.js +107 -0
  133. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts +15 -0
  134. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.d.ts.map +1 -0
  135. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.js +44 -0
  136. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +19 -0
  137. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts.map +1 -0
  138. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +48 -0
  139. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +29 -0
  140. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts.map +1 -0
  141. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +90 -0
  142. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.d.ts +10 -0
  143. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.d.ts.map +1 -0
  144. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_brick4.js +55 -0
  145. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.d.ts +10 -0
  146. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.d.ts.map +1 -0
  147. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_ibl.js +47 -0
  148. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.d.ts +10 -0
  149. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.d.ts.map +1 -0
  150. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi_lpv.js +63 -0
  151. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts +17 -0
  152. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.d.ts.map +1 -0
  153. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.js +26 -0
  154. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +8 -1
  155. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  156. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +50 -2
  157. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  158. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +488 -436
  159. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +1 -1
  160. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  161. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +254 -63
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Advanced 3D game engine",
7
7
  "type": "module",
8
8
  "author": "Alexander Goldring",
9
- "version": "3.34.0",
9
+ "version": "3.36.0",
10
10
  "exports": {
11
11
  "./build/*": "./build/*",
12
12
  "./src/*": "./src/*",
@@ -114,6 +114,7 @@ declare class Engine {
114
114
  pointer: PointerDevice;
115
115
  keyboard: KeyboardDevice;
116
116
  gamepad: GamepadDevice;
117
+ xr: XRInputDevice;
117
118
  };
118
119
  /**
119
120
  * Toggles GraphicsEngine rendering on and off
@@ -179,6 +180,7 @@ import SceneManager from "./scene/SceneManager.js";
179
180
  import { PointerDevice } from "./input/devices/PointerDevice.js";
180
181
  import KeyboardDevice from "./input/devices/KeyboardDevice.js";
181
182
  import { GamepadDevice } from "./input/devices/GamepadDevice.js";
183
+ import { XRInputDevice } from "./input/devices/XRInputDevice.js";
182
184
  import EmptyView from "../view/elements/EmptyView.js";
183
185
  import { AssetPreloader } from "./asset/preloader/AssetPreloader.js";
184
186
  import ObservedBoolean from "../core/model/ObservedBoolean.js";
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../../src/engine/Engine.js"],"names":[],"mappings":";6BAoCa,OAAO,8BAA8B,EAAE,cAAc;AAwClE;IAiGI;;;;;;;;;OASG;IACH,sBARW,cAAc;QAEU,aAAa,GAArC,aAAa;QACK,cAAc,GAAhC,OAAO;QACW,WAAW,GAA7B,OAAO;QACW,KAAK,GAAvB,OAAO;OA+OjB;IApSD;;;OAGG;IACH,UAFU,cAAc,GAAC,IAAI,CAEb;IAEhB;;;OAGG;IACH,OAFU,WAAW,GAAC,IAAI,CAEb;IAEb,qBAA4B;IAE5B;;;;;;;;;OASG;IACH,0BAFU,uBAAuB,CAEe;IAEhD;;;OAGG;IACH,kBAFU,mBAAmB,CAEO;IAEpC;;;;OAIG;IACH,iBAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,mBAFU,kBAAkB,CAEa;IAoBrC;;;OAGG;IACH,UAFU,cAAc,CAEA;IAKxB;;;OAGG;IACH,aAFU,gBAAgB,CAEe;IAGzC,yCAAkE;IAK9D,6BAAkC;IAMtC;;;OAGG;IACH,cAFU,aAAa,MAAM,CAAC,CAK5B;IAEF,8CAiCE;IAgCF;;;OAGG;IACH,SAFU,WAAW,CAEoB;IAEzC;;;OAGG;IACH,oCAA0C;IAE1C;;;OAGG;IACH,sCAFU,2BAA2B,CAE+B;IAEpE,yBAAoC;IAGpC;;OAEG;IACH,aAAkB;IAElB;;;OAGG;IACH,SAFU,OAAO,CAEwB;IAGzC,2BAAsC;IAuCtC;;;OAGG;IACH,KAFU,SAAS,CAEO;IAE1B;;;OAGG;IACH,uBAFU,YAAY,CAEqD;IAI3E;;;;MAIC;IA6BD;;;OAGG;IACH,kBAFU,OAAO,CAEW;IAwIhC,wBAgCC;IApBG,oBAAwB;IAsB5B,2BA8CC;IAED,oBAiBC;IAED;;;OAGG;IACH,+CAUC;IAED,eAkDC;IAED;;;OAGG;IACH,sBAuGC;IAqBD;;OAEG;IACH,sBA+DC;IAED,aAEC;IAED;;OAEG;IACH,4BAOC;IAIL;;;OAGG;IACH,mBAFU,OAAO,CAEQ;;CAPxB;+BA94B8B,+BAA+B;wBAUtC,wBAAwB;0BApBtB,0CAA0C;wCAcN,iDAAiD;oCAG3E,iCAAiC;mBAElD,wBAAwB;+BArBZ,gDAAgD;iCAO9C,+CAA+C;8BAGlD,wBAAwB;6BALzB,yBAAyB;uCAIf,6DAA6D;4BASxE,0BAA0B;+BApBvB,iCAAiC;4CAapB,qDAAqD;AAejG;;GAEG;AAGH;IACI,gDAA2D;IAC3D,0BAAkC;IAClC,iCAAyC;CAC5C;6BAtC4B,sCAAsC;sBA2B7C,mBAAmB;yBAJhB,yBAAyB;8BALpB,kCAAkC;2BADrC,mCAAmC;8BADhC,kCAAkC;sBAZ1C,+BAA+B;+BAKtB,qCAAqC;4BAPxC,kCAAkC;oBAH1C,yBAAyB"}
1
+ {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../../src/engine/Engine.js"],"names":[],"mappings":";6BAqCa,OAAO,8BAA8B,EAAE,cAAc;AAwClE;IAiGI;;;;;;;;;OASG;IACH,sBARW,cAAc;QAEU,aAAa,GAArC,aAAa;QACK,cAAc,GAAhC,OAAO;QACW,WAAW,GAA7B,OAAO;QACW,KAAK,GAAvB,OAAO;OAiPjB;IAtSD;;;OAGG;IACH,UAFU,cAAc,GAAC,IAAI,CAEb;IAEhB;;;OAGG;IACH,OAFU,WAAW,GAAC,IAAI,CAEb;IAEb,qBAA4B;IAE5B;;;;;;;;;OASG;IACH,0BAFU,uBAAuB,CAEe;IAEhD;;;OAGG;IACH,kBAFU,mBAAmB,CAEO;IAEpC;;;;OAIG;IACH,iBAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,mBAFU,kBAAkB,CAEa;IAoBrC;;;OAGG;IACH,UAFU,cAAc,CAEA;IAKxB;;;OAGG;IACH,aAFU,gBAAgB,CAEe;IAGzC,yCAAkE;IAK9D,6BAAkC;IAMtC;;;OAGG;IACH,cAFU,aAAa,MAAM,CAAC,CAK5B;IAEF,8CAiCE;IAgCF;;;OAGG;IACH,SAFU,WAAW,CAEoB;IAEzC;;;OAGG;IACH,oCAA0C;IAE1C;;;OAGG;IACH,sCAFU,2BAA2B,CAE+B;IAEpE,yBAAoC;IAGpC;;OAEG;IACH,aAAkB;IAElB;;;OAGG;IACH,SAFU,OAAO,CAEwB;IAGzC,2BAAsC;IAuCtC;;;OAGG;IACH,KAFU,SAAS,CAEO;IAE1B;;;OAGG;IACH,uBAFU,YAAY,CAEqD;IAI3E;;;;;MAKC;IA8BD;;;OAGG;IACH,kBAFU,OAAO,CAEW;IAwIhC,wBAgCC;IApBG,oBAAwB;IAsB5B,2BA8CC;IAED,oBAiBC;IAED;;;OAGG;IACH,+CAUC;IAED,eAkDC;IAED;;;OAGG;IACH,sBAuGC;IAqBD;;OAEG;IACH,sBAgEC;IAED,aAEC;IAED;;OAEG;IACH,4BAOC;IAIL;;;OAGG;IACH,mBAFU,OAAO,CAEQ;;CAPxB;+BAl5B8B,+BAA+B;wBAWtC,wBAAwB;0BArBtB,0CAA0C;wCAeN,iDAAiD;oCAG3E,iCAAiC;mBAElD,wBAAwB;+BAtBZ,gDAAgD;iCAO9C,+CAA+C;8BAGlD,wBAAwB;6BALzB,yBAAyB;uCAIf,6DAA6D;4BAUxE,0BAA0B;+BArBvB,iCAAiC;4CAapB,qDAAqD;AAgBjG;;GAEG;AAGH;IACI,gDAA2D;IAC3D,0BAAkC;IAClC,iCAAyC;CAC5C;6BAvC4B,sCAAsC;sBA4B7C,mBAAmB;yBAJhB,yBAAyB;8BALpB,kCAAkC;2BADrC,mCAAmC;8BAFhC,kCAAkC;8BAClC,kCAAkC;sBAb1C,+BAA+B;+BAKtB,qCAAqC;4BAPxC,kCAAkC;oBAH1C,yBAAyB"}
@@ -21,6 +21,7 @@ import { EntityManager } from "./ecs/EntityManager.js";
21
21
  import { BinarySerializationRegistry } from "./ecs/storage/binary/BinarySerializationRegistry.js";
22
22
  import { GraphicsEngine } from './graphics3/GraphicsEngine.js';
23
23
  import { GamepadDevice } from "./input/devices/GamepadDevice.js";
24
+ import { XRInputDevice } from "./input/devices/XRInputDevice.js";
24
25
  import KeyboardDevice from "./input/devices/KeyboardDevice.js";
25
26
  import { PointerDevice } from "./input/devices/PointerDevice.js";
26
27
  import { StaticKnowledgeDatabase, StaticKnowledgeState } from "./knowledge/database/StaticKnowledgeDatabase.js";
@@ -379,12 +380,14 @@ class Engine {
379
380
  this.devices = {
380
381
  pointer: new PointerDevice(this.viewStack.el),
381
382
  keyboard: new KeyboardDevice(this.viewStack.el),
382
- gamepad: new GamepadDevice()
383
+ gamepad: new GamepadDevice(),
384
+ xr: new XRInputDevice()
383
385
  };
384
386
 
385
387
  this.devices.pointer.start();
386
388
  this.devices.keyboard.start();
387
389
  this.devices.gamepad.start();
390
+ this.devices.xr.start();
388
391
 
389
392
  /*
390
393
  Only the focused element receives keyboard events. `ViewStack` sets `tabindex` on its
@@ -869,6 +872,7 @@ class Engine {
869
872
  this.devices.pointer.stop();
870
873
  this.devices.keyboard.stop();
871
874
  this.devices.gamepad.stop();
875
+ this.devices.xr.stop();
872
876
 
873
877
  // shutdown entity manager
874
878
  if (!this.__using_external_entity_manager) {
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Session-owned WebXR input. Safe to construct/start without a browser, XR support, or hardware.
3
+ * This device never requests a session or schedules frames. The application owns both:
4
+ *
5
+ * @example
6
+ * engine.devices.xr.setSession(session, referenceSpace);
7
+ * // In the session's requestAnimationFrame callback, before gameplay reads input:
8
+ * engine.devices.xr.poll(frame);
9
+ * // Ordinary Vector1 and Signal bindings, valid even before a session exists:
10
+ * engine.devices.xr.right.select.onChanged.add(amount => { });
11
+ * engine.devices.xr.right.select.completed.add(() => { });
12
+ *
13
+ * left/right/none are stable slots, each retaining the oldest available source of that handedness.
14
+ * sources contains every live source, keyed internally by native object identity (never gamepad.index).
15
+ * A slot swap neutralises its old controls and cancels unfinished actions before adopting new hardware.
16
+ * Completed actions are not cancelled. Binding a slot midway through an action does not replay it.
17
+ *
18
+ * Lifecycle changes requested by signal handlers take effect after the current update. This keeps a
19
+ * stop/session replacement from being overwritten by the remainder of that update. Native frames are
20
+ * consumed synchronously and never retained. Recursive poll calls are ignored.
21
+ */
22
+ export class XRInputDevice {
23
+ /** @readonly */
24
+ readonly left: XRInputHandle;
25
+ /** @readonly */
26
+ readonly right: XRInputHandle;
27
+ /** @readonly */
28
+ readonly none: XRInputHandle;
29
+ /** @readonly @type {XRInputHandle[]} Read only; membership is owned by the device. */
30
+ readonly sources: XRInputHandle[];
31
+ /** @readonly */
32
+ readonly on: {
33
+ /** @type {Signal} Dispatches the connected XRInputHandle. */
34
+ connected: Signal;
35
+ /** @type {Signal} Dispatches the XRInputHandle, already neutral and detached. */
36
+ disconnected: Signal;
37
+ };
38
+ /** @readonly @type {import('./xr/XRInputTypes.js').XRSession|null} Change through setSession. */
39
+ readonly session: import('./xr/XRInputTypes.js').XRSession | null;
40
+ /** @readonly @type {EventTarget|null} Change through setReferenceSpace. */
41
+ readonly referenceSpace: EventTarget | null;
42
+ get isRunning(): boolean;
43
+ start(): void;
44
+ /** Detach without ending the application's native XRSession. */
45
+ stop(): void;
46
+ /**
47
+ * May be called before start. Null detaches; attaching does not request permission or own session.end().
48
+ * @param {import('./xr/XRInputTypes.js').XRSession|null} session
49
+ * @param {EventTarget|null} [referenceSpace=null] Null still samples controls, with invalid poses.
50
+ */
51
+ setSession(session: import('./xr/XRInputTypes.js').XRSession | null, referenceSpace?: EventTarget | null): void;
52
+ /** @param {EventTarget|null} referenceSpace */
53
+ setReferenceSpace(referenceSpace: EventTarget | null): void;
54
+ /**
55
+ * No-op without a running session. Otherwise call only within that session's active frame callback.
56
+ * @param {import('./xr/XRInputTypes.js').XRFrame} [frame]
57
+ */
58
+ poll(frame?: import('./xr/XRInputTypes.js').XRFrame): void;
59
+ #private;
60
+ }
61
+ import { XRInputHandle } from "./xr/XRInputHandle.js";
62
+ import Signal from "../../../core/events/signal/Signal.js";
63
+ //# sourceMappingURL=XRInputDevice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"XRInputDevice.d.ts","sourceRoot":"","sources":["../../../../../src/engine/input/devices/XRInputDevice.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IACI,gBAAgB;IAChB,6BAA2B;IAC3B,gBAAgB;IAChB,8BAA4B;IAC5B,gBAAgB;IAChB,6BAA2B;IAC3B,sFAAsF;IACtF,kBADqB,aAAa,EAAE,CACvB;IACb,gBAAgB;IAChB;QACI,6DAA6D;mBAAlD,MAAM;QAEjB,iFAAiF;sBAAtE,MAAM;MAEnB;IAOF,iGAAiG;IACjG,kBADqB,OAAO,sBAAsB,EAAE,SAAS,GAAC,IAAI,CACnD;IACf,2EAA2E;IAC3E,yBADqB,WAAW,GAAC,IAAI,CACf;IAOtB,yBAAyC;IAEzC,cAiBC;IAED,gEAAgE;IAChE,aAYC;IAED;;;;OAIG;IACH,oBAHW,OAAO,sBAAsB,EAAE,SAAS,GAAC,IAAI,mBAC7C,WAAW,GAAC,IAAI,QA4B1B;IAED,+CAA+C;IAC/C,kCADY,WAAW,GAAC,IAAI,QAuB3B;IAED;;;OAGG;IACH,aAFW,OAAO,sBAAsB,EAAE,OAAO,QAehD;;CAsNJ;8BA/X6B,uBAAuB;mBADlC,uCAAuC"}
@@ -0,0 +1,386 @@
1
+ import { assert } from "../../../core/assert.js";
2
+ import Signal from "../../../core/events/signal/Signal.js";
3
+ import { XRInputHandle } from "./xr/XRInputHandle.js";
4
+
5
+ const SESSION_EVENTS = ['inputsourceschange', 'selectstart', 'select', 'selectend',
6
+ 'squeezestart', 'squeeze', 'squeezeend', 'visibilitychange', 'end'];
7
+
8
+ /**
9
+ * Session-owned WebXR input. Safe to construct/start without a browser, XR support, or hardware.
10
+ * This device never requests a session or schedules frames. The application owns both:
11
+ *
12
+ * @example
13
+ * engine.devices.xr.setSession(session, referenceSpace);
14
+ * // In the session's requestAnimationFrame callback, before gameplay reads input:
15
+ * engine.devices.xr.poll(frame);
16
+ * // Ordinary Vector1 and Signal bindings, valid even before a session exists:
17
+ * engine.devices.xr.right.select.onChanged.add(amount => { });
18
+ * engine.devices.xr.right.select.completed.add(() => { });
19
+ *
20
+ * left/right/none are stable slots, each retaining the oldest available source of that handedness.
21
+ * sources contains every live source, keyed internally by native object identity (never gamepad.index).
22
+ * A slot swap neutralises its old controls and cancels unfinished actions before adopting new hardware.
23
+ * Completed actions are not cancelled. Binding a slot midway through an action does not replay it.
24
+ *
25
+ * Lifecycle changes requested by signal handlers take effect after the current update. This keeps a
26
+ * stop/session replacement from being overwritten by the remainder of that update. Native frames are
27
+ * consumed synchronously and never retained. Recursive poll calls are ignored.
28
+ */
29
+ export class XRInputDevice {
30
+ /** @readonly */
31
+ left = new XRInputHandle();
32
+ /** @readonly */
33
+ right = new XRInputHandle();
34
+ /** @readonly */
35
+ none = new XRInputHandle();
36
+ /** @readonly @type {XRInputHandle[]} Read only; membership is owned by the device. */
37
+ sources = [];
38
+ /** @readonly */
39
+ on = {
40
+ /** @type {Signal} Dispatches the connected XRInputHandle. */
41
+ connected: new Signal(),
42
+ /** @type {Signal} Dispatches the XRInputHandle, already neutral and detached. */
43
+ disconnected: new Signal()
44
+ };
45
+
46
+ #slots = [this.left, this.right, this.none];
47
+ /** @type {Map<import('./xr/XRInputTypes.js').XRInputSource, XRInputHandle>} */
48
+ #handles = new Map();
49
+ /** @type {XRInputHandle[]} */
50
+ #connected = [];
51
+ /** @readonly @type {import('./xr/XRInputTypes.js').XRSession|null} Change through setSession. */
52
+ session = null;
53
+ /** @readonly @type {EventTarget|null} Change through setReferenceSpace. */
54
+ referenceSpace = null;
55
+ #running = false;
56
+ #busy = false;
57
+ #draining = false;
58
+ /** @type {Array<()=>void>} Only reentrant configuration changes are queued, never frames. */
59
+ #pending = [];
60
+
61
+ get isRunning() { return this.#running; }
62
+
63
+ start() {
64
+ if (this.#busy) {
65
+ this.#pending.push(() => this.start());
66
+ return;
67
+ }
68
+ if (this.#running) {
69
+ return;
70
+ }
71
+ this.#busy = true;
72
+ try {
73
+ this.#running = true;
74
+ this.#listen(true);
75
+ this.#reconcile();
76
+ this.#sample(null);
77
+ } finally {
78
+ this.#finish();
79
+ }
80
+ }
81
+
82
+ /** Detach without ending the application's native XRSession. */
83
+ stop() {
84
+ if (this.#busy) {
85
+ this.#pending.push(() => this.stop());
86
+ return;
87
+ }
88
+ this.#busy = true;
89
+ try {
90
+ this.#detach();
91
+ this.#running = false;
92
+ } finally {
93
+ this.#finish();
94
+ }
95
+ }
96
+
97
+ /**
98
+ * May be called before start. Null detaches; attaching does not request permission or own session.end().
99
+ * @param {import('./xr/XRInputTypes.js').XRSession|null} session
100
+ * @param {EventTarget|null} [referenceSpace=null] Null still samples controls, with invalid poses.
101
+ */
102
+ setSession(session, referenceSpace = null) {
103
+ assert.defined(session, 'session');
104
+ if (session === null) {
105
+ referenceSpace = null;
106
+ }
107
+ if (this.#busy) {
108
+ this.#pending.push(() => this.setSession(session, referenceSpace));
109
+ return;
110
+ }
111
+ if (session === this.session) {
112
+ this.setReferenceSpace(referenceSpace);
113
+ return;
114
+ }
115
+ this.#busy = true;
116
+ try {
117
+ this.#detach();
118
+ this.session = session;
119
+ this.referenceSpace = session === null ? null : referenceSpace;
120
+ if (this.#running) {
121
+ this.#listen(true);
122
+ this.#reconcile();
123
+ this.#sample(null);
124
+ }
125
+ } finally {
126
+ this.#finish();
127
+ }
128
+ }
129
+
130
+ /** @param {EventTarget|null} referenceSpace */
131
+ setReferenceSpace(referenceSpace) {
132
+ assert.defined(referenceSpace, 'referenceSpace');
133
+ if (this.#busy) {
134
+ this.#pending.push(() => this.setReferenceSpace(referenceSpace));
135
+ return;
136
+ }
137
+ if (referenceSpace === this.referenceSpace) {
138
+ return;
139
+ }
140
+ this.#busy = true;
141
+ try {
142
+ if (this.referenceSpace !== null && this.#running) {
143
+ this.referenceSpace.removeEventListener('reset', this.#onReset);
144
+ }
145
+ this.referenceSpace = referenceSpace;
146
+ if (referenceSpace !== null && this.#running) {
147
+ referenceSpace.addEventListener('reset', this.#onReset);
148
+ }
149
+ this.#invalidatePoses();
150
+ } finally {
151
+ this.#finish();
152
+ }
153
+ }
154
+
155
+ /**
156
+ * No-op without a running session. Otherwise call only within that session's active frame callback.
157
+ * @param {import('./xr/XRInputTypes.js').XRFrame} [frame]
158
+ */
159
+ poll(frame) {
160
+ if (!this.#running || this.session === null || this.#busy) {
161
+ return;
162
+ }
163
+ assert.defined(frame, 'frame');
164
+ assert.equal(frame.session, this.session, 'frame.session');
165
+ this.#busy = true;
166
+ try {
167
+ this.#reconcile();
168
+ this.#sample(frame);
169
+ } finally {
170
+ this.#finish();
171
+ }
172
+ }
173
+
174
+ /** @param {boolean} add */
175
+ #listen(add) {
176
+ const method = add ? 'addEventListener' : 'removeEventListener';
177
+ if (this.session !== null) {
178
+ for (let i = 0; i < SESSION_EVENTS.length; i++) {
179
+ this.session[method](SESSION_EVENTS[i], this.#onEvent);
180
+ }
181
+ }
182
+ if (this.referenceSpace !== null) {
183
+ this.referenceSpace[method]('reset', this.#onReset);
184
+ }
185
+ }
186
+
187
+ #detach() {
188
+ this.#listen(false);
189
+ this.session = null;
190
+ this.referenceSpace = null;
191
+ this.#clear();
192
+ for (let i = 0; i < this.#slots.length; i++) {
193
+ this.#slots[i].bind(null);
194
+ }
195
+ while (this.sources.length > 0) {
196
+ const handle = this.sources.pop();
197
+ this.#handles.delete(handle.nativeSource);
198
+ handle.bind(null);
199
+ this.on.disconnected.send1(handle);
200
+ }
201
+ this.#connected.length = 0;
202
+ }
203
+
204
+ /** @param {import('./xr/XRInputTypes.js').XRInputSource} source */
205
+ #contains(source) {
206
+ const sources = this.session.inputSources;
207
+ for (let i = 0; i < sources.length; i++) {
208
+ if (sources[i] === source) {
209
+ return true;
210
+ }
211
+ }
212
+ return false;
213
+ }
214
+
215
+ #reconcile() {
216
+ if (this.session === null) {
217
+ return;
218
+ }
219
+ for (let i = this.sources.length - 1; i >= 0; i--) {
220
+ const handle = this.sources[i];
221
+ const source = handle.nativeSource;
222
+ if (!this.#contains(source)) {
223
+ this.sources.splice(i, 1);
224
+ this.#handles.delete(source);
225
+ for (let j = 0; j < this.#slots.length; j++) {
226
+ if (this.#slots[j].nativeSource === source) {
227
+ this.#slots[j].bind(null);
228
+ }
229
+ }
230
+ handle.bind(null);
231
+ this.on.disconnected.send1(handle);
232
+ }
233
+ }
234
+ const sources = this.session.inputSources;
235
+ for (let i = 0; i < sources.length; i++) {
236
+ const source = sources[i];
237
+ if (!this.#handles.has(source)) {
238
+ const handle = new XRInputHandle();
239
+ handle.bind(source);
240
+ this.#handles.set(source, handle);
241
+ this.sources.push(handle);
242
+ this.#connected.push(handle);
243
+ }
244
+ }
245
+ this.#bindSlot(this.left, 'left');
246
+ this.#bindSlot(this.right, 'right');
247
+ this.#bindSlot(this.none, 'none');
248
+ }
249
+
250
+ /** @param {XRInputHandle} slot @param {string} handedness */
251
+ #bindSlot(slot, handedness) {
252
+ if (slot.connected) {
253
+ return;
254
+ }
255
+ for (let i = 0; i < this.sources.length; i++) {
256
+ const source = this.sources[i].nativeSource;
257
+ if (source.handedness === handedness) {
258
+ slot.bind(source);
259
+ return;
260
+ }
261
+ }
262
+ }
263
+
264
+ /** @param {import('./xr/XRInputTypes.js').XRFrame|null} frame */
265
+ #sample(frame) {
266
+ if (this.session !== null && this.session.visibilityState === 'visible') {
267
+ for (let i = 0; i < this.sources.length; i++) {
268
+ this.sources[i].sample(frame, this.referenceSpace);
269
+ }
270
+ for (let i = 0; i < this.#slots.length; i++) {
271
+ this.#slots[i].sample(frame, this.referenceSpace);
272
+ }
273
+ this.#flush();
274
+ } else {
275
+ this.#clear();
276
+ }
277
+ for (let i = 0; i < this.#connected.length; i++) {
278
+ this.on.connected.send1(this.#connected[i]);
279
+ }
280
+ this.#connected.length = 0;
281
+ }
282
+
283
+ #clear() {
284
+ for (let i = 0; i < this.sources.length; i++) {
285
+ this.sources[i].clear();
286
+ }
287
+ for (let i = 0; i < this.#slots.length; i++) {
288
+ this.#slots[i].clear();
289
+ }
290
+ this.#flush();
291
+ }
292
+
293
+ #flush() {
294
+ for (let i = 0; i < this.sources.length; i++) {
295
+ this.sources[i].flush();
296
+ }
297
+ for (let i = 0; i < this.#slots.length; i++) {
298
+ this.#slots[i].flush();
299
+ }
300
+ }
301
+
302
+ #invalidatePoses() {
303
+ for (let i = 0; i < this.sources.length; i++) {
304
+ this.sources[i].invalidatePoses();
305
+ }
306
+ for (let i = 0; i < this.#slots.length; i++) {
307
+ this.#slots[i].invalidatePoses();
308
+ }
309
+ }
310
+
311
+ #onReset = () => {
312
+ if (this.#busy) {
313
+ this.#pending.push(() => this.#onReset());
314
+ return;
315
+ }
316
+ this.#busy = true;
317
+ try {
318
+ this.#invalidatePoses();
319
+ } finally {
320
+ this.#finish();
321
+ }
322
+ };
323
+
324
+ /** @param {import('./xr/XRInputTypes.js').XRSessionInputEvent} event */
325
+ #onEvent = (event) => {
326
+ if (!this.#running || event.currentTarget !== this.session || this.#busy) {
327
+ return;
328
+ }
329
+ this.#busy = true;
330
+ try {
331
+ if (event.type === 'end') {
332
+ this.#detach();
333
+ return;
334
+ }
335
+ this.#reconcile();
336
+ const frame = event.frame === undefined ? null : event.frame;
337
+ if (frame !== null && frame.session !== this.session) {
338
+ return;
339
+ }
340
+ this.#sample(frame);
341
+ if (this.session.visibilityState !== 'visible' || event.inputSource === undefined) {
342
+ return;
343
+ }
344
+ const handle = this.#handles.get(event.inputSource);
345
+ if (handle === undefined) {
346
+ return;
347
+ }
348
+ this.#actionEvent(handle, event.type);
349
+ for (let i = 0; i < this.#slots.length; i++) {
350
+ const slot = this.#slots[i];
351
+ if (slot.nativeSource === event.inputSource) {
352
+ this.#actionEvent(slot, event.type);
353
+ }
354
+ }
355
+ } finally {
356
+ this.#finish();
357
+ }
358
+ };
359
+
360
+ /** @param {XRInputHandle} handle @param {string} type */
361
+ #actionEvent(handle, type) {
362
+ switch (type) {
363
+ case 'selectstart': handle.select.begin(); break;
364
+ case 'select': handle.select.complete(); break;
365
+ case 'selectend': handle.select.end(); break;
366
+ case 'squeezestart': handle.squeeze.begin(); break;
367
+ case 'squeeze': handle.squeeze.complete(); break;
368
+ case 'squeezeend': handle.squeeze.end(); break;
369
+ }
370
+ }
371
+
372
+ #finish() {
373
+ this.#busy = false;
374
+ if (this.#draining) {
375
+ return;
376
+ }
377
+ this.#draining = true;
378
+ try {
379
+ while (this.#pending.length > 0) {
380
+ this.#pending.shift()();
381
+ }
382
+ } finally {
383
+ this.#draining = false;
384
+ }
385
+ }
386
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Observable amount of a select/squeeze action, in [0, 1]. Read x and subscribe to onChanged as with
3
+ * any Vector1. The device owns mutation. Scalar changes never manufacture an action outcome.
4
+ *
5
+ * Completion/cancellation describe a browser interaction, independently of the amount. There is no
6
+ * public up/down state or inferred threshold. The private lifecycle only pairs native events so an
7
+ * interrupted interaction is cancelled once and an already completed one is never cancelled.
8
+ */
9
+ export class XRInputAction extends Vector1 {
10
+ /** @readonly @type {Signal} No arguments. */
11
+ readonly completed: Signal;
12
+ /** @readonly @type {Signal} No arguments. */
13
+ readonly cancelled: Signal;
14
+ /** @type {XRInputValueSource} Do not modify directly. */
15
+ valueSource: XRInputValueSource;
16
+ /**
17
+ * @internal
18
+ * @param {XRInputValueSource} source
19
+ * @param {number} value
20
+ */
21
+ update(source: XRInputValueSource, value: number): void;
22
+ /** @internal Called only for a native start, never inferred from the amount. */
23
+ begin(): void;
24
+ /** @internal A completion without an observed start is not replayed after a rebind/interruption. */
25
+ complete(): void;
26
+ /** @internal */
27
+ end(): void;
28
+ /** @internal Stage cancellation so the whole handle can become neutral before its notification. */
29
+ reset(): void;
30
+ /** @internal */
31
+ flushCancellation(): void;
32
+ #private;
33
+ }
34
+ import { Vector1 } from "../../../../core/geom/Vector1.js";
35
+ import Signal from "../../../../core/events/signal/Signal.js";
36
+ import { XRInputValueSource } from "./XRInputValueSource.js";
37
+ //# sourceMappingURL=XRInputAction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"XRInputAction.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/input/devices/xr/XRInputAction.js"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH;IACI,6CAA6C;IAC7C,oBADqB,MAAM,CACF;IAEzB,6CAA6C;IAC7C,oBADqB,MAAM,CACF;IAEzB,yDAAyD;IACzD,aADW,kBAAkB,CACgB;IAO7C;;;;OAIG;IACH,eAHW,kBAAkB,SAClB,MAAM,QAKhB;IAED,gFAAgF;IAChF,cAQC;IAED,oGAAoG;IACpG,iBAMC;IAED,gBAAgB;IAChB,YASC;IAED,mGAAmG;IACnG,cAKC;IAED,gBAAgB;IAChB,0BAKC;;CACJ;wBAnFuB,kCAAkC;mBADvC,0CAA0C;mCAE1B,yBAAyB"}
@@ -0,0 +1,85 @@
1
+ import Signal from "../../../../core/events/signal/Signal.js";
2
+ import { Vector1 } from "../../../../core/geom/Vector1.js";
3
+ import { XRInputValueSource } from "./XRInputValueSource.js";
4
+
5
+ /**
6
+ * Observable amount of a select/squeeze action, in [0, 1]. Read x and subscribe to onChanged as with
7
+ * any Vector1. The device owns mutation. Scalar changes never manufacture an action outcome.
8
+ *
9
+ * Completion/cancellation describe a browser interaction, independently of the amount. There is no
10
+ * public up/down state or inferred threshold. The private lifecycle only pairs native events so an
11
+ * interrupted interaction is cancelled once and an already completed one is never cancelled.
12
+ */
13
+ export class XRInputAction extends Vector1 {
14
+ /** @readonly @type {Signal} No arguments. */
15
+ completed = new Signal();
16
+
17
+ /** @readonly @type {Signal} No arguments. */
18
+ cancelled = new Signal();
19
+
20
+ /** @type {XRInputValueSource} Do not modify directly. */
21
+ valueSource = XRInputValueSource.Unavailable;
22
+
23
+ /** 0: idle, 1: awaiting outcome, 2: completed, awaiting native end. */
24
+ #interaction = 0;
25
+
26
+ #cancelled = false;
27
+
28
+ /**
29
+ * @internal
30
+ * @param {XRInputValueSource} source
31
+ * @param {number} value
32
+ */
33
+ update(source, value) {
34
+ this.valueSource = source;
35
+ this.set(source === XRInputValueSource.Gamepad ? value : source === XRInputValueSource.Action && this.#interaction !== 0 ? 1 : 0);
36
+ }
37
+
38
+ /** @internal Called only for a native start, never inferred from the amount. */
39
+ begin() {
40
+ if (this.#interaction !== 0) {
41
+ return;
42
+ }
43
+ this.#interaction = 1;
44
+ if (this.valueSource === XRInputValueSource.Action) {
45
+ this.set(1);
46
+ }
47
+ }
48
+
49
+ /** @internal A completion without an observed start is not replayed after a rebind/interruption. */
50
+ complete() {
51
+ if (this.#interaction !== 1) {
52
+ return;
53
+ }
54
+ this.#interaction = 2;
55
+ this.completed.send0();
56
+ }
57
+
58
+ /** @internal */
59
+ end() {
60
+ const cancelled = this.#interaction === 1;
61
+ this.#interaction = 0;
62
+ if (this.valueSource === XRInputValueSource.Action) {
63
+ this.set(0);
64
+ }
65
+ if (cancelled) {
66
+ this.cancelled.send0();
67
+ }
68
+ }
69
+
70
+ /** @internal Stage cancellation so the whole handle can become neutral before its notification. */
71
+ reset() {
72
+ this.#cancelled = this.#cancelled || this.#interaction === 1;
73
+ this.#interaction = 0;
74
+ this.valueSource = XRInputValueSource.Unavailable;
75
+ this.set(0);
76
+ }
77
+
78
+ /** @internal */
79
+ flushCancellation() {
80
+ if (this.#cancelled) {
81
+ this.#cancelled = false;
82
+ this.cancelled.send0();
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * One raw GamepadButton: its scalar amount and the two binary facts reported by the browser.
3
+ * pressed is not inferred from x; a partially depressed trigger need not be pressed.
4
+ * The device owns mutation. Switches and onChanged keep their identity across source replacement.
5
+ */
6
+ export class XRInputButton extends Vector1 {
7
+ /** @readonly */
8
+ readonly pressed: InputDeviceSwitch;
9
+ /** @readonly */
10
+ readonly touched: InputDeviceSwitch;
11
+ /**
12
+ * Stage binary state while updating the scalar. All numeric channels and poses are sampled before
13
+ * the device calls flushSwitches, so an input-map action can read the corresponding amount.
14
+ * @internal
15
+ * @param {{value: number, pressed: boolean, touched: boolean}|undefined} button
16
+ */
17
+ update(button: {
18
+ value: number;
19
+ pressed: boolean;
20
+ touched: boolean;
21
+ } | undefined): void;
22
+ /** @internal */
23
+ flushSwitches(): void;
24
+ #private;
25
+ }
26
+ import { Vector1 } from "../../../../core/geom/Vector1.js";
27
+ import { InputDeviceSwitch } from "../InputDeviceSwitch.js";
28
+ //# sourceMappingURL=XRInputButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"XRInputButton.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/input/devices/xr/XRInputButton.js"],"names":[],"mappings":"AAGA;;;;GAIG;AACH;IACI,gBAAgB;IAChB,oCAAkC;IAClC,gBAAgB;IAChB,oCAAkC;IAKlC;;;;;OAKG;IACH,eAFW;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAC,GAAC,SAAS,QAMvE;IAED,gBAAgB;IAChB,sBAWC;;CACJ;wBA1CuB,kCAAkC;kCACxB,yBAAyB"}