@woosh/meep-engine 2.155.0 → 2.157.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 (1098) hide show
  1. package/README.md +2 -4
  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/editor/view/ecs/components/common/AutoCanvasView.js +100 -53
  7. package/editor/view/ecs/components/common/TextController.js +59 -0
  8. package/editor/view/node-graph/NodeGraphCamera.js +90 -0
  9. package/editor/view/node-graph/NodeGraphEditorView.js +121 -22
  10. package/editor/view/node-graph/NodeGraphSelection.js +89 -0
  11. package/editor/view/node-graph/NodeGraphView.js +669 -453
  12. package/editor/view/node-graph/NodeView.js +211 -135
  13. package/editor/view/node-graph/actions/ConnectionCreateAction.js +53 -0
  14. package/editor/view/node-graph/actions/ConnectionDeleteAction.js +36 -0
  15. package/editor/view/node-graph/actions/NodeDeleteAction.js +88 -0
  16. package/editor/view/node-graph/actions/NodeParameterSetAction.js +52 -0
  17. package/editor/view/node-graph/actions/NodesMoveAction.js +41 -0
  18. package/editor/view/node-graph/actions/SelectionSetAction.js +60 -0
  19. package/editor/view/node-graph/connection_wire_geometry.js +107 -0
  20. package/package.json +1 -1
  21. package/samples/generation/SampleGenerator0.js +8 -1
  22. package/src/core/binary/32BitEncoder.js +1 -1
  23. package/src/core/binary/reinterpret_float32_as_uint32.d.ts +7 -0
  24. package/src/core/binary/reinterpret_float32_as_uint32.d.ts.map +1 -0
  25. package/src/core/binary/reinterpret_float32_as_uint32.js +13 -0
  26. package/src/core/binary/reinterpret_uint32_as_float32.d.ts +7 -0
  27. package/src/core/binary/reinterpret_uint32_as_float32.d.ts.map +1 -0
  28. package/src/core/binary/reinterpret_uint32_as_float32.js +14 -0
  29. package/src/core/binary/to_half_float_uint16.js +3 -3
  30. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_incremental.d.ts.map +1 -1
  31. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_incremental.js +1 -3
  32. package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts.map +1 -1
  33. package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js +275 -253
  34. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.d.ts +12 -0
  35. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.d.ts.map +1 -0
  36. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.js +92 -0
  37. package/src/core/bvh8/BVH8.d.ts +127 -0
  38. package/src/core/bvh8/BVH8.d.ts.map +1 -0
  39. package/src/core/bvh8/BVH8.js +436 -0
  40. package/src/core/bvh8/NOTES.md +63 -0
  41. package/src/core/bvh8/build/BVH8Converter.d.ts +59 -0
  42. package/src/core/bvh8/build/BVH8Converter.d.ts.map +1 -0
  43. package/src/core/bvh8/build/BVH8Converter.js +588 -0
  44. package/src/core/bvh8/build/NodeProxy.d.ts +66 -0
  45. package/src/core/bvh8/build/NodeProxy.d.ts.map +1 -0
  46. package/src/core/bvh8/build/NodeProxy.js +308 -0
  47. package/src/core/bvh8/build/TriangleCluster.d.ts +29 -0
  48. package/src/core/bvh8/build/TriangleCluster.d.ts.map +1 -0
  49. package/src/core/bvh8/build/TriangleCluster.js +123 -0
  50. package/src/core/bvh8/build/aabb3_compute_merge_cost.d.ts +8 -0
  51. package/src/core/bvh8/build/aabb3_compute_merge_cost.d.ts.map +1 -0
  52. package/src/core/bvh8/build/aabb3_compute_merge_cost.js +29 -0
  53. package/src/core/bvh8/build/aabb3_from_triangle_by_index.d.ts +10 -0
  54. package/src/core/bvh8/build/aabb3_from_triangle_by_index.d.ts.map +1 -0
  55. package/src/core/bvh8/build/aabb3_from_triangle_by_index.js +18 -0
  56. package/src/core/bvh8/build/bvh8_build_for_geometry.d.ts +10 -0
  57. package/src/core/bvh8/build/bvh8_build_for_geometry.d.ts.map +1 -0
  58. package/src/core/bvh8/build/bvh8_build_for_geometry.js +303 -0
  59. package/src/core/bvh8/build/bvh8_from_proxy.d.ts +9 -0
  60. package/src/core/bvh8/build/bvh8_from_proxy.d.ts.map +1 -0
  61. package/src/core/bvh8/build/bvh8_from_proxy.js +256 -0
  62. package/src/core/bvh8/build/byte.d.ts +7 -0
  63. package/src/core/bvh8/build/byte.d.ts.map +1 -0
  64. package/src/core/bvh8/build/byte.js +10 -0
  65. package/src/core/bvh8/build/encode_bounds_e.d.ts +9 -0
  66. package/src/core/bvh8/build/encode_bounds_e.d.ts.map +1 -0
  67. package/src/core/bvh8/build/encode_bounds_e.js +12 -0
  68. package/src/core/bvh8/bvh8_convert_to_dot.d.ts +11 -0
  69. package/src/core/bvh8/bvh8_convert_to_dot.d.ts.map +1 -0
  70. package/src/core/bvh8/bvh8_convert_to_dot.js +133 -0
  71. package/src/core/bvh8/bvh8_count_primitives.d.ts +22 -0
  72. package/src/core/bvh8/bvh8_count_primitives.d.ts.map +1 -0
  73. package/src/core/bvh8/bvh8_count_primitives.js +98 -0
  74. package/src/core/bvh8/bvh8_geometry_validate.d.ts +16 -0
  75. package/src/core/bvh8/bvh8_geometry_validate.d.ts.map +1 -0
  76. package/src/core/bvh8/bvh8_geometry_validate.js +149 -0
  77. package/src/core/bvh8/bvh8_geometry_validate_indirect.d.ts +16 -0
  78. package/src/core/bvh8/bvh8_geometry_validate_indirect.d.ts.map +1 -0
  79. package/src/core/bvh8/bvh8_geometry_validate_indirect.js +177 -0
  80. package/src/core/bvh8/bvh8_get_node_bounds.d.ts +9 -0
  81. package/src/core/bvh8/bvh8_get_node_bounds.d.ts.map +1 -0
  82. package/src/core/bvh8/bvh8_get_node_bounds.js +35 -0
  83. package/src/core/bvh8/bvh8_get_node_child_bounds.d.ts +10 -0
  84. package/src/core/bvh8/bvh8_get_node_child_bounds.d.ts.map +1 -0
  85. package/src/core/bvh8/bvh8_get_node_child_bounds.js +53 -0
  86. package/src/core/bvh8/bvh8_node_child_surface_area.d.ts +9 -0
  87. package/src/core/bvh8/bvh8_node_child_surface_area.d.ts.map +1 -0
  88. package/src/core/bvh8/bvh8_node_child_surface_area.js +18 -0
  89. package/src/core/bvh8/bvh8_node_count_triangles.d.ts +8 -0
  90. package/src/core/bvh8/bvh8_node_count_triangles.d.ts.map +1 -0
  91. package/src/core/bvh8/bvh8_node_count_triangles.js +28 -0
  92. package/src/core/bvh8/bvh8_quality.d.ts +8 -0
  93. package/src/core/bvh8/bvh8_quality.d.ts.map +1 -0
  94. package/src/core/bvh8/bvh8_quality.js +73 -0
  95. package/src/core/bvh8/bvh8_validate_structure.d.ts +15 -0
  96. package/src/core/bvh8/bvh8_validate_structure.d.ts.map +1 -0
  97. package/src/core/bvh8/bvh8_validate_structure.js +87 -0
  98. package/src/core/cache/Cache.d.ts.map +1 -1
  99. package/src/core/cache/Cache.js +7 -0
  100. package/src/core/cache/FrequencySketch.d.ts.map +1 -1
  101. package/src/core/cache/FrequencySketch.js +8 -4
  102. package/src/core/clipboard/obtainClipBoard.d.ts +6 -0
  103. package/src/core/clipboard/obtainClipBoard.d.ts.map +1 -0
  104. package/src/core/clipboard/obtainClipBoard.js +29 -0
  105. package/src/core/clipboard/safeClipboardReadText.d.ts +6 -0
  106. package/src/core/clipboard/safeClipboardReadText.d.ts.map +1 -0
  107. package/src/core/clipboard/safeClipboardReadText.js +55 -0
  108. package/src/core/clipboard/safeClipboardWriteText.d.ts +8 -0
  109. package/src/core/clipboard/safeClipboardWriteText.d.ts.map +1 -0
  110. package/src/core/clipboard/safeClipboardWriteText.js +23 -0
  111. package/src/core/collection/Uint32MinHeap.d.ts +56 -0
  112. package/src/core/collection/Uint32MinHeap.d.ts.map +1 -0
  113. package/src/core/collection/Uint32MinHeap.js +109 -0
  114. package/src/core/collection/array/array_quick_sort_by_lookup_map.js +1 -1
  115. package/src/core/collection/array/array_set_diff_sorting.d.ts.map +1 -1
  116. package/src/core/collection/array/array_set_diff_sorting.js +4 -1
  117. package/src/core/collection/array/array_shuffle.d.ts.map +1 -1
  118. package/src/core/collection/array/array_shuffle.js +30 -27
  119. package/src/core/collection/array/binarySearchLowIndex.d.ts.map +1 -1
  120. package/src/core/collection/array/binarySearchLowIndex.js +4 -3
  121. package/src/core/collection/array/typed/array_buffer_hash.js +1 -1
  122. package/src/core/collection/array/typed/is_typed_array_equals.d.ts.map +1 -1
  123. package/src/core/collection/array/typed/is_typed_array_equals.js +12 -2
  124. package/src/core/collection/heap/BinaryHeap.d.ts.map +1 -1
  125. package/src/core/collection/heap/BinaryHeap.js +12 -2
  126. package/src/core/collection/list/FilteredListProjection.js +1 -1
  127. package/src/core/collection/queue/Deque.d.ts.map +1 -1
  128. package/src/core/collection/queue/Deque.js +10 -8
  129. package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
  130. package/src/core/collection/table/RowFirstTable.js +4 -2
  131. package/src/core/collection/table/RowFirstTableSpec.js +2 -2
  132. package/src/{engine/physics/island → core/collection/union-find}/union_find.d.ts +8 -5
  133. package/src/core/collection/union-find/union_find.d.ts.map +1 -0
  134. package/src/{engine/physics/island → core/collection/union-find}/union_find.js +8 -5
  135. package/src/core/color/operations/color_lerp.d.ts.map +1 -1
  136. package/src/core/color/operations/color_lerp.js +10 -3
  137. package/src/core/color/rgb2uint32.js +1 -1
  138. package/src/core/color/rgbe9995_to_rgb.js +1 -1
  139. package/src/core/dom/isImageBitmap.d.ts +7 -0
  140. package/src/core/dom/isImageBitmap.d.ts.map +1 -0
  141. package/src/core/dom/isImageBitmap.js +12 -0
  142. package/src/core/function/frameThrottle.d.ts +8 -0
  143. package/src/core/function/frameThrottle.d.ts.map +1 -0
  144. package/src/core/function/frameThrottle.js +23 -0
  145. package/src/core/function/objectsEqual.d.ts.map +1 -1
  146. package/src/core/function/objectsEqual.js +2 -1
  147. package/src/core/geom/2d/aabb/AABB2.d.ts.map +1 -1
  148. package/src/core/geom/2d/aabb/AABB2.js +12 -11
  149. package/src/core/geom/2d/convex-hull/convex_hull_jarvis_2d.d.ts.map +1 -1
  150. package/src/core/geom/2d/convex-hull/convex_hull_jarvis_2d.js +30 -4
  151. package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.d.ts.map +1 -1
  152. package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +6 -2
  153. package/src/core/geom/2d/hash-grid/SpatialHashGrid.d.ts.map +1 -1
  154. package/src/core/geom/2d/hash-grid/SpatialHashGrid.js +388 -386
  155. package/src/core/geom/2d/hash-grid/shg_query_elements_line.d.ts.map +1 -1
  156. package/src/core/geom/2d/hash-grid/shg_query_elements_line.js +8 -3
  157. package/src/{engine/physics/narrowphase/clip_against_axis_uv.d.ts → core/geom/2d/polygon/polygon2_clip_axis_halfplane.d.ts} +3 -3
  158. package/src/core/geom/2d/polygon/polygon2_clip_axis_halfplane.d.ts.map +1 -0
  159. package/src/{engine/physics/narrowphase/clip_against_axis_uv.js → core/geom/2d/polygon/polygon2_clip_axis_halfplane.js} +51 -51
  160. package/src/core/geom/2d/quad-tree/QuadTreeDatum.d.ts.map +1 -1
  161. package/src/core/geom/2d/quad-tree/QuadTreeDatum.js +9 -1
  162. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.d.ts +3 -1
  163. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.d.ts.map +1 -1
  164. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +3 -1
  165. package/src/core/geom/2d/quad-tree-binary/QuadTree.js +714 -714
  166. package/src/core/geom/2d/r-tree/StaticR2Tree.d.ts.map +1 -1
  167. package/src/core/geom/2d/r-tree/StaticR2Tree.js +5 -4
  168. package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.d.ts.map +1 -1
  169. package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +33 -29
  170. package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.d.ts.map +1 -1
  171. package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.js +3 -1
  172. package/src/core/geom/3d/aabb/aabb3_signed_distance_to_aabb3.d.ts.map +1 -1
  173. package/src/core/geom/3d/aabb/aabb3_signed_distance_to_aabb3.js +10 -7
  174. package/src/{engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts → core/geom/3d/aabb/aabb3_transform_oriented_inverse.d.ts} +9 -7
  175. package/src/core/geom/3d/aabb/aabb3_transform_oriented_inverse.d.ts.map +1 -0
  176. package/src/{engine/physics/narrowphase/decomposition/aabb_world_to_local.js → core/geom/3d/aabb/aabb3_transform_oriented_inverse.js} +9 -7
  177. package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.d.ts.map +1 -1
  178. package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.js +30 -9
  179. package/src/core/geom/3d/aabb/compute_aabb_from_points.js +3 -3
  180. package/src/core/geom/3d/aabb/compute_triangle_group_aabb3.d.ts +12 -0
  181. package/src/core/geom/3d/aabb/compute_triangle_group_aabb3.d.ts.map +1 -0
  182. package/src/core/geom/3d/aabb/compute_triangle_group_aabb3.js +46 -0
  183. package/src/core/geom/3d/box/box3_projected_half_extent.d.ts +28 -0
  184. package/src/core/geom/3d/box/box3_projected_half_extent.d.ts.map +1 -0
  185. package/src/core/geom/3d/box/box3_projected_half_extent.js +35 -0
  186. package/src/core/geom/3d/box/box3_raycast.d.ts +37 -0
  187. package/src/core/geom/3d/box/box3_raycast.d.ts.map +1 -0
  188. package/src/core/geom/3d/box/box3_raycast.js +81 -0
  189. package/src/core/geom/3d/capsule/capsule_raycast.d.ts +35 -0
  190. package/src/core/geom/3d/capsule/capsule_raycast.d.ts.map +1 -0
  191. package/src/core/geom/3d/capsule/capsule_raycast.js +93 -0
  192. package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.d.ts.map +1 -1
  193. package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.js +4 -0
  194. package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +1 -1
  195. package/src/core/geom/3d/frustum/read_cluster_frustum_corners.js +1 -1
  196. package/src/core/geom/3d/frustum/read_frustum_corner.d.ts +9 -0
  197. package/src/core/geom/3d/frustum/read_frustum_corner.d.ts.map +1 -0
  198. package/src/core/geom/3d/frustum/read_frustum_corner.js +14 -0
  199. package/src/core/geom/3d/gjk/gjk.d.ts.map +1 -0
  200. package/src/{engine/physics → core/geom/3d}/gjk/gjk.js +430 -372
  201. package/src/{engine/physics → core/geom/3d}/gjk/gjk_epa_penetration.d.ts +8 -5
  202. package/src/core/geom/3d/gjk/gjk_epa_penetration.d.ts.map +1 -0
  203. package/src/{engine/physics → core/geom/3d}/gjk/gjk_epa_penetration.js +520 -548
  204. package/src/{engine/physics → core/geom/3d}/gjk/minkowski_support.d.ts +5 -4
  205. package/src/core/geom/3d/gjk/minkowski_support.d.ts.map +1 -0
  206. package/src/{engine/physics → core/geom/3d}/gjk/minkowski_support.js +71 -70
  207. package/src/{engine/physics → core/geom/3d}/gjk/mpr.d.ts +3 -3
  208. package/src/core/geom/3d/gjk/mpr.d.ts.map +1 -0
  209. package/src/{engine/physics → core/geom/3d}/gjk/mpr.js +368 -362
  210. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.d.ts.map +1 -1
  211. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.js +3 -2
  212. package/src/core/geom/3d/mat4/decompose_matrix_4_array.d.ts.map +1 -1
  213. package/src/core/geom/3d/mat4/decompose_matrix_4_array.js +12 -2
  214. package/src/core/geom/3d/mat4/eulerAnglesFromMatrix.js +2 -2
  215. package/src/core/geom/3d/mat4/m4_multiply_alphatensor.d.ts +1 -1
  216. package/src/core/geom/3d/mat4/m4_multiply_alphatensor.d.ts.map +1 -1
  217. package/src/core/geom/3d/mat4/m4_multiply_alphatensor.js +19 -13
  218. package/src/core/geom/3d/octahedra/octahedral_direction_to_uv.d.ts.map +1 -1
  219. package/src/core/geom/3d/octahedra/octahedral_direction_to_uv.js +3 -2
  220. package/src/core/geom/3d/plane/plane3_compute_plane_intersection.js +3 -2
  221. package/src/{engine/physics/integration/quat_integrate.d.ts → core/geom/3d/quaternion/quat3_integrate.d.ts} +2 -2
  222. package/src/core/geom/3d/quaternion/quat3_integrate.d.ts.map +1 -0
  223. package/src/{engine/physics/integration/quat_integrate.js → core/geom/3d/quaternion/quat3_integrate.js} +1 -1
  224. package/src/core/geom/3d/shape/MeshShape3D.d.ts.map +1 -1
  225. package/src/core/geom/3d/shape/MeshShape3D.js +7 -0
  226. package/src/{engine/physics/narrowphase/PosedShape.d.ts → core/geom/3d/shape/PosedShape3D.d.ts} +9 -8
  227. package/src/{engine/physics/narrowphase/PosedShape.d.ts.map → core/geom/3d/shape/PosedShape3D.d.ts.map} +1 -1
  228. package/src/{engine/physics/narrowphase/PosedShape.js → core/geom/3d/shape/PosedShape3D.js} +10 -9
  229. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  230. package/src/core/geom/3d/shape/TransformedShape3D.js +15 -11
  231. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  232. package/src/core/geom/3d/shape/UnionShape3D.js +3 -2
  233. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts.map +1 -1
  234. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +153 -148
  235. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.d.ts.map +1 -1
  236. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +7 -0
  237. package/src/core/geom/3d/sphere/harmonics/sh3_sample_by_direction.d.ts.map +1 -1
  238. package/src/core/geom/3d/sphere/harmonics/sh3_sample_by_direction.js +13 -10
  239. package/src/core/geom/3d/sphere/sphere_projected_sphere_radius_sqr.d.ts +1 -1
  240. package/src/core/geom/3d/sphere/sphere_projected_sphere_radius_sqr.js +2 -2
  241. package/src/core/geom/3d/sphere/sphere_raycast.d.ts +33 -0
  242. package/src/core/geom/3d/sphere/sphere_raycast.d.ts.map +1 -0
  243. package/src/core/geom/3d/sphere/sphere_raycast.js +47 -0
  244. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.d.ts +24 -0
  245. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.d.ts.map +1 -0
  246. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.js +39 -0
  247. package/src/core/geom/3d/tetrahedra/triangle/trace_triangular_depth_map.d.ts.map +1 -1
  248. package/src/core/geom/3d/tetrahedra/triangle/trace_triangular_depth_map.js +4 -2
  249. package/src/core/geom/3d/topology/bounds/computeTriangleClusterNormalBoundingCone.js +3 -3
  250. package/src/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.js +1 -1
  251. package/src/core/geom/3d/topology/tm_vertex_compute_normal.d.ts.map +1 -1
  252. package/src/core/geom/3d/topology/tm_vertex_compute_normal.js +4 -2
  253. package/src/core/geom/3d/util/make_justified_point_grid.d.ts.map +1 -1
  254. package/src/core/geom/3d/util/make_justified_point_grid.js +18 -10
  255. package/src/core/geom/ConicRay.d.ts.map +1 -1
  256. package/src/core/geom/ConicRay.js +11 -13
  257. package/src/core/geom/packing/max-rect/removeRedundantBoxes.d.ts.map +1 -1
  258. package/src/core/geom/packing/max-rect/removeRedundantBoxes.js +19 -4
  259. package/src/core/geom/vec3/v3_orthonormal_matrix_from_normal.d.ts.map +1 -0
  260. package/src/{engine/graphics/sh3/path_tracer/sampling → core/geom/vec3}/v3_orthonormal_matrix_from_normal.js +1 -1
  261. package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts +1 -1
  262. package/src/core/geom/vec3/v3_quat3_apply_inverse.js +1 -1
  263. package/src/core/graph/coloring/colorizeGraph.js +2 -2
  264. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  265. package/src/core/graph/csr/CSRGraph.js +325 -319
  266. package/src/core/graph/layout/CircleLayout.d.ts.map +1 -1
  267. package/src/core/graph/layout/CircleLayout.js +8 -6
  268. package/src/core/graph/metis/native/refine/compute_kway_params.d.ts.map +1 -1
  269. package/src/core/graph/metis/native/refine/compute_kway_params.js +139 -138
  270. package/src/core/graph/mn_graph_coarsen.d.ts.map +1 -1
  271. package/src/core/graph/mn_graph_coarsen.js +4 -2
  272. package/src/core/graph/v2/NodeContainer.js +7 -7
  273. package/src/core/localization/LocalizationEngine.js +1 -1
  274. package/src/core/math/bell_membership_function.d.ts.map +1 -1
  275. package/src/core/math/bell_membership_function.js +3 -1
  276. package/src/core/math/complex/complex_add.d.ts +4 -4
  277. package/src/core/math/complex/complex_add.d.ts.map +1 -1
  278. package/src/core/math/complex/complex_add.js +14 -5
  279. package/src/core/math/complex/complex_div.d.ts +4 -4
  280. package/src/core/math/complex/complex_div.d.ts.map +1 -1
  281. package/src/core/math/complex/complex_div.js +13 -6
  282. package/src/core/math/complex/complex_mul.d.ts +4 -4
  283. package/src/core/math/complex/complex_mul.d.ts.map +1 -1
  284. package/src/core/math/complex/complex_mul.js +12 -5
  285. package/src/core/math/complex/complex_sub.d.ts +4 -4
  286. package/src/core/math/complex/complex_sub.d.ts.map +1 -1
  287. package/src/core/math/complex/complex_sub.js +14 -5
  288. package/src/core/math/idct_1d.d.ts +4 -4
  289. package/src/core/math/idct_1d.d.ts.map +1 -1
  290. package/src/core/math/idct_1d.js +3 -3
  291. package/src/{engine/physics/fluid/solver/optimal_sor_omega.d.ts → core/math/linalg/sor_optimal_omega.d.ts} +4 -3
  292. package/src/core/math/linalg/sor_optimal_omega.d.ts.map +1 -0
  293. package/src/{engine/physics/fluid/solver/optimal_sor_omega.js → core/math/linalg/sor_optimal_omega.js} +4 -3
  294. package/src/core/math/lookup/ParameterLookupTable.d.ts +123 -0
  295. package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -0
  296. package/src/core/math/lookup/ParameterLookupTable.js +495 -0
  297. package/src/core/math/lookup/ParameterLookupTableFlags.d.ts +5 -0
  298. package/src/core/math/lookup/ParameterLookupTableFlags.d.ts.map +1 -0
  299. package/src/core/math/lookup/ParameterLookupTableFlags.js +6 -0
  300. package/src/core/math/noise/create_simplex_noise_2d.d.ts.map +1 -1
  301. package/src/core/math/noise/create_simplex_noise_2d.js +4 -2
  302. package/src/core/math/noise/sdnoise.d.ts.map +1 -1
  303. package/src/core/math/noise/sdnoise.js +12 -9
  304. package/src/core/math/physics/kinematics/computeInterceptPoint.d.ts.map +1 -0
  305. package/src/{engine/physics → core/math/physics/kinematics}/computeInterceptPoint.js +79 -79
  306. package/src/core/math/physics/mie/compute_bhmie_optical_properties.d.ts.map +1 -1
  307. package/src/core/math/physics/mie/compute_bhmie_optical_properties.js +94 -50
  308. package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts +3 -6
  309. package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts.map +1 -1
  310. package/src/core/math/physics/mie/lorenz_mie_coefs.js +180 -157
  311. package/src/core/math/physics/mie/mie_ab_to_optical_properties.d.ts +3 -4
  312. package/src/core/math/physics/mie/mie_ab_to_optical_properties.d.ts.map +1 -1
  313. package/src/core/math/physics/mie/mie_ab_to_optical_properties.js +47 -21
  314. package/src/core/math/physics/mie/ri_air.d.ts.map +1 -1
  315. package/src/core/math/physics/mie/ri_air.js +1 -3
  316. package/src/core/math/physics/mie/ri_ammonium_sulfate.d.ts.map +1 -1
  317. package/src/core/math/physics/mie/ri_ammonium_sulfate.js +1 -3
  318. package/src/core/math/physics/mie/ri_brine.d.ts.map +1 -1
  319. package/src/core/math/physics/mie/ri_brine.js +1 -3
  320. package/src/core/math/physics/mie/ri_dust.d.ts.map +1 -1
  321. package/src/core/math/physics/mie/ri_dust.js +1 -3
  322. package/src/core/math/physics/mie/ri_pollen.d.ts.map +1 -1
  323. package/src/core/math/physics/mie/ri_pollen.js +1 -3
  324. package/src/core/math/physics/mie/ri_smoke.d.ts.map +1 -1
  325. package/src/core/math/physics/mie/ri_smoke.js +1 -3
  326. package/src/core/math/physics/mie/ri_soot.d.ts.map +1 -1
  327. package/src/core/math/physics/mie/ri_soot.js +1 -3
  328. package/src/core/math/physics/mie/ri_water.d.ts.map +1 -1
  329. package/src/core/math/physics/mie/ri_water.js +1 -3
  330. package/src/core/math/random/randomIntegerBetween.d.ts.map +1 -1
  331. package/src/core/math/random/randomIntegerBetween.js +4 -1
  332. package/src/core/math/random/random_pick_weighted_index.d.ts +10 -0
  333. package/src/core/math/random/random_pick_weighted_index.d.ts.map +1 -0
  334. package/src/core/math/random/random_pick_weighted_index.js +26 -0
  335. package/src/core/math/solveCubic.d.ts.map +1 -1
  336. package/src/core/math/solveCubic.js +95 -82
  337. package/src/core/math/spline/computeCatmullRomSplineUniformDistance.d.ts.map +1 -1
  338. package/src/core/math/spline/computeCatmullRomSplineUniformDistance.js +13 -0
  339. package/src/core/math/statistics/softmax.js +1 -1
  340. package/src/core/model/node-graph/NodeGraph.d.ts +9 -0
  341. package/src/core/model/node-graph/NodeGraph.d.ts.map +1 -1
  342. package/src/core/model/node-graph/NodeGraph.js +38 -0
  343. package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts +24 -0
  344. package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts.map +1 -1
  345. package/src/core/model/node-graph/visual/NodeGraphVisualData.js +56 -1
  346. package/src/core/model/node-graph/visual/NodeVisualData.js +1 -1
  347. package/src/core/model/object/ImmutableObjectPool.d.ts +7 -0
  348. package/src/core/model/object/ImmutableObjectPool.d.ts.map +1 -1
  349. package/src/core/model/object/ImmutableObjectPool.js +20 -10
  350. package/src/core/model/reactive/evaluation/MultiPredicateEvaluator.d.ts.map +1 -1
  351. package/src/core/model/reactive/evaluation/MultiPredicateEvaluator.js +39 -2
  352. package/src/core/model/reactive/model/terminal/ReactiveReference.d.ts.map +1 -1
  353. package/src/core/model/reactive/model/terminal/ReactiveReference.js +2 -0
  354. package/src/core/parser/simple/readHexToken.d.ts.map +1 -1
  355. package/src/core/parser/simple/readHexToken.js +6 -0
  356. package/src/core/path/convertPathToURL.d.ts +9 -0
  357. package/src/core/path/convertPathToURL.d.ts.map +1 -0
  358. package/src/core/path/convertPathToURL.js +107 -0
  359. package/src/core/primitives/numbers/number_pretty_print.d.ts.map +1 -1
  360. package/src/core/primitives/numbers/number_pretty_print.js +4 -1
  361. package/src/core/primitives/strings/string_jaro_winkler.js +1 -1
  362. package/src/core/process/CompositeProcess.js +1 -1
  363. package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
  364. package/src/core/process/executor/ConcurrentExecutor.js +3 -2
  365. package/src/core/process/task/util/randomCountTask.d.ts.map +1 -1
  366. package/src/core/process/task/util/randomCountTask.js +3 -1
  367. package/src/core/process/undo/ActionProcessor.d.ts.map +1 -1
  368. package/src/core/process/undo/ActionProcessor.js +5 -3
  369. package/src/core/process/worker/WorkerBuilder.js +4 -4
  370. package/src/core/process/worker/extractTransferables.js +1 -1
  371. package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
  372. package/src/engine/animation/curve/AnimationCurve.js +4 -2
  373. package/src/engine/animation/curve/draw/build_tangent_editor.d.ts.map +1 -1
  374. package/src/engine/animation/curve/draw/build_tangent_editor.js +8 -1
  375. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts.map +1 -1
  376. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.js +11 -5
  377. package/src/engine/asset/Asset.d.ts.map +1 -1
  378. package/src/engine/asset/Asset.js +16 -6
  379. package/src/engine/asset/AssetManager.d.ts +61 -52
  380. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  381. package/src/engine/asset/AssetManager.js +1411 -1045
  382. package/src/engine/asset/AssetRequest.d.ts +1 -1
  383. package/src/engine/asset/AssetRequest.d.ts.map +1 -1
  384. package/src/engine/asset/AssetRequest.js +1 -1
  385. package/src/engine/asset/AssetRequestScope.d.ts.map +1 -1
  386. package/src/engine/asset/AssetRequestScope.js +7 -0
  387. package/src/engine/asset/PendingAsset.d.ts +32 -1
  388. package/src/engine/asset/PendingAsset.d.ts.map +1 -1
  389. package/src/engine/asset/PendingAsset.js +108 -61
  390. package/src/engine/asset/loaders/ArrayBufferLoader.js +2 -2
  391. package/src/engine/asset/loaders/AssetLoader.d.ts.map +1 -1
  392. package/src/engine/asset/loaders/AssetLoader.js +19 -2
  393. package/src/engine/asset/loaders/GLTFAssetLoader.d.ts.map +1 -1
  394. package/src/engine/asset/loaders/GLTFAssetLoader.js +123 -114
  395. package/src/engine/asset/loaders/JavascriptAssetLoader.d.ts +1 -1
  396. package/src/engine/asset/loaders/JavascriptAssetLoader.d.ts.map +1 -1
  397. package/src/engine/asset/loaders/JavascriptAssetLoader.js +31 -47
  398. package/src/engine/asset/loaders/JsonAssetLoader.js +1 -1
  399. package/src/engine/asset/loaders/SVGAssetLoader.js +2 -2
  400. package/src/engine/asset/loaders/SoundAssetLoader.js +1 -1
  401. package/src/engine/asset/loaders/TextAssetLoader.js +2 -2
  402. package/src/{core → engine/asset/loaders}/font/FontAsset.d.ts +1 -1
  403. package/src/engine/asset/loaders/font/FontAsset.d.ts.map +1 -0
  404. package/src/{core → engine/asset/loaders}/font/FontAsset.js +21 -21
  405. package/src/{core → engine/asset/loaders}/font/FontAssetLoader.d.ts +1 -1
  406. package/src/engine/asset/loaders/font/FontAssetLoader.d.ts.map +1 -0
  407. package/src/{core → engine/asset/loaders}/font/FontAssetLoader.js +20 -20
  408. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +1 -1
  409. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
  410. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +11 -20
  411. package/src/engine/asset/loaders/texture/TextureAssetLoader.d.ts.map +1 -1
  412. package/src/engine/asset/loaders/texture/TextureAssetLoader.js +8 -2
  413. package/src/engine/asset/preloader/AssetPreloader.js +1 -1
  414. package/src/engine/control/first-person/DESIGN.md +1 -1
  415. package/src/engine/control/first-person/FirstPersonMotionPhase.d.ts +55 -0
  416. package/src/engine/control/first-person/FirstPersonMotionPhase.d.ts.map +1 -0
  417. package/src/engine/control/first-person/FirstPersonMotionPhase.js +134 -0
  418. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +23 -2
  419. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  420. package/src/engine/control/first-person/FirstPersonPlayerController.js +1 -1
  421. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +168 -0
  422. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  423. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +115 -0
  424. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +71 -0
  425. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
  426. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +255 -55
  427. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts +82 -43
  428. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
  429. package/src/engine/control/first-person/abilities/LedgeGrab.js +405 -213
  430. package/src/engine/control/first-person/abilities/Mantle.d.ts +6 -0
  431. package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -1
  432. package/src/engine/control/first-person/abilities/Mantle.js +104 -45
  433. package/src/engine/control/first-person/abilities/ScrambleUp.d.ts +61 -0
  434. package/src/engine/control/first-person/abilities/ScrambleUp.d.ts.map +1 -0
  435. package/src/engine/control/first-person/abilities/ScrambleUp.js +182 -0
  436. package/src/engine/control/first-person/math/jumpDynamics.d.ts +84 -0
  437. package/src/engine/control/first-person/math/jumpDynamics.d.ts.map +1 -0
  438. package/src/engine/control/first-person/math/jumpDynamics.js +108 -0
  439. package/src/engine/control/first-person/prototype_first_person_controller.js +45 -1
  440. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts +1 -1
  441. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts.map +1 -1
  442. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.js +19 -22
  443. package/src/engine/graphics/FrameThrottle.d.ts +1 -7
  444. package/src/engine/graphics/FrameThrottle.d.ts.map +1 -1
  445. package/src/engine/graphics/FrameThrottle.js +2 -24
  446. package/src/engine/graphics/camera/testClippingPlaneComputation.js +1 -1
  447. package/src/{core/geom/3d/shape/util → engine/graphics/debug}/shape_to_visual_entity.d.ts +1 -1
  448. package/src/engine/graphics/debug/shape_to_visual_entity.d.ts.map +1 -0
  449. package/src/{core/geom/3d/shape/util → engine/graphics/debug}/shape_to_visual_entity.js +159 -159
  450. package/src/{core/geom/3d/tetrahedra → engine/graphics/debug}/visualize_tetrahedral_mesh.d.ts +1 -1
  451. package/src/engine/graphics/debug/visualize_tetrahedral_mesh.d.ts.map +1 -0
  452. package/src/{core/geom/3d/tetrahedra → engine/graphics/debug}/visualize_tetrahedral_mesh.js +46 -46
  453. package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.d.ts +1 -1
  454. package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.d.ts.map +1 -1
  455. package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.js +22 -32
  456. package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +1 -1
  457. package/src/engine/graphics/particles/particular/engine/emitter/serde/ParameterLookupTableSerializationAdapter.d.ts.map +1 -1
  458. package/src/engine/graphics/particles/particular/engine/emitter/serde/ParameterLookupTableSerializationAdapter.js +2 -76
  459. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.d.ts.map +1 -1
  460. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +2 -427
  461. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTableFlags.d.ts +1 -4
  462. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTableFlags.d.ts.map +1 -1
  463. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTableFlags.js +2 -6
  464. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +2 -2
  465. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +1 -1
  466. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
  467. package/src/engine/graphics/render/forward_plus/read_frustum_corner.d.ts +1 -8
  468. package/src/engine/graphics/render/forward_plus/read_frustum_corner.d.ts.map +1 -1
  469. package/src/engine/graphics/render/forward_plus/read_frustum_corner.js +2 -14
  470. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
  471. package/src/engine/graphics/sh3/path_tracer/geometry/compute_triangle_group_aabb3.d.ts +1 -11
  472. package/src/engine/graphics/sh3/path_tracer/geometry/compute_triangle_group_aabb3.d.ts.map +1 -1
  473. package/src/engine/graphics/sh3/path_tracer/geometry/compute_triangle_group_aabb3.js +2 -46
  474. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +1 -1
  475. package/src/engine/graphics/sh3/prototypeSH3Probe.js +1 -1
  476. package/src/engine/graphics/shadows/testShadowMapRendering.js +1 -1
  477. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts +27 -0
  478. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts.map +1 -0
  479. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +81 -0
  480. package/src/engine/graphics/texture/isImageBitmap.d.ts +1 -6
  481. package/src/engine/graphics/texture/isImageBitmap.d.ts.map +1 -1
  482. package/src/engine/graphics/texture/isImageBitmap.js +2 -12
  483. package/src/{core/process/action → engine/intelligence/behavior/util}/AsynchronousDelayAction.d.ts +2 -2
  484. package/src/engine/intelligence/behavior/util/AsynchronousDelayAction.d.ts.map +1 -0
  485. package/src/{core/process/action → engine/intelligence/behavior/util}/AsynchronousDelayAction.js +55 -52
  486. package/src/engine/network/NetworkSession.d.ts +12 -1
  487. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  488. package/src/engine/network/NetworkSession.js +52 -1
  489. package/src/engine/network/README.md +45 -0
  490. package/src/engine/network/convertPathToURL.d.ts +1 -8
  491. package/src/engine/network/convertPathToURL.d.ts.map +1 -1
  492. package/src/engine/network/convertPathToURL.js +2 -107
  493. package/src/engine/network/core/quantize/quantize_float.d.ts.map +1 -1
  494. package/src/engine/network/core/quantize/quantize_float.js +7 -0
  495. package/src/engine/network/core/quantize/quantize_position.d.ts.map +1 -1
  496. package/src/engine/network/core/quantize/quantize_position.js +12 -1
  497. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  498. package/src/engine/network/orchestrator/NetworkPeer.js +15 -1
  499. package/src/engine/network/replication/Replicator.d.ts +8 -0
  500. package/src/engine/network/replication/Replicator.d.ts.map +1 -1
  501. package/src/engine/network/replication/Replicator.js +48 -0
  502. package/src/engine/network/transport/Channel.d.ts.map +1 -1
  503. package/src/engine/network/transport/Channel.js +46 -12
  504. package/src/engine/network/transport/ReliableCommandPipeline.d.ts +16 -0
  505. package/src/engine/network/transport/ReliableCommandPipeline.d.ts.map +1 -1
  506. package/src/engine/network/transport/ReliableCommandPipeline.js +29 -0
  507. package/src/engine/network/transport/adapters/NodeUDPTransport.d.ts.map +1 -1
  508. package/src/engine/network/transport/adapters/NodeUDPTransport.js +7 -1
  509. package/src/engine/network/transport/fragments/packet_size.d.ts +5 -5
  510. package/src/engine/network/transport/fragments/packet_size.d.ts.map +1 -1
  511. package/src/engine/network/transport/fragments/packet_size.js +5 -5
  512. package/src/engine/physics/BULLET_REVIEW.md +1 -1
  513. package/src/engine/physics/CONSTRAINT_SOLVER_BENCH_LOG.md +208 -0
  514. package/src/engine/physics/CONSTRAINT_SOLVER_IMPROVEMENTS_PLAN.md +364 -0
  515. package/src/engine/physics/JOLT_REVIEW.md +2 -2
  516. package/src/engine/physics/PLAN.md +1094 -944
  517. package/src/engine/physics/RAPIER_REVIEW.md +2 -2
  518. package/src/engine/physics/body/BodyStorage.d.ts +2 -12
  519. package/src/engine/physics/body/BodyStorage.d.ts.map +1 -1
  520. package/src/engine/physics/body/BodyStorage.js +406 -452
  521. package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -1
  522. package/src/engine/physics/body/SolverBodyState.js +12 -3
  523. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +28 -3
  524. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -1
  525. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +60 -24
  526. package/src/engine/physics/broadphase/generate_pairs.d.ts +9 -5
  527. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
  528. package/src/engine/physics/broadphase/generate_pairs.js +52 -37
  529. package/src/engine/physics/ccd/linear_sweep.d.ts +15 -5
  530. package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
  531. package/src/engine/physics/ccd/linear_sweep.js +122 -40
  532. package/src/engine/physics/constraint/solve_constraints.d.ts +4 -1
  533. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  534. package/src/engine/physics/constraint/solve_constraints.js +830 -691
  535. package/src/engine/physics/contact/ManifoldStore.d.ts +91 -16
  536. package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
  537. package/src/engine/physics/contact/ManifoldStore.js +204 -60
  538. package/src/engine/physics/ecs/BodyKind.d.ts +7 -3
  539. package/src/engine/physics/ecs/BodyKind.d.ts.map +1 -1
  540. package/src/engine/physics/ecs/BodyKind.js +29 -25
  541. package/src/engine/physics/ecs/Collider.d.ts +7 -0
  542. package/src/engine/physics/ecs/Collider.d.ts.map +1 -1
  543. package/src/engine/physics/ecs/Collider.js +7 -0
  544. package/src/engine/physics/ecs/ColliderSerializationAdapter.js +1 -1
  545. package/src/engine/physics/ecs/PhysicsSystem.d.ts +110 -6
  546. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  547. package/src/engine/physics/ecs/PhysicsSystem.js +2172 -1747
  548. package/src/engine/physics/ecs/RigidBody.d.ts +20 -5
  549. package/src/engine/physics/ecs/RigidBody.d.ts.map +1 -1
  550. package/src/engine/physics/ecs/RigidBody.js +307 -286
  551. package/src/engine/physics/ecs/RigidBodyFlags.d.ts +6 -3
  552. package/src/engine/physics/ecs/RigidBodyFlags.d.ts.map +1 -1
  553. package/src/engine/physics/ecs/RigidBodyFlags.js +31 -28
  554. package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts +12 -4
  555. package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts.map +1 -1
  556. package/src/engine/physics/ecs/RigidBodySerializationAdapter.js +19 -5
  557. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.d.ts +10 -0
  558. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.d.ts.map +1 -0
  559. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.js +37 -0
  560. package/src/engine/physics/ecs/find_non_finite_physics_state.d.ts +28 -0
  561. package/src/engine/physics/ecs/find_non_finite_physics_state.d.ts.map +1 -0
  562. package/src/engine/physics/ecs/find_non_finite_physics_state.js +76 -0
  563. package/src/engine/physics/events/ContactEventBuffer.d.ts +11 -0
  564. package/src/engine/physics/events/ContactEventBuffer.d.ts.map +1 -1
  565. package/src/engine/physics/events/ContactEventBuffer.js +40 -0
  566. package/src/engine/physics/events/diff_manifolds.d.ts +30 -13
  567. package/src/engine/physics/events/diff_manifolds.d.ts.map +1 -1
  568. package/src/engine/physics/events/diff_manifolds.js +87 -50
  569. package/src/engine/physics/fluid/FluidField.d.ts +45 -17
  570. package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
  571. package/src/engine/physics/fluid/FluidField.js +53 -23
  572. package/src/engine/physics/fluid/FluidSimulator.d.ts +141 -5
  573. package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
  574. package/src/engine/physics/fluid/FluidSimulator.js +336 -43
  575. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +114 -0
  576. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +4 -3
  577. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts.map +1 -1
  578. package/src/engine/physics/fluid/ecs/FluidComponent.js +4 -3
  579. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +3 -3
  580. package/src/engine/physics/fluid/effector/AmbientWindFluidEffector.d.ts +41 -0
  581. package/src/engine/physics/fluid/effector/AmbientWindFluidEffector.d.ts.map +1 -0
  582. package/src/engine/physics/fluid/effector/AmbientWindFluidEffector.js +124 -0
  583. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts +27 -8
  584. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
  585. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +67 -18
  586. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.d.ts +42 -0
  587. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.d.ts.map +1 -0
  588. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.js +136 -0
  589. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.d.ts +37 -0
  590. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.d.ts.map +1 -0
  591. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +169 -0
  592. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.d.ts +36 -0
  593. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.d.ts.map +1 -0
  594. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +100 -0
  595. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts +6 -0
  596. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts.map +1 -1
  597. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.js +6 -0
  598. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts +7 -2
  599. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts.map +1 -1
  600. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.js +17 -12
  601. package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.d.ts +42 -0
  602. package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.d.ts.map +1 -0
  603. package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.js +131 -0
  604. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts +32 -22
  605. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts.map +1 -1
  606. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +43 -26
  607. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.d.ts +31 -0
  608. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.d.ts.map +1 -0
  609. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.js +77 -0
  610. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts +26 -19
  611. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts.map +1 -1
  612. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +46 -42
  613. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts +38 -10
  614. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts.map +1 -1
  615. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +158 -75
  616. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +22 -17
  617. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -1
  618. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +108 -96
  619. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +30 -1
  620. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
  621. package/src/engine/physics/inertia/world_inverse_inertia.js +160 -116
  622. package/src/engine/physics/integration/integrate_position.js +97 -97
  623. package/src/engine/physics/island/IslandBuilder.d.ts +49 -8
  624. package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -1
  625. package/src/engine/physics/island/IslandBuilder.js +93 -14
  626. package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
  627. package/src/engine/physics/narrowphase/box_box_manifold.js +683 -673
  628. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -1
  629. package/src/engine/physics/narrowphase/box_triangle_contact.js +899 -749
  630. package/src/engine/physics/narrowphase/capsule_contacts.d.ts +27 -0
  631. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
  632. package/src/engine/physics/narrowphase/capsule_contacts.js +624 -459
  633. package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts.map +1 -1
  634. package/src/engine/physics/narrowphase/capsule_triangle_contact.js +58 -38
  635. package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -1
  636. package/src/engine/physics/narrowphase/compute_penetration.js +369 -325
  637. package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts +3 -1
  638. package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts.map +1 -1
  639. package/src/engine/physics/narrowphase/convex_convex_manifold.js +568 -425
  640. package/src/engine/physics/narrowphase/convex_decomposition.d.ts +32 -13
  641. package/src/engine/physics/narrowphase/convex_decomposition.d.ts.map +1 -1
  642. package/src/engine/physics/narrowphase/convex_decomposition.js +61 -65
  643. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts +6 -3
  644. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts.map +1 -1
  645. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.js +66 -10
  646. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts +4 -1
  647. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -1
  648. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +97 -94
  649. package/src/engine/physics/narrowphase/mesh_convex_hull.d.ts.map +1 -1
  650. package/src/engine/physics/narrowphase/mesh_convex_hull.js +13 -8
  651. package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +117 -117
  652. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  653. package/src/engine/physics/narrowphase/narrowphase_step.js +1738 -1739
  654. package/src/engine/physics/narrowphase/reduce_manifold_contacts.d.ts +14 -7
  655. package/src/engine/physics/narrowphase/reduce_manifold_contacts.d.ts.map +1 -1
  656. package/src/engine/physics/narrowphase/reduce_manifold_contacts.js +74 -69
  657. package/src/engine/physics/narrowphase/refine_ray_concave.d.ts.map +1 -1
  658. package/src/engine/physics/narrowphase/refine_ray_concave.js +5 -3
  659. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
  660. package/src/engine/physics/narrowphase/refine_ray_hit.js +81 -78
  661. package/src/engine/physics/persistence/solver_caches.d.ts +20 -0
  662. package/src/engine/physics/persistence/solver_caches.d.ts.map +1 -0
  663. package/src/engine/physics/persistence/solver_caches.js +309 -0
  664. package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -1
  665. package/src/engine/physics/queries/overlap_shape.js +187 -184
  666. package/src/engine/physics/queries/raycast.d.ts +3 -2
  667. package/src/engine/physics/queries/raycast.d.ts.map +1 -1
  668. package/src/engine/physics/queries/raycast.js +37 -11
  669. package/src/engine/physics/queries/shape_cast.d.ts +18 -5
  670. package/src/engine/physics/queries/shape_cast.d.ts.map +1 -1
  671. package/src/engine/physics/queries/shape_cast.js +417 -393
  672. package/src/engine/physics/solver/solve_contacts.d.ts +22 -6
  673. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
  674. package/src/engine/physics/solver/solve_contacts.js +1482 -1338
  675. package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
  676. package/src/engine/physics/vehicle/RaycastVehicle.js +344 -339
  677. package/src/engine/sound/SoundEngine.d.ts.map +1 -1
  678. package/src/engine/sound/SoundEngine.js +28 -0
  679. package/src/engine/sound/dB2Volume.d.ts +1 -1
  680. package/src/engine/sound/dB2Volume.d.ts.map +1 -1
  681. package/src/engine/sound/dB2Volume.js +1 -1
  682. package/src/engine/sound/ecs/SoundController.d.ts +4 -0
  683. package/src/engine/sound/ecs/SoundController.d.ts.map +1 -1
  684. package/src/engine/sound/ecs/SoundController.js +4 -0
  685. package/src/engine/sound/ecs/SoundControllerSystem.d.ts +5 -0
  686. package/src/engine/sound/ecs/SoundControllerSystem.d.ts.map +1 -1
  687. package/src/engine/sound/ecs/SoundControllerSystem.js +5 -0
  688. package/src/engine/sound/ecs/audio/AudioEmitter.d.ts +69 -0
  689. package/src/engine/sound/ecs/audio/AudioEmitter.d.ts.map +1 -0
  690. package/src/engine/sound/ecs/audio/AudioEmitter.js +83 -0
  691. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts +97 -0
  692. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts.map +1 -0
  693. package/src/engine/sound/ecs/audio/AudioEmitterSystem.js +238 -0
  694. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts +90 -0
  695. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts.map +1 -0
  696. package/src/engine/sound/ecs/audio/LiveEmitterSet.js +324 -0
  697. package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts +59 -0
  698. package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts.map +1 -0
  699. package/src/engine/sound/ecs/audio/SpatialAudioIndex.js +140 -0
  700. package/src/engine/sound/ecs/emitter/SoundEmitter.d.ts +16 -65
  701. package/src/engine/sound/ecs/emitter/SoundEmitter.d.ts.map +1 -1
  702. package/src/engine/sound/ecs/emitter/SoundEmitter.js +19 -224
  703. package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.d.ts +26 -29
  704. package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.d.ts.map +1 -1
  705. package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.js +168 -135
  706. package/src/engine/sound/ecs/emitter/SoundEmitterSystem.d.ts +36 -59
  707. package/src/engine/sound/ecs/emitter/SoundEmitterSystem.d.ts.map +1 -1
  708. package/src/engine/sound/ecs/emitter/SoundEmitterSystem.js +154 -390
  709. package/src/engine/sound/ecs/emitter/SoundTrack.d.ts +20 -23
  710. package/src/engine/sound/ecs/emitter/SoundTrack.d.ts.map +1 -1
  711. package/src/engine/sound/ecs/emitter/SoundTrack.js +34 -152
  712. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +993 -0
  713. package/src/engine/sound/sopra/README.md +643 -7
  714. package/src/engine/sound/sopra/SopraEngine.d.ts +229 -0
  715. package/src/engine/sound/sopra/SopraEngine.d.ts.map +1 -0
  716. package/src/engine/sound/sopra/SopraEngine.js +423 -0
  717. package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.d.ts +26 -0
  718. package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.d.ts.map +1 -0
  719. package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.js +71 -0
  720. package/src/engine/sound/sopra/asset/BufferProvider.d.ts +24 -0
  721. package/src/engine/sound/sopra/asset/BufferProvider.d.ts.map +1 -0
  722. package/src/engine/sound/sopra/asset/BufferProvider.js +29 -0
  723. package/src/engine/sound/sopra/asset/StubBufferProvider.d.ts +31 -0
  724. package/src/engine/sound/sopra/asset/StubBufferProvider.d.ts.map +1 -0
  725. package/src/engine/sound/sopra/asset/StubBufferProvider.js +58 -0
  726. package/src/engine/sound/sopra/definition/BusDefinition.d.ts +83 -0
  727. package/src/engine/sound/sopra/definition/BusDefinition.d.ts.map +1 -0
  728. package/src/engine/sound/sopra/definition/BusDefinition.js +142 -0
  729. package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.d.ts +17 -0
  730. package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.d.ts.map +1 -0
  731. package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.js +54 -0
  732. package/src/engine/sound/sopra/definition/DuckingRule.d.ts +71 -0
  733. package/src/engine/sound/sopra/definition/DuckingRule.d.ts.map +1 -0
  734. package/src/engine/sound/sopra/definition/DuckingRule.js +106 -0
  735. package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.d.ts +18 -0
  736. package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.d.ts.map +1 -0
  737. package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.js +31 -0
  738. package/src/engine/sound/sopra/definition/EventDescription.d.ts +132 -0
  739. package/src/engine/sound/sopra/definition/EventDescription.d.ts.map +1 -0
  740. package/src/engine/sound/sopra/definition/EventDescription.js +259 -0
  741. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts +17 -0
  742. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts.map +1 -0
  743. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +71 -0
  744. package/src/engine/sound/sopra/definition/MixerSnapshot.d.ts +51 -0
  745. package/src/engine/sound/sopra/definition/MixerSnapshot.d.ts.map +1 -0
  746. package/src/engine/sound/sopra/definition/MixerSnapshot.js +83 -0
  747. package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.d.ts +18 -0
  748. package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.d.ts.map +1 -0
  749. package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.js +39 -0
  750. package/src/engine/sound/sopra/definition/ParameterDefinition.d.ts +72 -0
  751. package/src/engine/sound/sopra/definition/ParameterDefinition.d.ts.map +1 -0
  752. package/src/engine/sound/sopra/definition/ParameterDefinition.js +117 -0
  753. package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.d.ts +18 -0
  754. package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.d.ts.map +1 -0
  755. package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.js +31 -0
  756. package/src/engine/sound/sopra/definition/SopraPanningModel.d.ts +14 -0
  757. package/src/engine/sound/sopra/definition/SopraPanningModel.d.ts.map +1 -0
  758. package/src/engine/sound/sopra/definition/SopraPanningModel.js +20 -0
  759. package/src/engine/sound/sopra/definition/VoiceStealMode.d.ts +10 -0
  760. package/src/engine/sound/sopra/definition/VoiceStealMode.d.ts.map +1 -0
  761. package/src/engine/sound/sopra/definition/VoiceStealMode.js +18 -0
  762. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +93 -0
  763. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -0
  764. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +109 -0
  765. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +80 -0
  766. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts.map +1 -0
  767. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.js +181 -0
  768. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.d.ts +17 -0
  769. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.d.ts.map +1 -0
  770. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.js +74 -0
  771. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts +34 -0
  772. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts.map +1 -0
  773. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.js +100 -0
  774. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +101 -0
  775. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -0
  776. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +230 -0
  777. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.d.ts +17 -0
  778. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.d.ts.map +1 -0
  779. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.js +54 -0
  780. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +103 -0
  781. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -0
  782. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +191 -0
  783. package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.d.ts +18 -0
  784. package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.d.ts.map +1 -0
  785. package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.js +39 -0
  786. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +40 -0
  787. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts.map +1 -0
  788. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.js +91 -0
  789. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.d.ts +17 -0
  790. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.d.ts.map +1 -0
  791. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.js +42 -0
  792. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.d.ts +44 -0
  793. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.d.ts.map +1 -0
  794. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.js +77 -0
  795. package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.d.ts +18 -0
  796. package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.d.ts.map +1 -0
  797. package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.js +27 -0
  798. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +65 -0
  799. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -0
  800. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.js +131 -0
  801. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.d.ts +17 -0
  802. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.d.ts.map +1 -0
  803. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.js +41 -0
  804. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts +24 -0
  805. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts.map +1 -0
  806. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +24 -0
  807. package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts +70 -0
  808. package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts.map +1 -0
  809. package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +120 -0
  810. package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.d.ts +18 -0
  811. package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.d.ts.map +1 -0
  812. package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.js +31 -0
  813. package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts +74 -0
  814. package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts.map +1 -0
  815. package/src/engine/sound/sopra/definition/effect/EqEffect.js +128 -0
  816. package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.d.ts +18 -0
  817. package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.d.ts.map +1 -0
  818. package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.js +29 -0
  819. package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts +49 -0
  820. package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts.map +1 -0
  821. package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +101 -0
  822. package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.d.ts +18 -0
  823. package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.d.ts.map +1 -0
  824. package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.js +25 -0
  825. package/src/engine/sound/sopra/legacy/soundEmitterToEventDescription.d.ts +31 -0
  826. package/src/engine/sound/sopra/legacy/soundEmitterToEventDescription.d.ts.map +1 -0
  827. package/src/engine/sound/sopra/legacy/soundEmitterToEventDescription.js +106 -0
  828. package/src/engine/sound/sopra/runtime/BusGraph.d.ts +79 -0
  829. package/src/engine/sound/sopra/runtime/BusGraph.d.ts.map +1 -0
  830. package/src/engine/sound/sopra/runtime/BusGraph.js +227 -0
  831. package/src/engine/sound/sopra/runtime/EventInstance.d.ts +144 -0
  832. package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -0
  833. package/src/engine/sound/sopra/runtime/EventInstance.js +579 -0
  834. package/src/engine/sound/sopra/runtime/ParameterStore.d.ts +42 -0
  835. package/src/engine/sound/sopra/runtime/ParameterStore.d.ts.map +1 -0
  836. package/src/engine/sound/sopra/runtime/ParameterStore.js +98 -0
  837. package/src/engine/sound/sopra/runtime/SopraPlaybackContext.d.ts +42 -0
  838. package/src/engine/sound/sopra/runtime/SopraPlaybackContext.d.ts.map +1 -0
  839. package/src/engine/sound/sopra/runtime/SopraPlaybackContext.js +68 -0
  840. package/src/engine/sound/sopra/runtime/Voice.d.ts +67 -0
  841. package/src/engine/sound/sopra/runtime/Voice.d.ts.map +1 -0
  842. package/src/engine/sound/sopra/runtime/Voice.js +145 -0
  843. package/src/engine/sound/sopra/runtime/VoiceManager.d.ts +38 -0
  844. package/src/engine/sound/sopra/runtime/VoiceManager.d.ts.map +1 -0
  845. package/src/engine/sound/sopra/runtime/VoiceManager.js +136 -0
  846. package/src/engine/sound/sopra/runtime/VoicePool.d.ts +12 -0
  847. package/src/engine/sound/sopra/runtime/VoicePool.d.ts.map +1 -0
  848. package/src/engine/sound/sopra/runtime/VoicePool.js +17 -0
  849. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts +11 -0
  850. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts.map +1 -0
  851. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +42 -0
  852. package/src/engine/sound/sopra/serialization/sopraJSON.d.ts +33 -0
  853. package/src/engine/sound/sopra/serialization/sopraJSON.d.ts.map +1 -0
  854. package/src/engine/sound/sopra/serialization/sopraJSON.js +99 -0
  855. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts +27 -0
  856. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts.map +1 -0
  857. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +49 -0
  858. package/src/engine/sound/sopra/util/MockAudioContext.d.ts +74 -0
  859. package/src/engine/sound/sopra/util/MockAudioContext.d.ts.map +1 -0
  860. package/src/engine/sound/sopra/util/MockAudioContext.js +215 -0
  861. package/src/engine/sound/sopra/util/buildAttenuationCurve.d.ts +15 -0
  862. package/src/engine/sound/sopra/util/buildAttenuationCurve.d.ts.map +1 -0
  863. package/src/engine/sound/sopra/util/buildAttenuationCurve.js +40 -0
  864. package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts +34 -0
  865. package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts.map +1 -0
  866. package/src/engine/sound/sopra/util/fadeOutAndStop.js +60 -0
  867. package/src/engine/sound/volume2dB.d.ts +1 -1
  868. package/src/engine/sound/volume2dB.d.ts.map +1 -1
  869. package/src/engine/sound/volume2dB.js +1 -1
  870. package/src/engine/ui/DraggableAspect.d.ts +12 -3
  871. package/src/engine/ui/DraggableAspect.d.ts.map +1 -1
  872. package/src/engine/ui/DraggableAspect.js +115 -83
  873. package/src/generation/COORDINATES.md +54 -0
  874. package/src/generation/GridTaskGroup.js +2 -2
  875. package/src/generation/REVIEW_01_ACTION_PLAN.md +628 -0
  876. package/src/generation/automata/CaveGeneratorCellularAutomata.d.ts +9 -1
  877. package/src/generation/automata/CaveGeneratorCellularAutomata.d.ts.map +1 -1
  878. package/src/generation/automata/CaveGeneratorCellularAutomata.js +79 -59
  879. package/src/generation/automata/CellularAutomata.d.ts +6 -3
  880. package/src/generation/automata/CellularAutomata.d.ts.map +1 -1
  881. package/src/generation/automata/CellularAutomata.js +22 -19
  882. package/src/generation/filtering/CellFilter.d.ts +17 -0
  883. package/src/generation/filtering/CellFilter.d.ts.map +1 -1
  884. package/src/generation/filtering/CellFilter.js +117 -77
  885. package/src/generation/filtering/CellFilterCellMatcher.d.ts.map +1 -1
  886. package/src/generation/filtering/CellFilterCellMatcher.js +2 -0
  887. package/src/generation/filtering/boolean/CellFilterLiteralBoolean.d.ts +5 -0
  888. package/src/generation/filtering/boolean/CellFilterLiteralBoolean.d.ts.map +1 -1
  889. package/src/generation/filtering/boolean/CellFilterLiteralBoolean.js +15 -0
  890. package/src/generation/filtering/core/CellFilterBinaryOperation.d.ts +0 -1
  891. package/src/generation/filtering/core/CellFilterBinaryOperation.d.ts.map +1 -1
  892. package/src/generation/filtering/core/CellFilterBinaryOperation.js +37 -50
  893. package/src/generation/filtering/core/CellFilterOperationTertiary.d.ts +0 -1
  894. package/src/generation/filtering/core/CellFilterOperationTertiary.d.ts.map +1 -1
  895. package/src/generation/filtering/core/CellFilterOperationTertiary.js +43 -59
  896. package/src/generation/filtering/core/CellFilterUnaryOperation.d.ts +0 -1
  897. package/src/generation/filtering/core/CellFilterUnaryOperation.d.ts.map +1 -1
  898. package/src/generation/filtering/core/CellFilterUnaryOperation.js +29 -33
  899. package/src/generation/filtering/numeric/CellFilterCache.d.ts +1 -0
  900. package/src/generation/filtering/numeric/CellFilterCache.d.ts.map +1 -1
  901. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.d.ts +3 -2
  902. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.d.ts.map +1 -1
  903. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.js +9 -35
  904. package/src/generation/filtering/numeric/complex/CellFilterCurvature.d.ts +0 -1
  905. package/src/generation/filtering/numeric/complex/CellFilterCurvature.d.ts.map +1 -1
  906. package/src/generation/filtering/numeric/complex/CellFilterCurvature.js +19 -43
  907. package/src/generation/filtering/numeric/complex/CellFilterFXAA.d.ts +0 -1
  908. package/src/generation/filtering/numeric/complex/CellFilterFXAA.d.ts.map +1 -1
  909. package/src/generation/filtering/numeric/complex/CellFilterFXAA.js +2 -6
  910. package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.d.ts.map +1 -1
  911. package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +9 -12
  912. package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.d.ts.map +1 -1
  913. package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +2 -1
  914. package/src/generation/filtering/numeric/complex/CellFilterSobel.d.ts +0 -1
  915. package/src/generation/filtering/numeric/complex/CellFilterSobel.d.ts.map +1 -1
  916. package/src/generation/filtering/numeric/complex/CellFilterSobel.js +2 -6
  917. package/src/generation/filtering/numeric/math/CellFilterInverseLerp.d.ts +5 -4
  918. package/src/generation/filtering/numeric/math/CellFilterInverseLerp.d.ts.map +1 -1
  919. package/src/generation/filtering/numeric/math/CellFilterInverseLerp.js +5 -4
  920. package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.d.ts +17 -0
  921. package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.d.ts.map +1 -0
  922. package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.js +42 -0
  923. package/src/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.d.ts.map +1 -1
  924. package/src/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.js +7 -1
  925. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.d.ts.map +1 -1
  926. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.js +7 -10
  927. package/src/generation/filtering/numeric/util/sampler_from_filter.d.ts.map +1 -1
  928. package/src/generation/filtering/numeric/util/sampler_from_filter.js +2 -1
  929. package/src/generation/grid/GridData.d.ts.map +1 -1
  930. package/src/generation/grid/GridData.js +14 -1
  931. package/src/generation/grid/actions/ContinuousGridCellAction.d.ts +10 -3
  932. package/src/generation/grid/actions/ContinuousGridCellAction.d.ts.map +1 -1
  933. package/src/generation/grid/actions/ContinuousGridCellAction.js +18 -3
  934. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainHeight.d.ts +11 -1
  935. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainHeight.d.ts.map +1 -1
  936. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainHeight.js +13 -3
  937. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainObstacle.d.ts +1 -1
  938. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainObstacle.js +2 -2
  939. package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.d.ts +1 -1
  940. package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.d.ts.map +1 -1
  941. package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.js +4 -6
  942. package/src/generation/grid/coords/grid_to_texel.d.ts +9 -0
  943. package/src/generation/grid/coords/grid_to_texel.d.ts.map +1 -0
  944. package/src/generation/grid/coords/grid_to_texel.js +10 -0
  945. package/src/generation/grid/coords/texel_to_grid.d.ts +9 -0
  946. package/src/generation/grid/coords/texel_to_grid.d.ts.map +1 -0
  947. package/src/generation/grid/coords/texel_to_grid.js +10 -0
  948. package/src/generation/grid/generation/GridTaskApplyActionToCells.d.ts +2 -2
  949. package/src/generation/grid/generation/GridTaskApplyActionToCells.d.ts.map +1 -1
  950. package/src/generation/grid/generation/GridTaskApplyActionToCells.js +10 -6
  951. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.d.ts.map +1 -1
  952. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +20 -21
  953. package/src/generation/grid/generation/GridTaskExecuteRuleTimes.d.ts +7 -0
  954. package/src/generation/grid/generation/GridTaskExecuteRuleTimes.d.ts.map +1 -1
  955. package/src/generation/grid/generation/GridTaskExecuteRuleTimes.js +18 -10
  956. package/src/generation/grid/generation/discrete/GridTaskCellularAutomata.d.ts.map +1 -1
  957. package/src/generation/grid/generation/discrete/GridTaskCellularAutomata.js +16 -7
  958. package/src/generation/grid/generation/discrete/GridTaskConnectRooms.d.ts +5 -3
  959. package/src/generation/grid/generation/discrete/GridTaskConnectRooms.d.ts.map +1 -1
  960. package/src/generation/grid/generation/discrete/GridTaskConnectRooms.js +26 -23
  961. package/src/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.d.ts.map +1 -1
  962. package/src/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.js +10 -1
  963. package/src/generation/grid/generation/grid/select/CellSupplierBestN.d.ts.map +1 -1
  964. package/src/generation/grid/generation/grid/select/CellSupplierBestN.js +4 -0
  965. package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts +15 -8
  966. package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts.map +1 -1
  967. package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +89 -92
  968. package/src/generation/markers/GridActionRuleSet.d.ts.map +1 -1
  969. package/src/generation/markers/GridActionRuleSet.js +10 -2
  970. package/src/generation/markers/GridCellActionPlaceMarker.d.ts +11 -0
  971. package/src/generation/markers/GridCellActionPlaceMarker.d.ts.map +1 -1
  972. package/src/generation/markers/GridCellActionPlaceMarker.js +20 -3
  973. package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts +3 -1
  974. package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts.map +1 -1
  975. package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +9 -2
  976. package/src/generation/markers/MarkerNode.d.ts +8 -3
  977. package/src/generation/markers/MarkerNode.d.ts.map +1 -1
  978. package/src/generation/markers/MarkerNode.js +12 -5
  979. package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +1 -1
  980. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.d.ts +1 -1
  981. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.d.ts.map +1 -1
  982. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.js +1 -1
  983. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.d.ts +1 -1
  984. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.d.ts.map +1 -1
  985. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.js +1 -1
  986. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.d.ts +1 -1
  987. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.d.ts.map +1 -1
  988. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.js +2 -2
  989. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorSequence.d.ts +1 -1
  990. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorSequence.d.ts.map +1 -1
  991. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorSequence.js +2 -2
  992. package/src/generation/markers/actions/probability/MarkerNodeActionSelectWeighted.d.ts.map +1 -1
  993. package/src/generation/markers/actions/probability/MarkerNodeActionSelectWeighted.js +6 -4
  994. package/src/generation/markers/actions/probability/MarkerNodeActionWeightedElement.d.ts.map +1 -1
  995. package/src/generation/markers/actions/probability/MarkerNodeActionWeightedElement.js +1 -3
  996. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.d.ts.map +1 -1
  997. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +12 -11
  998. package/src/generation/markers/matcher/MarkerNodeMatcherAnd.js +2 -2
  999. package/src/generation/markers/transform/MarkerNodeTransformer.d.ts +4 -1
  1000. package/src/generation/markers/transform/MarkerNodeTransformer.d.ts.map +1 -1
  1001. package/src/generation/markers/transform/MarkerNodeTransformer.js +4 -1
  1002. package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.d.ts.map +1 -1
  1003. package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.js +1 -3
  1004. package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.d.ts +5 -0
  1005. package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.d.ts.map +1 -1
  1006. package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +15 -0
  1007. package/src/generation/markers/transform/MarkerNodeTransformerRecordProperty.d.ts.map +1 -1
  1008. package/src/generation/markers/transform/MarkerNodeTransformerRecordProperty.js +1 -3
  1009. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.d.ts.map +1 -1
  1010. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.js +2 -4
  1011. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.d.ts.map +1 -1
  1012. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.js +1 -3
  1013. package/src/generation/placement/GridCellPlacementRule.d.ts.map +1 -1
  1014. package/src/generation/placement/GridCellPlacementRule.js +1 -3
  1015. package/src/generation/placement/action/GridCellActionWriteFilterToLayer.d.ts.map +1 -1
  1016. package/src/generation/placement/action/GridCellActionWriteFilterToLayer.js +8 -10
  1017. package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.d.ts.map +1 -1
  1018. package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.js +6 -4
  1019. package/src/generation/placement/action/random/weighted/WeightedGridCellAction.d.ts.map +1 -1
  1020. package/src/generation/placement/action/random/weighted/WeightedGridCellAction.js +1 -3
  1021. package/src/generation/rules/CellMatcher.d.ts +3 -1
  1022. package/src/generation/rules/CellMatcher.d.ts.map +1 -1
  1023. package/src/generation/rules/CellMatcher.js +3 -1
  1024. package/src/generation/rules/CellMatcherFromFilter.d.ts.map +1 -1
  1025. package/src/generation/rules/CellMatcherFromFilter.js +1 -3
  1026. package/src/generation/rules/CellMatcherLayerBitMaskTest.d.ts.map +1 -1
  1027. package/src/generation/rules/CellMatcherLayerBitMaskTest.js +6 -20
  1028. package/src/generation/test_support/executeTaskTreeSync.d.ts +9 -0
  1029. package/src/generation/test_support/executeTaskTreeSync.d.ts.map +1 -0
  1030. package/src/generation/test_support/executeTaskTreeSync.js +78 -0
  1031. package/src/generation/theme/TerrainLayerRuleAggregator.d.ts +2 -1
  1032. package/src/generation/theme/TerrainLayerRuleAggregator.d.ts.map +1 -1
  1033. package/src/generation/theme/TerrainLayerRuleAggregator.js +9 -6
  1034. package/src/generation/theme/Theme.d.ts +1 -1
  1035. package/src/generation/theme/Theme.d.ts.map +1 -1
  1036. package/src/generation/theme/Theme.js +2 -2
  1037. package/src/generation/theme/ThemeEngine.d.ts +3 -3
  1038. package/src/generation/theme/ThemeEngine.d.ts.map +1 -1
  1039. package/src/generation/theme/ThemeEngine.js +26 -16
  1040. package/src/generation/theme/cell/CellProcessingRule.d.ts +3 -3
  1041. package/src/generation/theme/cell/CellProcessingRule.d.ts.map +1 -1
  1042. package/src/generation/theme/cell/CellProcessingRule.js +6 -10
  1043. package/src/generation/theme/cell/CellProcessingRuleSet.d.ts +1 -1
  1044. package/src/generation/theme/cell/CellProcessingRuleSet.d.ts.map +1 -1
  1045. package/src/generation/theme/cell/CellProcessingRuleSet.js +2 -2
  1046. package/src/view/common/ListView.js +1 -1
  1047. package/src/view/elements/BottomLeftResizeHandleView.d.ts.map +1 -1
  1048. package/src/view/elements/BottomLeftResizeHandleView.js +13 -5
  1049. package/src/core/font/FontAsset.d.ts.map +0 -1
  1050. package/src/core/font/FontAssetLoader.d.ts.map +0 -1
  1051. package/src/core/geom/3d/shape/util/shape_to_visual_entity.d.ts.map +0 -1
  1052. package/src/core/geom/3d/tetrahedra/visualize_tetrahedral_mesh.d.ts.map +0 -1
  1053. package/src/core/process/action/AsynchronousDelayAction.d.ts.map +0 -1
  1054. package/src/engine/graphics/sh3/path_tracer/sampling/v3_orthonormal_matrix_from_normal.d.ts.map +0 -1
  1055. package/src/engine/physics/computeInterceptPoint.d.ts.map +0 -1
  1056. package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts.map +0 -1
  1057. package/src/engine/physics/gjk/gjk.d.ts.map +0 -1
  1058. package/src/engine/physics/gjk/gjk_epa_penetration.d.ts.map +0 -1
  1059. package/src/engine/physics/gjk/minkowski_support.d.ts.map +0 -1
  1060. package/src/engine/physics/gjk/mpr.d.ts.map +0 -1
  1061. package/src/engine/physics/integration/quat_integrate.d.ts.map +0 -1
  1062. package/src/engine/physics/island/union_find.d.ts.map +0 -1
  1063. package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts.map +0 -1
  1064. package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts.map +0 -1
  1065. package/src/engine/physics/narrowphase/ray_shapes.d.ts +0 -66
  1066. package/src/engine/physics/narrowphase/ray_shapes.d.ts.map +0 -1
  1067. package/src/engine/physics/narrowphase/ray_shapes.js +0 -187
  1068. package/src/engine/sound/ecs/emitter/SoundEmitterChannel.d.ts +0 -23
  1069. package/src/engine/sound/ecs/emitter/SoundEmitterChannel.d.ts.map +0 -1
  1070. package/src/engine/sound/ecs/emitter/SoundEmitterChannel.js +0 -32
  1071. package/src/engine/sound/ecs/emitter/SoundTrackNodes.d.ts +0 -18
  1072. package/src/engine/sound/ecs/emitter/SoundTrackNodes.d.ts.map +0 -1
  1073. package/src/engine/sound/ecs/emitter/SoundTrackNodes.js +0 -18
  1074. package/src/engine/sound/sopra/AbstractAudioClip.d.ts +0 -26
  1075. package/src/engine/sound/sopra/AbstractAudioClip.d.ts.map +0 -1
  1076. package/src/engine/sound/sopra/AbstractAudioClip.js +0 -29
  1077. package/src/engine/sound/sopra/ContainerAudioClip.d.ts +0 -12
  1078. package/src/engine/sound/sopra/ContainerAudioClip.d.ts.map +0 -1
  1079. package/src/engine/sound/sopra/ContainerAudioClip.js +0 -13
  1080. package/src/engine/sound/sopra/RandomContainerAudioClip.d.ts +0 -12
  1081. package/src/engine/sound/sopra/RandomContainerAudioClip.d.ts.map +0 -1
  1082. package/src/engine/sound/sopra/RandomContainerAudioClip.js +0 -15
  1083. package/src/engine/sound/sopra/SequenceContainerAudioClip.d.ts +0 -7
  1084. package/src/engine/sound/sopra/SequenceContainerAudioClip.d.ts.map +0 -1
  1085. package/src/engine/sound/sopra/SequenceContainerAudioClip.js +0 -8
  1086. package/src/engine/sound/sopra/SilenceAudioClip.d.ts +0 -13
  1087. package/src/engine/sound/sopra/SilenceAudioClip.d.ts.map +0 -1
  1088. package/src/engine/sound/sopra/SilenceAudioClip.js +0 -15
  1089. package/src/generation/grid/generation/discrete/layer/GridTaskDistanceToMarkers.d.ts +0 -21
  1090. package/src/generation/grid/generation/discrete/layer/GridTaskDistanceToMarkers.d.ts.map +0 -1
  1091. package/src/generation/grid/generation/discrete/layer/GridTaskDistanceToMarkers.js +0 -68
  1092. package/src/generation/grid/generation/grid/GridTaskGridAlignedNodeGenerator.d.ts +0 -10
  1093. package/src/generation/grid/generation/grid/GridTaskGridAlignedNodeGenerator.d.ts.map +0 -1
  1094. package/src/generation/grid/generation/grid/GridTaskGridAlignedNodeGenerator.js +0 -17
  1095. /package/src/{engine/physics → core/geom/3d}/gjk/NOTES.md +0 -0
  1096. /package/src/{engine/physics → core/geom/3d}/gjk/gjk.d.ts +0 -0
  1097. /package/src/{engine/graphics/sh3/path_tracer/sampling → core/geom/vec3}/v3_orthonormal_matrix_from_normal.d.ts +0 -0
  1098. /package/src/{engine/physics → core/math/physics/kinematics}/computeInterceptPoint.d.ts +0 -0
