@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,108 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+
3
+ /**
4
+ * Jump power as physics, not a magic velocity.
5
+ *
6
+ * A jump is the legs doing WORK: a push-off force `F` (newtons) applied over a
7
+ * leg-extension distance `d` (meters) while the body is still on the ground.
8
+ * That work becomes the body's kinetic energy at the instant it leaves the
9
+ * ground, which gravity then trades back for height:
10
+ *
11
+ * F · d = ½ · m · v₀² (leg work → launch kinetic energy)
12
+ * ½ · m · v₀² = m · g · h (launch KE → potential energy at apex)
13
+ *
14
+ * Eliminating v₀ collapses the two into a single, mass-honest relationship
15
+ * between the force the legs deliver and the apex the body reaches:
16
+ *
17
+ * h = F · d / (m · g)
18
+ * F = m · g · h / d
19
+ * v₀ = √(2 · F · d / m) = √(2 · g · h)
20
+ *
21
+ * Why express jump power as a FORCE (newtons) rather than a launch velocity?
22
+ * - It is a property of the CHARACTER (the legs), not of the jump. A fixed
23
+ * leg force makes a heavier body jump lower — `h ∝ 1/m` — for free, which a
24
+ * raw launch-velocity number cannot express (the same v₀ ignores mass).
25
+ * - It composes: momentum, fatigue, and surface bonuses all add/scale in the
26
+ * same physical currency (newtons) before a single conversion to velocity.
27
+ *
28
+ * `d` (the push-off distance) is the one extra parameter a newtons model needs:
29
+ * force alone can't determine a launch without the distance (or time) it acts
30
+ * over. It is a body constant — roughly the crouch-to-full-extension travel of
31
+ * the legs (~0.4–0.5 m for a ~1.8 m human countermovement jump).
32
+ *
33
+ * All three functions are pure and frame-independent. The headline is
34
+ * {@link jumpForceForHeight}: the newtons a designer needs to reach a desired
35
+ * apex on a given character. {@link launchVelocityForForce} is the forward
36
+ * conversion an ability applies at launch.
37
+ *
38
+ * @author Alex Goldring
39
+ * @copyright Company Named Limited (c) 2026
40
+ */
41
+
42
+ /**
43
+ * The push-off force (newtons) the legs must deliver for the body to reach a
44
+ * given apex height — i.e. newtons BACK-CALCULATED from the desired maximum
45
+ * jump height on this character.
46
+ *
47
+ * F = m · g · h / d
48
+ *
49
+ * Heavier body → more force for the same height; stronger gravity → more force;
50
+ * a longer push-off distance → less force (the work is spread over more travel).
51
+ *
52
+ * @param {number} mass body mass, kg (> 0)
53
+ * @param {number} gravity gravitational acceleration, m/s² (> 0)
54
+ * @param {number} pushoffDistance leg push-off distance, m (> 0)
55
+ * @param {number} height desired apex height above launch, m (>= 0)
56
+ * @returns {number} push-off force in newtons
57
+ */
58
+ export function jumpForceForHeight(mass, gravity, pushoffDistance, height) {
59
+ assert.greaterThan(mass, 0, "mass");
60
+ assert.greaterThan(gravity, 0, "gravity");
61
+ assert.greaterThan(pushoffDistance, 0, "pushoffDistance");
62
+ assert.greaterThanOrEqual(height, 0, "height");
63
+
64
+ return (mass * gravity * height) / pushoffDistance;
65
+ }
66
+
67
+ /**
68
+ * The apex height (meters) a given push-off force produces on this character —
69
+ * the inverse of {@link jumpForceForHeight}.
70
+ *
71
+ * h = F · d / (m · g)
72
+ *
73
+ * @param {number} force push-off force, newtons (>= 0)
74
+ * @param {number} mass body mass, kg (> 0)
75
+ * @param {number} gravity gravitational acceleration, m/s² (> 0)
76
+ * @param {number} pushoffDistance leg push-off distance, m (> 0)
77
+ * @returns {number} apex height above launch, meters
78
+ */
79
+ export function jumpHeightForForce(force, mass, gravity, pushoffDistance) {
80
+ assert.greaterThanOrEqual(force, 0, "force");
81
+ assert.greaterThan(mass, 0, "mass");
82
+ assert.greaterThan(gravity, 0, "gravity");
83
+ assert.greaterThan(pushoffDistance, 0, "pushoffDistance");
84
+
85
+ return (force * pushoffDistance) / (mass * gravity);
86
+ }
87
+
88
+ /**
89
+ * The launch velocity (m/s) a given push-off force imparts to this character —
90
+ * the forward conversion an ability applies at the instant of launch.
91
+ *
92
+ * v₀ = √(2 · F · d / m)
93
+ *
94
+ * Note this is independent of gravity: gravity only governs the apex the launch
95
+ * velocity then reaches, not the launch itself.
96
+ *
97
+ * @param {number} force push-off force, newtons (>= 0)
98
+ * @param {number} mass body mass, kg (> 0)
99
+ * @param {number} pushoffDistance leg push-off distance, m (> 0)
100
+ * @returns {number} launch velocity, m/s
101
+ */
102
+ export function launchVelocityForForce(force, mass, pushoffDistance) {
103
+ assert.greaterThanOrEqual(force, 0, "force");
104
+ assert.greaterThan(mass, 0, "mass");
105
+ assert.greaterThan(pushoffDistance, 0, "pushoffDistance");
106
+
107
+ return Math.sqrt((2 * force * pushoffDistance) / mass);
108
+ }
@@ -30,6 +30,7 @@ import { RigidBody } from "../../physics/ecs/RigidBody.js";
30
30
  import { PhysicsSurfacePoint } from "../../physics/queries/PhysicsSurfacePoint.js";
