@woosh/meep-engine 2.155.0 → 2.156.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (475) hide show
  1. package/README.md +1 -1
  2. package/build/bundle-worker-image-decoder.js +1 -1
  3. package/build/bundle-worker-terrain.js +1 -1
  4. package/editor/view/ecs/ComponentControlView.d.ts +0 -9
  5. package/editor/view/ecs/ComponentControlView.js +2 -98
  6. package/package.json +1 -1
  7. package/src/core/binary/32BitEncoder.js +1 -1
  8. package/src/core/binary/to_half_float_uint16.js +3 -3
  9. package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts.map +1 -1
  10. package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js +275 -253
  11. package/src/core/cache/Cache.d.ts.map +1 -1
  12. package/src/core/cache/Cache.js +7 -0
  13. package/src/core/cache/FrequencySketch.d.ts.map +1 -1
  14. package/src/core/cache/FrequencySketch.js +8 -4
  15. package/src/core/clipboard/obtainClipBoard.d.ts +6 -0
  16. package/src/core/clipboard/obtainClipBoard.d.ts.map +1 -0
  17. package/src/core/clipboard/obtainClipBoard.js +29 -0
  18. package/src/core/clipboard/safeClipboardReadText.d.ts +6 -0
  19. package/src/core/clipboard/safeClipboardReadText.d.ts.map +1 -0
  20. package/src/core/clipboard/safeClipboardReadText.js +55 -0
  21. package/src/core/clipboard/safeClipboardWriteText.d.ts +8 -0
  22. package/src/core/clipboard/safeClipboardWriteText.d.ts.map +1 -0
  23. package/src/core/clipboard/safeClipboardWriteText.js +23 -0
  24. package/src/core/collection/array/array_quick_sort_by_lookup_map.js +1 -1
  25. package/src/core/collection/array/array_set_diff_sorting.d.ts.map +1 -1
  26. package/src/core/collection/array/array_set_diff_sorting.js +4 -1
  27. package/src/core/collection/array/array_shuffle.d.ts.map +1 -1
  28. package/src/core/collection/array/array_shuffle.js +30 -27
  29. package/src/core/collection/array/binarySearchLowIndex.d.ts.map +1 -1
  30. package/src/core/collection/array/binarySearchLowIndex.js +4 -3
  31. package/src/core/collection/array/typed/array_buffer_hash.js +1 -1
  32. package/src/core/collection/array/typed/is_typed_array_equals.d.ts.map +1 -1
  33. package/src/core/collection/array/typed/is_typed_array_equals.js +12 -2
  34. package/src/core/collection/heap/BinaryHeap.d.ts.map +1 -1
  35. package/src/core/collection/heap/BinaryHeap.js +12 -2
  36. package/src/core/collection/queue/Deque.d.ts.map +1 -1
  37. package/src/core/collection/queue/Deque.js +10 -8
  38. package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
  39. package/src/core/collection/table/RowFirstTable.js +4 -2
  40. package/src/core/collection/table/RowFirstTableSpec.js +2 -2
  41. package/src/core/color/operations/color_lerp.d.ts.map +1 -1
  42. package/src/core/color/operations/color_lerp.js +10 -3
  43. package/src/core/color/rgb2uint32.js +1 -1
  44. package/src/core/color/rgbe9995_to_rgb.js +1 -1
  45. package/src/core/function/objectsEqual.d.ts.map +1 -1
  46. package/src/core/function/objectsEqual.js +2 -1
  47. package/src/core/geom/2d/aabb/AABB2.d.ts.map +1 -1
  48. package/src/core/geom/2d/aabb/AABB2.js +12 -11
  49. package/src/core/geom/2d/convex-hull/convex_hull_jarvis_2d.d.ts.map +1 -1
  50. package/src/core/geom/2d/convex-hull/convex_hull_jarvis_2d.js +30 -4
  51. package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.d.ts.map +1 -1
  52. package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +6 -2
  53. package/src/core/geom/2d/hash-grid/SpatialHashGrid.d.ts.map +1 -1
  54. package/src/core/geom/2d/hash-grid/SpatialHashGrid.js +388 -386
  55. package/src/core/geom/2d/hash-grid/shg_query_elements_line.d.ts.map +1 -1
  56. package/src/core/geom/2d/hash-grid/shg_query_elements_line.js +8 -3
  57. package/src/core/geom/2d/quad-tree/QuadTreeDatum.d.ts.map +1 -1
  58. package/src/core/geom/2d/quad-tree/QuadTreeDatum.js +9 -1
  59. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.d.ts +3 -1
  60. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.d.ts.map +1 -1
  61. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +3 -1
  62. package/src/core/geom/2d/quad-tree-binary/QuadTree.js +714 -714
  63. package/src/core/geom/2d/r-tree/StaticR2Tree.d.ts.map +1 -1
  64. package/src/core/geom/2d/r-tree/StaticR2Tree.js +5 -4
  65. package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.d.ts.map +1 -1
  66. package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +33 -29
  67. package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.d.ts.map +1 -1
  68. package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.js +3 -1
  69. package/src/core/geom/3d/aabb/aabb3_signed_distance_to_aabb3.d.ts.map +1 -1
  70. package/src/core/geom/3d/aabb/aabb3_signed_distance_to_aabb3.js +10 -7
  71. package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.d.ts.map +1 -1
  72. package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.js +30 -9
  73. package/src/core/geom/3d/aabb/compute_aabb_from_points.js +3 -3
  74. package/src/core/geom/3d/box/box3_raycast.d.ts +37 -0
  75. package/src/core/geom/3d/box/box3_raycast.d.ts.map +1 -0
  76. package/src/core/geom/3d/box/box3_raycast.js +81 -0
  77. package/src/core/geom/3d/capsule/capsule_raycast.d.ts +35 -0
  78. package/src/core/geom/3d/capsule/capsule_raycast.d.ts.map +1 -0
  79. package/src/core/geom/3d/capsule/capsule_raycast.js +93 -0
  80. package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.d.ts.map +1 -1
  81. package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.js +4 -0
  82. package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +1 -1
  83. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.d.ts.map +1 -1
  84. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.js +3 -2
  85. package/src/core/geom/3d/mat4/decompose_matrix_4_array.d.ts.map +1 -1
  86. package/src/core/geom/3d/mat4/decompose_matrix_4_array.js +12 -2
  87. package/src/core/geom/3d/mat4/eulerAnglesFromMatrix.js +2 -2
  88. package/src/core/geom/3d/mat4/m4_multiply_alphatensor.d.ts +1 -1
  89. package/src/core/geom/3d/mat4/m4_multiply_alphatensor.d.ts.map +1 -1
  90. package/src/core/geom/3d/mat4/m4_multiply_alphatensor.js +19 -13
  91. package/src/core/geom/3d/octahedra/octahedral_direction_to_uv.d.ts.map +1 -1
  92. package/src/core/geom/3d/octahedra/octahedral_direction_to_uv.js +3 -2
  93. package/src/core/geom/3d/plane/plane3_compute_plane_intersection.js +3 -2
  94. package/src/core/geom/3d/shape/MeshShape3D.d.ts.map +1 -1
  95. package/src/core/geom/3d/shape/MeshShape3D.js +7 -0
  96. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  97. package/src/core/geom/3d/shape/UnionShape3D.js +3 -2
  98. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts.map +1 -1
  99. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +153 -148
  100. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.d.ts.map +1 -1
  101. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +7 -0
  102. package/src/core/geom/3d/sphere/harmonics/sh3_sample_by_direction.d.ts.map +1 -1
  103. package/src/core/geom/3d/sphere/harmonics/sh3_sample_by_direction.js +13 -10
  104. package/src/core/geom/3d/sphere/sphere_projected_sphere_radius_sqr.d.ts +1 -1
  105. package/src/core/geom/3d/sphere/sphere_projected_sphere_radius_sqr.js +2 -2
  106. package/src/core/geom/3d/sphere/sphere_raycast.d.ts +33 -0
  107. package/src/core/geom/3d/sphere/sphere_raycast.d.ts.map +1 -0
  108. package/src/core/geom/3d/sphere/sphere_raycast.js +47 -0
  109. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.d.ts +24 -0
  110. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.d.ts.map +1 -0
  111. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.js +39 -0
  112. package/src/core/geom/3d/tetrahedra/triangle/trace_triangular_depth_map.d.ts.map +1 -1
  113. package/src/core/geom/3d/tetrahedra/triangle/trace_triangular_depth_map.js +4 -2
  114. package/src/core/geom/3d/topology/bounds/computeTriangleClusterNormalBoundingCone.js +3 -3
  115. package/src/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.js +1 -1
  116. package/src/core/geom/3d/topology/tm_vertex_compute_normal.d.ts.map +1 -1
  117. package/src/core/geom/3d/topology/tm_vertex_compute_normal.js +4 -2
  118. package/src/core/geom/3d/util/make_justified_point_grid.d.ts.map +1 -1
  119. package/src/core/geom/3d/util/make_justified_point_grid.js +18 -10
  120. package/src/core/geom/ConicRay.d.ts.map +1 -1
  121. package/src/core/geom/ConicRay.js +11 -13
  122. package/src/core/geom/packing/max-rect/removeRedundantBoxes.d.ts.map +1 -1
  123. package/src/core/geom/packing/max-rect/removeRedundantBoxes.js +19 -4
  124. package/src/core/geom/vec3/v3_orthonormal_matrix_from_normal.d.ts.map +1 -0
  125. package/src/{engine/graphics/sh3/path_tracer/sampling → core/geom/vec3}/v3_orthonormal_matrix_from_normal.js +1 -1
  126. package/src/core/graph/coloring/colorizeGraph.js +2 -2
  127. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  128. package/src/core/graph/csr/CSRGraph.js +325 -319
  129. package/src/core/graph/layout/CircleLayout.d.ts.map +1 -1
  130. package/src/core/graph/layout/CircleLayout.js +8 -6
  131. package/src/core/graph/metis/native/refine/compute_kway_params.d.ts.map +1 -1
  132. package/src/core/graph/metis/native/refine/compute_kway_params.js +139 -138
  133. package/src/core/graph/mn_graph_coarsen.d.ts.map +1 -1
  134. package/src/core/graph/mn_graph_coarsen.js +4 -2
  135. package/src/core/graph/v2/NodeContainer.js +7 -7
  136. package/src/core/localization/LocalizationEngine.js +1 -1
  137. package/src/core/math/bell_membership_function.d.ts.map +1 -1
  138. package/src/core/math/bell_membership_function.js +3 -1
  139. package/src/core/math/complex/complex_add.d.ts +4 -4
  140. package/src/core/math/complex/complex_add.d.ts.map +1 -1
  141. package/src/core/math/complex/complex_add.js +3 -3
  142. package/src/core/math/complex/complex_div.d.ts +4 -4
  143. package/src/core/math/complex/complex_div.d.ts.map +1 -1
  144. package/src/core/math/complex/complex_div.js +3 -3
  145. package/src/core/math/complex/complex_mul.d.ts +4 -4
  146. package/src/core/math/complex/complex_mul.d.ts.map +1 -1
  147. package/src/core/math/complex/complex_mul.js +3 -3
  148. package/src/core/math/complex/complex_sub.d.ts +4 -4
  149. package/src/core/math/complex/complex_sub.d.ts.map +1 -1
  150. package/src/core/math/complex/complex_sub.js +3 -3
  151. package/src/core/math/idct_1d.d.ts +4 -4
  152. package/src/core/math/idct_1d.d.ts.map +1 -1
  153. package/src/core/math/idct_1d.js +3 -3
  154. package/src/core/math/noise/create_simplex_noise_2d.d.ts.map +1 -1
  155. package/src/core/math/noise/create_simplex_noise_2d.js +4 -2
  156. package/src/core/math/noise/sdnoise.d.ts.map +1 -1
  157. package/src/core/math/noise/sdnoise.js +12 -9
  158. package/src/core/math/physics/mie/compute_bhmie_optical_properties.d.ts.map +1 -1
  159. package/src/core/math/physics/mie/compute_bhmie_optical_properties.js +94 -50
  160. package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts +3 -6
  161. package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts.map +1 -1
  162. package/src/core/math/physics/mie/lorenz_mie_coefs.js +180 -157
  163. package/src/core/math/physics/mie/mie_ab_to_optical_properties.d.ts +3 -4
  164. package/src/core/math/physics/mie/mie_ab_to_optical_properties.d.ts.map +1 -1
  165. package/src/core/math/physics/mie/mie_ab_to_optical_properties.js +47 -21
  166. package/src/core/math/random/randomIntegerBetween.d.ts.map +1 -1
  167. package/src/core/math/random/randomIntegerBetween.js +4 -1
  168. package/src/core/math/solveCubic.d.ts.map +1 -1
  169. package/src/core/math/solveCubic.js +95 -82
  170. package/src/core/math/spline/computeCatmullRomSplineUniformDistance.d.ts.map +1 -1
  171. package/src/core/math/spline/computeCatmullRomSplineUniformDistance.js +13 -0
  172. package/src/core/math/statistics/softmax.js +1 -1
  173. package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts +1 -0
  174. package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts.map +1 -1
  175. package/src/core/model/node-graph/visual/NodeGraphVisualData.js +2 -1
  176. package/src/core/model/node-graph/visual/NodeVisualData.js +1 -1
  177. package/src/core/model/object/ImmutableObjectPool.d.ts +7 -0
  178. package/src/core/model/object/ImmutableObjectPool.d.ts.map +1 -1
  179. package/src/core/model/object/ImmutableObjectPool.js +20 -10
  180. package/src/core/model/reactive/evaluation/MultiPredicateEvaluator.d.ts.map +1 -1
  181. package/src/core/model/reactive/evaluation/MultiPredicateEvaluator.js +39 -2
  182. package/src/core/model/reactive/model/terminal/ReactiveReference.d.ts.map +1 -1
  183. package/src/core/model/reactive/model/terminal/ReactiveReference.js +2 -0
  184. package/src/core/parser/simple/readHexToken.d.ts.map +1 -1
  185. package/src/core/parser/simple/readHexToken.js +6 -0
  186. package/src/core/primitives/numbers/number_pretty_print.d.ts.map +1 -1
  187. package/src/core/primitives/numbers/number_pretty_print.js +4 -1
  188. package/src/core/primitives/strings/string_jaro_winkler.js +1 -1
  189. package/src/core/process/CompositeProcess.js +1 -1
  190. package/src/core/process/action/AsynchronousDelayAction.d.ts.map +1 -1
  191. package/src/core/process/action/AsynchronousDelayAction.js +3 -0
  192. package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
  193. package/src/core/process/executor/ConcurrentExecutor.js +3 -2
  194. package/src/core/process/task/util/randomCountTask.d.ts.map +1 -1
  195. package/src/core/process/task/util/randomCountTask.js +3 -1
  196. package/src/core/process/undo/ActionProcessor.d.ts.map +1 -1
  197. package/src/core/process/undo/ActionProcessor.js +5 -3
  198. package/src/core/process/worker/WorkerBuilder.js +3 -3
  199. package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
  200. package/src/engine/animation/curve/AnimationCurve.js +4 -2
  201. package/src/engine/control/first-person/DESIGN.md +1 -1
  202. package/src/engine/control/first-person/FirstPersonMotionPhase.d.ts +55 -0
  203. package/src/engine/control/first-person/FirstPersonMotionPhase.d.ts.map +1 -0
  204. package/src/engine/control/first-person/FirstPersonMotionPhase.js +134 -0
  205. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +23 -2
  206. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  207. package/src/engine/control/first-person/FirstPersonPlayerController.js +1 -1
  208. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +168 -0
  209. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  210. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +115 -0
  211. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +71 -0
  212. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
  213. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +255 -55
  214. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts +82 -43
  215. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
  216. package/src/engine/control/first-person/abilities/LedgeGrab.js +405 -213
  217. package/src/engine/control/first-person/abilities/Mantle.d.ts +6 -0
  218. package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -1
  219. package/src/engine/control/first-person/abilities/Mantle.js +104 -45
  220. package/src/engine/control/first-person/abilities/ScrambleUp.d.ts +61 -0
  221. package/src/engine/control/first-person/abilities/ScrambleUp.d.ts.map +1 -0
  222. package/src/engine/control/first-person/abilities/ScrambleUp.js +182 -0
  223. package/src/engine/control/first-person/math/jumpDynamics.d.ts +84 -0
  224. package/src/engine/control/first-person/math/jumpDynamics.d.ts.map +1 -0
  225. package/src/engine/control/first-person/math/jumpDynamics.js +108 -0
  226. package/src/engine/control/first-person/prototype_first_person_controller.js +45 -1
  227. package/src/engine/graphics/camera/testClippingPlaneComputation.js +1 -1
  228. package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +1 -1
  229. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
  230. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +1 -1
  231. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
  232. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
  233. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +1 -1
  234. package/src/engine/graphics/shadows/testShadowMapRendering.js +1 -1
  235. package/src/engine/physics/CONSTRAINT_SOLVER_BENCH_LOG.md +208 -0
  236. package/src/engine/physics/CONSTRAINT_SOLVER_IMPROVEMENTS_PLAN.md +364 -0
  237. package/src/engine/physics/PLAN.md +6 -5
  238. package/src/engine/physics/constraint/solve_constraints.d.ts +4 -1
  239. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  240. package/src/engine/physics/constraint/solve_constraints.js +147 -33
  241. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  242. package/src/engine/physics/ecs/PhysicsSystem.js +1750 -1747
  243. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +3 -3
  244. package/src/engine/physics/gjk/gjk_epa_penetration.d.ts.map +1 -1
  245. package/src/engine/physics/gjk/gjk_epa_penetration.js +5 -9
  246. package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts.map +1 -1
  247. package/src/engine/physics/narrowphase/convex_convex_manifold.js +22 -25
  248. package/src/engine/physics/narrowphase/convex_decomposition.d.ts +32 -13
  249. package/src/engine/physics/narrowphase/convex_decomposition.d.ts.map +1 -1
  250. package/src/engine/physics/narrowphase/convex_decomposition.js +61 -65
  251. package/src/engine/physics/narrowphase/mesh_convex_hull.d.ts.map +1 -1
  252. package/src/engine/physics/narrowphase/mesh_convex_hull.js +13 -8
  253. package/src/engine/physics/narrowphase/refine_ray_concave.d.ts.map +1 -1
  254. package/src/engine/physics/narrowphase/refine_ray_concave.js +5 -3
  255. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
  256. package/src/engine/physics/narrowphase/refine_ray_hit.js +81 -78
  257. package/src/engine/sound/SoundEngine.d.ts.map +1 -1
  258. package/src/engine/sound/SoundEngine.js +28 -0
  259. package/src/engine/sound/dB2Volume.d.ts +1 -1
  260. package/src/engine/sound/dB2Volume.d.ts.map +1 -1
  261. package/src/engine/sound/dB2Volume.js +1 -1
  262. package/src/engine/sound/ecs/SoundController.d.ts +4 -0
  263. package/src/engine/sound/ecs/SoundController.d.ts.map +1 -1
  264. package/src/engine/sound/ecs/SoundController.js +4 -0
  265. package/src/engine/sound/ecs/SoundControllerSystem.d.ts +5 -0
  266. package/src/engine/sound/ecs/SoundControllerSystem.d.ts.map +1 -1
  267. package/src/engine/sound/ecs/SoundControllerSystem.js +5 -0
  268. package/src/engine/sound/ecs/audio/AudioEmitter.d.ts +69 -0
  269. package/src/engine/sound/ecs/audio/AudioEmitter.d.ts.map +1 -0
  270. package/src/engine/sound/ecs/audio/AudioEmitter.js +83 -0
  271. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts +97 -0
  272. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts.map +1 -0
  273. package/src/engine/sound/ecs/audio/AudioEmitterSystem.js +238 -0
  274. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts +90 -0
  275. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts.map +1 -0
  276. package/src/engine/sound/ecs/audio/LiveEmitterSet.js +324 -0
  277. package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts +59 -0
  278. package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts.map +1 -0
  279. package/src/engine/sound/ecs/audio/SpatialAudioIndex.js +140 -0
  280. package/src/engine/sound/ecs/emitter/SoundEmitter.d.ts +16 -65
  281. package/src/engine/sound/ecs/emitter/SoundEmitter.d.ts.map +1 -1
  282. package/src/engine/sound/ecs/emitter/SoundEmitter.js +19 -224
  283. package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.d.ts +26 -29
  284. package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.d.ts.map +1 -1
  285. package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.js +168 -135
  286. package/src/engine/sound/ecs/emitter/SoundEmitterSystem.d.ts +36 -59
  287. package/src/engine/sound/ecs/emitter/SoundEmitterSystem.d.ts.map +1 -1
  288. package/src/engine/sound/ecs/emitter/SoundEmitterSystem.js +154 -390
  289. package/src/engine/sound/ecs/emitter/SoundTrack.d.ts +20 -23
  290. package/src/engine/sound/ecs/emitter/SoundTrack.d.ts.map +1 -1
  291. package/src/engine/sound/ecs/emitter/SoundTrack.js +34 -152
  292. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +993 -0
  293. package/src/engine/sound/sopra/README.md +643 -7
  294. package/src/engine/sound/sopra/SopraEngine.d.ts +229 -0
  295. package/src/engine/sound/sopra/SopraEngine.d.ts.map +1 -0
  296. package/src/engine/sound/sopra/SopraEngine.js +423 -0
  297. package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.d.ts +26 -0
  298. package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.d.ts.map +1 -0
  299. package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.js +71 -0
  300. package/src/engine/sound/sopra/asset/BufferProvider.d.ts +24 -0
  301. package/src/engine/sound/sopra/asset/BufferProvider.d.ts.map +1 -0
  302. package/src/engine/sound/sopra/asset/BufferProvider.js +29 -0
  303. package/src/engine/sound/sopra/asset/StubBufferProvider.d.ts +31 -0
  304. package/src/engine/sound/sopra/asset/StubBufferProvider.d.ts.map +1 -0
  305. package/src/engine/sound/sopra/asset/StubBufferProvider.js +58 -0
  306. package/src/engine/sound/sopra/definition/BusDefinition.d.ts +83 -0
  307. package/src/engine/sound/sopra/definition/BusDefinition.d.ts.map +1 -0
  308. package/src/engine/sound/sopra/definition/BusDefinition.js +142 -0
  309. package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.d.ts +17 -0
  310. package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.d.ts.map +1 -0
  311. package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.js +54 -0
  312. package/src/engine/sound/sopra/definition/DuckingRule.d.ts +71 -0
  313. package/src/engine/sound/sopra/definition/DuckingRule.d.ts.map +1 -0
  314. package/src/engine/sound/sopra/definition/DuckingRule.js +106 -0
  315. package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.d.ts +18 -0
  316. package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.d.ts.map +1 -0
  317. package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.js +31 -0
  318. package/src/engine/sound/sopra/definition/EventDescription.d.ts +132 -0
  319. package/src/engine/sound/sopra/definition/EventDescription.d.ts.map +1 -0
  320. package/src/engine/sound/sopra/definition/EventDescription.js +259 -0
  321. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts +17 -0
  322. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts.map +1 -0
  323. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +71 -0
  324. package/src/engine/sound/sopra/definition/MixerSnapshot.d.ts +51 -0
  325. package/src/engine/sound/sopra/definition/MixerSnapshot.d.ts.map +1 -0
  326. package/src/engine/sound/sopra/definition/MixerSnapshot.js +83 -0
  327. package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.d.ts +18 -0
  328. package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.d.ts.map +1 -0
  329. package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.js +39 -0
  330. package/src/engine/sound/sopra/definition/ParameterDefinition.d.ts +72 -0
  331. package/src/engine/sound/sopra/definition/ParameterDefinition.d.ts.map +1 -0
  332. package/src/engine/sound/sopra/definition/ParameterDefinition.js +117 -0
  333. package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.d.ts +18 -0
  334. package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.d.ts.map +1 -0
  335. package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.js +31 -0
  336. package/src/engine/sound/sopra/definition/SopraPanningModel.d.ts +14 -0
  337. package/src/engine/sound/sopra/definition/SopraPanningModel.d.ts.map +1 -0
  338. package/src/engine/sound/sopra/definition/SopraPanningModel.js +20 -0
  339. package/src/engine/sound/sopra/definition/VoiceStealMode.d.ts +10 -0
  340. package/src/engine/sound/sopra/definition/VoiceStealMode.d.ts.map +1 -0
  341. package/src/engine/sound/sopra/definition/VoiceStealMode.js +18 -0
  342. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +93 -0
  343. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -0
  344. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +109 -0
  345. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +80 -0
  346. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts.map +1 -0
  347. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.js +181 -0
  348. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.d.ts +17 -0
  349. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.d.ts.map +1 -0
  350. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.js +74 -0
  351. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts +34 -0
  352. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts.map +1 -0
  353. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.js +100 -0
  354. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +101 -0
  355. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -0
  356. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +230 -0
  357. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.d.ts +17 -0
  358. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.d.ts.map +1 -0
  359. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.js +54 -0
  360. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +103 -0
  361. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -0
  362. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +191 -0
  363. package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.d.ts +18 -0
  364. package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.d.ts.map +1 -0
  365. package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.js +39 -0
  366. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +40 -0
  367. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts.map +1 -0
  368. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.js +91 -0
  369. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.d.ts +17 -0
  370. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.d.ts.map +1 -0
  371. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.js +42 -0
  372. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.d.ts +44 -0
  373. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.d.ts.map +1 -0
  374. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.js +77 -0
  375. package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.d.ts +18 -0
  376. package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.d.ts.map +1 -0
  377. package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.js +27 -0
  378. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +65 -0
  379. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -0
  380. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.js +131 -0
  381. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.d.ts +17 -0
  382. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.d.ts.map +1 -0
  383. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.js +41 -0
  384. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts +24 -0
  385. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts.map +1 -0
  386. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +24 -0
  387. package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts +70 -0
  388. package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts.map +1 -0
  389. package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +120 -0
  390. package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.d.ts +18 -0
  391. package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.d.ts.map +1 -0
  392. package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.js +31 -0
  393. package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts +74 -0
  394. package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts.map +1 -0
  395. package/src/engine/sound/sopra/definition/effect/EqEffect.js +128 -0
  396. package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.d.ts +18 -0
  397. package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.d.ts.map +1 -0
  398. package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.js +29 -0
  399. package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts +49 -0
  400. package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts.map +1 -0
  401. package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +101 -0
  402. package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.d.ts +18 -0
  403. package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.d.ts.map +1 -0
  404. package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.js +25 -0
  405. package/src/engine/sound/sopra/legacy/soundEmitterToEventDescription.d.ts +31 -0
  406. package/src/engine/sound/sopra/legacy/soundEmitterToEventDescription.d.ts.map +1 -0
  407. package/src/engine/sound/sopra/legacy/soundEmitterToEventDescription.js +106 -0
  408. package/src/engine/sound/sopra/runtime/BusGraph.d.ts +79 -0
  409. package/src/engine/sound/sopra/runtime/BusGraph.d.ts.map +1 -0
  410. package/src/engine/sound/sopra/runtime/BusGraph.js +227 -0
  411. package/src/engine/sound/sopra/runtime/EventInstance.d.ts +144 -0
  412. package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -0
  413. package/src/engine/sound/sopra/runtime/EventInstance.js +579 -0
  414. package/src/engine/sound/sopra/runtime/ParameterStore.d.ts +42 -0
  415. package/src/engine/sound/sopra/runtime/ParameterStore.d.ts.map +1 -0
  416. package/src/engine/sound/sopra/runtime/ParameterStore.js +98 -0
  417. package/src/engine/sound/sopra/runtime/SopraPlaybackContext.d.ts +42 -0
  418. package/src/engine/sound/sopra/runtime/SopraPlaybackContext.d.ts.map +1 -0
  419. package/src/engine/sound/sopra/runtime/SopraPlaybackContext.js +68 -0
  420. package/src/engine/sound/sopra/runtime/Voice.d.ts +67 -0
  421. package/src/engine/sound/sopra/runtime/Voice.d.ts.map +1 -0
  422. package/src/engine/sound/sopra/runtime/Voice.js +145 -0
  423. package/src/engine/sound/sopra/runtime/VoiceManager.d.ts +38 -0
  424. package/src/engine/sound/sopra/runtime/VoiceManager.d.ts.map +1 -0
  425. package/src/engine/sound/sopra/runtime/VoiceManager.js +136 -0
  426. package/src/engine/sound/sopra/runtime/VoicePool.d.ts +12 -0
  427. package/src/engine/sound/sopra/runtime/VoicePool.d.ts.map +1 -0
  428. package/src/engine/sound/sopra/runtime/VoicePool.js +17 -0
  429. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts +11 -0
  430. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts.map +1 -0
  431. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +42 -0
  432. package/src/engine/sound/sopra/serialization/sopraJSON.d.ts +33 -0
  433. package/src/engine/sound/sopra/serialization/sopraJSON.d.ts.map +1 -0
  434. package/src/engine/sound/sopra/serialization/sopraJSON.js +99 -0
  435. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts +27 -0
  436. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts.map +1 -0
  437. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +49 -0
  438. package/src/engine/sound/sopra/util/MockAudioContext.d.ts +74 -0
  439. package/src/engine/sound/sopra/util/MockAudioContext.d.ts.map +1 -0
  440. package/src/engine/sound/sopra/util/MockAudioContext.js +215 -0
  441. package/src/engine/sound/sopra/util/buildAttenuationCurve.d.ts +15 -0
  442. package/src/engine/sound/sopra/util/buildAttenuationCurve.d.ts.map +1 -0
  443. package/src/engine/sound/sopra/util/buildAttenuationCurve.js +40 -0
  444. package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts +34 -0
  445. package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts.map +1 -0
  446. package/src/engine/sound/sopra/util/fadeOutAndStop.js +60 -0
  447. package/src/engine/sound/volume2dB.d.ts +1 -1
  448. package/src/engine/sound/volume2dB.d.ts.map +1 -1
  449. package/src/engine/sound/volume2dB.js +1 -1
  450. package/src/engine/graphics/sh3/path_tracer/sampling/v3_orthonormal_matrix_from_normal.d.ts.map +0 -1
  451. package/src/engine/physics/narrowphase/ray_shapes.d.ts +0 -66
  452. package/src/engine/physics/narrowphase/ray_shapes.d.ts.map +0 -1
  453. package/src/engine/physics/narrowphase/ray_shapes.js +0 -187
  454. package/src/engine/sound/ecs/emitter/SoundEmitterChannel.d.ts +0 -23
  455. package/src/engine/sound/ecs/emitter/SoundEmitterChannel.d.ts.map +0 -1
  456. package/src/engine/sound/ecs/emitter/SoundEmitterChannel.js +0 -32
  457. package/src/engine/sound/ecs/emitter/SoundTrackNodes.d.ts +0 -18
  458. package/src/engine/sound/ecs/emitter/SoundTrackNodes.d.ts.map +0 -1
  459. package/src/engine/sound/ecs/emitter/SoundTrackNodes.js +0 -18
  460. package/src/engine/sound/sopra/AbstractAudioClip.d.ts +0 -26
  461. package/src/engine/sound/sopra/AbstractAudioClip.d.ts.map +0 -1
  462. package/src/engine/sound/sopra/AbstractAudioClip.js +0 -29
  463. package/src/engine/sound/sopra/ContainerAudioClip.d.ts +0 -12
  464. package/src/engine/sound/sopra/ContainerAudioClip.d.ts.map +0 -1
  465. package/src/engine/sound/sopra/ContainerAudioClip.js +0 -13
  466. package/src/engine/sound/sopra/RandomContainerAudioClip.d.ts +0 -12
  467. package/src/engine/sound/sopra/RandomContainerAudioClip.d.ts.map +0 -1
  468. package/src/engine/sound/sopra/RandomContainerAudioClip.js +0 -15
  469. package/src/engine/sound/sopra/SequenceContainerAudioClip.d.ts +0 -7
  470. package/src/engine/sound/sopra/SequenceContainerAudioClip.d.ts.map +0 -1
  471. package/src/engine/sound/sopra/SequenceContainerAudioClip.js +0 -8
  472. package/src/engine/sound/sopra/SilenceAudioClip.d.ts +0 -13
  473. package/src/engine/sound/sopra/SilenceAudioClip.d.ts.map +0 -1
  474. package/src/engine/sound/sopra/SilenceAudioClip.js +0 -15
  475. /package/src/{engine/graphics/sh3/path_tracer/sampling → core/geom/vec3}/v3_orthonormal_matrix_from_normal.d.ts +0 -0