@@ -1,691 +1,830 @@
1
- import { quat3_multiply } from "../../../core/geom/3d/quaternion/quat3_multiply.js";
2
- import { quat3_to_matrix3 } from "../../../core/geom/3d/quaternion/quat3_to_matrix3.js";
3
- import { v3_quat3_apply } from "../../../core/geom/vec3/v3_quat3_apply.js";
4
- import { body_id_index } from "../body/BodyStorage.js";
5
- import {
6
- SBS_AV_X,
7
- SBS_AV_Y,
8
- SBS_AV_Z,
9
- SBS_INV_I_X,
10
- SBS_INV_I_Y,
11
- SBS_INV_I_Z,
12
- SBS_INV_MASS,
13
- SBS_LV_X,
14
- SBS_LV_Y,
15
- SBS_LV_Z,
16
- SBS_QW,
17
- SBS_QX,
18
- SBS_QY,
19
- SBS_QZ,
20
- SBS_STRIDE,
21
- } from "../body/SolverBodyState.js";
22
- import { JOINT_WORLD } from "../ecs/Joint.js";
23
- import { SleepState } from "../ecs/SleepState.js";
24
- import { world_inverse_inertia_apply_raw } from "../inertia/world_inverse_inertia.js";
25
- import { DofMode } from "./DofMode.js";
26
-
27
- /**
28
- * # 6-DOF constraint (joint) solver
29
- *
30
- * Runs alongside the contact solver inside the same TGS substep loop: each
31
- * substep the joints are warm-started and their velocity rows solved, sharing
32
- * the contact solver's per-substep / warm-start / SPOOK-bias model so the two
33
- * constraint families converge together (a body touched by both a contact and
34
- * a joint sees a single coupled Gauss-Seidel sweep across the substep loop).
35
- *
36
- * A joint is a configurable 6-DOF constraint ({@link Joint}); each relative
37
- * degree of freedom is independently locked / free / limited / springy /
38
- * motorised. This module implements **LOCKED** and **LIMITED** DOFs (linear
39
- * and angular). LOCKED + FREE express the ball-socket, hinge, weld, and
40
- * prismatic joints; LIMITED adds slider end-stops and joint range-of-motion.
41
- * Springs and motors slot into the same per-DOF row model as they land.
42
- *
43
- * ## One row model, parameterised by mode
44
- *
45
- * Every DOF resolves to the same scalar velocity row, contact-shaped: for a
46
- * unit axis `d` and lever arms `rA = anchorA − comA`, `rB = anchorB − comB`,
47
- * `K = invMA + invMB + (rA×d)·Iw_A·(rA×d) + (rB×d)·Iw_B·(rB×d)` (linear)
48
- * `K = d·Iw_A·d + d·Iw_B·d` (angular)
49
- * `vrel = (vA + ωA×rA − vB − ωB×rB) · d` (linear, A−B)
50
- * `vrel = (ωB − ωA) · d` (angular, B−A)
51
- * `λ = clamp(λ_acc − (1/K)·(vrel + bias)) − λ_acc`,
52
- * applied as `±λ·d`. The **mode** picks only two row parameters:
53
- * - LOCKED → `bias = β/h · error`, impulse clamp `(−∞, +∞)` (bilateral).
54
- * - LIMITED → row active only when the DOF position is at/beyond a bound;
55
- * `bias = β/h · (position − bound)`, impulse clamp one-sided
56
- * (`[0, +∞)` at the lower stop, `(−∞, 0]` at the upper). The clamp makes
57
- * it a unilateral push-out-of-violation constraint, exactly like a contact
58
- * normal — the limit can only resist crossing the stop, never pull the DOF
59
- * back into range.
60
- * The warm-start and the iteration loop are mode-agnostic; they read the
61
- * per-DOF `(active, effMass, bias, clampLo, clampHi)` filled by the mode-aware
62
- * setup. Geometry (anchors / lever arms / position error) is recomputed from
63
- * the current pose every substep, so the joint tracks the bodies as they move.
64
- *
65
- * The "position" along a DOF is `C · axis` for linear (signed anchor offset in
66
- * metres) and `e · axis` for angular, where `e = 2·sign(qD.w)·qD.xyz` is the
67
- * small-angle rotation vector of the relative rotation `qD = conj(qA)⊗qB`,
68
- * expressed in frame-A-local coordinates (so error component `k` pairs with
69
- * frame axis `k`). The angular position is therefore a first-order (small
70
- * angle) measure: accurate for the modest ranges of slider/hinge end-stops,
71
- * but it under-reports large angles (`2·sin(θ/2)` vs `θ`). Accurate wide-cone
72
- * range-of-motion (ragdoll shoulders) needs the swing-twist decomposition,
73
- * tracked as the follow-up; angular LIMITED here is the moderate-range cut.
74
- * The decomposition itself is already implemented — reuse
75
- * `Quaternion.computeSwingAndTwist(axis, swing, twist)` /
76
- * `computeTwistAngle(axis)` (`core/geom/Quaternion.js`) on the relative
77
- * rotation `qD` rather than writing a new one.
78
- *
79
- * @author Alex Goldring
80
- * @copyright Company Named Limited (c) 2026
81
- */
82
-
83
- /**
84
- * Maximum SPOOK position-correction bias for a joint row, m/s — belt-and-braces
85
- * against a wildly-violated constraint (e.g. a freshly-teleported body)
86
- * yanking the solve. Equality joints sit near zero error at steady state, so
87
- * this only clamps transients.
88
- * @type {number}
89
- */
90
- const MAX_JOINT_BIAS = 4;
91
-
92
- /**
93
- * Baumgarte / SPOOK position-correction gain `β`. The per-substep gain is
94
- * `β / dt_sub`; with `β = 0.2` this matches the contact solver's position
95
- * stiffness. Joints are bilateral equality constraints, so this only nudges
96
- * residual position error toward zero (no clamp interplay to destabilise).
97
- * @type {number}
98
- */
99
- const JOINT_BAUMGARTE = 0.2;
100
-
101
- const scratch_inertia = new Float64Array(3);
102
- const scratch_anchor = new Float64Array(3);
103
- /** Frame-A world basis (rows = A's frame axes in world), from quat3_to_matrix3. */
104
- const scratch_frame_a = new Float64Array(9);
105
- /** Scratch quaternion for frame composition / relative rotation. */
106
- const scratch_q = new Float64Array(4);
107
- /** Angular position error `e` per frame axis (frame-A-local small-angle vector). */
108
- const scratch_ang_err = new Float64Array(3);
109
-
110
- // Per-DOF row parameters, filled per joint by the mode-aware setup and consumed
111
- // by the mode-agnostic warm-start + iteration. Indexed 0..2 (the three frame
112
- // axes); the linear set drives imp[0..2], the angular set drives imp[3..5].
113
- const lin_active = new Uint8Array(3);
114
- const lin_eff = new Float64Array(3);
115
- const lin_bias = new Float64Array(3);
116
- const lin_clo = new Float64Array(3);
117
- const lin_chi = new Float64Array(3);
118
- const lin_gamma = new Float64Array(3);
119
- const ang_active = new Uint8Array(3);
120
- const ang_eff = new Float64Array(3);
121
- const ang_bias = new Float64Array(3);
122
- const ang_clo = new Float64Array(3);
123
- const ang_chi = new Float64Array(3);
124
- const ang_gamma = new Float64Array(3);
125
-
126
- /**
127
- * Angular effective-mass contribution of one body about a unit world axis:
128
- * `a · Iw⁻¹ · a`. Zero for non-dynamic / rotation-locked bodies (whose
129
- * {@link SolverBodyState} inverse-inertia diagonal is zero).
130
- * @param {Float64Array} ss solver-body-state data array
131
- * @param {number} base `body_index * SBS_STRIDE`
132
- * @returns {number}
133
- */
134
- function angular_axis_effective_mass(ss, base, ax, ay, az) {
135
- const iix = ss[base + SBS_INV_I_X], iiy = ss[base + SBS_INV_I_Y], iiz = ss[base + SBS_INV_I_Z];
136
- if (iix === 0 && iiy === 0 && iiz === 0) return 0;
137
- world_inverse_inertia_apply_raw(scratch_inertia, 0, iix, iiy, iiz,
138
- ss[base + SBS_QX], ss[base + SBS_QY], ss[base + SBS_QZ], ss[base + SBS_QW], ax, ay, az);
139
- return ax * scratch_inertia[0] + ay * scratch_inertia[1] + az * scratch_inertia[2];
140
- }
141
-
142
- /**
143
- * Apply a pure angular impulse `sign·λ·axis`: Δω = Iw⁻¹·(sign·λ·axis).
144
- * @param {Float64Array} ss solver-body-state data array
145
- * @param {number} base `body_index * SBS_STRIDE`
146
- * @param {number} ax @param {number} ay @param {number} az
147
- * @param {number} lambda @param {number} sign
148
- */
149
- function apply_angular_impulse(ss, base, ax, ay, az, lambda, sign) {
150
- const iix = ss[base + SBS_INV_I_X], iiy = ss[base + SBS_INV_I_Y], iiz = ss[base + SBS_INV_I_Z];
151
- if (iix === 0 && iiy === 0 && iiz === 0) return;
152
- const L = sign * lambda;
153
- world_inverse_inertia_apply_raw(scratch_inertia, 0, iix, iiy, iiz,
154
- ss[base + SBS_QX], ss[base + SBS_QY], ss[base + SBS_QZ], ss[base + SBS_QW], ax * L, ay * L, az * L);
155
- ss[base + SBS_AV_X] += scratch_inertia[0];
156
- ss[base + SBS_AV_Y] += scratch_inertia[1];
157
- ss[base + SBS_AV_Z] += scratch_inertia[2];
158
- }
159
-
160
- /**
161
- * Effective-mass denominator contribution of one body along a unit axis:
162
- * `invM + (r×d)·Iw⁻¹·(r×d)`. Static / kinematic bodies (invM === 0) contribute
163
- * nothing.
164
- *
165
- * @param {Float64Array} ss solver-body-state data array
166
- * @param {number} base `body_index * SBS_STRIDE`
167
- * @param {number} invM
168
- * @param {number} rx @param {number} ry @param {number} rz
169
- * @param {number} dx @param {number} dy @param {number} dz
170
- * @returns {number}
171
- */
172
- function axis_effective_mass(ss, base, invM, rx, ry, rz, dx, dy, dz) {
173
- if (invM === 0) return 0;
174
- let k = invM;
175
- const iix = ss[base + SBS_INV_I_X], iiy = ss[base + SBS_INV_I_Y], iiz = ss[base + SBS_INV_I_Z];
176
- if (iix !== 0 || iiy !== 0 || iiz !== 0) {
177
- const cx = ry * dz - rz * dy;
178
- const cy = rz * dx - rx * dz;
179
- const cz = rx * dy - ry * dx;
180
- world_inverse_inertia_apply_raw(scratch_inertia, 0, iix, iiy, iiz,
181
- ss[base + SBS_QX], ss[base + SBS_QY], ss[base + SBS_QZ], ss[base + SBS_QW], cx, cy, cz);
182
- k += cx * scratch_inertia[0] + cy * scratch_inertia[1] + cz * scratch_inertia[2];
183
- }
184
- return k;
185
- }
186
-
187
- /**
188
- * Apply impulse `P` at body-relative offset `r`: Δv = P·invM, Δω = Iw⁻¹·(r×P).
189
- * Reads / writes the body's {@link SolverBodyState} span.
190
- *
191
- * @param {Float64Array} ss solver-body-state data array
192
- * @param {number} base `body_index * SBS_STRIDE`
193
- * @param {number} invM
194
- * @param {number} rx @param {number} ry @param {number} rz
195
- * @param {number} Px @param {number} Py @param {number} Pz
196
- * @param {number} sign +1 / −1
197
- */
198
- function apply_impulse(ss, base, invM, rx, ry, rz, Px, Py, Pz, sign) {
199
- if (invM === 0) return;
200
- const sPx = sign * Px, sPy = sign * Py, sPz = sign * Pz;
201
- ss[base + SBS_LV_X] += sPx * invM;
202
- ss[base + SBS_LV_Y] += sPy * invM;
203
- ss[base + SBS_LV_Z] += sPz * invM;
204
-
205
- const tx = ry * sPz - rz * sPy;
206
- const ty = rz * sPx - rx * sPz;
207
- const tz = rx * sPy - ry * sPx;
208
- world_inverse_inertia_apply_raw(scratch_inertia, 0,
209
- ss[base + SBS_INV_I_X], ss[base + SBS_INV_I_Y], ss[base + SBS_INV_I_Z],
210
- ss[base + SBS_QX], ss[base + SBS_QY], ss[base + SBS_QZ], ss[base + SBS_QW], tx, ty, tz);
211
- ss[base + SBS_AV_X] += scratch_inertia[0];
212
- ss[base + SBS_AV_Y] += scratch_inertia[1];
213
- ss[base + SBS_AV_Z] += scratch_inertia[2];
214
- }
215
-
216
- /**
217
- * Clamp the SPOOK position bias to ±{@link MAX_JOINT_BIAS}.
218
- * @param {number} b @returns {number}
219
- */
220
- function clamp_bias(b) {
221
- if (b > MAX_JOINT_BIAS) return MAX_JOINT_BIAS;
222
- if (b < -MAX_JOINT_BIAS) return -MAX_JOINT_BIAS;
223
- return b;
224
- }
225
-
226
- /**
227
- * Swing-twist decomposition of the relative rotation `qD = conj(qA)⊗qB`, giving
228
- * the per-frame-axis angular positions used by wide-cone angular DOFs.
229
- *
230
- * Decomposes `qD = swing twist`, with **twist** the rotation about frame
231
- * axis X (the bone / twist axis) and **swing** the residual tilt (a rotation
232
- * about an axis in the YZ plane that carries X to its new direction). Writes,
233
- * into `out`:
234
- * - `out[0]` = signed twist angle about X, in `(−π, π]` — *exact*, so a twist
235
- * limit engages at the true angle, not the `2·sin(θ/2)` small-angle proxy;
236
- * - `out[1]`, `out[2]` = the swing angle distributed over Y and Z
237
- * (`φ·axis`, φ the true swing angle), so independent Y/Z swing limits form
238
- * an accurate (box-shaped) cone that holds at large tilt.
239
- * Reduces continuously to the small-angle vector near identity. Pure scratch /
240
- * locals no allocation, suitable for the per-substep hot loop. (The Quaternion
241
- * class has an object-based `computeSwingAndTwist`; this is the inlined,
242
- * allocation-free form — see the bench that justifies it.)
243
- *
244
- * @param {number} dx @param {number} dy @param {number} dz @param {number} dw qD
245
- * @param {Float64Array} out length-3 destination (frame-axis positions)
246
- */
247
- export function swing_twist_error(dx, dy, dz, dw, out) {
248
- // Shortest arc: work with the hemisphere where dw 0.
249
- if (dw < 0) { dx = -dx; dy = -dy; dz = -dz; dw = -dw; }
250
-
251
- const nxt = Math.sqrt(dx * dx + dw * dw); // |twist| (before normalising)
252
- let sy, sz, sw;
253
- if (nxt < 1e-12) {
254
- // dw ≈ 0 and dx ≈ 0: a ~180° pure swing — twist is undefined, take 0.
255
- out[0] = 0;
256
- // Swing is qD itself; distribute its angle over Y/Z below.
257
- sy = dy; sz = dz; sw = dw;
258
- } else {
259
- out[0] = 2 * Math.atan2(dx, dw); // exact signed twist about X
260
- const tx = dx / nxt, tw = dw / nxt; // normalised twist (tx,0,0,tw)
261
- // swing = qD ⊗ conj(twist); its X component is identically 0.
262
- sy = dy * tw - dz * tx;
263
- sz = dy * tx + dz * tw;
264
- sw = dw * tw + dx * tx;
265
- }
266
-
267
- if (sw < 0) { sy = -sy; sz = -sz; sw = -sw; }
268
- const syz = Math.sqrt(sy * sy + sz * sz);
269
- if (syz < 1e-9) {
270
- // Near-zero swing: small-angle vector (continuous with φ·axis as φ→0).
271
- out[1] = 2 * sy;
272
- out[2] = 2 * sz;
273
- } else {
274
- const phi = 2 * Math.atan2(syz, sw); // exact swing angle in [0, π]
275
- const s = phi / syz;
276
- out[1] = sy * s;
277
- out[2] = sz * s;
278
- }
279
- }
280
-
281
- /**
282
- * Fill the row parameters for one DOF given its mode, signed position and
283
- * signed velocity.
284
- *
285
- * Writes `active / eff / bias / clampLo / clampHi` at index `k` of the supplied
286
- * arrays and, for LIMITED, resets the warm-start impulse when the active bound
287
- * flipped (a stale opposite-side impulse must not warm-start).
288
- *
289
- * ## LIMITED is a speculative = 1) one-sided velocity constraint
290
- *
291
- * Rather than waiting for the DOF to cross a stop and then pushing back with a
292
- * Baumgarte bias — which injects real velocity and makes the stop *bounce* when
293
- * nothing else loads the joint — the limit row is always live and uses the full
294
- * `(position − bound)/h` as its bias. With the impulse clamped to one side this
295
- * removes exactly the approach velocity that would overshoot, so the DOF
296
- * **lands on the bound** with zero relative velocity (an inelastic stop, no
297
- * penetration to recover, no rebound). When the DOF is far from the bound the
298
- * large same-signed bias drives the clamp to zero, so the row is a no-op — it
299
- * self-gates on approach. At a stop held by a sustained load (gravity on a
300
- * slider) the per-substep load and the per-substep warm-start cancel, so the
301
- * DOF rests exactly on the bound, mirroring a resting contact.
302
- *
303
- * Only the *push-out* side of the bias is clamped (to {@link MAX_JOINT_BIAS}),
304
- * so a body teleported deep past a stop is eased out rather than yanked; the
305
- * gating side is left unbounded.
306
- *
307
- * The active bound is the violated one, else within range — the one the DOF
308
- * is moving toward (`vel` sign). LOCKED is unchanged: a bilateral row with a
309
- * `β/h` Baumgarte bias and no clamp.
310
- *
311
- * ## MOTOR drives the relative velocity toward a target
312
- *
313
- * A motor is a velocity row biased to the target (`bias = −target`, so the
314
- * solve drives the relative velocity to the target) with the impulse clamped to
315
- * `±maxForce·h` — a force-limited servo. With an unbounded force budget it is a
316
- * perfect velocity drive; with a finite one it pulls toward the target as hard
317
- * as it can (a weak motor cannot overcome a heavier load). The target follows
318
- * the row's sign convention: linear is A−B along the frame axis, angular is
319
- * B−A about it.
320
- *
321
- * ## SPRING is a SPOOK soft (compliant) constraint
322
- *
323
- * A spring drives the DOF position toward zero with stiffness `k` (N/m or
324
- * N·m/rad) and damping `c`, as a *regularised* row rather than a hard one. The
325
- * implicit-Euler soft constraint (Catto, "Soft Constraints") gives, per substep
326
- * `h`, with `denom = c + h·k`:
327
- * = 1 / (h·denom)` the compliance / regularisation (inverse mass),
328
- * `bias = (k/denom)·C` the restoring velocity, and a softened effective
329
- * `effMass = 1/(K + γ)` mass so the row solves
330
- * = −effMass·(vrel + bias + γ·λ_accum)`.
331
- * The `γ·λ_accum` term is what makes it compliant (the constraint yields in
332
- * proportion to the force it carries), so a spring under load settles at a
333
- * deflection rather than snapping rigid. Stiffness-only (`c = 0`) oscillates
334
- * undamped; damping-only (`k = 0`) is a pure damper; both zero is inert. The
335
- * row is bilateral (no clamp). This is the suspension / bungee / soft-return
336
- * element, and the soft basis for cone-twist later. The angular position uses
337
- * the same small-angle measure as LIMITED (good for modest ranges).
338
- *
339
- * @param {Joint} joint the joint (per-DOF config + warm-start impulse read here)
340
- * @param {number} dofIndex DOF 0..5 (selects mode / limits / motor / imp slot)
341
- * @param {number} k axis index 0..2 (output-array slot for this DOF group)
342
- * @param {number} keff raw effective-mass denominator `K` (0 ⇒ no row); the
343
- * row's effective mass is `1/K`, or `1/(K+γ)` softened for a spring.
344
- * @param {number} pos signed DOF position (`C·axis` linear / `e·axis` angular)
345
- * @param {number} vel signed DOF velocity along the same axis (selects the
346
- * approached bound for an in-range LIMITED DOF)
347
- * @param {number} spook_locked Baumgarte gain `β / dt_sub` (LOCKED)
348
- * @param {number} spook_spec speculative gain `1 / dt_sub` (LIMITED)
349
- * @param {number} dt_sub substep size (MOTOR impulse cap = `maxForce·dt_sub`;
350
- * SPRING compliance derives from it)
351
- * @param {Uint8Array} active @param {Float64Array} effOut
352
- * @param {Float64Array} biasOut @param {Float64Array} cloOut @param {Float64Array} chiOut
353
- * @param {Float64Array} gammaOut per-row regularisation (0 for non-spring rows)
354
- */
355
- function fill_row(joint, dofIndex, k, keff, pos, vel, spook_locked, spook_spec, dt_sub,
356
- active, effOut, biasOut, cloOut, chiOut, gammaOut) {
357
- const mode = joint.dofMode[dofIndex];
358
- const imp = joint.dofImpulse;
359
-
360
- if (mode === DofMode.LOCKED) {
361
- if (keff === 0) { active[k] = 0; return; }
362
- effOut[k] = 1 / keff;
363
- biasOut[k] = clamp_bias(spook_locked * pos);
364
- cloOut[k] = -Infinity;
365
- chiOut[k] = Infinity;
366
- gammaOut[k] = 0;
367
- active[k] = 1;
368
- return;
369
- }
370
- if (mode === DofMode.LIMITED) {
371
- if (keff === 0) { imp[dofIndex] = 0; active[k] = 0; return; }
372
- const lower = joint.dofLowerLimit[dofIndex];
373
- const upper = joint.dofUpperLimit[dofIndex];
374
- // Select the bound: the violated one, else the one being approached.
375
- let bound, lower_side;
376
- if (pos <= lower) { bound = lower; lower_side = true; }
377
- else if (pos >= upper) { bound = upper; lower_side = false; }
378
- else { lower_side = vel <= 0; bound = lower_side ? lower : upper; }
379
-
380
- let b = spook_spec * (pos - bound);
381
- if (lower_side) {
382
- // Lower stop: impulse pushes the DOF up (+), clamp [0, +∞). The
383
- // push-out side of the bias is the negative one bound it.
384
- cloOut[k] = 0; chiOut[k] = Infinity;
385
- if (imp[dofIndex] < 0) imp[dofIndex] = 0; // drop stale upper-side impulse
386
- if (b < -MAX_JOINT_BIAS) b = -MAX_JOINT_BIAS;
387
- } else {
388
- // Upper stop: impulse pushes the DOF down (−), clamp (−∞, 0]. The
389
- // push-out side of the bias is the positive one bound it.
390
- cloOut[k] = -Infinity; chiOut[k] = 0;
391
- if (imp[dofIndex] > 0) imp[dofIndex] = 0; // drop stale lower-side impulse
392
- if (b > MAX_JOINT_BIAS) b = MAX_JOINT_BIAS;
393
- }
394
- effOut[k] = 1 / keff;
395
- biasOut[k] = b;
396
- gammaOut[k] = 0;
397
- active[k] = 1;
398
- return;
399
- }
400
- if (mode === DofMode.MOTOR) {
401
- if (keff === 0) { imp[dofIndex] = 0; active[k] = 0; return; }
402
- const maxImpulse = joint.dofMotorMaxForce[dofIndex] * dt_sub;
403
- if (maxImpulse <= 0) { imp[dofIndex] = 0; active[k] = 0; return; }
404
- effOut[k] = 1 / keff;
405
- // Drive the relative velocity to the target: λ = −eff·(vrel target).
406
- biasOut[k] = -joint.dofMotorTargetVelocity[dofIndex];
407
- cloOut[k] = -maxImpulse;
408
- chiOut[k] = maxImpulse;
409
- gammaOut[k] = 0;
410
- active[k] = 1;
411
- return;
412
- }
413
- if (mode === DofMode.SPRING) {
414
- if (keff === 0) { imp[dofIndex] = 0; active[k] = 0; return; }
415
- const ks = joint.dofStiffness[dofIndex];
416
- const cs = joint.dofDamping[dofIndex];
417
- const denom = cs + dt_sub * ks;
418
- if (denom <= 0) { imp[dofIndex] = 0; active[k] = 0; return; } // inert (no k, no c)
419
- const gamma = 1 / (dt_sub * denom);
420
- effOut[k] = 1 / (keff + gamma);
421
- biasOut[k] = (ks / denom) * pos; // restoring velocity toward pos = 0
422
- cloOut[k] = -Infinity;
423
- chiOut[k] = Infinity;
424
- gammaOut[k] = gamma;
425
- active[k] = 1;
426
- return;
427
- }
428
- // FREE: no row this substep.
429
- imp[dofIndex] = 0;
430
- active[k] = 0;
431
- }
432
-
433
- /**
434
- * Solve every joint for one substep: recompute geometry at the current poses,
435
- * derive each DOF's row parameters from its mode, replay the per-substep
436
- * warm-start, and run `iters` velocity iterations.
437
- *
438
- * Called once per substep from `PhysicsSystem.fixedUpdate`, after the contact
439
- * solve so the two share the substep / warm-start cadence.
440
- *
441
- * @param {Joint[]} joints live joints (sparse array; holes skipped)
442
- * @param {PhysicsSystem} system reads `__bodies` / `__transforms` / index map
443
- * @param {number} dt_sub substep size in seconds (the SPOOK gain is derived
444
- * from it, matching the contact solver's per-substep position stiffness)
445
- * @param {number} iters velocity iterations
446
- */
447
- export function solve_joints(joints, system, dt_sub, iters) {
448
- const n = joints.length;
449
- if (n === 0 || dt_sub <= 0) return;
450
-
451
- const spook_locked = JOINT_BAUMGARTE / dt_sub;
452
- const spook_spec = 1 / dt_sub;
453
-
454
- const storage = system.storage;
455
- const ss = system.__solver_state.data;
456
-
457
- for (let ji = 0; ji < n; ji++) {
458
- const joint = joints[ji];
459
- if (joint === undefined || joint === null) continue;
460
-
461
- // Generation-checked validity: if A's body was unlinked (and its slot
462
- // possibly reused by a different body), the stored packed id no longer
463
- // validates skip the stale joint rather than attach to the wrong body.
464
- if (!storage.is_valid(joint._bodyIdA)) continue;
465
- const idxA = body_id_index(joint._bodyIdA);
466
- const baseA = idxA * SBS_STRIDE;
467
- const rbA = system.__bodies[idxA];
468
- if (rbA === undefined) continue;
469
- const trA = system.__transforms[idxA];
470
-
471
- const to_world = joint._bodyIdB === JOINT_WORLD;
472
- let rbB = null, trB = null, idxB = -1, baseB = -1;
473
- if (!to_world) {
474
- if (!storage.is_valid(joint._bodyIdB)) continue;
475
- idxB = body_id_index(joint._bodyIdB);
476
- baseB = idxB * SBS_STRIDE;
477
- rbB = system.__bodies[idxB];
478
- if (rbB === undefined) continue;
479
- trB = system.__transforms[idxB];
480
- }
481
-
482
- // Skip while a participating dynamic body sleeps — its velocity must
483
- // stay zero until woken. (Island-aware joint sleep is a follow-up; for
484
- // now jointed bodies that should stay coupled use DisableSleep.)
485
- if (rbA.sleepState === SleepState.Sleeping) continue;
486
- if (!to_world && rbB.sleepState === SleepState.Sleeping) continue;
487
-
488
- // Both bodies static/kinematic → nothing to solve.
489
- const invMA = ss[baseA + SBS_INV_MASS];
490
- const invMB = to_world ? 0 : ss[baseB + SBS_INV_MASS];
491
- if (invMA === 0 && invMB === 0) continue;
492
-
493
- const mode = joint.dofMode;
494
- const linConstrained = mode[0] !== DofMode.FREE || mode[1] !== DofMode.FREE || mode[2] !== DofMode.FREE;
495
- const angConstrained = mode[3] !== DofMode.FREE || mode[4] !== DofMode.FREE || mode[5] !== DofMode.FREE;
496
- if (!linConstrained && !angConstrained) continue;
497
-
498
- // World anchor A and its lever arm rA = R_A · localAnchorA.
499
- const la = joint.localAnchorA;
500
- v3_quat3_apply(scratch_anchor, 0, la.x, la.y, la.z,
501
- trA.rotation[0], trA.rotation[1], trA.rotation[2], trA.rotation[3]);
502
- const rAx = scratch_anchor[0], rAy = scratch_anchor[1], rAz = scratch_anchor[2];
503
- const anchorAx = trA.position.x + rAx;
504
- const anchorAy = trA.position.y + rAy;
505
- const anchorAz = trA.position.z + rAz;
506
-
507
- // World anchor B + lever arm rB. For a world anchor, localAnchorB is a
508
- // fixed world point and there is no body B lever.
509
- let rBx = 0, rBy = 0, rBz = 0;
510
- let anchorBx, anchorBy, anchorBz;
511
- const lb = joint.localAnchorB;
512
- if (to_world) {
513
- anchorBx = lb.x; anchorBy = lb.y; anchorBz = lb.z;
514
- } else {
515
- v3_quat3_apply(scratch_anchor, 0, lb.x, lb.y, lb.z,
516
- trB.rotation[0], trB.rotation[1], trB.rotation[2], trB.rotation[3]);
517
- rBx = scratch_anchor[0]; rBy = scratch_anchor[1]; rBz = scratch_anchor[2];
518
- anchorBx = trB.position.x + rBx;
519
- anchorBy = trB.position.y + rBy;
520
- anchorBz = trB.position.z + rBz;
521
- }
522
-
523
- // Position error C = anchorA anchorB (its projection on a frame axis
524
- // is the signed DOF offset; locked axes drive it to zero, limited axes
525
- // bound it).
526
- const Cx = anchorAx - anchorBx;
527
- const Cy = anchorAy - anchorBy;
528
- const Cz = anchorAz - anchorBz;
529
-
530
- const imp = joint.dofImpulse;
531
-
532
- // === Frame A world axes shared by the linear AND angular rows ===
533
- // Every DOF is expressed in the joint's frame on body A. Frame A =
534
- // body-A rotation localBasisA; the rows of its matrix are the frame
535
- // axes in world (see quat3_to_matrix3).
536
- const lba = joint.localBasisA;
537
- quat3_multiply(scratch_q, 0, trA.rotation[0], trA.rotation[1], trA.rotation[2], trA.rotation[3], lba[0], lba[1], lba[2], lba[3]);
538
- const qAx = scratch_q[0], qAy = scratch_q[1], qAz = scratch_q[2], qAw = scratch_q[3];
539
- quat3_to_matrix3(scratch_frame_a, 0, qAx, qAy, qAz, qAw);
540
- const fa = scratch_frame_a;
541
-
542
- // --- Linear DOF row setup (frame axes). Position along axis k is
543
- // `C · axis_k`; convention is A−B (impulse +to A / −to B). ---
544
- if (linConstrained) {
545
- for (let k = 0; k < 3; k++) {
546
- lin_active[k] = 0;
547
- const m = mode[k];
548
- if (m === DofMode.FREE) { imp[k] = 0; continue; }
549
- const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
550
- const keff = axis_effective_mass(ss, baseA, invMA, rAx, rAy, rAz, ax, ay, az)
551
- + (to_world ? 0 : axis_effective_mass(ss, baseB, invMB, rBx, rBy, rBz, ax, ay, az));
552
- const pos = Cx * ax + Cy * ay + Cz * az;
553
- // Relative anchor velocity along the axis (A−B), for LIMITED
554
- // bound selection. Cheap; only the projection is used.
555
- let vel = 0;
556
- if (m === DofMode.LIMITED) {
557
- const rvx = (ss[baseA + SBS_LV_X] + ss[baseA + SBS_AV_Y] * rAz - ss[baseA + SBS_AV_Z] * rAy) - (to_world ? 0 : (ss[baseB + SBS_LV_X] + ss[baseB + SBS_AV_Y] * rBz - ss[baseB + SBS_AV_Z] * rBy));
558
- const rvy = (ss[baseA + SBS_LV_Y] + ss[baseA + SBS_AV_Z] * rAx - ss[baseA + SBS_AV_X] * rAz) - (to_world ? 0 : (ss[baseB + SBS_LV_Y] + ss[baseB + SBS_AV_Z] * rBx - ss[baseB + SBS_AV_X] * rBz));
559
- const rvz = (ss[baseA + SBS_LV_Z] + ss[baseA + SBS_AV_X] * rAy - ss[baseA + SBS_AV_Y] * rAx) - (to_world ? 0 : (ss[baseB + SBS_LV_Z] + ss[baseB + SBS_AV_X] * rBy - ss[baseB + SBS_AV_Y] * rBx));
560
- vel = rvx * ax + rvy * ay + rvz * az;
561
- }
562
- fill_row(joint, k, k, keff, pos, vel, spook_locked, spook_spec, dt_sub,
563
- lin_active, lin_eff, lin_bias, lin_clo, lin_chi, lin_gamma);
564
- }
565
- } else {
566
- lin_active[0] = lin_active[1] = lin_active[2] = 0;
567
- }
568
-
569
- // --- Angular DOF row setup (frame axes). Position along axis k is the
570
- // k-th component of the frame-local small-angle error vector `e`;
571
- // convention is B−A (impulse +to B / −to A). ---
572
- if (angConstrained) {
573
- // Frame B world rotation (identity for a world anchor → locks A's
574
- // frame to world axes).
575
- let qBx = 0, qBy = 0, qBz = 0, qBw = 1;
576
- if (!to_world) {
577
- const lbb = joint.localBasisB;
578
- quat3_multiply(scratch_q, 0, trB.rotation[0], trB.rotation[1], trB.rotation[2], trB.rotation[3], lbb[0], lbb[1], lbb[2], lbb[3]);
579
- qBx = scratch_q[0]; qBy = scratch_q[1]; qBz = scratch_q[2]; qBw = scratch_q[3];
580
- }
581
- // qD = conj(qA) ⊗ qB the per-axis angular position in frame-A
582
- // coords. Two measures: the cheap small-angle rotation vector
583
- // (default exact at the origin, fine for welds / hinges / modest
584
- // limits) or, when the joint opts into `swingTwist`, the swing-twist
585
- // decomposition (X = twist, Y/Z = swing) with *exact* angles, for
586
- // wide cone-twist range-of-motion (ragdoll shoulders) where the
587
- // small-angle measure under-reports.
588
- quat3_multiply(scratch_q, 0, -qAx, -qAy, -qAz, qAw, qBx, qBy, qBz, qBw);
589
- if (joint.swingTwist) {
590
- swing_twist_error(scratch_q[0], scratch_q[1], scratch_q[2], scratch_q[3], scratch_ang_err);
591
- } else {
592
- const es = scratch_q[3] < 0 ? -2 : 2;
593
- scratch_ang_err[0] = es * scratch_q[0];
594
- scratch_ang_err[1] = es * scratch_q[1];
595
- scratch_ang_err[2] = es * scratch_q[2];
596
- }
597
-
598
- for (let k = 0; k < 3; k++) {
599
- ang_active[k] = 0;
600
- const m = mode[3 + k];
601
- if (m === DofMode.FREE) { imp[3 + k] = 0; continue; }
602
- const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
603
- const keff = angular_axis_effective_mass(ss, baseA, ax, ay, az)
604
- + (to_world ? 0 : angular_axis_effective_mass(ss, baseB, ax, ay, az));
605
- const pos = scratch_ang_err[k];
606
- // Relative angular velocity about the axis (B−A), for LIMITED
607
- // bound selection.
608
- let vel = 0;
609
- if (m === DofMode.LIMITED) {
610
- vel = -(ss[baseA + SBS_AV_X] * ax + ss[baseA + SBS_AV_Y] * ay + ss[baseA + SBS_AV_Z] * az);
611
- if (!to_world) vel += ss[baseB + SBS_AV_X] * ax + ss[baseB + SBS_AV_Y] * ay + ss[baseB + SBS_AV_Z] * az;
612
- }
613
- fill_row(joint, 3 + k, k, keff, pos, vel, spook_locked, spook_spec, dt_sub,
614
- ang_active, ang_eff, ang_bias, ang_clo, ang_chi, ang_gamma);
615
- }
616
- } else {
617
- ang_active[0] = ang_active[1] = ang_active[2] = 0;
618
- }
619
-
620
- if (!lin_active[0] && !lin_active[1] && !lin_active[2]
621
- && !ang_active[0] && !ang_active[1] && !ang_active[2]) continue;
622
-
623
- // --- Per-substep warm-start (frame axes): linear impulse `Σ imp[k]·aₖ`
624
- // applied at the anchors, angular impulse `Σ imp[3+k]·aₖ` about the
625
- // frame axes (+to B / −to A). ---
626
- {
627
- let Px = 0, Py = 0, Pz = 0;
628
- for (let k = 0; k < 3; k++) {
629
- if (!lin_active[k]) continue;
630
- const w = imp[k];
631
- Px += w * fa[3 * k]; Py += w * fa[3 * k + 1]; Pz += w * fa[3 * k + 2];
632
- }
633
- if (Px !== 0 || Py !== 0 || Pz !== 0) {
634
- apply_impulse(ss, baseA, invMA, rAx, rAy, rAz, Px, Py, Pz, +1);
635
- if (!to_world) apply_impulse(ss, baseB, invMB, rBx, rBy, rBz, Px, Py, Pz, -1);
636
- }
637
- let Lx = 0, Ly = 0, Lz = 0;
638
- for (let k = 0; k < 3; k++) {
639
- if (!ang_active[k]) continue;
640
- const w = imp[3 + k];
641
- Lx += w * fa[3 * k]; Ly += w * fa[3 * k + 1]; Lz += w * fa[3 * k + 2];
642
- }
643
- if (Lx !== 0 || Ly !== 0 || Lz !== 0) {
644
- if (!to_world) apply_angular_impulse(ss, baseB, Lx, Ly, Lz, 1, +1);
645
- apply_angular_impulse(ss, baseA, Lx, Ly, Lz, 1, -1);
646
- }
647
- }
648
-
649
- for (let it = 0; it < iters; it++) {
650
- // Linear rows (frame axes). The relative anchor velocity is
651
- // recomputed before each row so successive rows see the prior
652
- // impulses (Gauss-Seidel coupling).
653
- for (let k = 0; k < 3; k++) {
654
- if (!lin_active[k]) continue;
655
- const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
656
- const rvx = (ss[baseA + SBS_LV_X] + ss[baseA + SBS_AV_Y] * rAz - ss[baseA + SBS_AV_Z] * rAy) - (to_world ? 0 : (ss[baseB + SBS_LV_X] + ss[baseB + SBS_AV_Y] * rBz - ss[baseB + SBS_AV_Z] * rBy));
657
- const rvy = (ss[baseA + SBS_LV_Y] + ss[baseA + SBS_AV_Z] * rAx - ss[baseA + SBS_AV_X] * rAz) - (to_world ? 0 : (ss[baseB + SBS_LV_Y] + ss[baseB + SBS_AV_Z] * rBx - ss[baseB + SBS_AV_X] * rBz));
658
- const rvz = (ss[baseA + SBS_LV_Z] + ss[baseA + SBS_AV_X] * rAy - ss[baseA + SBS_AV_Y] * rAx) - (to_world ? 0 : (ss[baseB + SBS_LV_Z] + ss[baseB + SBS_AV_X] * rBy - ss[baseB + SBS_AV_Y] * rBx));
659
- const vrel = rvx * ax + rvy * ay + rvz * az;
660
- const old = imp[k];
661
- // `+ γ·old` regularises a spring row (γ = 0 otherwise → exact).
662
- let nv = old - lin_eff[k] * (vrel + lin_bias[k] + lin_gamma[k] * old);
663
- if (nv < lin_clo[k]) nv = lin_clo[k]; else if (nv > lin_chi[k]) nv = lin_chi[k];
664
- imp[k] = nv;
665
- const d = nv - old;
666
- if (d !== 0) {
667
- apply_impulse(ss, baseA, invMA, rAx, rAy, rAz, d * ax, d * ay, d * az, +1);
668
- if (!to_world) apply_impulse(ss, baseB, invMB, rBx, rBy, rBz, d * ax, d * ay, d * az, -1);
669
- }
670
- }
671
-
672
- // Angular rows (frame axes): drive ωB−ωA about each axis toward the
673
- // bias target, clamped per the row's bound.
674
- for (let k = 0; k < 3; k++) {
675
- if (!ang_active[k]) continue;
676
- const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
677
- let wrel = -(ss[baseA + SBS_AV_X] * ax + ss[baseA + SBS_AV_Y] * ay + ss[baseA + SBS_AV_Z] * az);
678
- if (!to_world) wrel += ss[baseB + SBS_AV_X] * ax + ss[baseB + SBS_AV_Y] * ay + ss[baseB + SBS_AV_Z] * az;
679
- const old = imp[3 + k];
680
- let nv = old - ang_eff[k] * (wrel + ang_bias[k] + ang_gamma[k] * old);
681
- if (nv < ang_clo[k]) nv = ang_clo[k]; else if (nv > ang_chi[k]) nv = ang_chi[k];
682
- imp[3 + k] = nv;
683
- const d = nv - old;
684
- if (d !== 0) {
685
- if (!to_world) apply_angular_impulse(ss, baseB, ax, ay, az, d, +1);
686
- apply_angular_impulse(ss, baseA, ax, ay, az, d, -1);
687
- }
688
- }
689
- }
690
- }
691
- }
1
+ import { quat3_multiply } from "../../../core/geom/3d/quaternion/quat3_multiply.js";
2
+ import { quat3_to_matrix3 } from "../../../core/geom/3d/quaternion/quat3_to_matrix3.js";
3
+ import { v3_quat3_apply } from "../../../core/geom/vec3/v3_quat3_apply.js";
4
+ import { body_id_index } from "../body/BodyStorage.js";
5
+ import {
6
+ SBS_AV_X,
7
+ SBS_AV_Y,
8
+ SBS_AV_Z,
9
+ SBS_INV_I_X,
10
+ SBS_INV_I_Y,
11
+ SBS_INV_I_Z,
12
+ SBS_INV_MASS,
13
+ SBS_LV_X,
14
+ SBS_LV_Y,
15
+ SBS_LV_Z,
16
+ SBS_QW,
17
+ SBS_QX,
18
+ SBS_QY,
19
+ SBS_QZ,
20
+ SBS_STRIDE,
21
+ } from "../body/SolverBodyState.js";
22
+ import { JOINT_WORLD } from "../ecs/Joint.js";
23
+ import { SleepState } from "../ecs/SleepState.js";
24
+ import { world_inverse_inertia_apply_raw } from "../inertia/world_inverse_inertia.js";
25
+ import { DofMode } from "./DofMode.js";
26
+
27
+ /**
28
+ * # 6-DOF constraint (joint) solver
29
+ *
30
+ * Runs alongside the contact solver inside the same TGS substep loop: each
31
+ * substep the joints are warm-started and their velocity rows solved, sharing
32
+ * the contact solver's per-substep / warm-start / SPOOK-bias model so the two
33
+ * constraint families converge together (a body touched by both a contact and
34
+ * a joint sees a single coupled Gauss-Seidel sweep across the substep loop).
35
+ *
36
+ * A joint is a configurable 6-DOF constraint ({@link Joint}); each relative
37
+ * degree of freedom is independently locked / free / limited / springy /
38
+ * motorised. This module implements **LOCKED** and **LIMITED** DOFs (linear
39
+ * and angular). LOCKED + FREE express the ball-socket, hinge, weld, and
40
+ * prismatic joints; LIMITED adds slider end-stops and joint range-of-motion.
41
+ * Springs and motors slot into the same per-DOF row model as they land.
42
+ *
43
+ * ## One row model, parameterised by mode
44
+ *
45
+ * Every DOF resolves to the same scalar velocity row, contact-shaped: for a
46
+ * unit axis `d` and lever arms `rA = anchorA − comA`, `rB = anchorB − comB`,
47
+ * `K = invMA + invMB + (rA×d)·Iw_A·(rA×d) + (rB×d)·Iw_B·(rB×d)` (linear)
48
+ * `K = d·Iw_A·d + d·Iw_B·d` (angular)
49
+ * `vrel = (vA + ωA×rA − vB − ωB×rB) · d` (linear, A−B)
50
+ * `vrel = (ωB − ωA) · d` (angular, B−A)
51
+ * `λ = clamp(λ_acc − (1/K)·(vrel + bias)) − λ_acc`,
52
+ * applied as `±λ·d`. The **mode** picks only two row parameters:
53
+ * - LOCKED → `bias = β/h · error`, impulse clamp `(−∞, +∞)` (bilateral).
54
+ * - LIMITED → row active only when the DOF position is at/beyond a bound;
55
+ * `bias = β/h · (position − bound)`, impulse clamp one-sided
56
+ * (`[0, +∞)` at the lower stop, `(−∞, 0]` at the upper). The clamp makes
57
+ * it a unilateral push-out-of-violation constraint, exactly like a contact
58
+ * normal — the limit can only resist crossing the stop, never pull the DOF
59
+ * back into range.
60
+ * The warm-start and the iteration loop are mode-agnostic; they read the
61
+ * per-DOF `(active, effMass, bias, clampLo, clampHi)` filled by the mode-aware
62
+ * setup. Geometry (anchors / lever arms / position error) is recomputed from
63
+ * the current pose every substep, so the joint tracks the bodies as they move.
64
+ *
65
+ * The "position" along a DOF is `C · axis` for linear (signed anchor offset in
66
+ * metres) and `e · axis` for angular, where `e = 2·sign(qD.w)·qD.xyz` is the
67
+ * small-angle rotation vector of the relative rotation `qD = conj(qA)⊗qB`,
68
+ * expressed in frame-A-local coordinates (so error component `k` pairs with
69
+ * frame axis `k`). The angular position is therefore a first-order (small
70
+ * angle) measure: accurate for the modest ranges of slider/hinge end-stops,
71
+ * but it under-reports large angles (`2·sin(θ/2)` vs `θ`). Accurate wide-cone
72
+ * range-of-motion (ragdoll shoulders) needs the swing-twist decomposition,
73
+ * tracked as the follow-up; angular LIMITED here is the moderate-range cut.
74
+ * The decomposition itself is already implemented — reuse
75
+ * `Quaternion.computeSwingAndTwist(axis, swing, twist)` /
76
+ * `computeTwistAngle(axis)` (`core/geom/Quaternion.js`) on the relative
77
+ * rotation `qD` rather than writing a new one.
78
+ *
79
+ * @author Alex Goldring
80
+ * @copyright Company Named Limited (c) 2026
81
+ */
82
+
83
+ /**
84
+ * Maximum SPOOK position-correction bias for a joint row, m/s — belt-and-braces
85
+ * against a wildly-violated constraint (e.g. a freshly-teleported body)
86
+ * yanking the solve. Equality joints sit near zero error at steady state, so
87
+ * this only clamps transients.
88
+ * @type {number}
89
+ */
90
+ const MAX_JOINT_BIAS = 4;
91
+
92
+ /**
93
+ * Baumgarte / SPOOK position-correction gain `β`. The per-substep gain is
94
+ * `β / dt_sub`; with `β = 0.2` this matches the contact solver's position
95
+ * stiffness. Joints are bilateral equality constraints, so this only nudges
96
+ * residual position error toward zero (no clamp interplay to destabilise).
97
+ * @type {number}
98
+ */
99
+ const JOINT_BAUMGARTE = 0.2;
100
+
101
+ const scratch_inertia = new Float64Array(3);
102
+ const scratch_anchor = new Float64Array(3);
103
+ /** Frame-A world basis (rows = A's frame axes in world), from quat3_to_matrix3. */
104
+ const scratch_frame_a = new Float64Array(9);
105
+ /** Scratch quaternion for frame composition / relative rotation. */
106
+ const scratch_q = new Float64Array(4);
107
+ /** Angular position error `e` per frame axis (frame-A-local small-angle vector). */
108
+ const scratch_ang_err = new Float64Array(3);
109
+
110
+ // Per-DOF row parameters, filled per joint by the mode-aware setup and consumed
111
+ // by the mode-agnostic warm-start + iteration. Indexed 0..2 (the three frame
112
+ // axes); the linear set drives imp[0..2], the angular set drives imp[3..5].
113
+ const lin_active = new Uint8Array(3);
114
+ const lin_eff = new Float64Array(3);
115
+ const lin_bias = new Float64Array(3);
116
+ const lin_clo = new Float64Array(3);
117
+ const lin_chi = new Float64Array(3);
118
+ const lin_gamma = new Float64Array(3);
119
+ const ang_active = new Uint8Array(3);
120
+ const ang_eff = new Float64Array(3);
121
+ const ang_bias = new Float64Array(3);
122
+ const ang_clo = new Float64Array(3);
123
+ const ang_chi = new Float64Array(3);
124
+ const ang_gamma = new Float64Array(3);
125
+
126
+ // A2 (block solve) scratch: the coupled 3×3 effective-mass of a fully-LOCKED
127
+ // linear point constraint and its inverse, stored as the 6 symmetric entries
128
+ // [00, 01, 02, 11, 12, 22]; plus the per-body cross products `r×aₖ` and their
129
+ // inverse-inertia images `Iw⁻¹·(r×aₖ)`.
130
+ const lin_K = new Float64Array(6);
131
+ const lin_Kinv = new Float64Array(6);
132
+ const block_c = new Float64Array(9);
133
+ const block_w = new Float64Array(9);
134
+
135
+ /**
136
+ * Angular effective-mass contribution of one body about a unit world axis:
137
+ * `a · Iw⁻¹ · a`. Zero for non-dynamic / rotation-locked bodies (whose
138
+ * {@link SolverBodyState} inverse-inertia diagonal is zero).
139
+ * @param {Float64Array} ss solver-body-state data array
140
+ * @param {number} base `body_index * SBS_STRIDE`
141
+ * @returns {number}
142
+ */
143
+ function angular_axis_effective_mass(ss, base, ax, ay, az) {
144
+ const iix = ss[base + SBS_INV_I_X], iiy = ss[base + SBS_INV_I_Y], iiz = ss[base + SBS_INV_I_Z];
145
+ if (iix === 0 && iiy === 0 && iiz === 0) return 0;
146
+ world_inverse_inertia_apply_raw(scratch_inertia, 0, iix, iiy, iiz,
147
+ ss[base + SBS_QX], ss[base + SBS_QY], ss[base + SBS_QZ], ss[base + SBS_QW], ax, ay, az);
148
+ return ax * scratch_inertia[0] + ay * scratch_inertia[1] + az * scratch_inertia[2];
149
+ }
150
+
151
+ /**
152
+ * Apply a pure angular impulse `sign·λ·axis`: Δω = Iw⁻¹·(sign·λ·axis).
153
+ * @param {Float64Array} ss solver-body-state data array
154
+ * @param {number} base `body_index * SBS_STRIDE`
155
+ * @param {number} ax @param {number} ay @param {number} az
156
+ * @param {number} lambda @param {number} sign
157
+ */
158
+ function apply_angular_impulse(ss, base, ax, ay, az, lambda, sign) {
159
+ const iix = ss[base + SBS_INV_I_X], iiy = ss[base + SBS_INV_I_Y], iiz = ss[base + SBS_INV_I_Z];
160
+ if (iix === 0 && iiy === 0 && iiz === 0) return;
161
+ const L = sign * lambda;
162
+ world_inverse_inertia_apply_raw(scratch_inertia, 0, iix, iiy, iiz,
163
+ ss[base + SBS_QX], ss[base + SBS_QY], ss[base + SBS_QZ], ss[base + SBS_QW], ax * L, ay * L, az * L);
164
+ ss[base + SBS_AV_X] += scratch_inertia[0];
165
+ ss[base + SBS_AV_Y] += scratch_inertia[1];
166
+ ss[base + SBS_AV_Z] += scratch_inertia[2];
167
+ }
168
+
169
+ /**
170
+ * Effective-mass denominator contribution of one body along a unit axis:
171
+ * `invM + (r×d)·Iw⁻¹·(r×d)`. Static / kinematic bodies (invM === 0) contribute
172
+ * nothing.
173
+ *
174
+ * @param {Float64Array} ss solver-body-state data array
175
+ * @param {number} base `body_index * SBS_STRIDE`
176
+ * @param {number} invM
177
+ * @param {number} rx @param {number} ry @param {number} rz
178
+ * @param {number} dx @param {number} dy @param {number} dz
179
+ * @returns {number}
180
+ */
181
+ function axis_effective_mass(ss, base, invM, rx, ry, rz, dx, dy, dz) {
182
+ if (invM === 0) return 0;
183
+ let k = invM;
184
+ const iix = ss[base + SBS_INV_I_X], iiy = ss[base + SBS_INV_I_Y], iiz = ss[base + SBS_INV_I_Z];
185
+ if (iix !== 0 || iiy !== 0 || iiz !== 0) {
186
+ const cx = ry * dz - rz * dy;
187
+ const cy = rz * dx - rx * dz;
188
+ const cz = rx * dy - ry * dx;
189
+ world_inverse_inertia_apply_raw(scratch_inertia, 0, iix, iiy, iiz,
190
+ ss[base + SBS_QX], ss[base + SBS_QY], ss[base + SBS_QZ], ss[base + SBS_QW], cx, cy, cz);
191
+ k += cx * scratch_inertia[0] + cy * scratch_inertia[1] + cz * scratch_inertia[2];
192
+ }
193
+ return k;
194
+ }
195
+
196
+ /**
197
+ * Relative velocity of the joint anchors, A − B: each side's anchor-point
198
+ * velocity `v + ω × r` read from its SolverBodyState span; the B term is
199
+ * zero for a world anchor. Writes 3 floats into `out`. Expressions are
200
+ * verbatim from the three solver sites that previously inlined this, so
201
+ * outputs are bit-identical. Re-evaluated before every row on purpose —
202
+ * Gauss-Seidel rows must see the prior rows' impulses.
203
+ *
204
+ * @param {Float64Array} out length >= 3
205
+ * @param {Float64Array} ss solver-body-state data
206
+ * @param {number} baseA
207
+ * @param {number} rAx
208
+ * @param {number} rAy
209
+ * @param {number} rAz anchor lever on A
210
+ * @param {number} baseB
211
+ * @param {number} rBx
212
+ * @param {number} rBy
213
+ * @param {number} rBz anchor lever on B
214
+ * @param {boolean} to_world B is a fixed world anchor (no B term)
215
+ */
216
+ function relative_anchor_velocity(out, ss, baseA, rAx, rAy, rAz, baseB, rBx, rBy, rBz, to_world) {
217
+ out[0] = (ss[baseA + SBS_LV_X] + ss[baseA + SBS_AV_Y] * rAz - ss[baseA + SBS_AV_Z] * rAy) - (to_world ? 0 : (ss[baseB + SBS_LV_X] + ss[baseB + SBS_AV_Y] * rBz - ss[baseB + SBS_AV_Z] * rBy));
218
+ out[1] = (ss[baseA + SBS_LV_Y] + ss[baseA + SBS_AV_Z] * rAx - ss[baseA + SBS_AV_X] * rAz) - (to_world ? 0 : (ss[baseB + SBS_LV_Y] + ss[baseB + SBS_AV_Z] * rBx - ss[baseB + SBS_AV_X] * rBz));
219
+ out[2] = (ss[baseA + SBS_LV_Z] + ss[baseA + SBS_AV_X] * rAy - ss[baseA + SBS_AV_Y] * rAx) - (to_world ? 0 : (ss[baseB + SBS_LV_Z] + ss[baseB + SBS_AV_X] * rBy - ss[baseB + SBS_AV_Y] * rBx));
220
+ }
221
+
222
+ /** Destination for {@link relative_anchor_velocity}. */
223
+ const scratch_rv = new Float64Array(3);
224
+
225
+ /**
226
+ * Apply impulse `P` at body-relative offset `r`: Δv = P·invM, Δω = Iw⁻¹·(r×P).
227
+ * Reads / writes the body's {@link SolverBodyState} span.
228
+ *
229
+ * @param {Float64Array} ss solver-body-state data array
230
+ * @param {number} base `body_index * SBS_STRIDE`
231
+ * @param {number} invM
232
+ * @param {number} rx @param {number} ry @param {number} rz
233
+ * @param {number} Px @param {number} Py @param {number} Pz
234
+ * @param {number} sign +1 / −1
235
+ */
236
+ function apply_impulse(ss, base, invM, rx, ry, rz, Px, Py, Pz, sign) {
237
+ if (invM === 0) return;
238
+ const sPx = sign * Px, sPy = sign * Py, sPz = sign * Pz;
239
+ ss[base + SBS_LV_X] += sPx * invM;
240
+ ss[base + SBS_LV_Y] += sPy * invM;
241
+ ss[base + SBS_LV_Z] += sPz * invM;
242
+
243
+ const tx = ry * sPz - rz * sPy;
244
+ const ty = rz * sPx - rx * sPz;
245
+ const tz = rx * sPy - ry * sPx;
246
+ world_inverse_inertia_apply_raw(scratch_inertia, 0,
247
+ ss[base + SBS_INV_I_X], ss[base + SBS_INV_I_Y], ss[base + SBS_INV_I_Z],
248
+ ss[base + SBS_QX], ss[base + SBS_QY], ss[base + SBS_QZ], ss[base + SBS_QW], tx, ty, tz);
249
+ ss[base + SBS_AV_X] += scratch_inertia[0];
250
+ ss[base + SBS_AV_Y] += scratch_inertia[1];
251
+ ss[base + SBS_AV_Z] += scratch_inertia[2];
252
+ }
253
+
254
+ /**
255
+ * Clamp the SPOOK position bias to ±{@link MAX_JOINT_BIAS}.
256
+ * @param {number} b @returns {number}
257
+ */
258
+ function clamp_bias(b) {
259
+ if (b > MAX_JOINT_BIAS) return MAX_JOINT_BIAS;
260
+ if (b < -MAX_JOINT_BIAS) return -MAX_JOINT_BIAS;
261
+ return b;
262
+ }
263
+
264
+ /**
265
+ * A2 — accumulate one body's angular contribution to the 3×3 point-constraint
266
+ * effective-mass block `K` (frame axes): for each frame axis `aₖ`,
267
+ * `cₖ = r×aₖ` and `wₖ = Iw⁻¹·cₖ`, then `K_kl += cₖ·w_l`. Symmetric, so only the
268
+ * upper triangle is written. Rotation-locked / non-dynamic bodies (zero inverse
269
+ * inertia) add nothing. The mass term `(invMA+invMB)·I` is seeded by the caller.
270
+ *
271
+ * @param {Float64Array} ss @param {number} base
272
+ * @param {number} rx @param {number} ry @param {number} rz lever arm
273
+ * @param {Float64Array} fa frame-A world basis (rows = axes)
274
+ * @param {Float64Array} K length-6 symmetric accumulator [00,01,02,11,12,22]
275
+ */
276
+ function accumulate_point_block(ss, base, rx, ry, rz, fa, K) {
277
+ const iix = ss[base + SBS_INV_I_X], iiy = ss[base + SBS_INV_I_Y], iiz = ss[base + SBS_INV_I_Z];
278
+ if (iix === 0 && iiy === 0 && iiz === 0) return;
279
+ const qx = ss[base + SBS_QX], qy = ss[base + SBS_QY], qz = ss[base + SBS_QZ], qw = ss[base + SBS_QW];
280
+ for (let k = 0; k < 3; k++) {
281
+ const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
282
+ const cx = ry * az - rz * ay, cy = rz * ax - rx * az, cz = rx * ay - ry * ax;
283
+ block_c[3 * k] = cx; block_c[3 * k + 1] = cy; block_c[3 * k + 2] = cz;
284
+ world_inverse_inertia_apply_raw(block_w, 3 * k, iix, iiy, iiz, qx, qy, qz, qw, cx, cy, cz);
285
+ }
286
+ K[0] += block_c[0] * block_w[0] + block_c[1] * block_w[1] + block_c[2] * block_w[2];
287
+ K[1] += block_c[0] * block_w[3] + block_c[1] * block_w[4] + block_c[2] * block_w[5];
288
+ K[2] += block_c[0] * block_w[6] + block_c[1] * block_w[7] + block_c[2] * block_w[8];
289
+ K[3] += block_c[3] * block_w[3] + block_c[4] * block_w[4] + block_c[5] * block_w[5];
290
+ K[4] += block_c[3] * block_w[6] + block_c[4] * block_w[7] + block_c[5] * block_w[8];
291
+ K[5] += block_c[6] * block_w[6] + block_c[7] * block_w[7] + block_c[8] * block_w[8];
292
+ }
293
+
294
+ /**
295
+ * Invert a symmetric positive-definite 3×3 (6-entry form) in closed form,
296
+ * writing the inverse (same 6-entry form) to `out`. Returns the determinant; a
297
+ * near-singular block (|det| < 1e-12) returns 0 and leaves `out` untouched so
298
+ * the caller falls back to the per-axis solve.
299
+ *
300
+ * @param {Float64Array} K [00,01,02,11,12,22] @param {Float64Array} out
301
+ * @returns {number} determinant
302
+ */
303
+ function invert_sym3(K, out) {
304
+ const a = K[0], b = K[1], c = K[2], d = K[3], e = K[4], f = K[5];
305
+ const A00 = d * f - e * e, A01 = c * e - b * f, A02 = b * e - c * d;
306
+ const A11 = a * f - c * c, A12 = b * c - a * e, A22 = a * d - b * b;
307
+ const det = a * A00 + b * A01 + c * A02;
308
+ if (det < 1e-12 && det > -1e-12) return 0;
309
+ const inv = 1 / det;
310
+ out[0] = A00 * inv; out[1] = A01 * inv; out[2] = A02 * inv;
311
+ out[3] = A11 * inv; out[4] = A12 * inv; out[5] = A22 * inv;
312
+ return det;
313
+ }
314
+
315
+ /**
316
+ * Swing-twist decomposition of the relative rotation `qD = conj(qA)⊗qB`, giving
317
+ * the per-frame-axis angular positions used by wide-cone angular DOFs.
318
+ *
319
+ * Decomposes `qD = swing ⊗ twist`, with **twist** the rotation about frame
320
+ * axis X (the bone / twist axis) and **swing** the residual tilt (a rotation
321
+ * about an axis in the YZ plane that carries X to its new direction). Writes,
322
+ * into `out`:
323
+ * - `out[0]` = signed twist angle about X, in `(−π, π]` *exact*, so a twist
324
+ * limit engages at the true angle, not the `2·sin(θ/2)` small-angle proxy;
325
+ * - `out[1]`, `out[2]` = the swing angle distributed over Y and Z
326
+ * (`φ·axis`, φ the true swing angle), so independent Y/Z swing limits form
327
+ * an accurate (box-shaped) cone that holds at large tilt.
328
+ * Reduces continuously to the small-angle vector near identity. Pure scratch /
329
+ * locals no allocation, suitable for the per-substep hot loop. (The Quaternion
330
+ * class has an object-based `computeSwingAndTwist`; this is the inlined,
331
+ * allocation-free form see the bench that justifies it.)
332
+ *
333
+ * @param {number} dx @param {number} dy @param {number} dz @param {number} dw qD
334
+ * @param {Float64Array} out length-3 destination (frame-axis positions)
335
+ */
336
+ export function swing_twist_error(dx, dy, dz, dw, out) {
337
+ // Shortest arc: work with the hemisphere where dw 0.
338
+ if (dw < 0) { dx = -dx; dy = -dy; dz = -dz; dw = -dw; }
339
+
340
+ const nxt = Math.sqrt(dx * dx + dw * dw); // |twist| (before normalising)
341
+ let sy, sz, sw;
342
+ if (nxt < 1e-12) {
343
+ // dw 0 and dx 0: a ~180° pure swing — twist is undefined, take 0.
344
+ out[0] = 0;
345
+ // Swing is qD itself; distribute its angle over Y/Z below.
346
+ sy = dy; sz = dz; sw = dw;
347
+ } else {
348
+ out[0] = 2 * Math.atan2(dx, dw); // exact signed twist about X
349
+ const tx = dx / nxt, tw = dw / nxt; // normalised twist (tx,0,0,tw)
350
+ // swing = qD conj(twist); its X component is identically 0.
351
+ sy = dy * tw - dz * tx;
352
+ sz = dy * tx + dz * tw;
353
+ sw = dw * tw + dx * tx;
354
+ }
355
+
356
+ if (sw < 0) { sy = -sy; sz = -sz; sw = -sw; }
357
+ const syz = Math.sqrt(sy * sy + sz * sz);
358
+ if (syz < 1e-9) {
359
+ // Near-zero swing: small-angle vector (continuous with φ·axis as φ→0).
360
+ out[1] = 2 * sy;
361
+ out[2] = 2 * sz;
362
+ } else {
363
+ const phi = 2 * Math.atan2(syz, sw); // exact swing angle in [0, π]
364
+ const s = phi / syz;
365
+ out[1] = sy * s;
366
+ out[2] = sz * s;
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Fill the row parameters for one DOF given its mode, signed position and
372
+ * signed velocity.
373
+ *
374
+ * Writes `active / eff / bias / clampLo / clampHi` at index `k` of the supplied
375
+ * arrays and, for LIMITED, resets the warm-start impulse when the active bound
376
+ * flipped (a stale opposite-side impulse must not warm-start).
377
+ *
378
+ * ## LIMITED is a speculative = 1) one-sided velocity constraint
379
+ *
380
+ * Rather than waiting for the DOF to cross a stop and then pushing back with a
381
+ * Baumgarte bias — which injects real velocity and makes the stop *bounce* when
382
+ * nothing else loads the joint the limit row is always live and uses the full
383
+ * `(position bound)/h` as its bias. With the impulse clamped to one side this
384
+ * removes exactly the approach velocity that would overshoot, so the DOF
385
+ * **lands on the bound** with zero relative velocity (an inelastic stop, no
386
+ * penetration to recover, no rebound). When the DOF is far from the bound the
387
+ * large same-signed bias drives the clamp to zero, so the row is a no-op — it
388
+ * self-gates on approach. At a stop held by a sustained load (gravity on a
389
+ * slider) the per-substep load and the per-substep warm-start cancel, so the
390
+ * DOF rests exactly on the bound, mirroring a resting contact.
391
+ *
392
+ * Only the *push-out* side of the bias is clamped (to {@link MAX_JOINT_BIAS}),
393
+ * so a body teleported deep past a stop is eased out rather than yanked; the
394
+ * gating side is left unbounded.
395
+ *
396
+ * The active bound is the violated one, else — within range — the one the DOF
397
+ * is moving toward (`vel` sign). LOCKED is unchanged: a bilateral row with a
398
+ * `β/h` Baumgarte bias and no clamp.
399
+ *
400
+ * ## MOTOR drives the relative velocity toward a target
401
+ *
402
+ * A motor is a velocity row biased to the target (`bias = −target`, so the
403
+ * solve drives the relative velocity to the target) with the impulse clamped to
404
+ * `±maxForce·h` a force-limited servo. With an unbounded force budget it is a
405
+ * perfect velocity drive; with a finite one it pulls toward the target as hard
406
+ * as it can (a weak motor cannot overcome a heavier load). The target follows
407
+ * the row's sign convention: linear is A−B along the frame axis, angular is
408
+ * B−A about it.
409
+ *
410
+ * ## SPRING is a SPOOK soft (compliant) constraint
411
+ *
412
+ * A spring drives the DOF position toward zero with stiffness `k` (N/m or
413
+ * N·m/rad) and damping `c`, as a *regularised* row rather than a hard one. The
414
+ * implicit-Euler soft constraint (Catto, "Soft Constraints") gives, per substep
415
+ * `h`, with `denom = c + h·k`:
416
+ * `γ = 1 / (h·denom)` the compliance / regularisation (inverse mass),
417
+ * `bias = (k/denom)·C` the restoring velocity, and a softened effective
418
+ * `effMass = 1/(K + γ)` mass so the row solves
419
+ * `λ = −effMass·(vrel + bias + γ·λ_accum)`.
420
+ * The `γ·λ_accum` term is what makes it compliant (the constraint yields in
421
+ * proportion to the force it carries), so a spring under load settles at a
422
+ * deflection rather than snapping rigid. Stiffness-only (`c = 0`) oscillates
423
+ * undamped; damping-only (`k = 0`) is a pure damper; both zero is inert. The
424
+ * row is bilateral (no clamp). This is the suspension / bungee / soft-return
425
+ * element, and the soft basis for cone-twist later. The angular position uses
426
+ * the same small-angle measure as LIMITED (good for modest ranges).
427
+ *
428
+ * @param {Joint} joint the joint (per-DOF config + warm-start impulse read here)
429
+ * @param {number} dofIndex DOF 0..5 (selects mode / limits / motor / imp slot)
430
+ * @param {number} k axis index 0..2 (output-array slot for this DOF group)
431
+ * @param {number} keff raw effective-mass denominator `K` (0 ⇒ no row); the
432
+ * row's effective mass is `1/K`, or `1/(K+γ)` softened for a spring.
433
+ * @param {number} pos signed DOF position (`C·axis` linear / `e·axis` angular)
434
+ * @param {number} vel signed DOF velocity along the same axis (selects the
435
+ * approached bound for an in-range LIMITED DOF)
436
+ * @param {number} spook_locked Baumgarte gain `β / dt_sub` (LOCKED)
437
+ * @param {number} spook_spec speculative gain `1 / dt_sub` (LIMITED)
438
+ * @param {number} dt_sub substep size (MOTOR impulse cap = `maxForce·dt_sub`;
439
+ * SPRING compliance derives from it)
440
+ * @param {Uint8Array} active @param {Float64Array} effOut
441
+ * @param {Float64Array} biasOut @param {Float64Array} cloOut @param {Float64Array} chiOut
442
+ * @param {Float64Array} gammaOut per-row regularisation (0 for non-spring rows)
443
+ */
444
+ function fill_row(joint, dofIndex, k, keff, pos, vel, spook_locked, spook_spec, dt_sub,
445
+ active, effOut, biasOut, cloOut, chiOut, gammaOut) {
446
+ const mode = joint.dofMode[dofIndex];
447
+ const imp = joint.dofImpulse;
448
+
449
+ if (mode === DofMode.LOCKED) {
450
+ if (keff === 0) { active[k] = 0; return; }
451
+ effOut[k] = 1 / keff;
452
+ biasOut[k] = clamp_bias(spook_locked * pos);
453
+ cloOut[k] = -Infinity;
454
+ chiOut[k] = Infinity;
455
+ gammaOut[k] = 0;
456
+ active[k] = 1;
457
+ return;
458
+ }
459
+ if (mode === DofMode.LIMITED) {
460
+ if (keff === 0) { imp[dofIndex] = 0; active[k] = 0; return; }
461
+ const lower = joint.dofLowerLimit[dofIndex];
462
+ const upper = joint.dofUpperLimit[dofIndex];
463
+ // Select the bound: the violated one, else the one being approached.
464
+ let bound, lower_side;
465
+ if (pos <= lower) { bound = lower; lower_side = true; }
466
+ else if (pos >= upper) { bound = upper; lower_side = false; }
467
+ else { lower_side = vel <= 0; bound = lower_side ? lower : upper; }
468
+
469
+ let b = spook_spec * (pos - bound);
470
+ if (lower_side) {
471
+ // Lower stop: impulse pushes the DOF up (+), clamp [0, +∞). The
472
+ // push-out side of the bias is the negative one bound it.
473
+ cloOut[k] = 0; chiOut[k] = Infinity;
474
+ if (imp[dofIndex] < 0) imp[dofIndex] = 0; // drop stale upper-side impulse
475
+ if (b < -MAX_JOINT_BIAS) b = -MAX_JOINT_BIAS;
476
+ } else {
477
+ // Upper stop: impulse pushes the DOF down (−), clamp (−∞, 0]. The
478
+ // push-out side of the bias is the positive one — bound it.
479
+ cloOut[k] = -Infinity; chiOut[k] = 0;
480
+ if (imp[dofIndex] > 0) imp[dofIndex] = 0; // drop stale lower-side impulse
481
+ if (b > MAX_JOINT_BIAS) b = MAX_JOINT_BIAS;
482
+ }
483
+ effOut[k] = 1 / keff;
484
+ biasOut[k] = b;
485
+ gammaOut[k] = 0;
486
+ active[k] = 1;
487
+ return;
488
+ }
489
+ if (mode === DofMode.MOTOR) {
490
+ if (keff === 0) { imp[dofIndex] = 0; active[k] = 0; return; }
491
+ const maxImpulse = joint.dofMotorMaxForce[dofIndex] * dt_sub;
492
+ if (maxImpulse <= 0) { imp[dofIndex] = 0; active[k] = 0; return; }
493
+ effOut[k] = 1 / keff;
494
+ // Drive the relative velocity to the target: λ = −eff·(vrel target).
495
+ biasOut[k] = -joint.dofMotorTargetVelocity[dofIndex];
496
+ cloOut[k] = -maxImpulse;
497
+ chiOut[k] = maxImpulse;
498
+ gammaOut[k] = 0;
499
+ active[k] = 1;
500
+ return;
501
+ }
502
+ if (mode === DofMode.SPRING) {
503
+ if (keff === 0) { imp[dofIndex] = 0; active[k] = 0; return; }
504
+ const ks = joint.dofStiffness[dofIndex];
505
+ const cs = joint.dofDamping[dofIndex];
506
+ const denom = cs + dt_sub * ks;
507
+ if (denom <= 0) { imp[dofIndex] = 0; active[k] = 0; return; } // inert (no k, no c)
508
+ const gamma = 1 / (dt_sub * denom);
509
+ effOut[k] = 1 / (keff + gamma);
510
+ biasOut[k] = (ks / denom) * pos; // restoring velocity toward pos = 0
511
+ cloOut[k] = -Infinity;
512
+ chiOut[k] = Infinity;
513
+ gammaOut[k] = gamma;
514
+ active[k] = 1;
515
+ return;
516
+ }
517
+ // FREE: no row this substep.
518
+ imp[dofIndex] = 0;
519
+ active[k] = 0;
520
+ }
521
+
522
+ /**
523
+ * Solve every joint for one substep: recompute geometry at the current poses,
524
+ * derive each DOF's row parameters from its mode, replay the per-substep
525
+ * warm-start, and run `iters` velocity iterations.
526
+ *
527
+ * Called once per substep from `PhysicsSystem.fixedUpdate`, after the contact
528
+ * solve so the two share the substep / warm-start cadence.
529
+ *
530
+ * @param {Joint[]} joints live joints (sparse array; holes skipped)
531
+ * @param {PhysicsSystem} system reads `__bodies` / `__transforms` / index map
532
+ * @param {number} dt_sub substep size in seconds (the SPOOK gain is derived
533
+ * from it, matching the contact solver's per-substep position stiffness)
534
+ * @param {number} iters velocity iterations
535
+ * @param {boolean} [reverse] A2: traverse the joint array tip→root this call
536
+ * (the caller alternates it per substep for a symmetric Gauss-Seidel sweep, so
537
+ * chain impulses propagate both ways). Default false original root→tip order.
538
+ */
539
+ export function solve_joints(joints, system, dt_sub, iters, reverse) {
540
+ const n = joints.length;
541
+ if (n === 0 || dt_sub <= 0) return;
542
+
543
+ const spook_locked = JOINT_BAUMGARTE / dt_sub;
544
+ const spook_spec = 1 / dt_sub;
545
+
546
+ const storage = system.storage;
547
+ const ss = system.__solver_state.data;
548
+
549
+ for (let jj = 0; jj < n; jj++) {
550
+ const ji = reverse ? (n - 1 - jj) : jj;
551
+ const joint = joints[ji];
552
+ if (joint === undefined || joint === null) continue;
553
+
554
+ // Generation-checked validity: if A's body was unlinked (and its slot
555
+ // possibly reused by a different body), the stored packed id no longer
556
+ // validates skip the stale joint rather than attach to the wrong body.
557
+ if (!storage.is_valid(joint._bodyIdA)) continue;
558
+ const idxA = body_id_index(joint._bodyIdA);
559
+ const baseA = idxA * SBS_STRIDE;
560
+ const rbA = system.__bodies[idxA];
561
+ if (rbA === undefined) continue;
562
+ const trA = system.__transforms[idxA];
563
+
564
+ const to_world = joint._bodyIdB === JOINT_WORLD;
565
+ let rbB = null, trB = null, idxB = -1, baseB = -1;
566
+ if (!to_world) {
567
+ if (!storage.is_valid(joint._bodyIdB)) continue;
568
+ idxB = body_id_index(joint._bodyIdB);
569
+ baseB = idxB * SBS_STRIDE;
570
+ rbB = system.__bodies[idxB];
571
+ if (rbB === undefined) continue;
572
+ trB = system.__transforms[idxB];
573
+ }
574
+
575
+ // Skip while a participating dynamic body sleeps its velocity must
576
+ // stay zero until woken. (Island-aware joint sleep is a follow-up; for
577
+ // now jointed bodies that should stay coupled use DisableSleep.)
578
+ if (rbA.sleepState === SleepState.Sleeping) continue;
579
+ if (!to_world && rbB.sleepState === SleepState.Sleeping) continue;
580
+
581
+ // Both bodies static/kinematicnothing to solve.
582
+ const invMA = ss[baseA + SBS_INV_MASS];
583
+ const invMB = to_world ? 0 : ss[baseB + SBS_INV_MASS];
584
+ if (invMA === 0 && invMB === 0) continue;
585
+
586
+ const mode = joint.dofMode;
587
+ const linConstrained = mode[0] !== DofMode.FREE || mode[1] !== DofMode.FREE || mode[2] !== DofMode.FREE;
588
+ const angConstrained = mode[3] !== DofMode.FREE || mode[4] !== DofMode.FREE || mode[5] !== DofMode.FREE;
589
+ if (!linConstrained && !angConstrained) continue;
590
+
591
+ // World anchor A and its lever arm rA = R_A · localAnchorA.
592
+ const la = joint.localAnchorA;
593
+ v3_quat3_apply(scratch_anchor, 0, la.x, la.y, la.z,
594
+ trA.rotation[0], trA.rotation[1], trA.rotation[2], trA.rotation[3]);
595
+ const rAx = scratch_anchor[0], rAy = scratch_anchor[1], rAz = scratch_anchor[2];
596
+ const anchorAx = trA.position.x + rAx;
597
+ const anchorAy = trA.position.y + rAy;
598
+ const anchorAz = trA.position.z + rAz;
599
+
600
+ // World anchor B + lever arm rB. For a world anchor, localAnchorB is a
601
+ // fixed world point and there is no body B lever.
602
+ let rBx = 0, rBy = 0, rBz = 0;
603
+ let anchorBx, anchorBy, anchorBz;
604
+ const lb = joint.localAnchorB;
605
+ if (to_world) {
606
+ anchorBx = lb.x; anchorBy = lb.y; anchorBz = lb.z;
607
+ } else {
608
+ v3_quat3_apply(scratch_anchor, 0, lb.x, lb.y, lb.z,
609
+ trB.rotation[0], trB.rotation[1], trB.rotation[2], trB.rotation[3]);
610
+ rBx = scratch_anchor[0]; rBy = scratch_anchor[1]; rBz = scratch_anchor[2];
611
+ anchorBx = trB.position.x + rBx;
612
+ anchorBy = trB.position.y + rBy;
613
+ anchorBz = trB.position.z + rBz;
614
+ }
615
+
616
+ // Position error C = anchorA − anchorB (its projection on a frame axis
617
+ // is the signed DOF offset; locked axes drive it to zero, limited axes
618
+ // bound it).
619
+ const Cx = anchorAx - anchorBx;
620
+ const Cy = anchorAy - anchorBy;
621
+ const Cz = anchorAz - anchorBz;
622
+
623
+ const imp = joint.dofImpulse;
624
+
625
+ // === Frame A world axes shared by the linear AND angular rows ===
626
+ // Every DOF is expressed in the joint's frame on body A. Frame A =
627
+ // body-A rotation localBasisA; the rows of its matrix are the frame
628
+ // axes in world (see quat3_to_matrix3).
629
+ const lba = joint.localBasisA;
630
+ quat3_multiply(scratch_q, 0, trA.rotation[0], trA.rotation[1], trA.rotation[2], trA.rotation[3], lba[0], lba[1], lba[2], lba[3]);
631
+ const qAx = scratch_q[0], qAy = scratch_q[1], qAz = scratch_q[2], qAw = scratch_q[3];
632
+ quat3_to_matrix3(scratch_frame_a, 0, qAx, qAy, qAz, qAw);
633
+ const fa = scratch_frame_a;
634
+
635
+ // --- Linear DOF row setup (frame axes). Position along axis k is
636
+ // `C · axis_k`; convention is A−B (impulse +to A / −to B). ---
637
+ let useLinBlock = false;
638
+ if (linConstrained) {
639
+ // A2: a fully-LOCKED linear triple is a ball-socket point — solve it
640
+ // as one coupled 3×3 block (frame axes) instead of axis-by-axis,
641
+ // removing the intra-joint coupling error the sequential per-axis
642
+ // Gauss-Seidel leaves behind. Falls back to per-axis if the block is
643
+ // near-singular.
644
+ if (mode[0] === DofMode.LOCKED && mode[1] === DofMode.LOCKED && mode[2] === DofMode.LOCKED) {
645
+ lin_K[0] = lin_K[3] = lin_K[5] = invMA + invMB;
646
+ lin_K[1] = lin_K[2] = lin_K[4] = 0;
647
+ accumulate_point_block(ss, baseA, rAx, rAy, rAz, fa, lin_K);
648
+ if (!to_world) accumulate_point_block(ss, baseB, rBx, rBy, rBz, fa, lin_K);
649
+ if (invert_sym3(lin_K, lin_Kinv) !== 0) {
650
+ for (let k = 0; k < 3; k++) {
651
+ const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
652
+ lin_bias[k] = clamp_bias(spook_locked * (Cx * ax + Cy * ay + Cz * az));
653
+ lin_active[k] = 1;
654
+ }
655
+ useLinBlock = true;
656
+ }
657
+ }
658
+ if (!useLinBlock) {
659
+ for (let k = 0; k < 3; k++) {
660
+ lin_active[k] = 0;
661
+ const m = mode[k];
662
+ if (m === DofMode.FREE) { imp[k] = 0; continue; }
663
+ const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
664
+ const keff = axis_effective_mass(ss, baseA, invMA, rAx, rAy, rAz, ax, ay, az)
665
+ + (to_world ? 0 : axis_effective_mass(ss, baseB, invMB, rBx, rBy, rBz, ax, ay, az));
666
+ const pos = Cx * ax + Cy * ay + Cz * az;
667
+ // Relative anchor velocity along the axis (A−B), for LIMITED
668
+ // bound selection. Cheap; only the projection is used.
669
+ let vel = 0;
670
+ if (m === DofMode.LIMITED) {
671
+ relative_anchor_velocity(scratch_rv, ss, baseA, rAx, rAy, rAz, baseB, rBx, rBy, rBz, to_world);
672
+ vel = scratch_rv[0] * ax + scratch_rv[1] * ay + scratch_rv[2] * az;
673
+ }
674
+ fill_row(joint, k, k, keff, pos, vel, spook_locked, spook_spec, dt_sub,
675
+ lin_active, lin_eff, lin_bias, lin_clo, lin_chi, lin_gamma);
676
+ }
677
+ }
678
+ } else {
679
+ lin_active[0] = lin_active[1] = lin_active[2] = 0;
680
+ }
681
+
682
+ // --- Angular DOF row setup (frame axes). Position along axis k is the
683
+ // k-th component of the frame-local small-angle error vector `e`;
684
+ // convention is B−A (impulse +to B / −to A). ---
685
+ if (angConstrained) {
686
+ // Frame B world rotation (identity for a world anchor locks A's
687
+ // frame to world axes).
688
+ let qBx = 0, qBy = 0, qBz = 0, qBw = 1;
689
+ if (!to_world) {
690
+ const lbb = joint.localBasisB;
691
+ quat3_multiply(scratch_q, 0, trB.rotation[0], trB.rotation[1], trB.rotation[2], trB.rotation[3], lbb[0], lbb[1], lbb[2], lbb[3]);
692
+ qBx = scratch_q[0]; qBy = scratch_q[1]; qBz = scratch_q[2]; qBw = scratch_q[3];
693
+ }
694
+ // qD = conj(qA) ⊗ qB → the per-axis angular position in frame-A
695
+ // coords. Two measures: the cheap small-angle rotation vector
696
+ // (default — exact at the origin, fine for welds / hinges / modest
697
+ // limits) or, when the joint opts into `swingTwist`, the swing-twist
698
+ // decomposition (X = twist, Y/Z = swing) with *exact* angles, for
699
+ // wide cone-twist range-of-motion (ragdoll shoulders) where the
700
+ // small-angle measure under-reports.
701
+ quat3_multiply(scratch_q, 0, -qAx, -qAy, -qAz, qAw, qBx, qBy, qBz, qBw);
702
+ if (joint.swingTwist) {
703
+ swing_twist_error(scratch_q[0], scratch_q[1], scratch_q[2], scratch_q[3], scratch_ang_err);
704
+ } else {
705
+ const es = scratch_q[3] < 0 ? -2 : 2;
706
+ scratch_ang_err[0] = es * scratch_q[0];
707
+ scratch_ang_err[1] = es * scratch_q[1];
708
+ scratch_ang_err[2] = es * scratch_q[2];
709
+ }
710
+
711
+ for (let k = 0; k < 3; k++) {
712
+ ang_active[k] = 0;
713
+ const m = mode[3 + k];
714
+ if (m === DofMode.FREE) { imp[3 + k] = 0; continue; }
715
+ const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
716
+ const keff = angular_axis_effective_mass(ss, baseA, ax, ay, az)
717
+ + (to_world ? 0 : angular_axis_effective_mass(ss, baseB, ax, ay, az));
718
+ const pos = scratch_ang_err[k];
719
+ // Relative angular velocity about the axis (B−A), for LIMITED
720
+ // bound selection.
721
+ let vel = 0;
722
+ if (m === DofMode.LIMITED) {
723
+ vel = -(ss[baseA + SBS_AV_X] * ax + ss[baseA + SBS_AV_Y] * ay + ss[baseA + SBS_AV_Z] * az);
724
+ if (!to_world) vel += ss[baseB + SBS_AV_X] * ax + ss[baseB + SBS_AV_Y] * ay + ss[baseB + SBS_AV_Z] * az;
725
+ }
726
+ fill_row(joint, 3 + k, k, keff, pos, vel, spook_locked, spook_spec, dt_sub,
727
+ ang_active, ang_eff, ang_bias, ang_clo, ang_chi, ang_gamma);
728
+ }
729
+ } else {
730
+ ang_active[0] = ang_active[1] = ang_active[2] = 0;
731
+ }
732
+
733
+ if (!lin_active[0] && !lin_active[1] && !lin_active[2]
734
+ && !ang_active[0] && !ang_active[1] && !ang_active[2]) continue;
735
+
736
+ // --- Per-substep warm-start (frame axes): linear impulse `Σ imp[k]·aₖ`
737
+ // applied at the anchors, angular impulse `Σ imp[3+k]·aₖ` about the
738
+ // frame axes (+to B / −to A). ---
739
+ {
740
+ let Px = 0, Py = 0, Pz = 0;
741
+ for (let k = 0; k < 3; k++) {
742
+ if (!lin_active[k]) continue;
743
+ const w = imp[k];
744
+ Px += w * fa[3 * k]; Py += w * fa[3 * k + 1]; Pz += w * fa[3 * k + 2];
745
+ }
746
+ if (Px !== 0 || Py !== 0 || Pz !== 0) {
747
+ apply_impulse(ss, baseA, invMA, rAx, rAy, rAz, Px, Py, Pz, +1);
748
+ if (!to_world) apply_impulse(ss, baseB, invMB, rBx, rBy, rBz, Px, Py, Pz, -1);
749
+ }
750
+ let Lx = 0, Ly = 0, Lz = 0;
751
+ for (let k = 0; k < 3; k++) {
752
+ if (!ang_active[k]) continue;
753
+ const w = imp[3 + k];
754
+ Lx += w * fa[3 * k]; Ly += w * fa[3 * k + 1]; Lz += w * fa[3 * k + 2];
755
+ }
756
+ if (Lx !== 0 || Ly !== 0 || Lz !== 0) {
757
+ if (!to_world) apply_angular_impulse(ss, baseB, Lx, Ly, Lz, 1, +1);
758
+ apply_angular_impulse(ss, baseA, Lx, Ly, Lz, 1, -1);
759
+ }
760
+ }
761
+
762
+ for (let it = 0; it < iters; it++) {
763
+ // Linear rows (frame axes). The relative anchor velocity is
764
+ // recomputed before each row so successive rows see the prior
765
+ // impulses (Gauss-Seidel coupling).
766
+ if (useLinBlock) {
767
+ // A2: coupled 3×3 point solve — one relative anchor velocity,
768
+ // projected onto the frame axes, solved against Kⁱⁿᵛ in a single
769
+ // Newton step (bilateral, no clamp). The point constraint is
770
+ // satisfied exactly each iteration; only its coupling with the
771
+ // angular rows remains to iterate.
772
+ relative_anchor_velocity(scratch_rv, ss, baseA, rAx, rAy, rAz, baseB, rBx, rBy, rBz, to_world);
773
+ const rvx = scratch_rv[0], rvy = scratch_rv[1], rvz = scratch_rv[2];
774
+ const a0x = fa[0], a0y = fa[1], a0z = fa[2];
775
+ const a1x = fa[3], a1y = fa[4], a1z = fa[5];
776
+ const a2x = fa[6], a2y = fa[7], a2z = fa[8];
777
+ const b0 = rvx * a0x + rvy * a0y + rvz * a0z + lin_bias[0];
778
+ const b1 = rvx * a1x + rvy * a1y + rvz * a1z + lin_bias[1];
779
+ const b2 = rvx * a2x + rvy * a2y + rvz * a2z + lin_bias[2];
780
+ const d0 = -(lin_Kinv[0] * b0 + lin_Kinv[1] * b1 + lin_Kinv[2] * b2);
781
+ const d1 = -(lin_Kinv[1] * b0 + lin_Kinv[3] * b1 + lin_Kinv[4] * b2);
782
+ const d2 = -(lin_Kinv[2] * b0 + lin_Kinv[4] * b1 + lin_Kinv[5] * b2);
783
+ imp[0] += d0; imp[1] += d1; imp[2] += d2;
784
+ const Px = d0 * a0x + d1 * a1x + d2 * a2x;
785
+ const Py = d0 * a0y + d1 * a1y + d2 * a2y;
786
+ const Pz = d0 * a0z + d1 * a1z + d2 * a2z;
787
+ if (Px !== 0 || Py !== 0 || Pz !== 0) {
788
+ apply_impulse(ss, baseA, invMA, rAx, rAy, rAz, Px, Py, Pz, +1);
789
+ if (!to_world) apply_impulse(ss, baseB, invMB, rBx, rBy, rBz, Px, Py, Pz, -1);
790
+ }
791
+ } else {
792
+ for (let k = 0; k < 3; k++) {
793
+ if (!lin_active[k]) continue;
794
+ const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
795
+ relative_anchor_velocity(scratch_rv, ss, baseA, rAx, rAy, rAz, baseB, rBx, rBy, rBz, to_world);
796
+ const rvx = scratch_rv[0], rvy = scratch_rv[1], rvz = scratch_rv[2];
797
+ const vrel = rvx * ax + rvy * ay + rvz * az;
798
+ const old = imp[k];
799
+ // `+ γ·old` regularises a spring row (γ = 0 otherwise → exact).
800
+ let nv = old - lin_eff[k] * (vrel + lin_bias[k] + lin_gamma[k] * old);
801
+ if (nv < lin_clo[k]) nv = lin_clo[k]; else if (nv > lin_chi[k]) nv = lin_chi[k];
802
+ imp[k] = nv;
803
+ const d = nv - old;
804
+ if (d !== 0) {
805
+ apply_impulse(ss, baseA, invMA, rAx, rAy, rAz, d * ax, d * ay, d * az, +1);
806
+ if (!to_world) apply_impulse(ss, baseB, invMB, rBx, rBy, rBz, d * ax, d * ay, d * az, -1);
807
+ }
808
+ }
809
+ }
810
+
811
+ // Angular rows (frame axes): drive ωB−ωA about each axis toward the
812
+ // bias target, clamped per the row's bound.
813
+ for (let k = 0; k < 3; k++) {
814
+ if (!ang_active[k]) continue;
815
+ const ax = fa[3 * k], ay = fa[3 * k + 1], az = fa[3 * k + 2];
816
+ let wrel = -(ss[baseA + SBS_AV_X] * ax + ss[baseA + SBS_AV_Y] * ay + ss[baseA + SBS_AV_Z] * az);
817
+ if (!to_world) wrel += ss[baseB + SBS_AV_X] * ax + ss[baseB + SBS_AV_Y] * ay + ss[baseB + SBS_AV_Z] * az;
818
+ const old = imp[3 + k];
819
+ let nv = old - ang_eff[k] * (wrel + ang_bias[k] + ang_gamma[k] * old);
820
+ if (nv < ang_clo[k]) nv = ang_clo[k]; else if (nv > ang_chi[k]) nv = ang_chi[k];
821
+ imp[3 + k] = nv;
822
+ const d = nv - old;
823
+ if (d !== 0) {
824
+ if (!to_world) apply_angular_impulse(ss, baseB, ax, ay, az, d, +1);
825
+ apply_angular_impulse(ss, baseA, ax, ay, az, d, -1);
826
+ }
827
+ }
828
+ }
829
+ }
830
+ }