31
31
  import { LedgeGrab } from "./abilities/LedgeGrab.js";
32
32
  import { Mantle } from "./abilities/Mantle.js";
33
+ import { ScrambleUp } from "./abilities/ScrambleUp.js";
33
34
  import { Slide } from "./abilities/Slide.js";
34
35
  import { WallJump } from "./abilities/WallJump.js";
35
36
  import { WallRun } from "./abilities/WallRun.js";
@@ -84,6 +85,7 @@ const COLOR_SLIDE = 0x44ddee;
84
85
  const COLOR_GAP = 0xff66cc;
85
86
  const COLOR_STAIRS = 0xeedd44;
86
87
  const COLOR_RAMP = 0x3377dd;
88
+ const COLOR_SCRAMBLE = 0x33ffaa;
87
89
  const COLOR_NEUTRAL = 0xaaaaaa;
88
90
 
89
91
  const eh = new EngineHarness();
@@ -234,6 +236,7 @@ function buildGym(ecd) {
234
236
  buildGapJumpStation(ecd);
235
237
  buildStairsStation(ecd);
236
238
  buildRampStation(ecd);
239
+ buildScrambleStation(ecd);
237
240
  buildMeshShapeShowcase(ecd);
238
241
  }
239
242
 
@@ -516,6 +519,34 @@ function buildLedgeGrabStation(ecd) {
516
519
  });
517
520
  }
518
521
 