@@ -0,0 +1,579 @@
1
+ import Signal from "../../../../core/events/signal/Signal.js";
2
+ import { dB2Volume } from "../../dB2Volume.js";
3
+ import { FADE_EPSILON, rampGain } from "../util/fadeOutAndStop.js";
4
+ import { SOPRA_PANNING_MODEL_TO_WEBAUDIO } from "../definition/SopraPanningModel.js";
5
+ import { VOICE_POOL } from "./VoicePool.js";
6
+
7
+ /**
8
+ * Lifecycle state of an {@link EventInstance}.
9
+ * @enum {number}
10
+ */
11
+ export const EventInstanceState = {
12
+ Initial: 0,
13
+ Playing: 1,
14
+ Stopped: 2
15
+ };
16
+
17
+ /**
18
+ * How far ahead (seconds) leaves are spawned before their scheduled start, so `source.start(when)`
19
+ * stays sample-accurate even when the driving frame is slightly late ("Tale of Two Clocks").
20
+ * @type {number}
21
+ */
22
+ const LOOKAHEAD_SECONDS = 0.2;
23
+
24
+ const DEFAULT_MAX_LIFETIME_SECONDS = 60;
25
+
26
+ /**
27
+ * One triggered playing of an {@link EventDescription}. Transient — never serialized.
28
+ *
29
+ * Playback is **cursor-based**: each frame {@link update} compares the logical playhead
30
+ * (`now - startedAt`) against the resolved timeline and, for each leaf whose window is current,
31
+ * spawns a voice — but only while the instance is audible. Out-of-range/below-threshold instances go
32
+ * **virtual** (their voices stop while the cursor keeps advancing) and revive at the correct child +
33
+ * buffer-offset when audible again (D3). 3D instances own a shared `attenuationGain → panner → bus`
34
+ * chain (D4); the attenuation gain is driven by distance through the event's attenuation curve.
35
+ */
36
+ export class EventInstance {
37
+
38
+ /**
39
+ * @type {number}
40
+ */
41
+ startedAt = 0;
42
+
43
+ /**
44
+ * @type {EventInstanceState|number}
45
+ */
46
+ state = EventInstanceState.Initial;
47
+
48
+ /**
49
+ * Current post-attenuation linear gain (1 for non-3D). Read by the VoiceManager for steal-quietest.
50
+ * @type {number}
51
+ */
52
+ currentGain = 1;
53
+
54
+ /**
55
+ * Fires `this` when the instance has fully stopped (ended, stopped, timed out, or failed to load).
56
+ * @type {Signal<EventInstance>}
57
+ */
58
+ onEnded = new Signal();
59
+
60
+ /**
61
+ * Resolved timeline: one entry per leaf play. Null until buffers are loaded and the timeline is
62
+ * resolved. Each entry: { clip, offset, gainDb, pitchCents, duration, voice }.
63
+ * @type {{clip: SampleAudioClip, offset: number, gainDb: number, pitchCents: number, duration: number, voice: Voice|null}[]|null}
64
+ */
65
+ #timeline = null;
66
+
67
+ /**
68
+ * @type {Map<SampleAudioClip, AudioBuffer>|null}
69
+ */
70
+ #bufferMap = null;
71
+
72
+ /**
73
+ * @type {number}
74
+ */
75
+ #totalDuration = 0;
76
+
77
+ /**
78
+ * Node that voices route into: the instance's attenuation gain (3D) or the bus input (2D).
79
+ * @type {AudioNode|null}
80
+ */
81
+ #chainHead = null;
82
+
83
+ /**
84
+ * @type {GainNode|null}
85
+ */
86
+ #attenuationGain = null;
87
+
88
+ /**
89
+ * @type {PannerNode|null}
90
+ */
91
+ #panner = null;
92
+
93
+ /**
94
+ * Always-on per-instance trim gain — the chain head ALL voices route through (2D and 3D). Carries
95
+ * the live instance volume (setGainDb / fades); composes (multiplies) with #attenuationGain in 3D.
96
+ * @type {GainNode|null}
97
+ */
98
+ #instanceGain = null;
99
+
100
+ /**
101
+ * Live instance gain in decibels (0 dB = unity). Applied to #instanceGain.
102
+ * @type {number}
103
+ */
104
+ #gainDb = 0;
105
+
106
+ /**
107
+ * Audio-clock time at which a scheduled fade-out stops the instance; Infinity = none.
108
+ * @type {number}
109
+ */
110
+ #stopDeadline = Infinity;
111
+
112
+ /**
113
+ * @type {boolean}
114
+ */
115
+ #audible = true;
116
+
117
+ /**
118
+ * Logical start timestamp (audio clock). When set, the playhead is `now - startTime` from the
119
+ * outset, so a promoted emitter resumes at the phase it "should" be at given elapsed real time
120
+ * (continuous-clock semantics); null = start now (playhead 0).
121
+ * @type {number|null}
122
+ */
123
+ #startTime = null;
124
+
125
+ /**
126
+ * @param {SopraEngine} engine
127
+ * @param {EventDescription} description
128
+ * @param {{busId?:string, position?:Vector3, oneShot?:boolean, maxLifetime?:number, playbackContext?:SopraPlaybackContext, startTime?:number}} [options]
129
+ */
130
+ constructor(engine, description, {
131
+ busId = description.busId,
132
+ position = null,
133
+ oneShot = false,
134
+ maxLifetime = DEFAULT_MAX_LIFETIME_SECONDS,
135
+ playbackContext = engine.defaultPlaybackContext,
136
+ startTime = null
137
+ } = {}) {
138
+ /**
139
+ * @type {SopraEngine}
140
+ */
141
+ this.engine = engine;
142
+
143
+ /**
144
+ * @type {EventDescription}
145
+ */
146
+ this.description = description;
147
+
148
+ /**
149
+ * @type {string}
150
+ */
151
+ this.busId = busId;
152
+
153
+ /**
154
+ * World position for spatialization. Null = non-positional.
155
+ * @type {Vector3|null}
156
+ */
157
+ this.position = position;
158
+
159
+ /**
160
+ * @type {boolean}
161
+ */
162
+ this.oneShot = oneShot;
163
+
164
+ /**
165
+ * @type {number}
166
+ */
167
+ this.maxLifetimeSeconds = maxLifetime;
168
+
169
+ /**
170
+ * @type {SopraPlaybackContext}
171
+ */
172
+ this.playbackContext = playbackContext;
173
+
174
+ this.#startTime = startTime;
175
+ }
176
+
177
+ /**
178
+ * Current playback position in seconds (now - startedAt, clamped at 0).
179
+ * @returns {number}
180
+ */
181
+ get playhead() {
182
+ return Math.max(0, this.engine.currentTime - this.startedAt);
183
+ }
184
+
185
+ /**
186
+ * Live voices currently sounding (timeline order).
187
+ * @returns {Voice[]}
188
+ */
189
+ get voices() {
190
+ const timeline = this.#timeline;
191
+
192
+ if (timeline === null) {
193
+ return [];
194
+ }
195
+
196
+ const result = [];
197
+ for (let i = 0; i < timeline.length; i++) {
198
+ if (timeline[i].voice !== null) {
199
+ result.push(timeline[i].voice);
200
+ }
201
+ }
202
+
203
+ return result;
204
+ }
205
+
206
+ /**
207
+ * Begin playback at context time `now`.
208
+ * @param {number} now
209
+ */
210
+ start(now) {
211
+ this.startedAt = this.#startTime !== null ? this.#startTime : now;
212
+ this.state = EventInstanceState.Playing;
213
+
214
+ const samples = this.description.rootClip.collectSampleClips();
215
+ const provider = this.engine.bufferProvider;
216
+
217
+ // synchronous fast path: all candidate buffers already decoded
218
+ const bufferMap = new Map();
219
+ let allReady = true;
220
+
221
+ for (let i = 0; i < samples.length; i++) {
222
+ const clip = samples[i];
223
+ const buffer = provider.tryGet(clip.url, clip.usingAlias);
224
+
225
+ if (buffer === null) {
226
+ allReady = false;
227
+ break;
228
+ }
229
+
230
+ bufferMap.set(clip, buffer);
231
+ }
232
+
233
+ if (allReady) {
234
+ this.#resolve(now, bufferMap);
235
+ return;
236
+ }
237
+
238
+ // deferred: load every candidate buffer, then resolve once they arrive
239
+ Promise.all(
240
+ samples.map(clip => provider.get(clip.url, clip.usingAlias).then(buffer => [clip, buffer]))
241
+ ).then(
242
+ entries => {
243
+ if (this.state === EventInstanceState.Playing) {
244
+ this.#resolve(this.engine.currentTime, new Map(entries));
245
+ }
246
+ },
247
+ error => this.#failLoad(error)
248
+ );
249
+ }
250
+
251
+ /**
252
+ * @param {number} now
253
+ * @param {Map<SampleAudioClip, AudioBuffer>} bufferMap
254
+ */
255
+ #resolve(now, bufferMap) {
256
+ this.#bufferMap = bufferMap;
257
+
258
+ const env = {
259
+ durationOf: (clip) => bufferMap.get(clip).duration,
260
+ playback: this.playbackContext,
261
+ getParameter: (name) => this.engine.getParameter(name)
262
+ };
263
+
264
+ const { plays, duration } = this.description.rootClip.planTimeline(env, this.description.gainDb, 0, 0);
265
+
266
+ const timeline = [];
267
+ for (let i = 0; i < plays.length; i++) {
268
+ const p = plays[i];
269
+
270
+ timeline.push({
271
+ clip: p.clip,
272
+ offset: p.offset,
273
+ gainDb: p.gainDb,
274
+ pitchCents: p.pitchCents,
275
+ duration: p.clip.loop ? Infinity : bufferMap.get(p.clip).duration,
276
+ voice: null
277
+ });
278
+ }
279
+
280
+ this.#timeline = timeline;
281
+ this.#totalDuration = duration;
282
+
283
+ this.#buildOutputChain();
284
+
285
+ // initial evaluation at the start time (spawns leaves due immediately, if audible)
286
+ this.update(now, this.engine.listenerPosition);
287
+ }
288
+
289
+ #buildOutputChain() {
290
+ const engine = this.engine;
291
+ const ctx = engine.audioContext;
292
+ const busInput = engine.busGraph.getInput(this.busId);
293
+ const description = this.description;
294
+
295
+ // the instance gain is the uniform chain head (2D and 3D), so live volume/fades have one home
296
+ this.#instanceGain = ctx.createGain();
297
+ this.#instanceGain.gain.setValueAtTime(dB2Volume(this.#gainDb), 0);
298
+
299
+ if (description.is3D) {
300
+ this.#attenuationGain = ctx.createGain();
301
+
302
+ const panner = ctx.createPanner();
303
+ panner.panningModel = SOPRA_PANNING_MODEL_TO_WEBAUDIO[description.panningModel] ?? 'HRTF';
304
+ // the panner does DIRECTION only; distance attenuation is the custom gain node (rolloff=0)
305
+ panner.distanceModel = 'linear';
306
+ panner.rolloffFactor = 0;
307
+ panner.refDistance = description.distanceMin;
308
+ panner.maxDistance = description.distanceMax;
309
+ this.#panner = panner;
310
+
311
+ // voices -> instanceGain -> attenuationGain -> panner -> bus
312
+ this.#instanceGain.connect(this.#attenuationGain);
313
+ this.#attenuationGain.connect(panner);
314
+ panner.connect(busInput);
315
+ } else {
316
+ // voices -> instanceGain -> bus
317
+ this.#instanceGain.connect(busInput);
318
+ }
319
+
320
+ this.#chainHead = this.#instanceGain;
321
+ }
322
+
323
+ /**
324
+ * Live instance gain in decibels (composes with 3D attenuation).
325
+ * @returns {number}
326
+ */
327
+ get gainDb() {
328
+ return this.#gainDb;
329
+ }
330
+
331
+ /**
332
+ * Set the instance gain immediately.
333
+ * @param {number} db
334
+ */
335
+ setGainDb(db) {
336
+ this.#gainDb = db;
337
+
338
+ if (this.#instanceGain !== null) {
339
+ this.#instanceGain.gain.setValueAtTime(dB2Volume(db), this.engine.currentTime);
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Ramp the instance gain to a target over `duration` (click-safe). Does not stop the instance.
345
+ * @param {number} targetDb
346
+ * @param {number} duration seconds
347
+ * @param {number} [startAfter=0] seconds
348
+ */
349
+ fadeToGainDb(targetDb, duration, startAfter = 0) {
350
+ this.#gainDb = targetDb;
351
+
352
+ if (this.#instanceGain !== null) {
353
+ rampGain(this.#instanceGain.gain, dB2Volume(targetDb), duration, this.engine.audioContext, startAfter);
354
+ }
355
+ }
356
+
357
+ /**
358
+ * Fade the instance out to silence over `duration`, then stop it (audio-clock deadline checked in
359
+ * {@link update}; no setTimeout).
360
+ * @param {number} duration seconds
361
+ * @param {number} [startAfter=0] seconds
362
+ */
363
+ fadeOutAndStop(duration, startAfter = 0) {
364
+ if (this.state !== EventInstanceState.Playing) {
365
+ return;
366
+ }
367
+
368
+ if (this.#instanceGain !== null) {
369
+ rampGain(this.#instanceGain.gain, FADE_EPSILON, duration, this.engine.audioContext, startAfter);
370
+ }
371
+
372
+ this.#stopDeadline = this.engine.currentTime + startAfter + duration;
373
+ }
374
+
375
+ /**
376
+ * Re-base the playhead to `seconds` and respawn voices at the new offset. Preserves the resolved
377
+ * timeline + playback RNG state (no re-pick / no reseed) — only the cursor moves.
378
+ * @param {number} seconds
379
+ */
380
+ seek(seconds) {
381
+ if (this.state !== EventInstanceState.Playing || this.#timeline === null) {
382
+ return;
383
+ }
384
+
385
+ this.startedAt = this.engine.currentTime - Math.max(0, seconds);
386
+
387
+ const timeline = this.#timeline;
388
+ for (let i = 0; i < timeline.length; i++) {
389
+ this.#retire(timeline[i]);
390
+ }
391
+
392
+ this.update(this.engine.currentTime, this.engine.listenerPosition);
393
+ }
394
+
395
+ /**
396
+ * Restart from the beginning (seek to 0).
397
+ */
398
+ restart() {
399
+ this.seek(0);
400
+ }
401
+
402
+ /**
403
+ * Advance the instance one frame: update spatialization, then evaluate the timeline against the
404
+ * playhead (spawning / virtualizing voices).
405
+ * @param {number} now context time
406
+ * @param {Vector3|null} listenerPosition
407
+ */
408
+ update(now, listenerPosition) {
409
+ if (this.state !== EventInstanceState.Playing) {
410
+ return;
411
+ }
412
+
413
+ if (this.#timeline === null) {
414
+ // still loading — only the lifetime backstop applies
415
+ if (this.oneShot && (now - this.startedAt) > this.maxLifetimeSeconds) {
416
+ this.stop();
417
+ }
418
+ return;
419
+ }
420
+
421
+ const description = this.description;
422
+
423
+ if (description.is3D && this.position !== null && listenerPosition !== null) {
424
+ const distance = this.position.distanceTo(listenerPosition);
425
+ const gain = Math.max(0, description.attenuation.evaluate(distance));
426
+
427
+ this.#attenuationGain.gain.setValueAtTime(gain, 0);
428
+ this.#panner.setPosition(this.position.x, this.position.y, this.position.z);
429
+
430
+ this.currentGain = gain;
431
+ this.#audible = distance <= description.distanceMax && gain > dB2Volume(description.virtualThresholdDb);
432
+ } else {
433
+ this.currentGain = 1;
434
+ this.#audible = true;
435
+ }
436
+
437
+ this.#evaluate(now);
438
+
439
+ // scheduled fade-out deadline (audio-clock based, not setTimeout)
440
+ if (this.state === EventInstanceState.Playing && now >= this.#stopDeadline) {
441
+ this.stop();
442
+ }
443
+
444
+ if (this.state === EventInstanceState.Playing && this.oneShot && (now - this.startedAt) > this.maxLifetimeSeconds) {
445
+ this.stop();
446
+ }
447
+ }
448
+
449
+ /**
450
+ * @param {number} now
451
+ */
452
+ #evaluate(now) {
453
+ const playhead = now - this.startedAt;
454
+ const timeline = this.#timeline;
455
+ const audible = this.#audible;
456
+
457
+ for (let i = 0; i < timeline.length; i++) {
458
+ const entry = timeline[i];
459
+
460
+ const start = entry.offset;
461
+ const end = entry.duration === Infinity ? Infinity : entry.offset + entry.duration;
462
+
463
+ const withinWindow = (playhead + LOOKAHEAD_SECONDS >= start) && (playhead < end);
464
+
465
+ if (withinWindow && audible) {
466
+ if (entry.voice === null) {
467
+ const when = Math.max(now, this.startedAt + start);
468
+ const bufferOffset = Math.max(0, playhead - start);
469
+
470
+ entry.voice = this.#spawnVoice(entry, when, bufferOffset);
471
+ }
472
+ } else if (entry.voice !== null) {
473
+ // out of range (virtualize) or past the leaf's window — stop, keep the cursor
474
+ this.#retire(entry);
475
+ }
476
+ }
477
+
478
+ if (this.oneShot && this.#totalDuration !== Infinity && playhead >= this.#totalDuration) {
479
+ this.stop();
480
+ }
481
+ }
482
+
483
+ /**
484
+ * @param {{clip: SampleAudioClip, gainDb: number, pitchCents: number}} entry
485
+ * @param {number} when
486
+ * @param {number} bufferOffset
487
+ * @returns {Voice}
488
+ */
489
+ #spawnVoice(entry, when, bufferOffset) {
490
+ const clip = entry.clip;
491
+ const buffer = this.#bufferMap.get(clip);
492
+
493
+ let offset = bufferOffset;
494
+
495
+ // A resumed/long-running loop can have an offset beyond the buffer — phase reconstruction on
496
+ // promote (playhead = now - startTime) or revival after a long virtual period. Wrap it into the
497
+ // loop region so the source starts at a valid in-buffer position. (Offsets within the first pass,
498
+ // i.e. ≤ loopEnd, are left as-is so a one-time intro region still plays.)
499
+ if (clip.loop) {
500
+ const loopEnd = clip.loopEnd > 0 ? clip.loopEnd : buffer.duration;
501
+ const loopStart = clip.loopStart;
502
+ const loopLength = loopEnd - loopStart;
503
+
504
+ if (loopLength > 0 && offset > loopEnd) {
505
+ offset = loopStart + ((offset - loopStart) % loopLength);
506
+ }
507
+ }
508
+
509
+ const voice = VOICE_POOL.get();
510
+
511
+ voice.play(this.engine.audioContext, this.#chainHead, buffer, {
512
+ gainLinear: dB2Volume(entry.gainDb),
513
+ detuneCents: entry.pitchCents,
514
+ loop: clip.loop,
515
+ loopStart: clip.loopStart,
516
+ loopEnd: clip.loopEnd,
517
+ when,
518
+ offset
519
+ });
520
+
521
+ return voice;
522
+ }
523
+
524
+ /**
525
+ * @param {{voice: Voice|null}} entry
526
+ */
527
+ #retire(entry) {
528
+ if (entry.voice !== null) {
529
+ entry.voice.stop();
530
+ VOICE_POOL.release(entry.voice);
531
+ entry.voice = null;
532
+ }
533
+ }
534
+
535
+ /**
536
+ * @param {Error} error
537
+ */
538
+ #failLoad(error) {
539
+ // expected-failure path (missing/failed asset): surface it (log) and release — do NOT hang
540
+ // and do NOT silently swallow.
541
+ console.error(`sopra: event '${this.description.label}' could not load its buffer`, error);
542
+
543
+ this.stop();
544
+ }
545
+
546
+ /**
547
+ * Stop all voices, tear down the output chain, and finish the instance.
548
+ */
549
+ stop() {
550
+ if (this.state === EventInstanceState.Stopped) {
551
+ return;
552
+ }
553
+
554
+ this.state = EventInstanceState.Stopped;
555
+
556
+ const timeline = this.#timeline;
557
+ if (timeline !== null) {
558
+ for (let i = 0; i < timeline.length; i++) {
559
+ this.#retire(timeline[i]);
560
+ }
561
+ }
562
+
563
+ if (this.#panner !== null) {
564
+ this.#panner.disconnect();
565
+ }
566
+ if (this.#attenuationGain !== null) {
567
+ this.#attenuationGain.disconnect();
568
+ }
569
+ if (this.#instanceGain !== null) {
570
+ this.#instanceGain.disconnect();
571
+ }
572
+
573
+ if (this.onEnded.hasHandlers()) {
574
+ this.onEnded.send1(this);
575
+ }
576
+
577
+ this.engine.__onInstanceFinished(this);
578
+ }
579
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Holds live values for named parameters (RTPC). P0 is the minimal store (define/get/set + a change
3
+ * signal); automation curves binding parameter values to gains/pitch/sends are layered on in P1.
4
+ */
5
+ export class ParameterStore {
6
+ /**
7
+ * Fires (name, value) whenever a parameter changes.
8
+ * @type {Signal<string, number>}
9
+ */
10
+ onChanged: Signal<string, number>;
11
+ /**
12
+ * Register a parameter with its default value (no-op if already defined).
13
+ * @param {string} name
14
+ * @param {number} defaultValue
15
+ */
16
+ define(name: string, defaultValue: number): void;
17
+ /**
18
+ * @param {string} name
19
+ * @returns {boolean}
20
+ */
21
+ has(name: string): boolean;
22
+ /**
23
+ * @param {string} name
24
+ * @returns {number|undefined}
25
+ */
26
+ get(name: string): number | undefined;
27
+ /**
28
+ * @param {string} name
29
+ * @param {number} value
30
+ */
31
+ set(name: string, value: number): void;
32
+ /**
33
+ * Bind a callback to a parameter; it runs on every change (and once now if the parameter already
34
+ * has a value). Used to drive bus gains / voice params from an automation curve.
35
+ * @param {string} name
36
+ * @param {function(number)} applyFn
37
+ */
38
+ bind(name: string, applyFn: (arg0: number) => any): void;
39
+ #private;
40
+ }
41
+ import Signal from "../../../../core/events/signal/Signal.js";
42
+ //# sourceMappingURL=ParameterStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParameterStore.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/sound/sopra/runtime/ParameterStore.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH;IAaI;;;OAGG;IACH,WAFU,OAAO,MAAM,EAAE,MAAM,CAAC,CAEP;IAEzB;;;;OAIG;IACH,aAHW,MAAM,gBACN,MAAM,QAMhB;IAED;;;OAGG;IACH,UAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;OAGG;IACH,UAHW,MAAM,GACJ,MAAM,GAAC,SAAS,CAI5B;IAED;;;OAGG;IACH,UAHW,MAAM,SACN,MAAM,QAqBhB;IAED;;;;;OAKG;IACH,WAHW,MAAM,kBACG,MAAM,gBAezB;;CACJ;mBAjGkB,0CAA0C"}