@onerjs/core 8.54.1 → 8.54.3

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 (238) hide show
  1. package/Animations/animatable.core.js.map +1 -1
  2. package/AudioV2/abstractAudio/abstractSoundSource.d.ts +26 -0
  3. package/AudioV2/abstractAudio/abstractSoundSource.js.map +1 -1
  4. package/AudioV2/webAudio/webAudioEngine.js +2 -0
  5. package/AudioV2/webAudio/webAudioEngine.js.map +1 -1
  6. package/AudioV2/webAudio/webAudioSoundSource.d.ts +16 -0
  7. package/AudioV2/webAudio/webAudioSoundSource.js +43 -1
  8. package/AudioV2/webAudio/webAudioSoundSource.js.map +1 -1
  9. package/Bones/skeleton.functions.js +1 -1
  10. package/Bones/skeleton.functions.js.map +1 -1
  11. package/Cameras/inputMapper.js.map +1 -1
  12. package/Collisions/gpuPicker.js +7 -6
  13. package/Collisions/gpuPicker.js.map +1 -1
  14. package/Debug/physicsViewer.pure.js +1 -1
  15. package/Debug/physicsViewer.pure.js.map +1 -1
  16. package/Engines/Extensions/engine.alphaToCoverage.d.ts +6 -0
  17. package/Engines/Extensions/engine.alphaToCoverage.js +9 -0
  18. package/Engines/Extensions/engine.alphaToCoverage.js.map +1 -0
  19. package/Engines/Extensions/engine.alphaToCoverage.pure.d.ts +6 -0
  20. package/Engines/Extensions/engine.alphaToCoverage.pure.js +54 -0
  21. package/Engines/Extensions/engine.alphaToCoverage.pure.js.map +1 -0
  22. package/Engines/Extensions/engine.alphaToCoverage.types.d.ts +21 -0
  23. package/Engines/Extensions/engine.alphaToCoverage.types.js +2 -0
  24. package/Engines/Extensions/engine.alphaToCoverage.types.js.map +1 -0
  25. package/Engines/Extensions/engine.texture2DArrayImageSource.d.ts +6 -0
  26. package/Engines/Extensions/engine.texture2DArrayImageSource.js +9 -0
  27. package/Engines/Extensions/engine.texture2DArrayImageSource.js.map +1 -0
  28. package/Engines/Extensions/engine.texture2DArrayImageSource.pure.d.ts +7 -0
  29. package/Engines/Extensions/engine.texture2DArrayImageSource.pure.js +40 -0
  30. package/Engines/Extensions/engine.texture2DArrayImageSource.pure.js.map +1 -0
  31. package/Engines/Extensions/engine.texture2DArrayImageSource.types.d.ts +21 -0
  32. package/Engines/Extensions/engine.texture2DArrayImageSource.types.js +2 -0
  33. package/Engines/Extensions/engine.texture2DArrayImageSource.types.js.map +1 -0
  34. package/Engines/Extensions/index.d.ts +1 -0
  35. package/Engines/Extensions/index.js +1 -0
  36. package/Engines/Extensions/index.js.map +1 -1
  37. package/Engines/Extensions/pure.d.ts +2 -0
  38. package/Engines/Extensions/pure.js +2 -0
  39. package/Engines/Extensions/pure.js.map +1 -1
  40. package/Engines/Native/nativeHelpers.js +6 -4
  41. package/Engines/Native/nativeHelpers.js.map +1 -1
  42. package/Engines/Native/nativeInterfaces.d.ts +1 -0
  43. package/Engines/Native/nativeInterfaces.js.map +1 -1
  44. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.d.ts +6 -0
  45. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.js +9 -0
  46. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.js.map +1 -0
  47. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.pure.d.ts +6 -0
  48. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.pure.js +34 -0
  49. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.pure.js.map +1 -0
  50. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.types.d.ts +16 -0
  51. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.types.js +2 -0
  52. package/Engines/WebGPU/Extensions/engine.alphaToCoverage.types.js.map +1 -0
  53. package/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource.d.ts +6 -0
  54. package/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource.js +9 -0
  55. package/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource.js.map +1 -0
  56. package/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource.pure.d.ts +7 -0
  57. package/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource.pure.js +23 -0
  58. package/Engines/WebGPU/Extensions/engine.texture2DArrayImageSource.pure.js.map +1 -0
  59. package/Engines/WebGPU/Extensions/index.d.ts +1 -0
  60. package/Engines/WebGPU/Extensions/index.js +1 -0
  61. package/Engines/WebGPU/Extensions/index.js.map +1 -1
  62. package/Engines/WebGPU/Extensions/pure.d.ts +2 -0
  63. package/Engines/WebGPU/Extensions/pure.js +2 -0
  64. package/Engines/WebGPU/Extensions/pure.js.map +1 -1
  65. package/Engines/WebGPU/webgpuCacheRenderPipeline.js +0 -1
  66. package/Engines/WebGPU/webgpuCacheRenderPipeline.js.map +1 -1
  67. package/Engines/abstractEngine.pure.d.ts +0 -15
  68. package/Engines/abstractEngine.pure.js +2 -23
  69. package/Engines/abstractEngine.pure.js.map +1 -1
  70. package/Engines/constants.d.ts +4 -0
  71. package/Engines/constants.js +4 -0
  72. package/Engines/constants.js.map +1 -1
  73. package/Engines/engine.d.ts +32 -2
  74. package/Engines/engine.js +1 -0
  75. package/Engines/engine.js.map +1 -1
  76. package/Engines/engine.pure.js +1 -1
  77. package/Engines/engine.pure.js.map +1 -1
  78. package/Engines/thinEngine.pure.d.ts +0 -11
  79. package/Engines/thinEngine.pure.js +0 -19
  80. package/Engines/thinEngine.pure.js.map +1 -1
  81. package/Engines/thinNativeEngine.pure.js +4 -4
  82. package/Engines/thinNativeEngine.pure.js.map +1 -1
  83. package/Engines/webgpuEngine.d.ts +2 -0
  84. package/Engines/webgpuEngine.js +2 -0
  85. package/Engines/webgpuEngine.js.map +1 -1
  86. package/Engines/webgpuEngine.pure.d.ts +0 -5
  87. package/Engines/webgpuEngine.pure.js +1 -10
  88. package/Engines/webgpuEngine.pure.js.map +1 -1
  89. package/FrameGraph/Node/Types/nodeRenderGraphTypes.js.map +1 -1
  90. package/Lights/Clustered/clusteredLightContainer.pure.js +6 -0
  91. package/Lights/Clustered/clusteredLightContainer.pure.js.map +1 -1
  92. package/Loading/Plugins/babylonFileLoader.d.ts +10 -0
  93. package/Loading/Plugins/babylonFileLoader.js +18 -0
  94. package/Loading/Plugins/babylonFileLoader.js.map +1 -1
  95. package/Loading/Plugins/babylonFileLoader.pure.js +10 -2
  96. package/Loading/Plugins/babylonFileLoader.pure.js.map +1 -1
  97. package/Loading/loadingScreen.pure.js +2 -0
  98. package/Loading/loadingScreen.pure.js.map +1 -1
  99. package/Materials/Node/Blocks/Fragment/ambientOcclusionBlock.pure.js.map +1 -1
  100. package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.pure.js +2 -1
  101. package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.pure.js.map +1 -1
  102. package/Materials/Node/nodeMaterial.pure.d.ts +13 -5
  103. package/Materials/Node/nodeMaterial.pure.js +20 -2
  104. package/Materials/Node/nodeMaterial.pure.js.map +1 -1
  105. package/Materials/Textures/index.d.ts +1 -0
  106. package/Materials/Textures/index.js +1 -0
  107. package/Materials/Textures/index.js.map +1 -1
  108. package/Materials/Textures/ktx2decoderTypes.d.ts +14 -3
  109. package/Materials/Textures/ktx2decoderTypes.js +2 -0
  110. package/Materials/Textures/ktx2decoderTypes.js.map +1 -1
  111. package/Materials/Textures/pure.d.ts +1 -0
  112. package/Materials/Textures/pure.js +1 -0
  113. package/Materials/Textures/pure.js.map +1 -1
  114. package/Materials/Textures/rawTexture2DArray.functions.d.ts +95 -0
  115. package/Materials/Textures/rawTexture2DArray.functions.js +201 -0
  116. package/Materials/Textures/rawTexture2DArray.functions.js.map +1 -0
  117. package/Materials/Textures/renderTargetTexture.pure.js +7 -0
  118. package/Materials/Textures/renderTargetTexture.pure.js.map +1 -1
  119. package/Materials/material.pure.d.ts +1 -0
  120. package/Materials/material.pure.js +1 -0
  121. package/Materials/material.pure.js.map +1 -1
  122. package/Meshes/Builders/pure.d.ts +2 -2
  123. package/Meshes/Builders/pure.js +2 -2
  124. package/Meshes/Builders/pure.js.map +1 -1
  125. package/Meshes/Builders/textBuilder.js.map +1 -1
  126. package/Meshes/Builders/tiledBoxBuilder.d.ts +1 -83
  127. package/Meshes/Builders/tiledBoxBuilder.js +3 -215
  128. package/Meshes/Builders/tiledBoxBuilder.js.map +1 -1
  129. package/Meshes/Builders/tiledBoxBuilder.pure.d.ts +89 -0
  130. package/Meshes/Builders/tiledBoxBuilder.pure.js +229 -0
  131. package/Meshes/Builders/tiledBoxBuilder.pure.js.map +1 -0
  132. package/Meshes/Builders/tiledPlaneBuilder.d.ts +1 -79
  133. package/Meshes/Builders/tiledPlaneBuilder.js +3 -429
  134. package/Meshes/Builders/tiledPlaneBuilder.js.map +1 -1
  135. package/Meshes/Builders/tiledPlaneBuilder.pure.d.ts +85 -0
  136. package/Meshes/Builders/tiledPlaneBuilder.pure.js +442 -0
  137. package/Meshes/Builders/tiledPlaneBuilder.pure.js.map +1 -0
  138. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.d.ts +13 -0
  139. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js +15 -0
  140. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js.map +1 -1
  141. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +29 -9
  142. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
  143. package/Meshes/Node/Blocks/bevelBlock.pure.js.map +1 -1
  144. package/Meshes/meshBuilder.d.ts +21 -57
  145. package/Meshes/meshBuilder.js +21 -58
  146. package/Meshes/meshBuilder.js.map +1 -1
  147. package/Meshes/meshBuilder.pure.d.ts +58 -0
  148. package/Meshes/meshBuilder.pure.js +60 -0
  149. package/Meshes/meshBuilder.pure.js.map +1 -0
  150. package/Meshes/pure.d.ts +1 -1
  151. package/Meshes/pure.js +1 -1
  152. package/Meshes/pure.js.map +1 -1
  153. package/Misc/greasedLineTools.js.map +1 -1
  154. package/Misc/khronosTextureContainer2.d.ts +10 -0
  155. package/Misc/khronosTextureContainer2.js +23 -12
  156. package/Misc/khronosTextureContainer2.js.map +1 -1
  157. package/Misc/perfCounter.d.ts +2 -0
  158. package/Misc/perfCounter.js +17 -2
  159. package/Misc/perfCounter.js.map +1 -1
  160. package/Misc/rgbdTextureTools.js +1 -1
  161. package/Misc/rgbdTextureTools.js.map +1 -1
  162. package/Misc/snapshotRenderingHelper.js +2 -1
  163. package/Misc/snapshotRenderingHelper.js.map +1 -1
  164. package/Misc/tools.pure.js +1 -1
  165. package/Misc/tools.pure.js.map +1 -1
  166. package/Navigation/Plugins/recastJSPlugin.js +1 -1
  167. package/Navigation/Plugins/recastJSPlugin.js.map +1 -1
  168. package/Physics/v2/Plugins/havokPlugin.js +15 -0
  169. package/Physics/v2/Plugins/havokPlugin.js.map +1 -1
  170. package/Physics/v2/characterController.d.ts +17 -0
  171. package/Physics/v2/characterController.js +40 -0
  172. package/Physics/v2/characterController.js.map +1 -1
  173. package/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.pure.js.map +1 -1
  174. package/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.pure.js.map +1 -1
  175. package/PostProcesses/thinSSAO2PostProcess.js.map +1 -1
  176. package/PostProcesses/volumetricLightScatteringPostProcess.d.ts +3 -0
  177. package/PostProcesses/volumetricLightScatteringPostProcess.js +3 -0
  178. package/PostProcesses/volumetricLightScatteringPostProcess.js.map +1 -1
  179. package/PostProcesses/volumetricLightScatteringPostProcess.pure.d.ts +1 -0
  180. package/PostProcesses/volumetricLightScatteringPostProcess.pure.js +25 -6
  181. package/PostProcesses/volumetricLightScatteringPostProcess.pure.js.map +1 -1
  182. package/Rendering/IBLShadows/iblShadowsAccumulationPass.d.ts +3 -1
  183. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js +25 -4
  184. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js.map +1 -1
  185. package/Rendering/IBLShadows/iblShadowsRenderPipeline.pure.js +6 -5
  186. package/Rendering/IBLShadows/iblShadowsRenderPipeline.pure.js.map +1 -1
  187. package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.d.ts +3 -1
  188. package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.js +16 -4
  189. package/Rendering/IBLShadows/iblShadowsSpatialBlurPass.js.map +1 -1
  190. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.js +6 -5
  191. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.js.map +1 -1
  192. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.d.ts +3 -1
  193. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js +16 -4
  194. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js.map +1 -1
  195. package/Rendering/depthRenderer.d.ts +2 -0
  196. package/Rendering/depthRenderer.js +2 -0
  197. package/Rendering/depthRenderer.js.map +1 -1
  198. package/Rendering/depthRenderer.pure.js +3 -2
  199. package/Rendering/depthRenderer.pure.js.map +1 -1
  200. package/Rendering/fluidRenderer/fluidRenderer.pure.js +6 -0
  201. package/Rendering/fluidRenderer/fluidRenderer.pure.js.map +1 -1
  202. package/Rendering/geometryBufferRenderer.pure.js +5 -5
  203. package/Rendering/geometryBufferRenderer.pure.js.map +1 -1
  204. package/Shaders/ShadersInclude/openpbrDielectricReflectance.js +6 -6
  205. package/Shaders/ShadersInclude/openpbrDielectricReflectance.js.map +1 -1
  206. package/ShadersWGSL/ShadersInclude/depthPrePass.js +2 -0
  207. package/ShadersWGSL/ShadersInclude/depthPrePass.js.map +1 -1
  208. package/ShadersWGSL/ShadersInclude/openpbrDielectricReflectance.js +7 -8
  209. package/ShadersWGSL/ShadersInclude/openpbrDielectricReflectance.js.map +1 -1
  210. package/ShadersWGSL/default.fragment.js +3 -0
  211. package/ShadersWGSL/default.fragment.js.map +1 -1
  212. package/ShadersWGSL/openpbr.fragment.js +3 -0
  213. package/ShadersWGSL/openpbr.fragment.js.map +1 -1
  214. package/ShadersWGSL/pbr.fragment.js +3 -0
  215. package/ShadersWGSL/pbr.fragment.js.map +1 -1
  216. package/ShadersWGSL/volumetricLightScattering.fragment.d.ts +5 -0
  217. package/ShadersWGSL/volumetricLightScattering.fragment.js +20 -0
  218. package/ShadersWGSL/volumetricLightScattering.fragment.js.map +1 -0
  219. package/ShadersWGSL/volumetricLightScatteringPass.fragment.d.ts +5 -0
  220. package/ShadersWGSL/volumetricLightScatteringPass.fragment.js +24 -0
  221. package/ShadersWGSL/volumetricLightScatteringPass.fragment.js.map +1 -0
  222. package/ShadersWGSL/volumetricLightScatteringPass.vertex.d.ts +5 -0
  223. package/ShadersWGSL/volumetricLightScatteringPass.vertex.js +67 -0
  224. package/ShadersWGSL/volumetricLightScatteringPass.vertex.js.map +1 -0
  225. package/SmartAssets/smartAssetManager.pure.js +9 -1
  226. package/SmartAssets/smartAssetManager.pure.js.map +1 -1
  227. package/States/alphaCullingState.d.ts +0 -9
  228. package/States/alphaCullingState.js +4 -31
  229. package/States/alphaCullingState.js.map +1 -1
  230. package/XR/features/WebXRBodyTracking.pure.d.ts +0 -28
  231. package/XR/features/WebXRBodyTracking.pure.js.map +1 -1
  232. package/XR/features/WebXRLayers.pure.js +4 -4
  233. package/XR/features/WebXRLayers.pure.js.map +1 -1
  234. package/node.d.ts +18 -1
  235. package/node.js +52 -1
  236. package/node.js.map +1 -1
  237. package/package.json +1 -1
  238. package/types.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"webAudioEngine.js","sourceRoot":"","sources":["../../../../../dev/core/src/AudioV2/webAudio/webAudioEngine.ts"],"names":[],"mappings":"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","sourcesContent":["import { Observable } from \"../../Misc/observable\";\nimport { type Nullable } from \"../../types\";\nimport { type AbstractNamedAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport { type AbstractSound } from \"../abstractAudio/abstractSound\";\nimport { SoundState } from \"../soundState\";\nimport { type AbstractSoundSource, type ISoundSourceOptions } from \"../abstractAudio/abstractSoundSource\";\nimport { type AudioBus, type IAudioBusOptions } from \"../abstractAudio/audioBus\";\nimport { type AudioEngineV2State, type IAudioEngineV2Options, AudioEngineV2, OnAudioEngineV2CreatedObservable } from \"../abstractAudio/audioEngineV2\";\nimport { type IMainAudioBusOptions, type MainAudioBus } from \"../abstractAudio/mainAudioBus\";\nimport { type IStaticSoundOptions, type StaticSound } from \"../abstractAudio/staticSound\";\nimport { type IStaticSoundBufferOptions, type StaticSoundBuffer } from \"../abstractAudio/staticSoundBuffer\";\nimport { type IStreamingSoundOptions, type StreamingSound } from \"../abstractAudio/streamingSound\";\nimport { type AbstractSpatialAudioListener, _HasSpatialAudioListenerOptions } from \"../abstractAudio/subProperties/abstractSpatialAudioListener\";\nimport { type _SpatialAudioListener } from \"../abstractAudio/subProperties/spatialAudioListener\";\nimport { type IAudioParameterRampOptions } from \"../audioParameter\";\nimport { _CreateSpatialAudioListener } from \"./subProperties/spatialWebAudioListener\";\nimport { _WebAudioMainOut } from \"./webAudioMainOut\";\nimport { _WebAudioUnmuteUI } from \"./webAudioUnmuteUI\";\n\n/**\n * Options for creating a v2 audio engine that uses the WebAudio API.\n */\nexport interface IWebAudioEngineOptions extends IAudioEngineV2Options {\n /**\n * The audio context to be used by the engine.\n */\n audioContext: AudioContext;\n /**\n * The default UI's parent element. Defaults to the last created graphics engine's canvas if it exists; otherwise the HTML document's body.\n */\n defaultUIParentElement?: HTMLElement;\n /**\n * Set to `true` to disable the default UI. Defaults to `false`.\n */\n disableDefaultUI?: boolean;\n /**\n * Set to `true` to automatically resume the audio context when the user interacts with the page. Defaults to `true`.\n */\n resumeOnInteraction: boolean;\n /**\n * Set to `true` to automatically resume the audio context when the browser pauses audio playback. Defaults to `true`.\n */\n resumeOnPause: boolean;\n /**\n * The interval in milliseconds to try resuming audio playback when `resumeOnPause` is `true`. Defaults to `1000`.\n */\n resumeOnPauseRetryInterval: number;\n}\n\n/**\n * Creates a new v2 audio engine that uses the WebAudio API.\n * @param options - The options for creating the audio engine.\n * @returns A promise that resolves with the created audio engine.\n */\nexport async function CreateAudioEngineAsync(options: Partial<IWebAudioEngineOptions> = {}): Promise<AudioEngineV2> {\n const engine = new _WebAudioEngine(options);\n await engine._initAsync(options);\n OnAudioEngineV2CreatedObservable.notifyObservers(engine);\n return engine;\n}\n\nconst FormatMimeTypes: { [key: string]: string } = {\n aac: \"audio/aac\",\n ac3: \"audio/ac3\",\n flac: \"audio/flac\",\n m4a: \"audio/mp4\",\n mp3: 'audio/mpeg; codecs=\"mp3\"',\n mp4: \"audio/mp4\",\n ogg: 'audio/ogg; codecs=\"vorbis\"',\n wav: \"audio/wav\",\n webm: 'audio/webm; codecs=\"vorbis\"',\n};\n\n/** @internal */\nexport class _WebAudioEngine extends AudioEngineV2 {\n private _audioContextStarted = false;\n private _destinationNode: Nullable<AudioNode> = null;\n private _invalidFormats = new Set<string>();\n private _isUpdating = false;\n private _listener: Nullable<_SpatialAudioListener> = null;\n private readonly _listenerAutoUpdate: boolean = true;\n private readonly _listenerMinUpdateTime: number = 0;\n private _mainOut: _WebAudioMainOut;\n private _pauseCalled = false;\n private _resumeOnInteraction = true;\n private _resumeOnPause = true;\n private _resumeOnPauseRetryInterval = 1000;\n private _resumeOnPauseTimerId: any = null;\n private _resumePromise: Nullable<Promise<void>> = null;\n private _silentHtmlAudio: Nullable<HTMLAudioElement> = null;\n private _unmuteUI: Nullable<_WebAudioUnmuteUI> = null;\n private _updateObservable: Nullable<Observable<void>> = null;\n private readonly _validFormats = new Set<string>();\n private _volume = 1;\n\n /** @internal */\n public readonly _audioContext: AudioContext;\n\n /** @internal */\n public readonly _isUsingOfflineAudioContext: boolean = false;\n\n /** @internal */\n public readonly isReadyPromise: Promise<void> = new Promise((resolve) => {\n this._resolveIsReadyPromise = resolve;\n });\n\n /** @internal */\n public stateChangedObservable: Observable<string> = new Observable();\n\n /** @internal */\n public userGestureObservable: Observable<void> = new Observable();\n\n /** @internal */\n public constructor(options: Partial<IWebAudioEngineOptions> = {}) {\n super(options);\n\n if (typeof options.listenerAutoUpdate === \"boolean\") {\n this._listenerAutoUpdate = options.listenerAutoUpdate;\n }\n\n if (typeof options.listenerMinUpdateTime === \"number\") {\n this._listenerMinUpdateTime = options.listenerMinUpdateTime;\n }\n\n this._volume = options.volume ?? 1;\n\n if (options.audioContext) {\n this._isUsingOfflineAudioContext = options.audioContext instanceof OfflineAudioContext;\n this._audioContext = options.audioContext;\n } else {\n this._audioContext = new AudioContext();\n }\n\n if (!options.disableDefaultUI) {\n this._unmuteUI = new _WebAudioUnmuteUI(this, options.defaultUIParentElement);\n }\n }\n\n /** @internal */\n public async _initAsync(options: Partial<IWebAudioEngineOptions>): Promise<void> {\n this._resumeOnInteraction = typeof options.resumeOnInteraction === \"boolean\" ? options.resumeOnInteraction : true;\n this._resumeOnPause = typeof options.resumeOnPause === \"boolean\" ? options.resumeOnPause : true;\n this._resumeOnPauseRetryInterval = options.resumeOnPauseRetryInterval ?? 1000;\n\n document.addEventListener(\"click\", this._onUserGestureAsync);\n\n await this._initAudioContextAsync();\n\n if (_HasSpatialAudioListenerOptions(options)) {\n this._listener = _CreateSpatialAudioListener(this, this._listenerAutoUpdate, this._listenerMinUpdateTime);\n this._listener.setOptions(options);\n }\n\n this._resolveIsReadyPromise();\n }\n\n /** @internal */\n public get currentTime(): number {\n return this._audioContext.currentTime ?? 0;\n }\n\n /** @internal */\n public get _inNode(): AudioNode {\n return this._audioContext.destination;\n }\n\n /** @internal */\n public get mainOut(): _WebAudioMainOut {\n return this._mainOut;\n }\n\n /** @internal */\n public get listener(): AbstractSpatialAudioListener {\n return this._listener ?? (this._listener = _CreateSpatialAudioListener(this, this._listenerAutoUpdate, this._listenerMinUpdateTime));\n }\n\n /** @internal */\n public get state(): AudioEngineV2State {\n // Always return \"running\" for OfflineAudioContext so sound `play` calls work while the context is suspended.\n return this._isUsingOfflineAudioContext ? \"running\" : this._audioContext.state;\n }\n\n /** @internal */\n public get volume(): number {\n return this._volume;\n }\n\n /** @internal */\n public set volume(value: number) {\n if (this._volume === value) {\n return;\n }\n\n this._volume = value;\n\n if (this._mainOut) {\n this._mainOut.volume = value;\n }\n }\n\n /**\n * This property should only be used by the legacy audio engine.\n * @internal\n * */\n public get _audioDestination(): AudioNode {\n return this._destinationNode ? this._destinationNode : (this._destinationNode = this._audioContext.destination);\n }\n\n public set _audioDestination(value: Nullable<AudioNode>) {\n this._destinationNode = value;\n }\n\n /**\n * This property should only be used by the legacy audio engine.\n * @internal\n */\n public get _unmuteUIEnabled(): boolean {\n return this._unmuteUI ? this._unmuteUI.enabled : false;\n }\n\n public set _unmuteUIEnabled(value: boolean) {\n if (this._unmuteUI) {\n this._unmuteUI.enabled = value;\n }\n }\n\n /** @internal */\n public async createBusAsync(name: string, options: Partial<IAudioBusOptions> = {}): Promise<AudioBus> {\n const module = await import(\"./webAudioBus\");\n\n const bus = new module._WebAudioBus(name, this, options);\n await bus._initAsync(options);\n\n return bus;\n }\n\n /** @internal */\n public async createMainBusAsync(name: string, options: Partial<IMainAudioBusOptions> = {}): Promise<MainAudioBus> {\n const module = await import(\"./webAudioMainBus\");\n\n const bus = new module._WebAudioMainBus(name, this);\n await bus._initAsync(options);\n\n return bus;\n }\n\n /** @internal */\n public async createMicrophoneSoundSourceAsync(name: string, options?: Partial<ISoundSourceOptions>): Promise<AbstractSoundSource> {\n let mediaStream: MediaStream;\n\n try {\n mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n } catch (e) {\n throw new Error(\"Unable to access microphone: \" + e, { cause: e });\n }\n\n return await this.createSoundSourceAsync(name, new MediaStreamAudioSourceNode(this._audioContext, { mediaStream }), {\n outBusAutoDefault: false,\n ...options,\n });\n }\n\n /** @internal */\n public async createSoundAsync(\n name: string,\n source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n options: Partial<IStaticSoundOptions> = {}\n ): Promise<StaticSound> {\n const module = await import(\"./webAudioStaticSound\");\n\n const sound = new module._WebAudioStaticSound(name, this, options);\n await sound._initAsync(source, options);\n\n return sound;\n }\n\n /** @internal */\n public async createSoundBufferAsync(\n source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n options: Partial<IStaticSoundBufferOptions> = {}\n ): Promise<StaticSoundBuffer> {\n const module = await import(\"./webAudioStaticSound\");\n\n const soundBuffer = new module._WebAudioStaticSoundBuffer(this);\n await soundBuffer._initAsync(source, options);\n\n return soundBuffer;\n }\n\n /** @internal */\n public async createSoundSourceAsync(name: string, source: AudioNode, options: Partial<ISoundSourceOptions> = {}): Promise<AbstractSoundSource> {\n const module = await import(\"./webAudioSoundSource\");\n\n const soundSource = new module._WebAudioSoundSource(name, source, this, options);\n await soundSource._initAsync(options);\n\n return soundSource;\n }\n\n /** @internal */\n public async createStreamingSoundAsync(name: string, source: HTMLMediaElement | string | string[], options: Partial<IStreamingSoundOptions> = {}): Promise<StreamingSound> {\n const module = await import(\"./webAudioStreamingSound\");\n\n const sound = new module._WebAudioStreamingSound(name, this, options);\n await sound._initAsync(source, options);\n\n return sound;\n }\n\n /** @internal */\n public override dispose(): void {\n super.dispose();\n\n this._listener?.dispose();\n this._listener = null;\n\n // Note that OfflineAudioContext does not have a `close` method.\n if (this._audioContext.state !== \"closed\" && !this._isUsingOfflineAudioContext) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this._audioContext.close();\n }\n\n document.removeEventListener(\"click\", this._onUserGestureAsync);\n this._audioContext.removeEventListener(\"statechange\", this._onAudioContextStateChange);\n\n this._silentHtmlAudio?.remove();\n\n this._updateObservable?.clear();\n this._updateObservable = null;\n\n this._unmuteUI?.dispose();\n this._unmuteUI = null;\n\n this.stateChangedObservable.clear();\n }\n\n /** @internal */\n public flagInvalidFormat(format: string): void {\n this._invalidFormats.add(format);\n }\n\n /** @internal */\n public isFormatValid(format: string): boolean {\n if (this._validFormats.has(format)) {\n return true;\n }\n\n if (this._invalidFormats.has(format)) {\n return false;\n }\n\n const mimeType = FormatMimeTypes[format];\n if (mimeType === undefined) {\n return false;\n }\n\n const audio = new Audio();\n if (audio.canPlayType(mimeType) === \"\") {\n this._invalidFormats.add(format);\n return false;\n }\n\n this._validFormats.add(format);\n\n return true;\n }\n\n /** @internal */\n public override async pauseAsync(): Promise<void> {\n await this._audioContext.suspend();\n\n this._pauseCalled = true;\n }\n\n /** @internal */\n // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\n public override resumeAsync(): Promise<void> {\n this._pauseCalled = false;\n\n if (this._resumePromise) {\n return this._resumePromise;\n }\n\n this._resumePromise = this._audioContext.resume();\n\n this.stateChangedObservable.notifyObservers(this.state);\n\n return this._resumePromise;\n }\n\n /** @internal */\n public setVolume(value: number, options: Nullable<Partial<IAudioParameterRampOptions>> = null): void {\n if (this._mainOut) {\n this._mainOut.setVolume(value, options);\n } else {\n throw new Error(\"Main output not initialized yet.\");\n }\n }\n\n /** @internal */\n public override _addMainBus(mainBus: MainAudioBus): void {\n super._addMainBus(mainBus);\n }\n\n /** @internal */\n public override _removeMainBus(mainBus: MainAudioBus): void {\n super._removeMainBus(mainBus);\n }\n\n /** @internal */\n public override _addNode(node: AbstractNamedAudioNode): void {\n super._addNode(node);\n }\n\n /** @internal */\n public override _removeNode(node: AbstractNamedAudioNode): void {\n super._removeNode(node);\n }\n\n /** @internal */\n public override _addSound(sound: AbstractSound): void {\n super._addSound(sound);\n }\n\n /** @internal */\n public override _removeSound(sound: AbstractSound): void {\n super._removeSound(sound);\n }\n\n /** @internal */\n public override _onSoundPlaybackStateChanged(): void {\n if (!this._silentHtmlAudio) {\n return;\n }\n\n const hasActiveSounds = this.sounds.some((s) => s.state === SoundState.Started || s.state === SoundState.Starting || s.state === SoundState.Stopping);\n\n if (hasActiveSounds && this._silentHtmlAudio.paused) {\n // Resume silent audio for iOS ringer switch workaround while sounds are playing.\n // Errors are safe to ignore — the silent audio element is a workaround, not a\n // user-facing sound, so a rejected play (e.g. missing user gesture) is harmless.\n // eslint-disable-next-line github/no-then\n void this._silentHtmlAudio.play().catch(() => {});\n } else if (!hasActiveSounds && !this._silentHtmlAudio.paused) {\n // Pause silent audio when no sounds are playing to avoid triggering iOS Safari's\n // audio playback detection, which causes FPS throttling and shows a blue audio icon.\n this._silentHtmlAudio.pause();\n }\n }\n\n /** @internal */\n public _addUpdateObserver(callback: () => void): void {\n if (!this._updateObservable) {\n this._updateObservable = new Observable<void>();\n }\n\n this._updateObservable.add(callback);\n this._startUpdating();\n }\n\n public _removeUpdateObserver(callback: () => void): void {\n if (this._updateObservable) {\n this._updateObservable.removeCallback(callback);\n }\n }\n\n private _initAudioContextAsync: () => Promise<void> = async () => {\n this._audioContext.addEventListener(\"statechange\", this._onAudioContextStateChange);\n\n this._mainOut = new _WebAudioMainOut(this);\n this._mainOut.volume = this._volume;\n\n await this.createMainBusAsync(\"default\");\n };\n\n private _onAudioContextStateChange = () => {\n if (this.state === \"running\") {\n clearInterval(this._resumeOnPauseTimerId);\n this._audioContextStarted = true;\n this._resumePromise = null;\n }\n if (this.state === \"suspended\" || this.state === \"interrupted\") {\n if (this._audioContextStarted && this._resumeOnPause && !this._pauseCalled) {\n clearInterval(this._resumeOnPauseTimerId);\n\n this._resumeOnPauseTimerId = setInterval(() => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.resumeAsync();\n }, this._resumeOnPauseRetryInterval);\n }\n }\n\n this.stateChangedObservable.notifyObservers(this.state);\n };\n\n private _onUserGestureAsync: () => void = async () => {\n if (this._resumeOnInteraction) {\n await this._audioContext.resume();\n }\n\n // On iOS the ringer switch must be turned on for WebAudio to play.\n // This gets WebAudio to play with the ringer switch turned off by playing an HTMLAudioElement.\n // The element is activated during a user gesture so it can be played/paused programmatically\n // later. It is immediately paused to avoid triggering iOS Safari's \"now playing\" detection,\n // which throttles the page to 30 FPS.\n if (!this._silentHtmlAudio) {\n this._silentHtmlAudio = document.createElement(\"audio\");\n\n const audio = this._silentHtmlAudio;\n audio.controls = false;\n audio.preload = \"auto\";\n audio.loop = true;\n\n // Wave data for 0.0001 seconds of silence.\n audio.src = \"data:audio/wav;base64,UklGRjAAAABXQVZFZm10IBAAAAABAAEAgLsAAAB3AQACABAAZGF0YQwAAAAAAAEA/v8CAP//AQA=\";\n\n // Play briefly to activate the element, then immediately pause.\n // The rejection handler is intentionally empty — play() can reject if the\n // browser requires a more specific user gesture; this is non-fatal since\n // the audio context unlock is the primary goal, and the silent element is\n // only a supplementary iOS ringer-switch workaround.\n // eslint-disable-next-line github/no-then\n audio.play().then(\n () => audio.pause(),\n () => {}\n );\n }\n\n this.userGestureObservable.notifyObservers();\n };\n\n private _resolveIsReadyPromise: () => void;\n\n private _startUpdating = () => {\n if (this._isUpdating) {\n return;\n }\n\n this._isUpdating = true;\n\n if (this.state === \"running\") {\n this._update();\n } else {\n const callback = () => {\n if (this.state === \"running\") {\n this._update();\n this.stateChangedObservable.removeCallback(callback);\n }\n };\n\n this.stateChangedObservable.add(callback);\n }\n };\n\n private _update = (): void => {\n if (this._updateObservable?.hasObservers()) {\n this._updateObservable.notifyObservers();\n requestAnimationFrame(this._update);\n } else {\n this._isUpdating = false;\n }\n };\n}\n"]}