522
+ /**
523
+ * Scramble-up station — a tall wall the player runs vertically UP a short
524
+ * distance (à la Assassin's Creed) to reach a grabbable top, or to kick off.
525
+ * East of spawn.
526
+ *
527
+ * 1. sprint at the wall (hold forward into it)
528
+ * 2. ScrambleUp launches a short vertical climb up the face
529
+ * 3. near the apex the top comes into reach → LedgeGrab catches it on the
530
+ * way down → press jump to Mantle up onto the platform
531
+ * 4. …or press jump DURING the climb for a wall-kick off the face
532
+ *
533
+ * The wall top (2.8 m) is just out of standing grab reach (~1.9 m), so a
534
+ * scramble is required — a shorter wall would just be a plain Mantle.
535
+ */
536
+ function buildScrambleStation(ecd) {
537
+ const baseX = SPAWN_X + 15;
538
+ spawnPad(ecd, baseX - 6, SPAWN_Z, COLOR_SCRAMBLE);
539
+
540
+ // Tall solid block: top at 2.8 m, wide + deep enough to stand on after the
541
+ // climb (so scramble → grab → mantle-up lands somewhere).
542
+ spawnBox(ecd, {
543
+ center: new Vector3(baseX, 1.4, SPAWN_Z),
544
+ size: new Vector3(4, 2.8, 8),
545
+ color: COLOR_SCRAMBLE,
546
+ roughness: 0.6,
547
+ });
548
+ }
549
+
519
550
  /**
520
551
  * Slide tunnel — a sprint run-up followed by a low ceiling that forces
521
552
  * the player to slide under. NE of spawn.
@@ -830,6 +861,7 @@ function buildPlayerEntity(ecd) {
830
861
  controller.abilities.add(new Slide());
831
862
  controller.abilities.add(new Mantle());
832
863
  controller.abilities.add(new LedgeGrab());
864
+ controller.abilities.add(new ScrambleUp());
833
865
  controller.abilities.add(new WallRun());
834
866
  controller.abilities.add(new WallJump());
835
867
 
@@ -971,8 +1003,20 @@ function setupPointerLock(engine) {
971
1003
  const captureEl = engine.viewStack.el;
972
1004
 
973
1005
  captureEl.addEventListener("click", () => {
974
- if (document.pointerLockElement !== el && el.requestPointerLock) {
1006
+ if (document.pointerLockElement === el || !el.requestPointerLock) return;
1007
+ // Request RAW mouse input (no OS pointer acceleration) where supported —
1008
+ // acceleration on a high-res mouse amplifies micro-bursts into spurious
1009
+ // `movementX` spikes (the camera-snap source). Browsers that don't
1010
+ // support the option reject/throw; fall back to a plain lock.
1011
+ let p;
1012
+ try {
1013
+ p = el.requestPointerLock({ unadjustedMovement: true });
1014
+ } catch (e) {
975
1015
  el.requestPointerLock();
1016
+ return;
1017
+ }
1018
+ if (p && typeof p.catch === "function") {
1019
+ p.catch(() => { el.requestPointerLock(); });
976
1020
  }
977
1021
  });
978
1022
 
@@ -73,7 +73,7 @@ function makeConfig(engine) {
73
73
  new ScriptSystem(),
74
74
  new FacingDirectionSystem(),
75
75
  new PathFollowingSystem(),
76
- new SoundEmitterSystem(assetManager, sound.destination, sound.context),
76
+ new SoundEmitterSystem(assetManager, sound),
77
77
  new SoundControllerSystem(),
78
78
  new SoundListenerSystem(sound.context),
79
79
  new TimerSystem(),
@@ -91,7 +91,7 @@ function makeConfig(engine) {
91
91
  new FacingDirectionSystem(),
92
92
  new PathFollowingSystem(),
93
93
  new AttachmentSystem(),
94
- new SoundEmitterSystem(assetManager, sound.destination, sound.context),
94
+ new SoundEmitterSystem(assetManager, sound),
95
95
  new SoundControllerSystem(),
96
96
  new SoundListenerSystem(sound.context),
97
97
  new TimerSystem(),
@@ -99,7 +99,7 @@ function makeConfig(engine) {
99
99
 
100
100
  config.addManySystems(
101
101
  new AttachmentSystem(),
102
- new SoundEmitterSystem(assetManager, sound.destination, sound.context),
102
+ new SoundEmitterSystem(assetManager, sound),
103
103
  new SoundControllerSystem(),
104
104
  new SoundListenerSystem(sound.context),
105
105
  guiSystem,
@@ -82,7 +82,7 @@ function makeConfig(engine) {
82
82
  new FacingDirectionSystem(),
83
83
  new PathFollowingSystem(),
84
84
  new AttachmentSystem(),
85
- new SoundEmitterSystem(assetManager, sound.destination, sound.context),
85
+ new SoundEmitterSystem(assetManager, sound),
86
86
  new SoundControllerSystem(),
87
87
  new SoundListenerSystem(sound.context),
88
88
  new TimerSystem(),
@@ -110,7 +110,7 @@ function makeConfig(engine) {
110
110
  new FacingDirectionSystem(),
111
111
  new PathFollowingSystem(),
112
112
  new AttachmentSystem(),
113
- new SoundEmitterSystem(assetManager, sound.destination, sound.context),
113
+ new SoundEmitterSystem(assetManager, sound),
114
114
  new SoundControllerSystem(),
115
115
  new SoundListenerSystem(sound.context),
116
116
  new TimerSystem(),
@@ -88,7 +88,7 @@ function makeConfig(engine) {
88
88
  new FacingDirectionSystem(),
89
89
  new PathFollowingSystem(),
90
90
  new AttachmentSystem(),
91
- new SoundEmitterSystem(assetManager, sound.destination, sound.context),
91
+ new SoundEmitterSystem(assetManager, sound),
92
92
  new SoundControllerSystem(),
93
93
  new SoundListenerSystem(sound.context),
94
94
  new TimerSystem(),
@@ -6,7 +6,7 @@ import { decode_attribute_value } from "../../../geometry/decode_attribute_value
6
6
  import { geometry_construct_triangle_normal } from "../../../geometry/geometry_construct_triangle_normal.js";
7
7
  import { sample_triangle_attribute } from "../geometry/sample_triangle_attribute.js";
8
8
 
9
- import { v3_orthonormal_matrix_from_normal } from "../sampling/v3_orthonormal_matrix_from_normal.js";
9
+ import { v3_orthonormal_matrix_from_normal } from "../../../../../core/geom/vec3/v3_orthonormal_matrix_from_normal.js";
10
10
 
11
11
  const texture_uv = [0, 0];
12
12
  const color = new Float64Array(3);
@@ -69,7 +69,7 @@ function makeConfig(engine) {
69
69
 
70
70
  config.addManySystems(
71
71
  new AttachmentSystem(),
72
- new SoundEmitterSystem(assetManager, sound.destination, sound.context),
72
+ new SoundEmitterSystem(assetManager, sound),
73
73
  new SoundControllerSystem(),
74
74
  new SoundListenerSystem(sound.context),
75
75
  guiSystem,
@@ -0,0 +1,208 @@
1
+ # Constraint-Solver Improvements — Benchmark Log
2
+
3
+ Evidence log for `CONSTRAINT_SOLVER_IMPROVEMENTS_PLAN.md`. One section per phase:
4
+ machine/Node, baseline vs after, delta, pass/fail, and any signed rationale for a
5
+ regression that exceeds budget.
6
+
7
+ **Environment:** Node v24.15.0 · Windows · single-thread JS · benches run via
8
+ `npx jest --config jest.conf.json -t "<name>"` (flip `test.skip`→`test`).
9
+ All numbers are a single in-process run unless noted (per the protocol, gate on
10
+ same-process flag A/B; absolute ms vary by machine/thermal). Tick times in ms.
11
+
12
+ ---
13
+
14
+ ## Phase 0 — Baseline (current `master` + inert flags)
15
+
16
+ Flags present but all at defaults (`contactBiasSmoothBand=0`, `jointBlockSolve=false`,
17
+ `jointSweepSymmetric=false`, `jointRelaxation=1`, `jointComplianceLin=0`) → behaviour
18
+ identical to pre-change master. Ragdoll spec: 3/3 pass, golden bands hold, determinism
19
+ intact.
20
+
21
+ ### ragdoll MICRO (1 ragdoll, 10 joints, floor+sphere, 600 ticks)
22
+
23
+ | metric | mean | median | p95 | p99 | max |
24
+ |--------|------|--------|-----|-----|-----|
25
+ | tick (all) | 0.4505 | 0.3802 | 0.7315 | 1.3891 | 4.2801 |
26
+ | tick (last 1s) | 0.4325 | 0.3664 | 0.8504 | 1.0324 | 1.0324 |
27
+
28
+ final awake **11 / 11** (never sleeps) · final max |v|+|ω| **0.1352**
29
+
30
+ ### ragdoll FIELD (N=64, 704 bodies, 640 joints, 600 ticks)
31
+
32
+ | metric | mean | median | p95 | p99 | max |
33
+ |--------|------|--------|-----|-----|-----|
34
+ | tick (all) | 33.55 | 32.68 | 46.22 | 56.10 | 62.74 |
35
+ | tick (first 1s, settle) | 27.31 | 24.99 | 37.62 | 62.57 | 62.57 |
36
+ | tick (last 1s, settled) | 34.67 | 33.83 | 47.28 | 52.07 | 52.07 |
37
+
38
+ avg awake 704.0 / 704 · final awake **704 / 704 (asleep 0)** · residual max |v|+|ω| **0.4997**
39
+ asleep histogram: **0.0 every second** — the pile never sleeps; steady-state cost
40
+ (34.7ms) is *higher* than settle (27ms). **This is the gap.** Target: A2/A3 drive
41
+ asleep ↑ and settled-window tick ↓.
42
+
43
+ ### settling grid (1024 shapes, A4 / sleep canary)
44
+
45
+ | metric | mean | median | p95 | p99 | max |
46
+ |--------|------|--------|-----|-----|-----|
47
+ | tick (all) | 4.155 | 1.732 | 29.74 | 33.31 | 79.96 |
48
+ | tick (first 1s) | 22.88 | 29.74 | 35.28 | 79.96 | 79.96 |
49
+ | tick (last 1s, settled) | 1.464 | 1.425 | 1.794 | 2.088 | 2.088 |
50
+
51
+ final awake **77 / 1024** (stacks sleep) · fall-through **0** — A4 must preserve both.
52
+
53
+ ### Deferred (run at phase boundaries / final sweep)
54
+ - KEVA tower (~15 min/run) — large-island contact; run pre/post per phase, not per-commit.
55
+ - falling tower, MeshStack, Rain, raycast — control benches; full sweep in Phase 4.
56
+
57
+ ---
58
+ ## Phase 1 — A4: smooth contact position bias
59
+
60
+ `position_correction_bias(depth, spook_a, band)` helper; both bias sites share it;
61
+ `contactBiasSmoothBand` (default **0**). At band=0 the math is bit-identical to the
62
+ old hard hinge → **140/141 physics tests pass unchanged** (ragdoll spec + PhysicsSystem
63
+ spec), determinism intact. **PASS (refactor).**
64
+
65
+ A/B on the settling-grid canary (band=0.005 vs baseline, same machine):
66
+
67
+ | metric | baseline | A4 on (0.005) | Δ |
68
+ |--------|----------|---------------|---|
69
+ | settled tick (last 1s, mean) | 1.464 | 1.535 | +4.8%* |
70
+ | settled tick (median) | 1.425 | 1.463 | +2.7% (within 3% noise) |
71
+ | final awake | 77/1024 | 77/1024 | — (sleep preserved) |
72
+ | fall-through | 0 | 0 | — |
73
+
74
+ \* sub-ms absolute; within run-to-run noise for this scene (grid settles below slop
75
+ fast, so A4's band barely engages here). **PASS** — quality gates green (fall-through 0,
76
+ sleep intact), perf within the ≤+2% budget on the median.
77
+
78
+ **Decision:** A4 implemented + validated-safe; **default stays off** (`band=0`). Whether
79
+ to default-on (and whether it helps the ragdoll residual) is judged combined with A2/A3
80
+ in Phase 4. Knob available for tuning.
81
+
82
+ ### Windowed-metric baselines (A4 off — used for A2/A3 A/B)
83
+ Bench residual metric switched from single-tick (noisy) to worst over last 1s.
84
+
85
+ | scene | tick mean | tick median | tick p99 | last-1s mean | residual | asleep |
86
+ |-------|-----------|-------------|----------|--------------|----------|--------|
87
+ | MICRO | 0.4250 | 0.3769 | 1.1478 | — | — | 0/11 |
88
+ | FIELD (N=64) | 31.92 | 31.68 | 46.13 | 32.27 | **0.7515** | **0/704** |
89
+
90
+ (Run-to-run variance vs Phase-0 ≈ 5% — gate on same-process A/B, not cross-run absolutes.)
91
+
92
+ ---
93
+ ## Phase 2 — A2: block 3×3 point-solve + symmetric sweep
94
+
95
+ `jointBlockSolve` + `jointSweepSymmetric` (both default **false**). Inert at default
96
+ → 167 joint/system tests pass unchanged. Same-process A/B on the ragdoll benches:
97
+
98
+ | scene | baseline | A2 on | Δ |
99
+ |-------|----------|-------|---|
100
+ | MICRO tick mean | 0.4250 | 0.3669 | **−13.7%** |
101
+ | FIELD tick mean | 31.92 | 26.81 | **−16.0%** |
102
+ | FIELD residual (max) | 0.7515 | 0.7445 | ~0 |
103
+
104
+ **A2 is a perf win, not a cost** (the block does 1 solve + ≤2 impulse applies vs 3
105
+ axes × 2 applies, and is better-conditioned). Well under the +10% budget — it's
106
+ negative. Residual ~unchanged (expected: A2 sharpens convergence; killing the limit
107
+ cycle is A3's job). **PASS.**
108
+
109
+ **Finding (drives A3):** A2 *enabled* against the full instrumented spec fails
110
+ `settledSpeedMean` (2.26 > 1.8). The under-converged per-axis solve was supplying
111
+ *incidental numerical damping*; the exact block solve removes it, leaving the
112
+ metastable on-sphere ragdoll livelier. A2 ⇒ must pair with A3 dissipation.
113
+
114
+ ## Phase 3 — A3: under-relaxation (ω) [+ compliance deferred]
115
+
116
+ `jointRelaxation` (default **1** = off). Applied to all three solve paths.
117
+ A2+A3 on the canonical seed (full instrumented spec):
118
+
119
+ | metric | baseline | A2+A3 (ω=0.90) | Δ |
120
+ |--------|----------|----------------|---|
121
+ | settled lin accel (per-pt) | 55.07 | **3.79** m/s² | −93% |
122
+ | settled ang accel (per-pt) | 36.9 | **4.21** rad/s² | −89% |
123
+ | settled lin speed (per-pt) | 0.73 | **0.067** m/s | −91% |
124
+ | settled ang speed (per-pt) | 0.75 | **0.189** rad/s | −75% |
125
+ | MICRO tick mean | 0.425 | 0.365 | −14% |
126
+ | transient pen (static) | 0.26 | 0.38 | **+46%** (cost) |
127
+
128
+ The settled residual collapses ~10–14× — the gap the whole effort targeted. With
129
+ defaults flipped on, **all 175 non-ragdoll joint/vehicle/IK/island tests still pass**;
130
+ only the ragdoll golden *lower* bounds trip (we improved past them).
131
+
132
+ ### ⚠ Complication — ω is chaotic on the metastable scene (why we did NOT burn it in)
133
+
134
+ Sweeping ω on the spec (single ragdoll draped on a convex sphere):
135
+
136
+ | ω | settled lin speed | verdict |
137
+ |---|-------------------|---------|
138
+ | 1.00 | 0.981 | livelier |
139
+ | 0.97 | **5.81** | slid off / unsettled |
140
+ | 0.95 | 0.437 | good |
141
+ | 0.92 | **4.50** | slid off / unsettled |
142
+ | 0.90 | 0.067 | great |
143
+ | 0.75 | 3.62 | unstable |
144
+
145
+ Non-monotone and **bimodal**: the ragdoll either settles on the dome or slides off,
146
+ and tiny ω changes flip the basin. So a good ω on one seed (0.90) is **not** a robust
147
+ global default — a neighbouring scene could land in a bad basin. Also ω<~0.8 starves
148
+ constraint convergence → energy injection. Plus the +46% transient-penetration cost.
149
+
150
+ **Decision:** Do **not** burn in ω as a default off single-seed data — that is exactly
151
+ the brittle-default risk this plan exists to avoid. A2/A3/A4 ship as **validated opt-in
152
+ knobs, default off (zero regression)**. Full physics suite with defaults off: **865
153
+ pass, 0 fail.**
154
+
155
+ ## Phase 4 — burn-in (no flags)
156
+
157
+ Directive: **no flags/toggles on the engine** — converge to one baked behaviour.
158
+ That required deciding each change on *robust* evidence, not the canonical seed.
159
+
160
+ ### Monte-Carlo settled-accel **median over 150 seeds** (the decider)
161
+
162
+ | config | worst-point setA median | worst-point setV median |
163
+ |--------|-------------------------|-------------------------|
164
+ | baseline (no A2/A3) | ~68 | ~1.23 |
165
+ | A2 only (ω=1) | ~71 | ~1.53 |
166
+ | A2 + ω=0.90 | **~102** | ~2.04 |
167
+
168
+ The single-seed ω=0.90 win (3.8 m/s²) was **basin luck** — across the seed space ω
169
+ *raises* the median residual, and A2 raises settled velocity ~20%. **The settled
170
+ jitter is basin/sleep-dominated, not solver-convergence-dominated** (per-seed variance
171
+ ≫ any config difference). No convergence/relaxation lever moves the median. So:
172
+
173
+ ### Burn-in decision
174
+
175
+ | change | verdict | action |
176
+ |--------|---------|--------|
177
+ | **A2** (block 3×3 point-solve + symmetric sweep) | robust **−9–16%** joint-solve time, exact ball-socket, mass-ratio-robust; residual-neutral in median | **BAKED as the single code path** (no flag) |
178
+ | **A3** (ω under-relaxation) | median-*worse*, chaotic/bimodal, +46% transient pen | **REMOVED** (disproven bandaid) |
179
+ | **A4** (contact bias smoothing) | neutral, benefit unproven; baking would churn contact determinism for no measured gain | **REVERTED** to original hard hinge |
180
+
181
+ All flags/config fields removed (`jointBlockSolve`, `jointSweepSymmetric`,
182
+ `jointRelaxation`, `contactBiasSmoothBand`). Solver has one path. Final:
183
+
184
+ | scene | pre (baseline) | post (A2 baked) | Δ |
185
+ |-------|----------------|-----------------|---|
186
+ | MICRO tick mean | 0.425 | 0.388 | −9% |
187
+ | FIELD tick mean | 31.92 | 28.65 | −10% |
188
+ | FIELD residual / asleep | 0.75 / 0 | 0.74 / 0 | neutral |
189
+
190
+ Re-baselined one golden band: `settledSpeedMean` 1.8→2.9 hi (A2's honest liveliness;
191
+ documented in the spec). Full physics suite: **865 pass / 0 fail.**
192
+
193
+ ### The jitter goal is NOT closed — and the data says why
194
+
195
+ A2 is a perf+correctness win but does **not** reduce the settled jitter (it slightly
196
+ raises it — removing the per-axis solve's incidental damping). The Monte-Carlo proves
197
+ the residual is basin/sleep-dominated. **The real lever is island sleep, not the
198
+ solver:** an *aggregate-energy + hysteresis* sleep criterion (plan item **B**) lets an
199
+ over-constrained island deactivate once its *total* energy is low, instead of requiring
200
+ every body under the per-body gate continuously (which the limit cycle never satisfies).
201
+ Recommended next step. Beyond that, **A1** (reduced-coordinate articulation) removes the
202
+ maximal-coordinate joint residual at the source.
203
+
204
+ **Net of this effort:** a faster, more correct joint solver (shipped, no flags) + a
205
+ rigorous, evidenced redirection of the jitter goal to the lever that can actually move
206
+ it (sleep), instead of a brittle solver knob that looked good on one seed.
207
+
208
+