1
+ {"version":3,"file":"webAudioEngine.js","sourceRoot":"","sources":["../../../../../dev/core/src/AudioV2/webAudio/webAudioEngine.ts"],"names":[],"mappings":"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","sourcesContent":["import { Observable } from \"../../Misc/observable\";\nimport { type Nullable } from \"../../types\";\nimport { type AbstractNamedAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport { type AbstractSound } from \"../abstractAudio/abstractSound\";\nimport { SoundState } from \"../soundState\";\nimport { type AbstractSoundSource, type ISoundSourceOptions } from \"../abstractAudio/abstractSoundSource\";\nimport { type AudioBus, type IAudioBusOptions } from \"../abstractAudio/audioBus\";\nimport { type AudioEngineV2State, type IAudioEngineV2Options, AudioEngineV2, OnAudioEngineV2CreatedObservable } from \"../abstractAudio/audioEngineV2\";\nimport { type IMainAudioBusOptions, type MainAudioBus } from \"../abstractAudio/mainAudioBus\";\nimport { type IStaticSoundOptions, type StaticSound } from \"../abstractAudio/staticSound\";\nimport { type IStaticSoundBufferOptions, type StaticSoundBuffer } from \"../abstractAudio/staticSoundBuffer\";\nimport { type IStreamingSoundOptions, type StreamingSound } from \"../abstractAudio/streamingSound\";\nimport { type AbstractSpatialAudioListener, _HasSpatialAudioListenerOptions } from \"../abstractAudio/subProperties/abstractSpatialAudioListener\";\nimport { type _SpatialAudioListener } from \"../abstractAudio/subProperties/spatialAudioListener\";\nimport { type IAudioParameterRampOptions } from \"../audioParameter\";\nimport { _CreateSpatialAudioListener } from \"./subProperties/spatialWebAudioListener\";\nimport { _WebAudioMainOut } from \"./webAudioMainOut\";\nimport { _WebAudioUnmuteUI } from \"./webAudioUnmuteUI\";\n\n/**\n * Options for creating a v2 audio engine that uses the WebAudio API.\n */\nexport interface IWebAudioEngineOptions extends IAudioEngineV2Options {\n /**\n * The audio context to be used by the engine.\n */\n audioContext: AudioContext;\n /**\n * The default UI's parent element. Defaults to the last created graphics engine's canvas if it exists; otherwise the HTML document's body.\n */\n defaultUIParentElement?: HTMLElement;\n /**\n * Set to `true` to disable the default UI. Defaults to `false`.\n */\n disableDefaultUI?: boolean;\n /**\n * Set to `true` to automatically resume the audio context when the user interacts with the page. Defaults to `true`.\n */\n resumeOnInteraction: boolean;\n /**\n * Set to `true` to automatically resume the audio context when the browser pauses audio playback. Defaults to `true`.\n */\n resumeOnPause: boolean;\n /**\n * The interval in milliseconds to try resuming audio playback when `resumeOnPause` is `true`. Defaults to `1000`.\n */\n resumeOnPauseRetryInterval: number;\n}\n\n/**\n * Creates a new v2 audio engine that uses the WebAudio API.\n * @param options - The options for creating the audio engine.\n * @returns A promise that resolves with the created audio engine.\n */\nexport async function CreateAudioEngineAsync(options: Partial<IWebAudioEngineOptions> = {}): Promise<AudioEngineV2> {\n const engine = new _WebAudioEngine(options);\n await engine._initAsync(options);\n OnAudioEngineV2CreatedObservable.notifyObservers(engine);\n return engine;\n}\n\nconst FormatMimeTypes: { [key: string]: string } = {\n aac: \"audio/aac\",\n ac3: \"audio/ac3\",\n flac: \"audio/flac\",\n m4a: \"audio/mp4\",\n mp3: 'audio/mpeg; codecs=\"mp3\"',\n mp4: \"audio/mp4\",\n ogg: 'audio/ogg; codecs=\"vorbis\"',\n wav: \"audio/wav\",\n webm: 'audio/webm; codecs=\"vorbis\"',\n};\n\n/** @internal */\nexport class _WebAudioEngine extends AudioEngineV2 {\n private _audioContextStarted = false;\n private _destinationNode: Nullable<AudioNode> = null;\n private _invalidFormats = new Set<string>();\n private _isUpdating = false;\n private _listener: Nullable<_SpatialAudioListener> = null;\n private readonly _listenerAutoUpdate: boolean = true;\n private readonly _listenerMinUpdateTime: number = 0;\n private _mainOut: _WebAudioMainOut;\n private _pauseCalled = false;\n private _resumeOnInteraction = true;\n private _resumeOnPause = true;\n private _resumeOnPauseRetryInterval = 1000;\n private _resumeOnPauseTimerId: any = null;\n private _resumePromise: Nullable<Promise<void>> = null;\n private _silentHtmlAudio: Nullable<HTMLAudioElement> = null;\n private _unmuteUI: Nullable<_WebAudioUnmuteUI> = null;\n private _updateObservable: Nullable<Observable<void>> = null;\n private readonly _validFormats = new Set<string>();\n private _volume = 1;\n\n /** @internal */\n public readonly _audioContext: AudioContext;\n\n /** @internal */\n public readonly _isUsingOfflineAudioContext: boolean = false;\n\n /** @internal */\n public readonly isReadyPromise: Promise<void> = new Promise((resolve) => {\n this._resolveIsReadyPromise = resolve;\n });\n\n /** @internal */\n public stateChangedObservable: Observable<string> = new Observable();\n\n /** @internal */\n public userGestureObservable: Observable<void> = new Observable();\n\n /** @internal */\n public constructor(options: Partial<IWebAudioEngineOptions> = {}) {\n super(options);\n\n if (typeof options.listenerAutoUpdate === \"boolean\") {\n this._listenerAutoUpdate = options.listenerAutoUpdate;\n }\n\n if (typeof options.listenerMinUpdateTime === \"number\") {\n this._listenerMinUpdateTime = options.listenerMinUpdateTime;\n }\n\n this._volume = options.volume ?? 1;\n\n if (options.audioContext) {\n this._isUsingOfflineAudioContext = options.audioContext instanceof OfflineAudioContext;\n this._audioContext = options.audioContext;\n } else {\n this._audioContext = new AudioContext();\n }\n\n if (!options.disableDefaultUI) {\n this._unmuteUI = new _WebAudioUnmuteUI(this, options.defaultUIParentElement);\n }\n }\n\n /** @internal */\n public async _initAsync(options: Partial<IWebAudioEngineOptions>): Promise<void> {\n this._resumeOnInteraction = typeof options.resumeOnInteraction === \"boolean\" ? options.resumeOnInteraction : true;\n this._resumeOnPause = typeof options.resumeOnPause === \"boolean\" ? options.resumeOnPause : true;\n this._resumeOnPauseRetryInterval = options.resumeOnPauseRetryInterval ?? 1000;\n\n document.addEventListener(\"click\", this._onUserGestureAsync);\n\n await this._initAudioContextAsync();\n\n if (_HasSpatialAudioListenerOptions(options)) {\n this._listener = _CreateSpatialAudioListener(this, this._listenerAutoUpdate, this._listenerMinUpdateTime);\n this._listener.setOptions(options);\n }\n\n this._resolveIsReadyPromise();\n }\n\n /** @internal */\n public get currentTime(): number {\n return this._audioContext.currentTime ?? 0;\n }\n\n /** @internal */\n public get _inNode(): AudioNode {\n return this._audioContext.destination;\n }\n\n /** @internal */\n public get mainOut(): _WebAudioMainOut {\n return this._mainOut;\n }\n\n /** @internal */\n public get listener(): AbstractSpatialAudioListener {\n return this._listener ?? (this._listener = _CreateSpatialAudioListener(this, this._listenerAutoUpdate, this._listenerMinUpdateTime));\n }\n\n /** @internal */\n public get state(): AudioEngineV2State {\n // Always return \"running\" for OfflineAudioContext so sound `play` calls work while the context is suspended.\n return this._isUsingOfflineAudioContext ? \"running\" : this._audioContext.state;\n }\n\n /** @internal */\n public get volume(): number {\n return this._volume;\n }\n\n /** @internal */\n public set volume(value: number) {\n if (this._volume === value) {\n return;\n }\n\n this._volume = value;\n\n if (this._mainOut) {\n this._mainOut.volume = value;\n }\n }\n\n /**\n * This property should only be used by the legacy audio engine.\n * @internal\n * */\n public get _audioDestination(): AudioNode {\n return this._destinationNode ? this._destinationNode : (this._destinationNode = this._audioContext.destination);\n }\n\n public set _audioDestination(value: Nullable<AudioNode>) {\n this._destinationNode = value;\n }\n\n /**\n * This property should only be used by the legacy audio engine.\n * @internal\n */\n public get _unmuteUIEnabled(): boolean {\n return this._unmuteUI ? this._unmuteUI.enabled : false;\n }\n\n public set _unmuteUIEnabled(value: boolean) {\n if (this._unmuteUI) {\n this._unmuteUI.enabled = value;\n }\n }\n\n /** @internal */\n public async createBusAsync(name: string, options: Partial<IAudioBusOptions> = {}): Promise<AudioBus> {\n const module = await import(\"./webAudioBus\");\n\n const bus = new module._WebAudioBus(name, this, options);\n await bus._initAsync(options);\n\n return bus;\n }\n\n /** @internal */\n public async createMainBusAsync(name: string, options: Partial<IMainAudioBusOptions> = {}): Promise<MainAudioBus> {\n const module = await import(\"./webAudioMainBus\");\n\n const bus = new module._WebAudioMainBus(name, this);\n await bus._initAsync(options);\n\n return bus;\n }\n\n /** @internal */\n public async createMicrophoneSoundSourceAsync(name: string, options?: Partial<ISoundSourceOptions>): Promise<AbstractSoundSource> {\n let mediaStream: MediaStream;\n\n try {\n mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n } catch (e) {\n throw new Error(\"Unable to access microphone: \" + e, { cause: e });\n }\n\n return await this.createSoundSourceAsync(name, new MediaStreamAudioSourceNode(this._audioContext, { mediaStream }), {\n outBusAutoDefault: false,\n mediaStreamSinkEnabled: false,\n stopMediaStreamTracksOnDispose: true,\n ...options,\n });\n }\n\n /** @internal */\n public async createSoundAsync(\n name: string,\n source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n options: Partial<IStaticSoundOptions> = {}\n ): Promise<StaticSound> {\n const module = await import(\"./webAudioStaticSound\");\n\n const sound = new module._WebAudioStaticSound(name, this, options);\n await sound._initAsync(source, options);\n\n return sound;\n }\n\n /** @internal */\n public async createSoundBufferAsync(\n source: ArrayBuffer | AudioBuffer | StaticSoundBuffer | string | string[],\n options: Partial<IStaticSoundBufferOptions> = {}\n ): Promise<StaticSoundBuffer> {\n const module = await import(\"./webAudioStaticSound\");\n\n const soundBuffer = new module._WebAudioStaticSoundBuffer(this);\n await soundBuffer._initAsync(source, options);\n\n return soundBuffer;\n }\n\n /** @internal */\n public async createSoundSourceAsync(name: string, source: AudioNode, options: Partial<ISoundSourceOptions> = {}): Promise<AbstractSoundSource> {\n const module = await import(\"./webAudioSoundSource\");\n\n const soundSource = new module._WebAudioSoundSource(name, source, this, options);\n await soundSource._initAsync(options);\n\n return soundSource;\n }\n\n /** @internal */\n public async createStreamingSoundAsync(name: string, source: HTMLMediaElement | string | string[], options: Partial<IStreamingSoundOptions> = {}): Promise<StreamingSound> {\n const module = await import(\"./webAudioStreamingSound\");\n\n const sound = new module._WebAudioStreamingSound(name, this, options);\n await sound._initAsync(source, options);\n\n return sound;\n }\n\n /** @internal */\n public override dispose(): void {\n super.dispose();\n\n this._listener?.dispose();\n this._listener = null;\n\n // Note that OfflineAudioContext does not have a `close` method.\n if (this._audioContext.state !== \"closed\" && !this._isUsingOfflineAudioContext) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this._audioContext.close();\n }\n\n document.removeEventListener(\"click\", this._onUserGestureAsync);\n this._audioContext.removeEventListener(\"statechange\", this._onAudioContextStateChange);\n\n this._silentHtmlAudio?.remove();\n\n this._updateObservable?.clear();\n this._updateObservable = null;\n\n this._unmuteUI?.dispose();\n this._unmuteUI = null;\n\n this.stateChangedObservable.clear();\n }\n\n /** @internal */\n public flagInvalidFormat(format: string): void {\n this._invalidFormats.add(format);\n }\n\n /** @internal */\n public isFormatValid(format: string): boolean {\n if (this._validFormats.has(format)) {\n return true;\n }\n\n if (this._invalidFormats.has(format)) {\n return false;\n }\n\n const mimeType = FormatMimeTypes[format];\n if (mimeType === undefined) {\n return false;\n }\n\n const audio = new Audio();\n if (audio.canPlayType(mimeType) === \"\") {\n this._invalidFormats.add(format);\n return false;\n }\n\n this._validFormats.add(format);\n\n return true;\n }\n\n /** @internal */\n public override async pauseAsync(): Promise<void> {\n await this._audioContext.suspend();\n\n this._pauseCalled = true;\n }\n\n /** @internal */\n // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax\n public override resumeAsync(): Promise<void> {\n this._pauseCalled = false;\n\n if (this._resumePromise) {\n return this._resumePromise;\n }\n\n this._resumePromise = this._audioContext.resume();\n\n this.stateChangedObservable.notifyObservers(this.state);\n\n return this._resumePromise;\n }\n\n /** @internal */\n public setVolume(value: number, options: Nullable<Partial<IAudioParameterRampOptions>> = null): void {\n if (this._mainOut) {\n this._mainOut.setVolume(value, options);\n } else {\n throw new Error(\"Main output not initialized yet.\");\n }\n }\n\n /** @internal */\n public override _addMainBus(mainBus: MainAudioBus): void {\n super._addMainBus(mainBus);\n }\n\n /** @internal */\n public override _removeMainBus(mainBus: MainAudioBus): void {\n super._removeMainBus(mainBus);\n }\n\n /** @internal */\n public override _addNode(node: AbstractNamedAudioNode): void {\n super._addNode(node);\n }\n\n /** @internal */\n public override _removeNode(node: AbstractNamedAudioNode): void {\n super._removeNode(node);\n }\n\n /** @internal */\n public override _addSound(sound: AbstractSound): void {\n super._addSound(sound);\n }\n\n /** @internal */\n public override _removeSound(sound: AbstractSound): void {\n super._removeSound(sound);\n }\n\n /** @internal */\n public override _onSoundPlaybackStateChanged(): void {\n if (!this._silentHtmlAudio) {\n return;\n }\n\n const hasActiveSounds = this.sounds.some((s) => s.state === SoundState.Started || s.state === SoundState.Starting || s.state === SoundState.Stopping);\n\n if (hasActiveSounds && this._silentHtmlAudio.paused) {\n // Resume silent audio for iOS ringer switch workaround while sounds are playing.\n // Errors are safe to ignore — the silent audio element is a workaround, not a\n // user-facing sound, so a rejected play (e.g. missing user gesture) is harmless.\n // eslint-disable-next-line github/no-then\n void this._silentHtmlAudio.play().catch(() => {});\n } else if (!hasActiveSounds && !this._silentHtmlAudio.paused) {\n // Pause silent audio when no sounds are playing to avoid triggering iOS Safari's\n // audio playback detection, which causes FPS throttling and shows a blue audio icon.\n this._silentHtmlAudio.pause();\n }\n }\n\n /** @internal */\n public _addUpdateObserver(callback: () => void): void {\n if (!this._updateObservable) {\n this._updateObservable = new Observable<void>();\n }\n\n this._updateObservable.add(callback);\n this._startUpdating();\n }\n\n public _removeUpdateObserver(callback: () => void): void {\n if (this._updateObservable) {\n this._updateObservable.removeCallback(callback);\n }\n }\n\n private _initAudioContextAsync: () => Promise<void> = async () => {\n this._audioContext.addEventListener(\"statechange\", this._onAudioContextStateChange);\n\n this._mainOut = new _WebAudioMainOut(this);\n this._mainOut.volume = this._volume;\n\n await this.createMainBusAsync(\"default\");\n };\n\n private _onAudioContextStateChange = () => {\n if (this.state === \"running\") {\n clearInterval(this._resumeOnPauseTimerId);\n this._audioContextStarted = true;\n this._resumePromise = null;\n }\n if (this.state === \"suspended\" || this.state === \"interrupted\") {\n if (this._audioContextStarted && this._resumeOnPause && !this._pauseCalled) {\n clearInterval(this._resumeOnPauseTimerId);\n\n this._resumeOnPauseTimerId = setInterval(() => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.resumeAsync();\n }, this._resumeOnPauseRetryInterval);\n }\n }\n\n this.stateChangedObservable.notifyObservers(this.state);\n };\n\n private _onUserGestureAsync: () => void = async () => {\n if (this._resumeOnInteraction) {\n await this._audioContext.resume();\n }\n\n // On iOS the ringer switch must be turned on for WebAudio to play.\n // This gets WebAudio to play with the ringer switch turned off by playing an HTMLAudioElement.\n // The element is activated during a user gesture so it can be played/paused programmatically\n // later. It is immediately paused to avoid triggering iOS Safari's \"now playing\" detection,\n // which throttles the page to 30 FPS.\n if (!this._silentHtmlAudio) {\n this._silentHtmlAudio = document.createElement(\"audio\");\n\n const audio = this._silentHtmlAudio;\n audio.controls = false;\n audio.preload = \"auto\";\n audio.loop = true;\n\n // Wave data for 0.0001 seconds of silence.\n audio.src = \"data:audio/wav;base64,UklGRjAAAABXQVZFZm10IBAAAAABAAEAgLsAAAB3AQACABAAZGF0YQwAAAAAAAEA/v8CAP//AQA=\";\n\n // Play briefly to activate the element, then immediately pause.\n // The rejection handler is intentionally empty — play() can reject if the\n // browser requires a more specific user gesture; this is non-fatal since\n // the audio context unlock is the primary goal, and the silent element is\n // only a supplementary iOS ringer-switch workaround.\n // eslint-disable-next-line github/no-then\n audio.play().then(\n () => audio.pause(),\n () => {}\n );\n }\n\n this.userGestureObservable.notifyObservers();\n };\n\n private _resolveIsReadyPromise: () => void;\n\n private _startUpdating = () => {\n if (this._isUpdating) {\n return;\n }\n\n this._isUpdating = true;\n\n if (this.state === \"running\") {\n this._update();\n } else {\n const callback = () => {\n if (this.state === \"running\") {\n this._update();\n this.stateChangedObservable.removeCallback(callback);\n }\n };\n\n this.stateChangedObservable.add(callback);\n }\n };\n\n private _update = (): void => {\n if (this._updateObservable?.hasObservers()) {\n this._updateObservable.notifyObservers();\n requestAnimationFrame(this._update);\n } else {\n this._isUpdating = false;\n }\n };\n}\n"]}
@@ -10,12 +10,28 @@ export declare class _WebAudioSoundSource extends AbstractSoundSource {
10
10
  private _stereo;
11
11
  protected _subGraph: _WebAudioBusAndSoundSubGraph;
12
12
  protected _webAudioNode: Nullable<AudioNode>;
13
+ private _mediaStreamAudioElement;
14
+ private _stopMediaStreamTracksOnDispose;
13
15
  /** @internal */
14
16
  _audioContext: AudioContext | OfflineAudioContext;
15
17
  /** @internal */
16
18
  readonly engine: _WebAudioEngine;
17
19
  /** @internal */
18
20
  constructor(name: string, webAudioNode: AudioNode, engine: _WebAudioEngine, options: Partial<ISoundSourceOptions>);
21
+ /**
22
+ * Keeps a `MediaStream`-backed source audible by attaching the stream to a hidden, muted audio element.
23
+ *
24
+ * Some browsers (notably Chromium) only deliver samples from a `MediaStreamAudioSourceNode` while its `MediaStream`
25
+ * is also being pulled by an `HTMLMediaElement`; without this, a remote WebRTC stream routed through Web Audio is
26
+ * silent and cannot be spatialized. The element is muted so it does not add a second, non-spatial playback.
27
+ * @param mediaStream - the `MediaStream` backing this sound source
28
+ */
29
+ private _attachMediaStreamSink;
30
+ /**
31
+ * Starts best-effort playback of the muted keep-alive media element.
32
+ * @param mediaElement - the muted media element pulling the source `MediaStream`
33
+ */
34
+ private _startMediaStreamSinkAsync;
19
35
  /** @internal */
20
36
  _initAsync(options: Partial<ISoundSourceOptions>): Promise<void>;
21
37
  /** @internal */
@@ -10,10 +10,47 @@ export class _WebAudioSoundSource extends AbstractSoundSource {
10
10
  super(name, engine, options);
11
11
  this._stereo = null;
12
12
  this._webAudioNode = null;
13
+ this._mediaStreamAudioElement = null;
14
+ this._stopMediaStreamTracksOnDispose = false;
13
15
  this._audioContext = this.engine._audioContext;
14
16
  this._webAudioNode = webAudioNode;
17
+ this._stopMediaStreamTracksOnDispose = options.stopMediaStreamTracksOnDispose === true;
18
+ if (options.mediaStreamSinkEnabled !== false && webAudioNode instanceof MediaStreamAudioSourceNode) {
19
+ this._attachMediaStreamSink(webAudioNode.mediaStream);
20
+ }
15
21
  this._subGraph = new _WebAudioSoundSource._SubGraph(this);
16
22
  }
23
+ /**
24
+ * Keeps a `MediaStream`-backed source audible by attaching the stream to a hidden, muted audio element.
25
+ *
26
+ * Some browsers (notably Chromium) only deliver samples from a `MediaStreamAudioSourceNode` while its `MediaStream`
27
+ * is also being pulled by an `HTMLMediaElement`; without this, a remote WebRTC stream routed through Web Audio is
28
+ * silent and cannot be spatialized. The element is muted so it does not add a second, non-spatial playback.
29
+ * @param mediaStream - the `MediaStream` backing this sound source
30
+ */
31
+ _attachMediaStreamSink(mediaStream) {
32
+ if (typeof Audio === "undefined") {
33
+ return;
34
+ }
35
+ const mediaElement = new Audio();
36
+ mediaElement.muted = true;
37
+ mediaElement.srcObject = mediaStream;
38
+ this._mediaStreamAudioElement = mediaElement;
39
+ void this._startMediaStreamSinkAsync(mediaElement);
40
+ }
41
+ /**
42
+ * Starts best-effort playback of the muted keep-alive media element.
43
+ * @param mediaElement - the muted media element pulling the source `MediaStream`
44
+ */
45
+ async _startMediaStreamSinkAsync(mediaElement) {
46
+ try {
47
+ // Muted media is allowed to autoplay without a user gesture.
48
+ await mediaElement.play();
49
+ }
50
+ catch {
51
+ // A rejected play() only means this browser-specific keep-alive is unavailable, which is non-fatal.
52
+ }
53
+ }
17
54
  /** @internal */
18
55
  async _initAsync(options) {
19
56
  if (options.outBus) {
@@ -44,8 +81,13 @@ export class _WebAudioSoundSource extends AbstractSoundSource {
44
81
  /** @internal */
45
82
  dispose() {
46
83
  super.dispose();
84
+ if (this._mediaStreamAudioElement) {
85
+ this._mediaStreamAudioElement.pause();
86
+ this._mediaStreamAudioElement.srcObject = null;
87
+ this._mediaStreamAudioElement = null;
88
+ }
47
89
  if (this._webAudioNode) {
48
- if (this._webAudioNode instanceof MediaStreamAudioSourceNode) {
90
+ if (this._stopMediaStreamTracksOnDispose && this._webAudioNode instanceof MediaStreamAudioSourceNode) {
49
91
  for (const track of this._webAudioNode.mediaStream.getTracks()) {
50
92
  track.stop();
51
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"webAudioSoundSource.js","sourceRoot":"","sources":["../../../../../dev/core/src/AudioV2/webAudio/webAudioSoundSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Nullable } from \"../../types\";\nimport { type AbstractAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport { type ISoundSourceOptions, AbstractSoundSource } from \"../abstractAudio/abstractSoundSource\";\nimport { type AbstractSpatialAudio, _HasSpatialAudioOptions } from \"../abstractAudio/subProperties/abstractSpatialAudio\";\nimport { _StereoAudio } from \"../abstractAudio/subProperties/stereoAudio\";\nimport { _WebAudioBusAndSoundSubGraph } from \"./subNodes/webAudioBusAndSoundSubGraph\";\nimport { _SpatialWebAudio } from \"./subProperties/spatialWebAudio\";\nimport { type _WebAudioEngine } from \"./webAudioEngine\";\nimport { type IWebAudioInNode } from \"./webAudioNode\";\n\n/** @internal */\nexport class _WebAudioSoundSource extends AbstractSoundSource {\n private _stereo: Nullable<_StereoAudio> = null;\n\n protected _subGraph: _WebAudioBusAndSoundSubGraph;\n protected _webAudioNode: Nullable<AudioNode> = null;\n\n /** @internal */\n public _audioContext: AudioContext | OfflineAudioContext;\n\n /** @internal */\n public override readonly engine: _WebAudioEngine;\n\n /** @internal */\n public constructor(name: string, webAudioNode: AudioNode, engine: _WebAudioEngine, options: Partial<ISoundSourceOptions>) {\n super(name, engine, options);\n\n this._audioContext = this.engine._audioContext;\n this._webAudioNode = webAudioNode;\n\n this._subGraph = new _WebAudioSoundSource._SubGraph(this);\n }\n\n /** @internal */\n public async _initAsync(options: Partial<ISoundSourceOptions>): Promise<void> {\n if (options.outBus) {\n this.outBus = options.outBus;\n } else if (options.outBusAutoDefault !== false) {\n await this.engine.isReadyPromise;\n this.outBus = this.engine.defaultMainBus;\n }\n\n await this._subGraph.initAsync(options);\n\n if (_HasSpatialAudioOptions(options)) {\n this._initSpatialProperty();\n }\n\n this.engine._addNode(this);\n }\n\n /** @internal */\n public get _inNode() {\n return this._webAudioNode;\n }\n\n /** @internal */\n public get _outNode() {\n return this._subGraph._outNode;\n }\n\n /** @internal */\n public override get stereo(): _StereoAudio {\n return this._stereo ?? (this._stereo = new _StereoAudio(this._subGraph));\n }\n\n /** @internal */\n public override dispose(): void {\n super.dispose();\n\n if (this._webAudioNode) {\n if (this._webAudioNode instanceof MediaStreamAudioSourceNode) {\n for (const track of this._webAudioNode.mediaStream.getTracks()) {\n track.stop();\n }\n }\n\n this._webAudioNode.disconnect();\n this._webAudioNode = null;\n }\n\n this._stereo = null;\n\n this._subGraph.dispose();\n\n this.engine._removeNode(this);\n }\n\n /** @internal */\n public getClassName(): string {\n return \"_WebAudioSoundSource\";\n }\n\n protected override _connect(node: IWebAudioInNode): boolean {\n const connected = super._connect(node);\n\n if (!connected) {\n return false;\n }\n\n // If the wrapped node is not available now, it will be connected later by the subgraph.\n if (node._inNode) {\n this._outNode?.connect(node._inNode);\n }\n\n return true;\n }\n\n protected override _disconnect(node: IWebAudioInNode): boolean {\n const disconnected = super._disconnect(node);\n\n if (!disconnected) {\n return false;\n }\n\n if (node._inNode) {\n this._outNode?.disconnect(node._inNode);\n }\n\n return true;\n }\n\n protected override _createSpatialProperty(autoUpdate: boolean, minUpdateTime: number): AbstractSpatialAudio {\n return new _SpatialWebAudio(this._subGraph, autoUpdate, minUpdateTime);\n }\n\n private static _SubGraph = class extends _WebAudioBusAndSoundSubGraph {\n protected override _owner: _WebAudioSoundSource;\n\n protected get _downstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n return this._owner._downstreamNodes ?? null;\n }\n\n protected get _upstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n return this._owner._upstreamNodes ?? null;\n }\n\n protected override _onSubNodesChanged(): void {\n super._onSubNodesChanged();\n\n this._owner._inNode?.disconnect();\n\n if (this._owner._subGraph._inNode) {\n this._owner._inNode?.connect(this._owner._subGraph._inNode);\n }\n }\n };\n}\n"]}
1
+ {"version":3,"file":"webAudioSoundSource.js","sourceRoot":"","sources":["../../../../../dev/core/src/AudioV2/webAudio/webAudioSoundSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Nullable } from \"../../types\";\nimport { type AbstractAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport { type ISoundSourceOptions, AbstractSoundSource } from \"../abstractAudio/abstractSoundSource\";\nimport { type AbstractSpatialAudio, _HasSpatialAudioOptions } from \"../abstractAudio/subProperties/abstractSpatialAudio\";\nimport { _StereoAudio } from \"../abstractAudio/subProperties/stereoAudio\";\nimport { _WebAudioBusAndSoundSubGraph } from \"./subNodes/webAudioBusAndSoundSubGraph\";\nimport { _SpatialWebAudio } from \"./subProperties/spatialWebAudio\";\nimport { type _WebAudioEngine } from \"./webAudioEngine\";\nimport { type IWebAudioInNode } from \"./webAudioNode\";\n\n/** @internal */\nexport class _WebAudioSoundSource extends AbstractSoundSource {\n private _stereo: Nullable<_StereoAudio> = null;\n\n protected _subGraph: _WebAudioBusAndSoundSubGraph;\n protected _webAudioNode: Nullable<AudioNode> = null;\n\n private _mediaStreamAudioElement: Nullable<HTMLAudioElement> = null;\n private _stopMediaStreamTracksOnDispose = false;\n\n /** @internal */\n public _audioContext: AudioContext | OfflineAudioContext;\n\n /** @internal */\n public override readonly engine: _WebAudioEngine;\n\n /** @internal */\n public constructor(name: string, webAudioNode: AudioNode, engine: _WebAudioEngine, options: Partial<ISoundSourceOptions>) {\n super(name, engine, options);\n\n this._audioContext = this.engine._audioContext;\n this._webAudioNode = webAudioNode;\n\n this._stopMediaStreamTracksOnDispose = options.stopMediaStreamTracksOnDispose === true;\n\n if (options.mediaStreamSinkEnabled !== false && webAudioNode instanceof MediaStreamAudioSourceNode) {\n this._attachMediaStreamSink(webAudioNode.mediaStream);\n }\n\n this._subGraph = new _WebAudioSoundSource._SubGraph(this);\n }\n\n /**\n * Keeps a `MediaStream`-backed source audible by attaching the stream to a hidden, muted audio element.\n *\n * Some browsers (notably Chromium) only deliver samples from a `MediaStreamAudioSourceNode` while its `MediaStream`\n * is also being pulled by an `HTMLMediaElement`; without this, a remote WebRTC stream routed through Web Audio is\n * silent and cannot be spatialized. The element is muted so it does not add a second, non-spatial playback.\n * @param mediaStream - the `MediaStream` backing this sound source\n */\n private _attachMediaStreamSink(mediaStream: MediaStream): void {\n if (typeof Audio === \"undefined\") {\n return;\n }\n\n const mediaElement = new Audio();\n mediaElement.muted = true;\n mediaElement.srcObject = mediaStream;\n this._mediaStreamAudioElement = mediaElement;\n\n void this._startMediaStreamSinkAsync(mediaElement);\n }\n\n /**\n * Starts best-effort playback of the muted keep-alive media element.\n * @param mediaElement - the muted media element pulling the source `MediaStream`\n */\n private async _startMediaStreamSinkAsync(mediaElement: HTMLAudioElement): Promise<void> {\n try {\n // Muted media is allowed to autoplay without a user gesture.\n await mediaElement.play();\n } catch {\n // A rejected play() only means this browser-specific keep-alive is unavailable, which is non-fatal.\n }\n }\n\n /** @internal */\n public async _initAsync(options: Partial<ISoundSourceOptions>): Promise<void> {\n if (options.outBus) {\n this.outBus = options.outBus;\n } else if (options.outBusAutoDefault !== false) {\n await this.engine.isReadyPromise;\n this.outBus = this.engine.defaultMainBus;\n }\n\n await this._subGraph.initAsync(options);\n\n if (_HasSpatialAudioOptions(options)) {\n this._initSpatialProperty();\n }\n\n this.engine._addNode(this);\n }\n\n /** @internal */\n public get _inNode() {\n return this._webAudioNode;\n }\n\n /** @internal */\n public get _outNode() {\n return this._subGraph._outNode;\n }\n\n /** @internal */\n public override get stereo(): _StereoAudio {\n return this._stereo ?? (this._stereo = new _StereoAudio(this._subGraph));\n }\n\n /** @internal */\n public override dispose(): void {\n super.dispose();\n\n if (this._mediaStreamAudioElement) {\n this._mediaStreamAudioElement.pause();\n this._mediaStreamAudioElement.srcObject = null;\n this._mediaStreamAudioElement = null;\n }\n\n if (this._webAudioNode) {\n if (this._stopMediaStreamTracksOnDispose && this._webAudioNode instanceof MediaStreamAudioSourceNode) {\n for (const track of this._webAudioNode.mediaStream.getTracks()) {\n track.stop();\n }\n }\n\n this._webAudioNode.disconnect();\n this._webAudioNode = null;\n }\n\n this._stereo = null;\n\n this._subGraph.dispose();\n\n this.engine._removeNode(this);\n }\n\n /** @internal */\n public getClassName(): string {\n return \"_WebAudioSoundSource\";\n }\n\n protected override _connect(node: IWebAudioInNode): boolean {\n const connected = super._connect(node);\n\n if (!connected) {\n return false;\n }\n\n // If the wrapped node is not available now, it will be connected later by the subgraph.\n if (node._inNode) {\n this._outNode?.connect(node._inNode);\n }\n\n return true;\n }\n\n protected override _disconnect(node: IWebAudioInNode): boolean {\n const disconnected = super._disconnect(node);\n\n if (!disconnected) {\n return false;\n }\n\n if (node._inNode) {\n this._outNode?.disconnect(node._inNode);\n }\n\n return true;\n }\n\n protected override _createSpatialProperty(autoUpdate: boolean, minUpdateTime: number): AbstractSpatialAudio {\n return new _SpatialWebAudio(this._subGraph, autoUpdate, minUpdateTime);\n }\n\n private static _SubGraph = class extends _WebAudioBusAndSoundSubGraph {\n protected override _owner: _WebAudioSoundSource;\n\n protected get _downstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n return this._owner._downstreamNodes ?? null;\n }\n\n protected get _upstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n return this._owner._upstreamNodes ?? null;\n }\n\n protected override _onSubNodesChanged(): void {\n super._onSubNodesChanged();\n\n this._owner._inNode?.disconnect();\n\n if (this._owner._subGraph._inNode) {\n this._owner._inNode?.connect(this._owner._subGraph._inNode);\n }\n }\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { Bone } from "./bone.js";
2
2
  import { Matrix } from "../Maths/math.vector.pure.js";
3
3
  import { Mesh } from "../Meshes/mesh.pure.js";
4
- import { MeshBuilder } from "../Meshes/meshBuilder.js";
4
+ import { MeshBuilder } from "../Meshes/meshBuilder.pure.js";
5
5
  import { VertexBuffer } from "../Buffers/buffer.pure.js";
6
6
  import { Skeleton } from "./skeleton.js";
7
7
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.functions.js","sourceRoot":"","sources":["../../../../dev/core/src/Bones/skeleton.functions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Bone } from \"./bone\";\r\nimport { Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type TransformNode } from \"core/Meshes/transformNode\";\r\nimport { Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { MeshBuilder } from \"core/Meshes/meshBuilder\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer.pure\";\r\nimport { Skeleton } from \"./skeleton\";\r\n\r\n/**\r\n * Creates a skeleton from a hierarchy of transform nodes by converting each node into a bone.\r\n * Each transform node in the hierarchy will be linked to its corresponding bone, allowing the skeleton\r\n * to be driven by the transform node transformations.\r\n * @param rootNode The root transform node of the hierarchy to convert into a skeleton\r\n * @param scene The scene in which to create the skeleton\r\n * @param options Optional parameters for skeleton creation\r\n * - name: The name for the created skeleton (defaults to rootNode.name + \"_skeleton\")\r\n * - boneMeshSize: The diameter of the sphere mesh created for each bone (defaults to 1, only used if createMesh is true)\r\n * - createMesh: If true, creates a mesh with spheres at each bone location for visualization purposes.\r\n * The mesh will be parented to the rootNode's parent and returned through options.mesh\r\n * - mesh: An existing mesh to attach the skeleton to. If provided, the skeleton will be assigned to this mesh\r\n * @returns A new skeleton with bones corresponding to the transform node hierarchy\r\n * @remarks\r\n * - Only transform nodes with a rotationQuaternion property will be converted into bones\r\n */\r\nexport function CreateSkeletonFromTransformNodeHierarchy(\r\n rootNode: TransformNode,\r\n scene: Scene,\r\n options?: { name?: string; boneMeshSize?: number; createMesh?: boolean; mesh?: Mesh }\r\n): Skeleton {\r\n const name = options?.name || rootNode.name + \"_skeleton\";\r\n const skeleton = new Skeleton(name, name, scene);\r\n\r\n const nodes = rootNode.getChildTransformNodes(false);\r\n\r\n nodes.unshift(rootNode);\r\n\r\n let mesh = options?.mesh || null;\r\n if (options?.createMesh) {\r\n mesh = new Mesh(`${name}_mesh`, scene);\r\n mesh.parent = rootNode.parent;\r\n mesh.skeleton = skeleton;\r\n\r\n options.mesh = mesh;\r\n } else if (mesh) {\r\n mesh.skeleton = skeleton;\r\n }\r\n\r\n const positions: number[] = [];\r\n const indices: number[] = [];\r\n const normals: number[] = [];\r\n const boneIndices: number[] = [];\r\n const boneWeights: number[] = [];\r\n\r\n const boneMesh = options?.createMesh ? MeshBuilder.CreateSphere(\"dummy\", { diameter: options?.boneMeshSize || 1, segments: 8 }, scene) : null;\r\n\r\n const boneMeshNumVertices = boneMesh?.getTotalVertices() || 0;\r\n const boneMeshPositions = boneMesh?.getVerticesData(VertexBuffer.PositionKind);\r\n const boneMeshIndices = boneMesh?.getIndices();\r\n const boneMeshNormals = boneMesh?.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n const mapNameToBone: { [name: string]: Bone } = {};\r\n\r\n for (const node of nodes) {\r\n if (!node.rotationQuaternion || node.getClassName() !== \"TransformNode\") {\r\n continue;\r\n }\r\n\r\n const currentVertexIndex = positions.length / 3;\r\n\r\n if (boneMeshPositions) {\r\n for (let i = 0; i < boneMeshPositions.length; ++i) {\r\n positions.push(boneMeshPositions[i]);\r\n }\r\n }\r\n if (boneMeshNormals) {\r\n for (let i = 0; i < boneMeshNormals.length; ++i) {\r\n normals.push(boneMeshNormals[i]);\r\n }\r\n }\r\n\r\n const boneIndex = skeleton.bones.length;\r\n\r\n if (boneMesh) {\r\n for (let i = 0; i < boneMeshNumVertices; ++i) {\r\n boneIndices.push(boneIndex, -1, -1, -1);\r\n boneWeights.push(1, 0, 0, 0);\r\n }\r\n }\r\n\r\n if (boneMeshIndices) {\r\n for (let i = 0; i < boneMeshIndices.length; ++i) {\r\n indices.push(currentVertexIndex + boneMeshIndices[i]);\r\n }\r\n }\r\n\r\n const bone = new Bone(\r\n node.name,\r\n skeleton,\r\n node.parent ? mapNameToBone[node.parent.name] : null,\r\n Matrix.Compose(node.scaling, node.rotationQuaternion, node.position), // local matrix\r\n undefined,\r\n Matrix.Identity() // bind matrix\r\n );\r\n\r\n bone.linkTransformNode(node);\r\n\r\n mapNameToBone[node.name] = bone;\r\n }\r\n\r\n mesh?.setVerticesData(VertexBuffer.PositionKind, positions);\r\n mesh?.setVerticesData(VertexBuffer.NormalKind, normals);\r\n mesh?.setVerticesData(VertexBuffer.MatricesIndicesKind, boneIndices);\r\n mesh?.setVerticesData(VertexBuffer.MatricesWeightsKind, boneWeights);\r\n mesh?.setIndices(indices);\r\n\r\n mesh?.refreshBoundingInfo(true, false);\r\n\r\n boneMesh?.dispose();\r\n\r\n return skeleton;\r\n}\r\n"]}
1
+ {"version":3,"file":"skeleton.functions.js","sourceRoot":"","sources":["../../../../dev/core/src/Bones/skeleton.functions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Bone } from \"./bone\";\r\nimport { Matrix } from \"../Maths/math.vector.pure\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type TransformNode } from \"core/Meshes/transformNode\";\r\nimport { Mesh } from \"core/Meshes/mesh.pure\";\r\nimport { MeshBuilder } from \"core/Meshes/meshBuilder.pure\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer.pure\";\r\nimport { Skeleton } from \"./skeleton\";\r\n\r\n/**\r\n * Creates a skeleton from a hierarchy of transform nodes by converting each node into a bone.\r\n * Each transform node in the hierarchy will be linked to its corresponding bone, allowing the skeleton\r\n * to be driven by the transform node transformations.\r\n * @param rootNode The root transform node of the hierarchy to convert into a skeleton\r\n * @param scene The scene in which to create the skeleton\r\n * @param options Optional parameters for skeleton creation\r\n * - name: The name for the created skeleton (defaults to rootNode.name + \"_skeleton\")\r\n * - boneMeshSize: The diameter of the sphere mesh created for each bone (defaults to 1, only used if createMesh is true)\r\n * - createMesh: If true, creates a mesh with spheres at each bone location for visualization purposes.\r\n * The mesh will be parented to the rootNode's parent and returned through options.mesh\r\n * - mesh: An existing mesh to attach the skeleton to. If provided, the skeleton will be assigned to this mesh\r\n * @returns A new skeleton with bones corresponding to the transform node hierarchy\r\n * @remarks\r\n * - Only transform nodes with a rotationQuaternion property will be converted into bones\r\n */\r\nexport function CreateSkeletonFromTransformNodeHierarchy(\r\n rootNode: TransformNode,\r\n scene: Scene,\r\n options?: { name?: string; boneMeshSize?: number; createMesh?: boolean; mesh?: Mesh }\r\n): Skeleton {\r\n const name = options?.name || rootNode.name + \"_skeleton\";\r\n const skeleton = new Skeleton(name, name, scene);\r\n\r\n const nodes = rootNode.getChildTransformNodes(false);\r\n\r\n nodes.unshift(rootNode);\r\n\r\n let mesh = options?.mesh || null;\r\n if (options?.createMesh) {\r\n mesh = new Mesh(`${name}_mesh`, scene);\r\n mesh.parent = rootNode.parent;\r\n mesh.skeleton = skeleton;\r\n\r\n options.mesh = mesh;\r\n } else if (mesh) {\r\n mesh.skeleton = skeleton;\r\n }\r\n\r\n const positions: number[] = [];\r\n const indices: number[] = [];\r\n const normals: number[] = [];\r\n const boneIndices: number[] = [];\r\n const boneWeights: number[] = [];\r\n\r\n const boneMesh = options?.createMesh ? MeshBuilder.CreateSphere(\"dummy\", { diameter: options?.boneMeshSize || 1, segments: 8 }, scene) : null;\r\n\r\n const boneMeshNumVertices = boneMesh?.getTotalVertices() || 0;\r\n const boneMeshPositions = boneMesh?.getVerticesData(VertexBuffer.PositionKind);\r\n const boneMeshIndices = boneMesh?.getIndices();\r\n const boneMeshNormals = boneMesh?.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n const mapNameToBone: { [name: string]: Bone } = {};\r\n\r\n for (const node of nodes) {\r\n if (!node.rotationQuaternion || node.getClassName() !== \"TransformNode\") {\r\n continue;\r\n }\r\n\r\n const currentVertexIndex = positions.length / 3;\r\n\r\n if (boneMeshPositions) {\r\n for (let i = 0; i < boneMeshPositions.length; ++i) {\r\n positions.push(boneMeshPositions[i]);\r\n }\r\n }\r\n if (boneMeshNormals) {\r\n for (let i = 0; i < boneMeshNormals.length; ++i) {\r\n normals.push(boneMeshNormals[i]);\r\n }\r\n }\r\n\r\n const boneIndex = skeleton.bones.length;\r\n\r\n if (boneMesh) {\r\n for (let i = 0; i < boneMeshNumVertices; ++i) {\r\n boneIndices.push(boneIndex, -1, -1, -1);\r\n boneWeights.push(1, 0, 0, 0);\r\n }\r\n }\r\n\r\n if (boneMeshIndices) {\r\n for (let i = 0; i < boneMeshIndices.length; ++i) {\r\n indices.push(currentVertexIndex + boneMeshIndices[i]);\r\n }\r\n }\r\n\r\n const bone = new Bone(\r\n node.name,\r\n skeleton,\r\n node.parent ? mapNameToBone[node.parent.name] : null,\r\n Matrix.Compose(node.scaling, node.rotationQuaternion, node.position), // local matrix\r\n undefined,\r\n Matrix.Identity() // bind matrix\r\n );\r\n\r\n bone.linkTransformNode(node);\r\n\r\n mapNameToBone[node.name] = bone;\r\n }\r\n\r\n mesh?.setVerticesData(VertexBuffer.PositionKind, positions);\r\n mesh?.setVerticesData(VertexBuffer.NormalKind, normals);\r\n mesh?.setVerticesData(VertexBuffer.MatricesIndicesKind, boneIndices);\r\n mesh?.setVerticesData(VertexBuffer.MatricesWeightsKind, boneWeights);\r\n mesh?.setIndices(indices);\r\n\r\n mesh?.refreshBoundingInfo(true, false);\r\n\r\n boneMesh?.dispose();\r\n\r\n return skeleton;\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"inputMapper.js","sourceRoot":"","sources":["../../../../dev/core/src/Cameras/inputMapper.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Physical input source that generated an interaction.\r\n */\r\nexport type InputSource = \"pointer\" | \"wheel\" | \"touch\" | \"keyboard\";\r\n\r\n/**\r\n * Modifier key state, shared across input sources that support modifiers.\r\n */\r\nexport type InputModifiers = {\r\n /** Ctrl key pressed */\r\n ctrl?: boolean;\r\n /** Shift key pressed */\r\n shift?: boolean;\r\n /** Alt key pressed */\r\n alt?: boolean;\r\n};\r\n\r\n// ── Per-source condition shapes ────────────────────────────────────\r\n\r\n/**\r\n * Conditions for pointer inputs.\r\n */\r\nexport type PointerConditions = {\r\n /** Mouse button (0=left, 1=middle, 2=right). Omit to match any button. */\r\n button?: number;\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for mouse wheel inputs.\r\n */\r\nexport type WheelConditions = {\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for touch inputs.\r\n */\r\nexport type TouchConditions = {\r\n /** Number of active touch points. Omit to match any count. */\r\n touchCount?: number;\r\n};\r\n\r\n/**\r\n * Conditions for keyboard inputs.\r\n */\r\nexport type KeyboardConditions = {\r\n /** Key code of the current key being resolved. Omit to match any key. */\r\n key?: number;\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n// ── Per-source inputMap entry types ────────────────────────────────\r\n\r\n/**\r\n * Mapping rule for pointer (mouse button) inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type PointerInputMapEntry<TInteraction extends string = string> = {\r\n source: \"pointer\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Optional per-axis override for the X (horizontal / yaw) component. Falls back to `sensitivity` if unset. */\r\n sensitivityX?: number;\r\n /** Optional per-axis override for the Y (vertical / pitch) component. Falls back to `sensitivity` if unset. */\r\n sensitivityY?: number;\r\n} & PointerConditions;\r\n\r\n/**\r\n * Mapping rule for mouse wheel inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type WheelInputMapEntry<TInteraction extends string = string> = {\r\n source: \"wheel\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n} & WheelConditions;\r\n\r\n/**\r\n * Mapping rule for touch inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type TouchInputMapEntry<TInteraction extends string = string> = {\r\n source: \"touch\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Optional per-axis override for the X component. Falls back to `sensitivity` if unset. */\r\n sensitivityX?: number;\r\n /** Optional per-axis override for the Y component. Falls back to `sensitivity` if unset. */\r\n sensitivityY?: number;\r\n} & TouchConditions;\r\n\r\n/**\r\n * Mapping rule for keyboard inputs.\r\n * The `key` field on the entry supports a single key code or an array of key codes for matching.\r\n * When resolving, the condition's `key` is checked against the entry's `key` value(s).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type KeyboardInputMapEntry<TInteraction extends string = string> = {\r\n /** Discriminator: keyboard input source */\r\n source: \"keyboard\";\r\n /** Interaction type to dispatch when this entry matches */\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Key code filter(s). Supports a single code or an array. Omit to match any key. */\r\n key?: number | number[];\r\n /** Modifier keys that must be active for this entry to match. Omit to match regardless of modifiers. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * A single mapping rule: source + optional conditions → interaction type.\r\n * The inputMap is an ordered array on the movement class; first matching entry wins.\r\n * The interaction string should match a handler property name on the camera's movement subclass.\r\n *\r\n * Discriminated union by `source` — only fields relevant to that source are available.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InputMapEntry<TInteraction extends string = string> =\r\n | PointerInputMapEntry<TInteraction>\r\n | WheelInputMapEntry<TInteraction>\r\n | TouchInputMapEntry<TInteraction>\r\n | KeyboardInputMapEntry<TInteraction>;\r\n\r\n/**\r\n * Flat conditions object passed to resolveInteraction().\r\n * Only the fields relevant to the source type need to be set.\r\n * Per-source condition types (PointerConditions, KeyboardConditions, etc.) are subtypes\r\n * of this and should be used at call sites for clarity.\r\n */\r\nexport type InputConditions = {\r\n /** Mouse button (0=left, 1=middle, 2=right) */\r\n button?: number;\r\n /** Current modifier key state */\r\n modifiers?: InputModifiers;\r\n /** Number of active touch points */\r\n touchCount?: number;\r\n /** Key code of the current key being resolved */\r\n key?: number;\r\n};\r\n\r\n/**\r\n * Extracts the string-typed interaction names from a handlers object type.\r\n * Equivalent to `keyof THandlers & string` — filters out symbol/number keys.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InteractionName<THandlers> = keyof THandlers & string;\r\n\r\n/**\r\n * Generic input-to-interaction mapper that resolves physical input events to semantic interaction types\r\n * and dispatches them to typed handlers.\r\n *\r\n * `InputMapper` is not tied to cameras — any object that needs a configurable, prioritized\r\n * mapping from physical inputs (pointer, keyboard, wheel, touch) to named interactions can use it.\r\n *\r\n * The mapper holds an ordered `inputMap` array. When `resolveInteraction` is called, the first\r\n * entry whose source and conditions match the current input wins. More specific entries (with more\r\n * conditions like button, key, modifiers) should be placed before less specific ones; use `addEntry`\r\n * to auto-insert based on specificity.\r\n *\r\n * @typeParam THandlers - Object type whose keys are the valid interaction type strings and values\r\n * are the handler functions/objects for each interaction (e.g. `ArcRotateHandlers`).\r\n * Interaction types are derived as `InteractionName<THandlers>`.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class InputMapper<THandlers extends Record<string, unknown>> {\r\n /**\r\n * Ordered list of input-to-interaction mapping rules. First matching entry wins.\r\n */\r\n public inputMap: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n\r\n /**\r\n * Interaction handlers keyed by interaction type.\r\n * Override individual handlers to customize behavior without changing input mapping.\r\n */\r\n public readonly handlers: THandlers;\r\n\r\n /**\r\n * Creates a new InputMapper.\r\n * @param handlers - The interaction handlers, keyed by interaction type.\r\n * @param createDefaultEntries - Optional factory that returns the default inputMap entries.\r\n * Called by `resetInputMap()` and during construction. When omitted, the default map is empty.\r\n */\r\n constructor(handlers: THandlers, createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[]) {\r\n this.handlers = handlers;\r\n this._createDefaultEntries = createDefaultEntries;\r\n this.resetInputMap();\r\n }\r\n\r\n private _createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[];\r\n\r\n /**\r\n * Resolves a physical input event to a matching inputMap entry.\r\n * Iterates the inputMap in order; the first entry whose source and conditions match wins.\r\n * @param source - The physical input source (e.g. \"pointer\", \"keyboard\")\r\n * @param currentConditions - Conditions to match against, specific to the source type\r\n * @returns The matched InputMapEntry, or null if no entry matches\r\n */\r\n public resolveInteraction(source: \"pointer\", currentConditions?: InputConditions): PointerInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"wheel\", currentConditions?: InputConditions): WheelInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"touch\", currentConditions?: InputConditions): TouchInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"keyboard\", currentConditions?: InputConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null {\r\n for (const entry of this.inputMap) {\r\n if (entry.source === source && this._entryMatches(entry, currentConditions)) {\r\n return entry;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Restores the inputMap to the default entries provided at construction time.\r\n * If no factory was provided, resets to an empty array.\r\n */\r\n public resetInputMap(): void {\r\n this.inputMap = this._createDefaultEntries?.() ?? [];\r\n }\r\n\r\n /**\r\n * Finds the first inputMap entry matching the given source, interaction, and optional entry conditions.\r\n * Useful for modifying entry properties (e.g. sensitivity) without rebuilding the entire inputMap.\r\n * @param source - The physical input source to match\r\n * @param interaction - The interaction type to match\r\n * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n * @returns The matching entry, or undefined if not found\r\n */\r\n public getEntry(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined {\r\n // Manual loop instead of `inputMap.find(arrow)` to avoid per-call closure allocation;\r\n // this is hit per pointer-move from multi-touch panning paths.\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const e = arr[i];\r\n if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n return e;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Finds all inputMap entries matching the given source, interaction, and optional entry conditions.\r\n * Useful for bulk updates when more than one physical input maps to the same interaction.\r\n * @param source - The physical input source to match\r\n * @param interaction - The interaction type to match\r\n * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n * @returns All matching entries, in inputMap order\r\n */\r\n public getEntries(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[] {\r\n const matches: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const e = arr[i];\r\n if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n matches.push(e);\r\n }\r\n }\r\n return matches;\r\n }\r\n\r\n /**\r\n * Adds an entry to the inputMap at the correct position based on specificity.\r\n * More specific entries (with more conditions like button, key, modifiers) are placed\r\n * before less specific ones, ensuring they match first. Among equally specific entries,\r\n * the new entry is placed after existing ones.\r\n * @param entry - The entry to add\r\n */\r\n public addEntry(entry: InputMapEntry<InteractionName<THandlers>>): void {\r\n const score = this._entrySpecificity(entry);\r\n let insertIndex = this.inputMap.length;\r\n for (let i = 0; i < this.inputMap.length; i++) {\r\n if (this._entrySpecificity(this.inputMap[i]) < score) {\r\n insertIndex = i;\r\n break;\r\n }\r\n }\r\n this.inputMap.splice(insertIndex, 0, entry);\r\n }\r\n\r\n /**\r\n * Sets the interaction for the input combination described by `conditions`. If an\r\n * existing entry maps that exact combination, its `interaction` is updated in place;\r\n * otherwise a new entry is inserted via {@link addEntry}.\r\n *\r\n * To force an update on every matching entry use {@link setInteractions}; to address\r\n * an individual entry beyond the first, look it up via {@link getEntries} and assign\r\n * `entry.interaction` directly.\r\n * @param source - The physical input source to match\r\n * @param conditions - Conditions describing the input combination (button, modifiers, key, etc.)\r\n * @param interaction - The interaction to assign / insert\r\n * @returns true (the mapping is always made effective)\r\n */\r\n public setInteraction(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): boolean {\r\n // resolveInteraction returns the first entry that fires for `conditions` (so its\r\n // conditions are no stricter than the request). If that entry also covers every\r\n // condition present in the request, it's an exact match — mutate. Otherwise it's\r\n // broader (or nothing matches): add a more-specific entry so we don't clobber the\r\n // broader one.\r\n const entry = this.resolveInteraction(source, conditions);\r\n if (entry && this._entryCoversAllConditionsOf(entry, conditions)) {\r\n entry.interaction = interaction;\r\n return true;\r\n }\r\n this.addEntry({ source, ...(conditions ?? {}), interaction } as InputMapEntry<InteractionName<THandlers>>);\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns true when `entry` constrains every field that `conditions` specifies — i.e.\r\n * `entry` covers all of the request's conditions. Used by {@link setInteraction} as one\r\n * half of the \"exactly as specific\" check: combined with {@link resolveInteraction}'s\r\n * guarantee that the returned entry is no *stricter* than the request, a true result\r\n * here means `entry` and `conditions` constrain the same fields, and mutating\r\n * `entry.interaction` is safe.\r\n *\r\n * On its own this predicate does not exclude entries that are stricter than `conditions`\r\n * (those would also trivially cover every field present in `conditions`); callers must\r\n * rely on the upstream resolve step to rule them out.\r\n *\r\n * `InputConditions` is a flat type covering all source-specific fields (`button`, `key`,\r\n * `touchCount`, `modifiers`); for any given source the irrelevant fields are `undefined`\r\n * on both `entry` and `conditions`, so checking them all is harmless.\r\n * @param entry - The matched inputMap entry to test\r\n * @param conditions - The conditions the caller supplied to `setInteraction`\r\n * @returns true if `entry` covers every condition present in `conditions`\r\n */\r\n private _entryCoversAllConditionsOf(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n if (!conditions) {\r\n return true;\r\n }\r\n // `as any` here because `entry` is a discriminated union and TypeScript can't narrow it\r\n // from a string-keyed loop. The runtime check is harmless: irrelevant-for-this-source\r\n // fields are undefined on both entry and conditions and skip the early return.\r\n const e = entry as any;\r\n for (const key of Object.keys(conditions) as (keyof InputConditions)[]) {\r\n const condValue = conditions[key];\r\n if (condValue === undefined) {\r\n continue;\r\n }\r\n if (key === \"modifiers\") {\r\n const entryMods = (e.modifiers ?? {}) as InputModifiers;\r\n for (const modKey of Object.keys(condValue) as (keyof InputModifiers)[]) {\r\n if ((condValue as InputModifiers)[modKey] !== undefined && entryMods[modKey] === undefined) {\r\n return false;\r\n }\r\n }\r\n } else if (e[key] === undefined) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Changes the interaction for every inputMap entry matching the given source and conditions.\r\n * Useful when more than one entry maps to the same physical input (e.g. duplicate bindings,\r\n * or several keys aliased to the same action) and all of them should be remapped together.\r\n * @param source - The physical input source to match\r\n * @param conditions - Conditions to match (button, modifiers, key, etc.). Uses the same\r\n * event-resolution semantics as {@link resolveInteraction}: omitted entry\r\n * condition fields are treated as wildcards and will match.\r\n * @param interaction - The new interaction to assign to every matched entry\r\n * @returns The number of entries that were updated\r\n */\r\n public setInteractions(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): number {\r\n let count = 0;\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const entry = arr[i];\r\n if (entry.source === source && this._entryMatches(entry, conditions)) {\r\n entry.interaction = interaction;\r\n count++;\r\n }\r\n }\r\n return count;\r\n }\r\n\r\n private _entryMatches(entry: InputMapEntry<InteractionName<THandlers>>, currentConditions?: InputConditions): boolean {\r\n switch (entry.source) {\r\n case \"pointer\":\r\n if (entry.button !== undefined && entry.button !== currentConditions?.button) {\r\n return false;\r\n }\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n case \"wheel\":\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n case \"touch\":\r\n if (entry.touchCount !== undefined && entry.touchCount !== currentConditions?.touchCount) {\r\n return false;\r\n }\r\n return true;\r\n case \"keyboard\":\r\n if (entry.key !== undefined) {\r\n if (Array.isArray(entry.key) ? entry.key.indexOf(currentConditions?.key ?? -1) === -1 : entry.key !== currentConditions?.key) {\r\n return false;\r\n }\r\n }\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n }\r\n }\r\n\r\n private _entryConditionsMatch(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n if (!conditions) {\r\n return true;\r\n }\r\n\r\n // NOTE: Uses the `\"key\" in conditions` form rather than `conditions.key !== undefined`\r\n // so that callers can explicitly target entries with no constraint via\r\n // `getEntries({ button: undefined })` — i.e. \"find catch-all entries that don't\r\n // require a specific button\". `!== undefined` would silently ignore a deliberate\r\n // `undefined` and behave like the property was omitted, which would be wrong here.\r\n switch (entry.source) {\r\n case \"pointer\":\r\n if (\"button\" in conditions && entry.button !== conditions.button) {\r\n return false;\r\n }\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n case \"wheel\":\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n case \"touch\":\r\n return !(\"touchCount\" in conditions) || entry.touchCount === conditions.touchCount;\r\n case \"keyboard\":\r\n if (\"key\" in conditions) {\r\n if (entry.key === undefined) {\r\n return conditions.key === undefined;\r\n }\r\n if (conditions.key === undefined || (Array.isArray(entry.key) ? entry.key.indexOf(conditions.key) === -1 : entry.key !== conditions.key)) {\r\n return false;\r\n }\r\n }\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n }\r\n }\r\n\r\n private _entrySpecificity(entry: InputMapEntry<InteractionName<THandlers>>): number {\r\n let score = 0;\r\n if (\"button\" in entry && entry.button !== undefined) {\r\n score++;\r\n }\r\n if (\"key\" in entry && entry.key !== undefined) {\r\n score++;\r\n }\r\n if (\"touchCount\" in entry && entry.touchCount !== undefined) {\r\n score++;\r\n }\r\n if (\"modifiers\" in entry && entry.modifiers) {\r\n score++;\r\n }\r\n return score;\r\n }\r\n\r\n private _matchModifiers(entryModifiers?: InputModifiers, currentModifiers?: InputModifiers): boolean {\r\n if (!entryModifiers) {\r\n return true;\r\n }\r\n if (entryModifiers.ctrl !== undefined && entryModifiers.ctrl !== (currentModifiers?.ctrl ?? false)) {\r\n return false;\r\n }\r\n if (entryModifiers.shift !== undefined && entryModifiers.shift !== (currentModifiers?.shift ?? false)) {\r\n return false;\r\n }\r\n if (entryModifiers.alt !== undefined && entryModifiers.alt !== (currentModifiers?.alt ?? false)) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private _entryModifiersMatch(entryModifiers?: InputModifiers, conditionsModifiers?: InputModifiers): boolean {\r\n if (!conditionsModifiers) {\r\n return !entryModifiers;\r\n }\r\n\r\n const hasModifierConditions = conditionsModifiers.ctrl !== undefined || conditionsModifiers.shift !== undefined || conditionsModifiers.alt !== undefined;\r\n if (!hasModifierConditions) {\r\n return !entryModifiers || (entryModifiers.ctrl === undefined && entryModifiers.shift === undefined && entryModifiers.alt === undefined);\r\n }\r\n\r\n if (conditionsModifiers.ctrl !== undefined && entryModifiers?.ctrl !== conditionsModifiers.ctrl) {\r\n return false;\r\n }\r\n if (conditionsModifiers.shift !== undefined && entryModifiers?.shift !== conditionsModifiers.shift) {\r\n return false;\r\n }\r\n if (conditionsModifiers.alt !== undefined && entryModifiers?.alt !== conditionsModifiers.alt) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"inputMapper.js","sourceRoot":"","sources":["../../../../dev/core/src/Cameras/inputMapper.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Physical input source that generated an interaction.\r\n */\r\nexport type InputSource = \"pointer\" | \"wheel\" | \"touch\" | \"keyboard\";\r\n\r\n/**\r\n * Modifier key state, shared across input sources that support modifiers.\r\n */\r\nexport type InputModifiers = {\r\n /** Ctrl key pressed */\r\n ctrl?: boolean;\r\n /** Shift key pressed */\r\n shift?: boolean;\r\n /** Alt key pressed */\r\n alt?: boolean;\r\n};\r\n\r\n// ── Per-source condition shapes ────────────────────────────────────\r\n\r\n/**\r\n * Conditions for pointer inputs.\r\n */\r\nexport type PointerConditions = {\r\n /** Mouse button (0=left, 1=middle, 2=right). Omit to match any button. */\r\n button?: number;\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for mouse wheel inputs.\r\n */\r\nexport type WheelConditions = {\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for touch inputs.\r\n */\r\nexport type TouchConditions = {\r\n /** Number of active touch points. Omit to match any count. */\r\n touchCount?: number;\r\n};\r\n\r\n/**\r\n * Conditions for keyboard inputs.\r\n */\r\nexport type KeyboardConditions = {\r\n /** Key code of the current key being resolved. Omit to match any key. */\r\n key?: number;\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n// ── Per-source inputMap entry types ────────────────────────────────\r\n\r\n/**\r\n * Mapping rule for pointer (mouse button) inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type PointerInputMapEntry<TInteraction extends string = string> = {\r\n source: \"pointer\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Optional per-axis override for the X (horizontal / yaw) component. Falls back to `sensitivity` if unset. */\r\n sensitivityX?: number;\r\n /** Optional per-axis override for the Y (vertical / pitch) component. Falls back to `sensitivity` if unset. */\r\n sensitivityY?: number;\r\n} & PointerConditions;\r\n\r\n/**\r\n * Mapping rule for mouse wheel inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type WheelInputMapEntry<TInteraction extends string = string> = {\r\n source: \"wheel\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n} & WheelConditions;\r\n\r\n/**\r\n * Mapping rule for touch inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type TouchInputMapEntry<TInteraction extends string = string> = {\r\n source: \"touch\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Optional per-axis override for the X component. Falls back to `sensitivity` if unset. */\r\n sensitivityX?: number;\r\n /** Optional per-axis override for the Y component. Falls back to `sensitivity` if unset. */\r\n sensitivityY?: number;\r\n} & TouchConditions;\r\n\r\n/**\r\n * Mapping rule for keyboard inputs.\r\n * The `key` field on the entry supports a single key code or an array of key codes for matching.\r\n * When resolving, the condition's `key` is checked against the entry's `key` value(s).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type KeyboardInputMapEntry<TInteraction extends string = string> = {\r\n /** Discriminator: keyboard input source */\r\n source: \"keyboard\";\r\n /** Interaction type to dispatch when this entry matches */\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Key code filter(s). Supports a single code or an array. Omit to match any key. */\r\n key?: number | number[];\r\n /** Modifier keys that must be active for this entry to match. Omit to match regardless of modifiers. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * A single mapping rule: source + optional conditions → interaction type.\r\n * The inputMap is an ordered array on the movement class; first matching entry wins.\r\n * The interaction string should match a handler property name on the camera's movement subclass.\r\n *\r\n * Discriminated union by `source` — only fields relevant to that source are available.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InputMapEntry<TInteraction extends string = string> =\r\n PointerInputMapEntry<TInteraction> | WheelInputMapEntry<TInteraction> | TouchInputMapEntry<TInteraction> | KeyboardInputMapEntry<TInteraction>;\r\n\r\n/**\r\n * Flat conditions object passed to resolveInteraction().\r\n * Only the fields relevant to the source type need to be set.\r\n * Per-source condition types (PointerConditions, KeyboardConditions, etc.) are subtypes\r\n * of this and should be used at call sites for clarity.\r\n */\r\nexport type InputConditions = {\r\n /** Mouse button (0=left, 1=middle, 2=right) */\r\n button?: number;\r\n /** Current modifier key state */\r\n modifiers?: InputModifiers;\r\n /** Number of active touch points */\r\n touchCount?: number;\r\n /** Key code of the current key being resolved */\r\n key?: number;\r\n};\r\n\r\n/**\r\n * Extracts the string-typed interaction names from a handlers object type.\r\n * Equivalent to `keyof THandlers & string` — filters out symbol/number keys.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InteractionName<THandlers> = keyof THandlers & string;\r\n\r\n/**\r\n * Generic input-to-interaction mapper that resolves physical input events to semantic interaction types\r\n * and dispatches them to typed handlers.\r\n *\r\n * `InputMapper` is not tied to cameras — any object that needs a configurable, prioritized\r\n * mapping from physical inputs (pointer, keyboard, wheel, touch) to named interactions can use it.\r\n *\r\n * The mapper holds an ordered `inputMap` array. When `resolveInteraction` is called, the first\r\n * entry whose source and conditions match the current input wins. More specific entries (with more\r\n * conditions like button, key, modifiers) should be placed before less specific ones; use `addEntry`\r\n * to auto-insert based on specificity.\r\n *\r\n * @typeParam THandlers - Object type whose keys are the valid interaction type strings and values\r\n * are the handler functions/objects for each interaction (e.g. `ArcRotateHandlers`).\r\n * Interaction types are derived as `InteractionName<THandlers>`.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class InputMapper<THandlers extends Record<string, unknown>> {\r\n /**\r\n * Ordered list of input-to-interaction mapping rules. First matching entry wins.\r\n */\r\n public inputMap: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n\r\n /**\r\n * Interaction handlers keyed by interaction type.\r\n * Override individual handlers to customize behavior without changing input mapping.\r\n */\r\n public readonly handlers: THandlers;\r\n\r\n /**\r\n * Creates a new InputMapper.\r\n * @param handlers - The interaction handlers, keyed by interaction type.\r\n * @param createDefaultEntries - Optional factory that returns the default inputMap entries.\r\n * Called by `resetInputMap()` and during construction. When omitted, the default map is empty.\r\n */\r\n constructor(handlers: THandlers, createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[]) {\r\n this.handlers = handlers;\r\n this._createDefaultEntries = createDefaultEntries;\r\n this.resetInputMap();\r\n }\r\n\r\n private _createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[];\r\n\r\n /**\r\n * Resolves a physical input event to a matching inputMap entry.\r\n * Iterates the inputMap in order; the first entry whose source and conditions match wins.\r\n * @param source - The physical input source (e.g. \"pointer\", \"keyboard\")\r\n * @param currentConditions - Conditions to match against, specific to the source type\r\n * @returns The matched InputMapEntry, or null if no entry matches\r\n */\r\n public resolveInteraction(source: \"pointer\", currentConditions?: InputConditions): PointerInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"wheel\", currentConditions?: InputConditions): WheelInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"touch\", currentConditions?: InputConditions): TouchInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"keyboard\", currentConditions?: InputConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null {\r\n for (const entry of this.inputMap) {\r\n if (entry.source === source && this._entryMatches(entry, currentConditions)) {\r\n return entry;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Restores the inputMap to the default entries provided at construction time.\r\n * If no factory was provided, resets to an empty array.\r\n */\r\n public resetInputMap(): void {\r\n this.inputMap = this._createDefaultEntries?.() ?? [];\r\n }\r\n\r\n /**\r\n * Finds the first inputMap entry matching the given source, interaction, and optional entry conditions.\r\n * Useful for modifying entry properties (e.g. sensitivity) without rebuilding the entire inputMap.\r\n * @param source - The physical input source to match\r\n * @param interaction - The interaction type to match\r\n * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n * @returns The matching entry, or undefined if not found\r\n */\r\n public getEntry(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined {\r\n // Manual loop instead of `inputMap.find(arrow)` to avoid per-call closure allocation;\r\n // this is hit per pointer-move from multi-touch panning paths.\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const e = arr[i];\r\n if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n return e;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Finds all inputMap entries matching the given source, interaction, and optional entry conditions.\r\n * Useful for bulk updates when more than one physical input maps to the same interaction.\r\n * @param source - The physical input source to match\r\n * @param interaction - The interaction type to match\r\n * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n * @returns All matching entries, in inputMap order\r\n */\r\n public getEntries(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[] {\r\n const matches: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const e = arr[i];\r\n if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n matches.push(e);\r\n }\r\n }\r\n return matches;\r\n }\r\n\r\n /**\r\n * Adds an entry to the inputMap at the correct position based on specificity.\r\n * More specific entries (with more conditions like button, key, modifiers) are placed\r\n * before less specific ones, ensuring they match first. Among equally specific entries,\r\n * the new entry is placed after existing ones.\r\n * @param entry - The entry to add\r\n */\r\n public addEntry(entry: InputMapEntry<InteractionName<THandlers>>): void {\r\n const score = this._entrySpecificity(entry);\r\n let insertIndex = this.inputMap.length;\r\n for (let i = 0; i < this.inputMap.length; i++) {\r\n if (this._entrySpecificity(this.inputMap[i]) < score) {\r\n insertIndex = i;\r\n break;\r\n }\r\n }\r\n this.inputMap.splice(insertIndex, 0, entry);\r\n }\r\n\r\n /**\r\n * Sets the interaction for the input combination described by `conditions`. If an\r\n * existing entry maps that exact combination, its `interaction` is updated in place;\r\n * otherwise a new entry is inserted via {@link addEntry}.\r\n *\r\n * To force an update on every matching entry use {@link setInteractions}; to address\r\n * an individual entry beyond the first, look it up via {@link getEntries} and assign\r\n * `entry.interaction` directly.\r\n * @param source - The physical input source to match\r\n * @param conditions - Conditions describing the input combination (button, modifiers, key, etc.)\r\n * @param interaction - The interaction to assign / insert\r\n * @returns true (the mapping is always made effective)\r\n */\r\n public setInteraction(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): boolean {\r\n // resolveInteraction returns the first entry that fires for `conditions` (so its\r\n // conditions are no stricter than the request). If that entry also covers every\r\n // condition present in the request, it's an exact match — mutate. Otherwise it's\r\n // broader (or nothing matches): add a more-specific entry so we don't clobber the\r\n // broader one.\r\n const entry = this.resolveInteraction(source, conditions);\r\n if (entry && this._entryCoversAllConditionsOf(entry, conditions)) {\r\n entry.interaction = interaction;\r\n return true;\r\n }\r\n this.addEntry({ source, ...(conditions ?? {}), interaction } as InputMapEntry<InteractionName<THandlers>>);\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns true when `entry` constrains every field that `conditions` specifies — i.e.\r\n * `entry` covers all of the request's conditions. Used by {@link setInteraction} as one\r\n * half of the \"exactly as specific\" check: combined with {@link resolveInteraction}'s\r\n * guarantee that the returned entry is no *stricter* than the request, a true result\r\n * here means `entry` and `conditions` constrain the same fields, and mutating\r\n * `entry.interaction` is safe.\r\n *\r\n * On its own this predicate does not exclude entries that are stricter than `conditions`\r\n * (those would also trivially cover every field present in `conditions`); callers must\r\n * rely on the upstream resolve step to rule them out.\r\n *\r\n * `InputConditions` is a flat type covering all source-specific fields (`button`, `key`,\r\n * `touchCount`, `modifiers`); for any given source the irrelevant fields are `undefined`\r\n * on both `entry` and `conditions`, so checking them all is harmless.\r\n * @param entry - The matched inputMap entry to test\r\n * @param conditions - The conditions the caller supplied to `setInteraction`\r\n * @returns true if `entry` covers every condition present in `conditions`\r\n */\r\n private _entryCoversAllConditionsOf(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n if (!conditions) {\r\n return true;\r\n }\r\n // `as any` here because `entry` is a discriminated union and TypeScript can't narrow it\r\n // from a string-keyed loop. The runtime check is harmless: irrelevant-for-this-source\r\n // fields are undefined on both entry and conditions and skip the early return.\r\n const e = entry as any;\r\n for (const key of Object.keys(conditions) as (keyof InputConditions)[]) {\r\n const condValue = conditions[key];\r\n if (condValue === undefined) {\r\n continue;\r\n }\r\n if (key === \"modifiers\") {\r\n const entryMods = (e.modifiers ?? {}) as InputModifiers;\r\n for (const modKey of Object.keys(condValue) as (keyof InputModifiers)[]) {\r\n if ((condValue as InputModifiers)[modKey] !== undefined && entryMods[modKey] === undefined) {\r\n return false;\r\n }\r\n }\r\n } else if (e[key] === undefined) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Changes the interaction for every inputMap entry matching the given source and conditions.\r\n * Useful when more than one entry maps to the same physical input (e.g. duplicate bindings,\r\n * or several keys aliased to the same action) and all of them should be remapped together.\r\n * @param source - The physical input source to match\r\n * @param conditions - Conditions to match (button, modifiers, key, etc.). Uses the same\r\n * event-resolution semantics as {@link resolveInteraction}: omitted entry\r\n * condition fields are treated as wildcards and will match.\r\n * @param interaction - The new interaction to assign to every matched entry\r\n * @returns The number of entries that were updated\r\n */\r\n public setInteractions(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): number {\r\n let count = 0;\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const entry = arr[i];\r\n if (entry.source === source && this._entryMatches(entry, conditions)) {\r\n entry.interaction = interaction;\r\n count++;\r\n }\r\n }\r\n return count;\r\n }\r\n\r\n private _entryMatches(entry: InputMapEntry<InteractionName<THandlers>>, currentConditions?: InputConditions): boolean {\r\n switch (entry.source) {\r\n case \"pointer\":\r\n if (entry.button !== undefined && entry.button !== currentConditions?.button) {\r\n return false;\r\n }\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n case \"wheel\":\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n case \"touch\":\r\n if (entry.touchCount !== undefined && entry.touchCount !== currentConditions?.touchCount) {\r\n return false;\r\n }\r\n return true;\r\n case \"keyboard\":\r\n if (entry.key !== undefined) {\r\n if (Array.isArray(entry.key) ? entry.key.indexOf(currentConditions?.key ?? -1) === -1 : entry.key !== currentConditions?.key) {\r\n return false;\r\n }\r\n }\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n }\r\n }\r\n\r\n private _entryConditionsMatch(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n if (!conditions) {\r\n return true;\r\n }\r\n\r\n // NOTE: Uses the `\"key\" in conditions` form rather than `conditions.key !== undefined`\r\n // so that callers can explicitly target entries with no constraint via\r\n // `getEntries({ button: undefined })` — i.e. \"find catch-all entries that don't\r\n // require a specific button\". `!== undefined` would silently ignore a deliberate\r\n // `undefined` and behave like the property was omitted, which would be wrong here.\r\n switch (entry.source) {\r\n case \"pointer\":\r\n if (\"button\" in conditions && entry.button !== conditions.button) {\r\n return false;\r\n }\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n case \"wheel\":\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n case \"touch\":\r\n return !(\"touchCount\" in conditions) || entry.touchCount === conditions.touchCount;\r\n case \"keyboard\":\r\n if (\"key\" in conditions) {\r\n if (entry.key === undefined) {\r\n return conditions.key === undefined;\r\n }\r\n if (conditions.key === undefined || (Array.isArray(entry.key) ? entry.key.indexOf(conditions.key) === -1 : entry.key !== conditions.key)) {\r\n return false;\r\n }\r\n }\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n }\r\n }\r\n\r\n private _entrySpecificity(entry: InputMapEntry<InteractionName<THandlers>>): number {\r\n let score = 0;\r\n if (\"button\" in entry && entry.button !== undefined) {\r\n score++;\r\n }\r\n if (\"key\" in entry && entry.key !== undefined) {\r\n score++;\r\n }\r\n if (\"touchCount\" in entry && entry.touchCount !== undefined) {\r\n score++;\r\n }\r\n if (\"modifiers\" in entry && entry.modifiers) {\r\n score++;\r\n }\r\n return score;\r\n }\r\n\r\n private _matchModifiers(entryModifiers?: InputModifiers, currentModifiers?: InputModifiers): boolean {\r\n if (!entryModifiers) {\r\n return true;\r\n }\r\n if (entryModifiers.ctrl !== undefined && entryModifiers.ctrl !== (currentModifiers?.ctrl ?? false)) {\r\n return false;\r\n }\r\n if (entryModifiers.shift !== undefined && entryModifiers.shift !== (currentModifiers?.shift ?? false)) {\r\n return false;\r\n }\r\n if (entryModifiers.alt !== undefined && entryModifiers.alt !== (currentModifiers?.alt ?? false)) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private _entryModifiersMatch(entryModifiers?: InputModifiers, conditionsModifiers?: InputModifiers): boolean {\r\n if (!conditionsModifiers) {\r\n return !entryModifiers;\r\n }\r\n\r\n const hasModifierConditions = conditionsModifiers.ctrl !== undefined || conditionsModifiers.shift !== undefined || conditionsModifiers.alt !== undefined;\r\n if (!hasModifierConditions) {\r\n return !entryModifiers || (entryModifiers.ctrl === undefined && entryModifiers.shift === undefined && entryModifiers.alt === undefined);\r\n }\r\n\r\n if (conditionsModifiers.ctrl !== undefined && entryModifiers?.ctrl !== conditionsModifiers.ctrl) {\r\n return false;\r\n }\r\n if (conditionsModifiers.shift !== undefined && entryModifiers?.shift !== conditionsModifiers.shift) {\r\n return false;\r\n }\r\n if (conditionsModifiers.alt !== undefined && entryModifiers?.alt !== conditionsModifiers.alt) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n}\r\n"]}
@@ -4,6 +4,7 @@ import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture.p
4
4
  import { ShaderMaterial } from "../Materials/shaderMaterial.pure.js";
5
5
  import { GaussianSplattingMaterial } from "../Materials/GaussianSplatting/gaussianSplattingMaterial.pure.js";
6
6
  import { GaussianSplattingGpuPickingMaterialPlugin } from "../Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.js";
7
+ import { IsGaussianSplattingClassName } from "../Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js";
7
8
  import { Color4 } from "../Maths/math.color.pure.js";
8
9
  import { Epsilon } from "../Maths/math.constants.js";
9
10
  import { Matrix, TmpVectors, Vector3 } from "../Maths/math.vector.pure.js";
@@ -110,7 +111,7 @@ export class GPUPicker {
110
111
  const className = mesh.getClassName();
111
112
  if (material instanceof ShaderMaterial &&
112
113
  !this._pickingMaterialCache.includes(material) &&
113
- className !== "GaussianSplattingMesh" &&
114
+ !IsGaussianSplattingClassName(className) &&
114
115
  className !== "GaussianSplattingPartProxyMesh") {
115
116
  return { mesh, material };
116
117
  }
@@ -305,8 +306,8 @@ export class GPUPicker {
305
306
  if (className === "GaussianSplattingPartProxyMesh") {
306
307
  continue;
307
308
  }
308
- // Skip thin instance cleanup for GaussianSplattingMesh (thin instances are for batching, not picking)
309
- if (className !== "GaussianSplattingMesh") {
309
+ // Skip thin instance cleanup for Gaussian Splatting meshes (thin instances are for batching, not picking)
310
+ if (!IsGaussianSplattingClassName(className)) {
310
311
  if (mesh.hasInstances) {
311
312
  mesh.removeVerticesData(GPUPicker._AttributeName);
312
313
  }
@@ -391,7 +392,7 @@ export class GPUPicker {
391
392
  }
392
393
  else {
393
394
  const className = item.getClassName();
394
- if (className === "GaussianSplattingMesh" || className === "GaussianSplattingPartProxyMesh") {
395
+ if (IsGaussianSplattingClassName(className) || className === "GaussianSplattingPartProxyMesh") {
395
396
  // GS meshes get special picking materials - handled in the ID assignment loop below
396
397
  newPickableMeshes[i] = item;
397
398
  }
@@ -428,8 +429,8 @@ export class GPUPicker {
428
429
  group.partEntries.push({ proxy, globalIndex });
429
430
  continue; // Don't add to render list - the compound mesh will render for all parts
430
431
  }
431
- // Handle non-compound GaussianSplatting meshes
432
- if (className === "GaussianSplattingMesh") {
432
+ // Handle non-compound GaussianSplatting meshes (including streamed)
433
+ if (IsGaussianSplattingClassName(className)) {
433
434
  const globalIndex = index + pickableMeshOffset;
434
435
  const pickId = nextFreeId;
435
436
  this._idMap[pickId] = globalIndex;