@woosh/meep-engine 3.44.0 → 3.46.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 (447) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/assert.d.ts.map +1 -1
  4. package/src/core/assert.js +5 -1
  5. package/src/core/binary/hash/XXH128Hash.d.ts +1 -37
  6. package/src/core/binary/hash/XXH128Hash.d.ts.map +1 -1
  7. package/src/core/binary/hash/XXH128Hash.js +4 -55
  8. package/src/core/binary/hash/XXH3_SECRET.d.ts +1 -12
  9. package/src/core/binary/hash/XXH3_SECRET.d.ts.map +1 -1
  10. package/src/core/binary/hash/XXH3_SECRET.js +4 -25
  11. package/src/core/binary/hash/crc32.d.ts +1 -15
  12. package/src/core/binary/hash/crc32.d.ts.map +1 -1
  13. package/src/core/binary/hash/crc32.js +4 -96
  14. package/src/core/binary/hash/xxh3_128.d.ts +1 -9
  15. package/src/core/binary/hash/xxh3_128.d.ts.map +1 -1
  16. package/src/core/binary/hash/xxh3_128.js +4 -341
  17. package/src/core/binary/hash/xxh3_64.d.ts +1 -8
  18. package/src/core/binary/hash/xxh3_64.d.ts.map +1 -1
  19. package/src/core/binary/hash/xxh3_64.js +4 -241
  20. package/src/core/binary/hash/xxh3_common.d.ts +1 -223
  21. package/src/core/binary/hash/xxh3_common.d.ts.map +1 -1
  22. package/src/core/binary/hash/xxh3_common.js +90 -476
  23. package/src/core/collection/array/array_sort_insertion_ascending.d.ts +19 -0
  24. package/src/core/collection/array/array_sort_insertion_ascending.d.ts.map +1 -0
  25. package/src/core/collection/array/array_sort_insertion_ascending.js +31 -0
  26. package/src/core/collection/array/combine_hash.d.ts +6 -0
  27. package/src/core/collection/array/combine_hash.d.ts.map +1 -1
  28. package/src/core/collection/array/combine_hash.js +6 -0
  29. package/src/core/function/FunctionCompiler.js +2 -2
  30. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts +27 -0
  31. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts.map +1 -0
  32. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.js +39 -0
  33. package/src/core/geom/3d/aabb/aabb3_from_v3_array.d.ts.map +1 -1
  34. package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +4 -1
  35. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts +2 -2
  36. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -1
  37. package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +1 -1
  38. package/src/core/geom/3d/mat4/m4_multiply.d.ts +3 -0
  39. package/src/core/geom/3d/mat4/m4_multiply.d.ts.map +1 -1
  40. package/src/core/geom/3d/mat4/m4_multiply.js +3 -0
  41. package/src/core/geom/3d/mat4/m4_multiply_f64.d.ts +30 -0
  42. package/src/core/geom/3d/mat4/m4_multiply_f64.d.ts.map +1 -0
  43. package/src/core/geom/3d/mat4/m4_multiply_f64.js +106 -0
  44. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts +21 -0
  45. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts.map +1 -0
  46. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.js +36 -0
  47. package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts +25 -0
  48. package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts.map +1 -0
  49. package/src/core/geom/3d/pose/pose3_apply_point_array.js +40 -0
  50. package/src/core/geom/3d/pose/pose3_compose_array.d.ts +28 -0
  51. package/src/core/geom/3d/pose/pose3_compose_array.d.ts.map +1 -0
  52. package/src/core/geom/3d/pose/pose3_compose_array.js +41 -0
  53. package/src/core/geom/3d/pose/pose3_to_local_array.d.ts +29 -0
  54. package/src/core/geom/3d/pose/pose3_to_local_array.d.ts.map +1 -0
  55. package/src/core/geom/3d/pose/pose3_to_local_array.js +42 -0
  56. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts +28 -0
  57. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts.map +1 -0
  58. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.js +66 -0
  59. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts +22 -0
  60. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts.map +1 -0
  61. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.js +30 -0
  62. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts +23 -0
  63. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts.map +1 -0
  64. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.js +31 -0
  65. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts +26 -0
  66. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts.map +1 -0
  67. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.js +46 -0
  68. package/src/core/geom/ConicRay.js +2 -2
  69. package/src/core/geom/Vector4.d.ts.map +1 -1
  70. package/src/core/geom/Vector4.js +8 -5
  71. package/src/core/geom/vec3/v3_distance_array.d.ts +11 -0
  72. package/src/core/geom/vec3/v3_distance_array.d.ts.map +1 -0
  73. package/src/core/geom/vec3/v3_distance_array.js +19 -0
  74. package/src/core/geom/vec3/v3_normalize_array_checked.d.ts +23 -0
  75. package/src/core/geom/vec3/v3_normalize_array_checked.d.ts.map +1 -0
  76. package/src/core/geom/vec3/v3_normalize_array_checked.js +49 -0
  77. package/src/core/geom/vec3/v3_reject_array.d.ts +15 -0
  78. package/src/core/geom/vec3/v3_reject_array.d.ts.map +1 -0
  79. package/src/core/geom/vec3/v3_reject_array.js +32 -0
  80. package/src/core/graph/csr/csr_build_incidence.d.ts +26 -0
  81. package/src/core/graph/csr/csr_build_incidence.d.ts.map +1 -0
  82. package/src/core/graph/csr/csr_build_incidence.js +71 -0
  83. package/src/core/graph/csr/csr_graph_color_greedy.d.ts +25 -0
  84. package/src/core/graph/csr/csr_graph_color_greedy.d.ts.map +1 -0
  85. package/src/core/graph/csr/csr_graph_color_greedy.js +83 -0
  86. package/src/core/graph/csr/csr_graph_validate_coloring.d.ts +15 -0
  87. package/src/core/graph/csr/csr_graph_validate_coloring.d.ts.map +1 -0
  88. package/src/core/graph/csr/csr_graph_validate_coloring.js +33 -0
  89. package/src/core/math/hash/XXH128Hash.d.ts +38 -0
  90. package/src/core/math/hash/XXH128Hash.d.ts.map +1 -0
  91. package/src/core/math/hash/XXH128Hash.js +55 -0
  92. package/src/core/math/hash/XXH3_SECRET.d.ts +13 -0
  93. package/src/core/math/hash/XXH3_SECRET.d.ts.map +1 -0
  94. package/src/core/math/hash/XXH3_SECRET.js +25 -0
  95. package/src/core/math/hash/crc32.d.ts +16 -0
  96. package/src/core/math/hash/crc32.d.ts.map +1 -0
  97. package/src/core/math/hash/crc32.js +96 -0
  98. package/src/core/math/hash/xxh3_128.d.ts +10 -0
  99. package/src/core/math/hash/xxh3_128.d.ts.map +1 -0
  100. package/src/core/math/hash/xxh3_128.js +341 -0
  101. package/src/core/math/hash/xxh3_64.d.ts +9 -0
  102. package/src/core/math/hash/xxh3_64.d.ts.map +1 -0
  103. package/src/core/math/hash/xxh3_64.js +241 -0
  104. package/src/core/math/hash/xxh3_common.d.ts +224 -0
  105. package/src/core/math/hash/xxh3_common.d.ts.map +1 -0
  106. package/src/core/math/hash/xxh3_common.js +476 -0
  107. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts +26 -0
  108. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts.map +1 -0
  109. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.js +71 -0
  110. package/src/core/math/lookup/ParameterLookupTable.js +2 -2
  111. package/src/core/math/max2_exact.d.ts +15 -0
  112. package/src/core/math/max2_exact.d.ts.map +1 -0
  113. package/src/core/math/max2_exact.js +30 -0
  114. package/src/core/math/min2_exact.d.ts +20 -0
  115. package/src/core/math/min2_exact.d.ts.map +1 -0
  116. package/src/core/math/min2_exact.js +35 -0
  117. package/src/core/model/node-graph/node/NodeInstancePortReference.js +2 -2
  118. package/src/core/model/reactive/model/ReactiveBinaryExpression.js +2 -2
  119. package/src/core/model/reactive/model/terminal/ReactiveReference.js +2 -2
  120. package/src/engine/asset/AssetDescription.js +2 -2
  121. package/src/engine/ecs/animation/Animation.js +2 -2
  122. package/src/engine/ecs/animation/AnimationClip.d.ts.map +1 -1
  123. package/src/engine/ecs/animation/AnimationClip.js +7 -5
  124. package/src/engine/ecs/gui/GUIElement.d.ts.map +1 -1
  125. package/src/engine/ecs/gui/GUIElement.js +7 -5
  126. package/src/engine/ecs/gui/hud/HeadsUpDisplay.js +2 -2
  127. package/src/engine/ecs/gui/position/ViewportPosition.d.ts.map +1 -1
  128. package/src/engine/ecs/gui/position/ViewportPosition.js +11 -7
  129. package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -1
  130. package/src/engine/ecs/ik/IKGoalSystem.js +3 -19
  131. package/src/engine/ecs/parent/parent_entity_model_of.d.ts +17 -0
  132. package/src/engine/ecs/parent/parent_entity_model_of.d.ts.map +1 -0
  133. package/src/engine/ecs/parent/parent_entity_model_of.js +26 -0
  134. package/src/engine/ecs/transform/Transform64.d.ts +1 -1
  135. package/src/engine/ecs/transform/Transform64.d.ts.map +1 -1
  136. package/src/engine/ecs/transform/Transform64.js +5 -4
  137. package/src/engine/ecs/transform/t64_read_pose_array.d.ts +15 -0
  138. package/src/engine/ecs/transform/t64_read_pose_array.d.ts.map +1 -0
  139. package/src/engine/ecs/transform/t64_read_pose_array.js +24 -0
  140. package/src/engine/graphics/ecs/animation/animator/AnimationClip.d.ts.map +1 -1
  141. package/src/engine/graphics/ecs/animation/animator/AnimationClip.js +8 -5
  142. package/src/engine/graphics/ecs/animation/animator/AnimationClipDefinition.js +2 -2
  143. package/src/engine/graphics/ecs/animation/animator/AnimationNotification.js +2 -2
  144. package/src/engine/graphics/ecs/animation/animator/AnimationNotificationDefinition.js +2 -2
  145. package/src/engine/graphics/ecs/animation/animator/graph/definition/AnimationGraphDefinition.js +2 -2
  146. package/src/engine/graphics/ecs/animation/animator/graph/definition/AnimationStateDefinition.js +2 -2
  147. package/src/engine/graphics/ecs/animation/animator/graph/definition/AnimationTransitionDefinition.d.ts.map +1 -1
  148. package/src/engine/graphics/ecs/animation/animator/graph/definition/AnimationTransitionDefinition.js +8 -5
  149. package/src/engine/graphics/ecs/decal/v2/Decal.d.ts.map +1 -1
  150. package/src/engine/graphics/ecs/decal/v2/Decal.js +9 -8
  151. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts +2 -0
  152. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts.map +1 -1
  153. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.js +10 -21
  154. package/src/engine/graphics/render/frame_graph/resource/TextureResourceDescriptor.d.ts.map +1 -1
  155. package/src/engine/graphics/render/frame_graph/resource/TextureResourceDescriptor.js +9 -6
  156. package/src/engine/graphics3/AnimationGraphSystem.d.ts +5 -0
  157. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
  158. package/src/engine/graphics3/AnimationGraphSystem.js +48 -2
  159. package/src/engine/graphics3/AnimationSystem.d.ts +5 -0
  160. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
  161. package/src/engine/graphics3/AnimationSystem.js +47 -2
  162. package/src/engine/graphics3/ParticipatingMedia.js +204 -204
  163. package/src/engine/graphics3/animation/AnimationClips.d.ts +5 -0
  164. package/src/engine/graphics3/animation/AnimationClips.d.ts.map +1 -1
  165. package/src/engine/graphics3/animation/AnimationClips.js +5 -0
  166. package/src/engine/graphics3/register_clips.d.ts +29 -0
  167. package/src/engine/graphics3/register_clips.d.ts.map +1 -1
  168. package/src/engine/graphics3/register_clips.js +52 -0
  169. package/src/engine/grid/obstacle/GridObstacle.js +2 -2
  170. package/src/engine/intelligence/behavior/selector/WeightedElement.js +2 -2
  171. package/src/engine/interpolation/Interpolated.js +2 -2
  172. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +9 -0
  173. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -1
  174. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +3 -1
  175. package/src/engine/physics/cloth/PLAN.md +10 -8
  176. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +22 -0
  177. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -1
  178. package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +51 -19
  179. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  180. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +16 -2
  181. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -1
  182. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +19 -24
  183. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +7 -0
  184. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
  185. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +85 -67
  186. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -1
  187. package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +19 -101
  188. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +2 -5
  189. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -1
  190. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +7 -15
  191. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -1
  192. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +16 -61
  193. package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -1
  194. package/src/engine/physics/cloth/ecs/Cloth.js +7 -5
  195. package/src/engine/physics/cloth/ecs/ClothCollider.d.ts.map +1 -1
  196. package/src/engine/physics/cloth/ecs/ClothCollider.js +7 -5
  197. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +0 -1
  198. package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +6 -19
  199. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +1 -2
  200. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
  201. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +3 -12
  202. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts.map +1 -1
  203. package/src/engine/physics/cloth/ecs/ClothDynamics.js +20 -11
  204. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  205. package/src/engine/physics/cloth/ecs/ClothWorld.js +40 -130
  206. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  207. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +17 -58
  208. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  209. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +3 -3
  210. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
  211. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +44 -104
  212. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -1
  213. package/src/engine/physics/cloth/ecs/cloth_geodesic.js +6 -13
  214. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -1
  215. package/src/engine/physics/cloth/ecs/cloth_holds.js +15 -40
  216. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
  217. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +45 -79
  218. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  219. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +7 -27
  220. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  221. package/src/engine/physics/cloth/ecs/cloth_write_back.js +30 -62
  222. package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts.map +1 -1
  223. package/src/engine/physics/cloth/playground/cloth_playground_build.js +2 -3
  224. package/src/engine/physics/cloth/playground/collide_main.js +2 -28
  225. package/src/engine/physics/cloth/playground/garment_main.js +4 -19
  226. package/src/engine/physics/cloth/playground/main.js +6 -48
  227. package/src/engine/physics/cloth/playground/rig_main.js +947 -955
  228. package/src/engine/physics/cloth/playground/wind_main.js +8 -7
  229. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  230. package/src/engine/physics/cloth/solver/ClothState.js +16 -76
  231. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts +10 -8
  232. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts.map +1 -1
  233. package/src/engine/physics/cloth/solver/cloth_color_particles.js +30 -102
  234. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  235. package/src/engine/physics/cloth/solver/cloth_contact_find.js +3 -2
  236. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -1
  237. package/src/engine/physics/cloth/solver/cloth_hold_line.js +2 -14
  238. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts +21 -0
  239. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts.map +1 -0
  240. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.js +45 -0
  241. package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts +32 -0
  242. package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts.map +1 -0
  243. package/src/engine/physics/cloth/solver/cloth_particle_coupling.js +133 -0
  244. package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts +16 -0
  245. package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts.map +1 -0
  246. package/src/engine/physics/cloth/solver/cloth_particle_of_source.js +19 -0
  247. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  248. package/src/engine/physics/cloth/solver/cloth_self_find.js +6 -55
  249. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
  250. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +30 -65
  251. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  252. package/src/engine/physics/cloth/solver/cloth_step.js +6 -28
  253. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  254. package/src/engine/physics/cloth/solver/cloth_step_instance.js +2 -3
  255. package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts +21 -0
  256. package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts.map +1 -0
  257. package/src/engine/physics/cloth/solver/cloth_stretch_residual.js +54 -0
  258. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts +15 -0
  259. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts.map +1 -1
  260. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.js +28 -0
  261. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts +30 -0
  262. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts.map +1 -0
  263. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.js +56 -0
  264. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
  265. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +3 -17
  266. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +2 -1
  267. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
  268. package/src/engine/physics/cloth/wind/ClothFluidWind.js +7 -25
  269. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +3 -1
  270. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
  271. package/src/engine/physics/cloth/wind/cloth_sample_air.js +40 -62
  272. package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -1
  273. package/src/engine/physics/ecs/ContactProbeSystem.js +2 -18
  274. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  275. package/src/engine/physics/ecs/PhysicsSystem.js +9 -50
  276. package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
  277. package/src/engine/physics/fluid/FluidField.js +7 -5
  278. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts.map +1 -1
  279. package/src/engine/physics/fluid/ecs/FluidComponent.js +19 -11
  280. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts +24 -0
  281. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts.map +1 -0
  282. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.js +42 -0
  283. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts +25 -0
  284. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts.map +1 -0
  285. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.js +40 -0
  286. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts +2 -2
  287. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +2 -2
  288. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
  289. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +11 -7
  290. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts.map +1 -1
  291. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +11 -7
  292. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
  293. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +16 -9
  294. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -1
  295. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +40 -90
  296. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
  297. package/src/engine/physics/narrowphase/capsule_contacts.js +3 -5
  298. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -1
  299. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +2 -14
  300. package/src/engine/physics/narrowphase/hull_sphere_contact.d.ts.map +1 -1
  301. package/src/engine/physics/narrowphase/hull_sphere_contact.js +2 -5
  302. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  303. package/src/engine/physics/narrowphase/narrowphase_step.js +13 -32
  304. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
  305. package/src/engine/physics/narrowphase/sphere_box_contact.js +2 -5
  306. package/src/engine/sound/ecs/audio/AudioEmitter.d.ts.map +1 -1
  307. package/src/engine/sound/ecs/audio/AudioEmitter.js +12 -7
  308. package/src/engine/sound/ecs/trigger/AudioEventTrigger.d.ts.map +1 -1
  309. package/src/engine/sound/ecs/trigger/AudioEventTrigger.js +192 -191
  310. package/src/engine/sound/simulation/core/AcousticMedium.js +2 -2
  311. package/src/engine/sound/simulation/definition/AcousticDirectivity.js +2 -2
  312. package/src/engine/sound/simulation/definition/AcousticMaterial.d.ts.map +1 -1
  313. package/src/engine/sound/simulation/definition/AcousticMaterial.js +11 -7
  314. package/src/engine/sound/sopra/definition/BusDefinition.d.ts.map +1 -1
  315. package/src/engine/sound/sopra/definition/BusDefinition.js +5 -4
  316. package/src/engine/sound/sopra/definition/DuckingRule.d.ts.map +1 -1
  317. package/src/engine/sound/sopra/definition/DuckingRule.js +7 -5
  318. package/src/engine/sound/sopra/definition/EventDescription.d.ts.map +1 -1
  319. package/src/engine/sound/sopra/definition/EventDescription.js +23 -13
  320. package/src/engine/sound/sopra/definition/MixerSnapshot.js +2 -2
  321. package/src/engine/sound/sopra/definition/ParameterDefinition.d.ts.map +1 -1
  322. package/src/engine/sound/sopra/definition/ParameterDefinition.js +7 -5
  323. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +2 -2
  324. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts.map +1 -1
  325. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.js +4 -3
  326. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.js +2 -2
  327. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +3 -3
  328. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -1
  329. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +16 -9
  330. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.js +2 -2
  331. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +1 -1
  332. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
  333. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.js +2 -2
  334. package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts.map +1 -1
  335. package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +7 -5
  336. package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts.map +1 -1
  337. package/src/engine/sound/sopra/definition/effect/EqEffect.js +8 -5
  338. package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +2 -2
  339. package/src/engine/sound/sopra/legacy/SoundEmitter.d.ts.map +1 -1
  340. package/src/engine/sound/sopra/legacy/SoundEmitter.js +357 -352
  341. package/src/engine/sound/sopra/legacy/SoundTrack.d.ts.map +1 -1
  342. package/src/engine/sound/sopra/legacy/SoundTrack.js +281 -278
  343. package/src/format/image/png/PNGReader.js +644 -644
  344. package/src/format/image/png/crc32.d.ts +1 -1
  345. package/src/format/image/png/crc32.js +7 -8
  346. package/src/format/texture/basis/transcode/etc1s_to_astc.d.ts.map +1 -1
  347. package/src/format/texture/basis/transcode/etc1s_to_astc.js +2 -1
  348. package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.js +2 -2
  349. package/src/shade/descriptor/binding/BindGroupLayoutEntry.d.ts.map +1 -1
  350. package/src/shade/descriptor/binding/BindGroupLayoutEntry.js +12 -8
  351. package/src/shade/descriptor/binding/StorageTextureBindingLayout.js +2 -2
  352. package/src/shade/descriptor/binding/TextureBindingLayout.js +2 -2
  353. package/src/shade/descriptor/blend/BlendComponent.js +2 -2
  354. package/src/shade/descriptor/pipeline/PipelineDescriptorBase.js +2 -2
  355. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +2 -2
  356. package/src/shade/descriptor/pipeline/ProgrammableStage.js +2 -2
  357. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +2 -2
  358. package/src/shade/descriptor/pipeline/render/ColorTargetState.js +2 -2
  359. package/src/shade/descriptor/pipeline/render/FragmentState.js +2 -2
  360. package/src/shade/descriptor/pipeline/render/PrimitiveState.js +2 -2
  361. package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.d.ts.map +1 -1
  362. package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.js +8 -5
  363. package/src/shade/descriptor/pipeline/render/VertexAttribute.js +2 -2
  364. package/src/shade/descriptor/texture/SamplerDescriptor.d.ts.map +1 -1
  365. package/src/shade/descriptor/texture/SamplerDescriptor.js +20 -12
  366. package/src/shade/descriptor/texture/TextureDescriptor.d.ts.map +1 -1
  367. package/src/shade/descriptor/texture/TextureDescriptor.js +11 -7
  368. package/src/shade/device/graph/BufferResourceDescriptor.d.ts.map +1 -1
  369. package/src/shade/device/graph/BufferResourceDescriptor.js +196 -193
  370. package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
  371. package/src/shade/device/graph/TextureResourceDescriptor.js +178 -173
  372. package/src/shade/device/timing/profile/sgpt_read_header.js +1 -1
  373. package/src/shade/device/timing/profile/sgpt_read_records.js +1 -1
  374. package/src/shade/device/timing/profile/sgpt_write_header.js +1 -1
  375. package/src/shade/device/timing/profile/sgpt_write_record.js +1 -1
  376. package/src/shade/playground/image_decode_bench/main.js +2 -1
  377. package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.d.ts.map +1 -1
  378. package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.js +2 -1
  379. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
  380. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +2 -1
  381. package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -1
  382. package/src/shade/playground/ssr_variance/statistics.js +2 -1
  383. package/src/shade/playground/texture_encode/main.d.ts.map +1 -1
  384. package/src/shade/playground/texture_encode/main.js +2 -1
  385. package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -1
  386. package/src/shade/playground/volumetrics_froxel/measure.js +2 -1
  387. package/src/shade/renderer/binding/BufferBinding.js +2 -2
  388. package/src/shade/renderer/buffer/table/gpu_database_check_links.d.ts.map +1 -1
  389. package/src/shade/renderer/buffer/table/gpu_database_check_links.js +2 -1
  390. package/src/shade/renderer/camera/Camera.js +2 -2
  391. package/src/shade/renderer/geometry/Attribute.js +2 -2
  392. package/src/shade/renderer/geometry/Geometry.js +2 -2
  393. package/src/shade/renderer/geometry/geometry_deduplicate_vertices.js +2 -2
  394. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +2 -2
  395. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -1
  396. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +3 -2
  397. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -1
  398. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +2 -1
  399. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -1
  400. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +2 -1
  401. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -1
  402. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +2 -1
  403. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -1
  404. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +3 -2
  405. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -1
  406. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.js +2 -1
  407. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
  408. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +2 -1
  409. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_asset_id.js +13 -13
  410. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_directory_block_checksum.js +41 -41
  411. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_frame_checksum.js +41 -41
  412. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_header_checksum.js +25 -25
  413. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  414. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +3 -2
  415. package/src/shade/renderer/material/StandardShadeMaterial.d.ts.map +1 -1
  416. package/src/shade/renderer/material/StandardShadeMaterial.js +13 -8
  417. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -1
  418. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +3 -2
  419. package/src/shade/renderer/scene/optimization/geometry/internal/triangle_fingerprint_stream.d.ts.map +1 -1
  420. package/src/shade/renderer/scene/optimization/geometry/internal/triangle_fingerprint_stream.js +14 -5
  421. package/src/shade/renderer/scene/optimization/sampler2d_from_image_bitmap.js +1 -1
  422. package/src/shade/renderer/shader/type/WGSLStructField.js +2 -2
  423. package/src/shade/renderer/shader/type/WebGPUArray.js +2 -2
  424. package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
  425. package/src/shade/renderer/shader/type/WebGPUStruct.js +9 -6
  426. package/src/shade/renderer/texture/ShadeTexture.d.ts.map +1 -1
  427. package/src/shade/renderer/texture/ShadeTexture.js +17 -10
  428. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.js +2 -2
  429. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +4 -4
  430. package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +6 -6
  431. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
  432. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +46 -55
  433. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts +3 -3
  434. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts.map +1 -1
  435. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js +14 -4
  436. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts +10 -1
  437. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -1
  438. package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +82 -40
  439. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts +4 -1
  440. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -1
  441. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +8 -4
  442. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts +98 -86
  443. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts.map +1 -1
  444. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +440 -298
  445. package/src/view/common/HTMLElementCacheKey.d.ts.map +1 -1
  446. package/src/view/common/HTMLElementCacheKey.js +4 -3
  447. package/src/view/minimap/MinimapMarker.js +2 -2
@@ -37,6 +37,18 @@ export const WATER_PARTICLE_STRETCH = [
37
37
  /** log₂(k/k_m) of the stretch table's first entry; entries are a quarter apart. */
38
38
  const WATER_PARTICLE_STRETCH_FIRST = -7;
39
39
 
40
+ /** Bits of a hash entry's run word that hold its count of particles; the two above them mark its open ends. */
41
+ export const WATER_PARTICLE_RUN_MEMBERS = 0x3fffffff;
42
+
43
+ /** A run whose first particle has no neighbour of its front before it: it tapers there by that particle's window. */
44
+ export const WATER_PARTICLE_RUN_OPEN_START = 0x40000000;
45
+
46
+ /** A run whose last particle has no neighbour of its front after it. */
47
+ export const WATER_PARTICLE_RUN_OPEN_END = 0x80000000;
48
+
49
+ /** A particle drawn alone: a run of one, open at both ends, which is its own window. */
50
+ export const WATER_PARTICLE_LONE = (1 | WATER_PARTICLE_RUN_OPEN_START | WATER_PARTICLE_RUN_OPEN_END) >>> 0;
51
+
40
52
  /**
41
53
  * The physics of one wave particle as pure functions (WATER_SURFACE_SIMULATION_PLAN_2026_10_06.md §5).
42
54
  *
@@ -52,7 +64,8 @@ const WATER_PARTICLE_STRETCH_FIRST = -7;
52
64
  * The particles of a front are β apart in angle around its centre, and a packet's crests are arcs around that
53
65
  * centre; a cosine window of half-angle β is a partition of unity over them at every radius, so the front's
54
66
  * height is the packet's amplitude whatever the spacing, splitting a front changes none of it, and one front
55
- * adds at most two particles at any point.
67
+ * adds at most two particles at any point. So a run of neighbours alike in all but angle is drawn as one: height one
68
+ * over its particles and its own window past either end that has no neighbour, the same surface its windows sum to.
56
69
  *
57
70
  * @type {CodeChunk}
58
71
  */
@@ -62,6 +75,10 @@ const WATER_PARTICLE_LEVEL_BITS: u32 = ${WATER_PARTICLE_LEVEL_BITS}u;
62
75
  const WATER_PARTICLE_LEVEL0_CELL: f32 = ${WATER_PARTICLE_LEVEL0_CELL};
63
76
  const WATER_PARTICLE_STRETCH = array<f32, ${WATER_PARTICLE_STRETCH.length}>(${WATER_PARTICLE_STRETCH.join(', ')});
64
77
  const WATER_PARTICLE_STRETCH_FIRST: f32 = ${WATER_PARTICLE_STRETCH_FIRST}.0;
78
+ const WATER_PARTICLE_RUN_MEMBERS: u32 = ${WATER_PARTICLE_RUN_MEMBERS}u;
79
+ const WATER_PARTICLE_RUN_OPEN_START: u32 = ${WATER_PARTICLE_RUN_OPEN_START}u;
80
+ const WATER_PARTICLE_RUN_OPEN_END: u32 = ${WATER_PARTICLE_RUN_OPEN_END}u;
81
+ const WATER_PARTICLE_LONE: u32 = ${WATER_PARTICLE_LONE}u;
65
82
  // kinematic viscosity of water, m²/s
66
83
  const WATER_VISCOSITY: f32 = 1e-6;
67
84
  const WATER_PI: f32 = 3.14159265358979;
@@ -153,38 +170,57 @@ fn water_particle_support_limit() -> f32 {
153
170
  return 0.5 * water_particle_cell_size(WATER_PARTICLE_LEVELS - 1u);
154
171
  }
155
172
 
156
- // Whether two particles are of one front: one splash's, neither reflected or faded apart, alike in all but angle.
157
- fn water_particle_same_front(a: ${WATER_PARTICLE_STRUCT.wgsl_ref}, b: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> bool {
173
+ // An angle as a turn from 0 round to 2π.
174
+ fn water_particle_turn(angle: f32) -> f32 {
175
+ return angle - WATER_TAU * floor(angle / WATER_TAU);
176
+ }
177
+
178
+ // Where round its centre a front's particles are not neighbours: an angle of the front's own, from its centre, so that
179
+ // fronts' ends lie anywhere rather than all to one side of them.
180
+ fn water_particle_break(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> f32 {
181
+ let bits = pcg3d(vec3<u32>(bitcast<u32>(particle.origin.x), bitcast<u32>(particle.origin.y), particle.body)).x;
182
+ return f32(bits >> 8u) * (WATER_TAU / 16777216.0);
183
+ }
184
+
185
+ // Whether two particles are of one front as it is drawn: one splash's, neither faded apart from the other, alike in all
186
+ // but angle. A doom does not part them until the fade it starts does: what is drawn is all that links them.
187
+ fn water_particle_alike(a: ${WATER_PARTICLE_STRUCT.wgsl_ref}, b: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> bool {
158
188
  return a.body == b.body && all(a.origin == b.origin) && a.age == b.age && a.amplitude == b.amplitude
159
189
  && a.radius == b.radius && a.dispersion == b.dispersion;
160
190
  }
161
191
 
162
- // How a particle is drawn, given its front's run of particles in the array and its place in it: 1 as itself; 0 not at
163
- // all, or a group of 3^g as one packet with 3^g times its window, when its front is whole. Whole is every particle
164
- // the front split into still there, in order and alike: as many as fill its circle. The step puts a particle's three
165
- // in its place, the middle at its own angle, so a group of 3^g is 3^g in a row and its middle stands at the angle
166
- // the group was emitted at; with curved crests the groups draw what the particles do. The largest group whose packet
167
- // the hash holds: the seven a front was emitted as, until their windows outgrow the coarsest cell.
168
- fn water_particle_group(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}, members: u32, offset: u32) -> u32 {
169
- if (members != u32(round(WATER_TAU / particle.dispersion))) { return 1u; }
170
- var group = 1u;
171
- for (var g = 0u; g < 20u && members % (3u * group) == 0u; g++) { group *= 3u; }
172
- let distance = water_particle_distance(particle);
173
- let half_length = water_particle_half_length_at(particle.radius, distance);
174
- for (var g = 0u; g < 20u && group > 1u; g++) {
175
- let dispersion = particle.dispersion * f32(group);
176
- let width = max(dispersion * distance, 1e-3 * particle.radius);
177
- if (water_particle_support(half_length, width, dispersion) <= water_particle_support_limit()) { break; }
178
- group /= 3u;
179
- }
180
- return select(0u, group, offset % group == group / 2u);
192
+ // Whether b is a's neighbour round their front, β further on. Angles are compared as turns from the front's break, so
193
+ // its particles either side of it are never neighbours and a run of them never closes on itself; that pair's windows sum
194
+ // to one there as any unlinked pair's do.
195
+ fn water_particle_linked(a: ${WATER_PARTICLE_STRUCT.wgsl_ref}, b: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> bool {
196
+ if (!water_particle_alike(a, b)) { return false; }
197
+ let cut = water_particle_break(a);
198
+ return abs(water_particle_turn(b.angle - cut) - water_particle_turn(a.angle - cut) - a.dispersion) < 0.01 * a.dispersion;
181
199
  }
182
200
 
183
- // The particle as its group draws it: one packet with the group's window.
184
- fn water_particle_drawn(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}, group: u32) -> ${WATER_PARTICLE_STRUCT.wgsl_ref} {
185
- var drawn = particle;
186
- drawn.dispersion *= f32(group);
187
- return drawn;
201
+ // A particle's window over x from its axis, |x| < β, and its derivative.
202
+ fn water_particle_taper(x: f32, dispersion: f32) -> vec2<f32> {
203
+ let t = WATER_PI * x / dispersion;
204
+ return vec2<f32>(0.5 * (1.0 + cos(t)), -0.5 * WATER_PI / dispersion * sin(t));
205
+ }
206
+
207
+ // The angular profile of a run of a front's particles at ψ round the front's centre from its first particle's axis, and
208
+ // its derivative: one from its first particle's axis to its last's, where the windows of neighbours β apart sum to one;
209
+ // past an open end the end particle's own window, all there is of the front there; past an end with a neighbour, nothing,
210
+ // since that neighbour's own run draws it there.
211
+ fn water_particle_run_profile(psi: f32, dispersion: f32, run: u32) -> vec2<f32> {
212
+ let span = f32(max(run & WATER_PARTICLE_RUN_MEMBERS, 1u) - 1u) * dispersion;
213
+ let onward = water_particle_turn(psi);
214
+ if (onward <= span) { return vec2<f32>(1.0, 0.0); }
215
+ var profile = vec2<f32>(0.0);
216
+ if ((run & WATER_PARTICLE_RUN_OPEN_START) != 0u && psi < 0.0 && psi > -dispersion) {
217
+ profile += water_particle_taper(psi, dispersion);
218
+ }
219
+ let past = onward - span;
220
+ if ((run & WATER_PARTICLE_RUN_OPEN_END) != 0u && past < dispersion) {
221
+ profile += water_particle_taper(past, dispersion);
222
+ }
223
+ return profile;
188
224
  }
189
225
 
190
226
  // The smallest hash level whose cell is at least the support's diameter, so the support overlaps at most
@@ -220,13 +256,13 @@ struct WaterParticleField {
220
256
  displacement_gradient: vec2<f32>,
221
257
  }
222
258
 
223
- // The packet at offset d from its particle, which stands distance from its front's centre. ρ the radius from the
224
- // centre and u = ρ − distance across the front, ψ the angle around the centre from the particle's direction:
225
- // envelope E(u) over half_length either side, window T(ψ) over the dispersion β either side, carrier phase πu/r − phase.
226
- // Height a·E·T·cos; horizontal displacement −a·E·T·sin along the radius (Gerstner-like orbits, Yuksel's longitudinal
227
- // sign); with derivatives, ∇ψ = e_ψ/ρ.
228
- fn water_particle_field(d: vec2<f32>, angle: f32, amplitude: f32, radius: f32, half_length: f32, dispersion: f32, distance: f32,
229
- phase: f32) -> WaterParticleField {
259
+ // The run of a front's packets from the particle at offset d (water_particle_run_profile), which stands distance from
260
+ // its front's centre. ρ the radius from the centre and u = ρ − distance across the front, ψ the angle around the centre
261
+ // from the particle's direction: envelope E(u) over half_length either side, the run's profile T(ψ), carrier phase
262
+ // πu/r − phase. Height a·E·T·cos; horizontal displacement −a·E·T·sin along the radius (Gerstner-like orbits, Yuksel's
263
+ // longitudinal sign); with derivatives, ∇ψ = e_ψ/ρ.
264
+ fn water_particle_run_field(d: vec2<f32>, angle: f32, amplitude: f32, radius: f32, half_length: f32, dispersion: f32, distance: f32,
265
+ phase: f32, run: u32) -> WaterParticleField {
230
266
  var field: WaterParticleField;
231
267
  let direction = water_particle_direction(angle);
232
268
  let tangent = vec2<f32>(-direction.y, direction.x);
@@ -236,15 +272,15 @@ fn water_particle_field(d: vec2<f32>, angle: f32, amplitude: f32, radius: f32, h
236
272
  let u = (dot(d, d) + 2.0 * distance * dot(d, direction)) / max(rho + distance, 1e-30);
237
273
  if (abs(u) >= half_length || !(rho > 0.0)) { return field; }
238
274
  let psi = atan2(dot(d, tangent), distance + dot(d, direction));
239
- if (abs(psi) >= dispersion) { return field; }
275
+ let profile = water_particle_run_profile(psi, dispersion, run);
276
+ if (!(profile.x > 0.0)) { return field; }
240
277
  let radial = q / rho;
241
278
  let around = vec2<f32>(-radial.y, radial.x);
242
279
  let eu = WATER_PI * u / half_length;
243
280
  let envelope = 0.5 * (1.0 + cos(eu));
244
281
  let envelope_du = -0.5 * WATER_PI / half_length * sin(eu);
245
- let tv = WATER_PI * psi / dispersion;
246
- let window = 0.5 * (1.0 + cos(tv));
247
- let window_dpsi = -0.5 * WATER_PI / dispersion * sin(tv);
282
+ let window = profile.x;
283
+ let window_dpsi = profile.y;
248
284
  let carrier = WATER_PI * u / radius - phase;
249
285
  let c = cos(carrier);
250
286
  let s = sin(carrier);
@@ -257,12 +293,18 @@ fn water_particle_field(d: vec2<f32>, angle: f32, amplitude: f32, radius: f32, h
257
293
  let h_psi = -amplitude * envelope * window_dpsi * s;
258
294
  let gradient_h = h_u * radial + (h_psi / rho) * around;
259
295
  // the radius turns as the point moves around the centre: ∂e_ρ/∂x_j = e_ψ (e_ψ)_j / ρ
260
- let turn = (h / rho) * around;
296
+ let swing = (h / rho) * around;
261
297
  field.height = z;
262
298
  field.slope = z_u * radial + (z_psi / rho) * around;
263
299
  field.displacement = h * radial;
264
- field.jacobian = mat2x2<f32>(radial * gradient_h.x + turn * around.x, radial * gradient_h.y + turn * around.y);
300
+ field.jacobian = mat2x2<f32>(radial * gradient_h.x + swing * around.x, radial * gradient_h.y + swing * around.y);
265
301
  field.displacement_gradient = gradient_h;
266
302
  return field;
267
303
  }
304
+
305
+ // One particle's packet: a run of one, its window over the dispersion β either side of its axis.
306
+ fn water_particle_field(d: vec2<f32>, angle: f32, amplitude: f32, radius: f32, half_length: f32, dispersion: f32, distance: f32,
307
+ phase: f32) -> WaterParticleField {
308
+ return water_particle_run_field(d, angle, amplitude, radius, half_length, dispersion, distance, phase, WATER_PARTICLE_LONE);
309
+ }
268
310
  `, [chunk_water_spectrum, chunk_pcg3d, WATER_PARTICLE_STRUCT.declaration_chunk, WATER_PARTICLE_ENTRY_STRUCT.declaration_chunk]);
@@ -1,4 +1,7 @@
1
- /** Seconds over which a packet that has fallen below the drawing threshold fades to a tenth of it, where it dies. */
1
+ /**
2
+ * Time constant of a dying packet's fade: one that has fallen below the drawing threshold fades to a tenth of it, where
3
+ * it dies, and one a crowd doomed to a tenth of its steepness then; about a third of a second either way.
4
+ */
2
5
  export const WATER_PARTICLE_FADE_SECONDS: 0.15;
3
6
  /**
4
7
  * One frame of one wave particle (WATER_SURFACE_SIMULATION_PLAN_2026_10_06.md §5.1): it ages, spreads over its
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_water_particle_step.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/chunk_water_particle_step.js"],"names":[],"mappings":"AAQA,qHAAqH;AACrH,+CAAgD;AAEhD;;;;;;;;;;;;;;GAcG;AACH,wCAFU,SAAS,CAsN8E;0BA9OvE,uCAAuC"}
1
+ {"version":3,"file":"chunk_water_particle_step.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/chunk_water_particle_step.js"],"names":[],"mappings":"AAQA;;;GAGG;AACH,+CAAgD;AAEhD;;;;;;;;;;;;;;GAcG;AACH,wCAFU,SAAS,CAuN8E;0BAlPvE,uCAAuC"}
@@ -6,7 +6,10 @@ import { RAY_HIT_INFO } from "../../../shader/chunk/geometry/ray/RAY_HIT_INFO.js
6
6
  import { WATER_PARTICLE_STRUCT } from "./WATER_PARTICLE_STRUCT.js";
7
7
  import { chunk_water_particle } from "./chunk_water_particle.js";
8
8
 
9
- /** Seconds over which a packet that has fallen below the drawing threshold fades to a tenth of it, where it dies. */
9
+ /**
10
+ * Time constant of a dying packet's fade: one that has fallen below the drawing threshold fades to a tenth of it, where
11
+ * it dies, and one a crowd doomed to a tenth of its steepness then; about a third of a second either way.
12
+ */
10
13
  export const WATER_PARTICLE_FADE_SECONDS = 0.15;
11
14
 
12
15
  /**
@@ -141,11 +144,12 @@ fn water_particle_advance(input: ${WATER_PARTICLE_STRUCT.wgsl_ref}, dt: f32, geo
141
144
  particle.amplitude *= sqrt(max(distance_before, 1e-30) / max(distance_after, 1e-30)
142
145
  * half_length_before / water_particle_half_length(particle)) * exp(-water_particle_damping(particle.radius) * dt);
143
146
  // below the threshold a packet fades out rather than vanishing: its amplitude decays on top of the water's own
144
- // damping until it is a tenth of the threshold's height, where it dies
147
+ // damping until it is a tenth of the threshold's height, where it dies; and so does one a crowd doomed, until it is
148
+ // as steep as its doom says
145
149
  let floor = threshold * particle.radius;
146
- if (!(abs(particle.amplitude) >= floor)) {
150
+ if (particle.fading > 0.0 || !(abs(particle.amplitude) >= floor)) {
147
151
  particle.amplitude *= exp(-dt / WATER_PARTICLE_FADE_SECONDS);
148
- if (!(abs(particle.amplitude) >= 0.1 * floor)) { return WaterParticleStep(particle, particle, 0u); }
152
+ if (!(abs(particle.amplitude) >= max(0.1 * floor, particle.fading * particle.radius))) { return WaterParticleStep(particle, particle, 0u); }
149
153
  }
150
154
  // its support: its envelope's half-length either side of its front, its window's angle either side of its axis
151
155
  let reach = water_particle_half_length(particle);
@@ -11,45 +11,47 @@ export const WATER_PARTICLE_CORNERS: 4;
11
11
  /** Buckets ordered by particle; a crowded bucket past this keeps its arrival order. */
12
12
  export const WATER_PARTICLE_RANK_LIMIT: 64;
13
13
  /**
14
- * Packets a crowded point keeps. A point reads a cell of every level its body has, and a cell is crowded where its most
15
- * crowded point reads more than this: a point of it at its level and the coarser ones, or one under it where finer
16
- * levels hold packets too. Then each run of a front in it is drawn by its packets' least share of their cells: this
17
- * many times the packet's steepness over the summed steepness that point reads, whatever the levels it is read at. So
18
- * about this many stay at a point, the steepest whole wherever they sit, and a front stays whole or goes. What is
19
- * elsewhere on the body does not count, so a splash far off, or a front moving to a coarser level, changes nothing here.
20
- *
21
- * A front's lot is its own for life and the same in every cell it reaches, so the fronts of the lowest lots are kept in
22
- * every crowd they are in, whatever their size: the count at a point varies by fronts' worth around this, and a front
23
- * the outline broke is drawn particle by particle, ~20 entries in one cell. Where a point would read more than the
24
- * gather budget, its cells keep no more of it than their steepness's part, the lowest keys first
25
- * ({@link WATER_PARTICLE_CROWD_BINS}), so no point reads past the budget. A whole front is drawn as the seven it was
26
- * emitted as (water_particle_group), so three fresh splashes cross whole, whatever their steepness and levels; a fourth
27
- * over them thins one.
28
- *
29
- * A cell only one front reaches is not crowded, however many of its packets it holds: one front puts at most ~40 in
30
- * a cell, within the gather budget.
31
- */
32
- export const WATER_PARTICLE_CELL_SHARE: 24;
33
- /**
34
- * Octaves a crowded cell counts its entries in, by the key its lottery keeps them by (a front's lot over its
35
- * steepness; the lowest kept first), below the most it can keep: bin j holds keys from 2^-(j+1) of that reach to
36
- * 2^-j of it, the last everything below. A cell whose point could read past the gather budget drops its octaves from
37
- * the top until the rest fit its part of the budget, so it may keep up to an octave's worth fewer than would fit.
38
- */
39
- export const WATER_PARTICLE_CROWD_BINS: 4;
40
- /**
41
- * Words a bucket's crowd takes, as the weigh pass sums it: its summed steepness, its largest front and complement of a
42
- * front entered, and its entries.
43
- */
44
- export const WATER_PARTICLE_CROWD_WORDS: 4;
45
- /**
46
- * Words the nest pass adds to a bucket's crowd, in a buffer of their own so that it reads weigh's sums as plain loads:
47
- * the most entries and the most summed steepness a point under it reads where finer levels hold packets, and its
48
- * entries by key, {@link WATER_PARTICLE_CROWD_BINS} octaves.
49
- */
50
- export const WATER_PARTICLE_NEST_WORDS: number;
51
- /** Width of the ramp a thinned packet fades over, a fraction of its share. */
52
- export const WATER_PARTICLE_THINNING_RAMP: 0.25;
14
+ * How many places along the array either side a particle looks for its front's neighbours. A front keeps its
15
+ * particles in a row and in order — a ring is emitted whole, a split puts its three in its place, the dead leave no
16
+ * gap — and a mirror image sits right after the packet it left, so a neighbour is a place or two away, a few where
17
+ * images split beside their packets. A pair further apart, as a ring's last and first are, is drawn as two runs whose
18
+ * windows meet, the same surface.
19
+ */
20
+ export const WATER_PARTICLE_LINK_REACH: 8;
21
+ /**
22
+ * Most particles one entry draws. A run ends where its neighbours' supports leave its cell. A cell is under four
23
+ * support radii s across, so the particles reaching it stand within a square of under 6s, and an arc of a circle inside a
24
+ * square of side L is at most about πL long; the step keeps a front's neighbours at least a third of their envelope's
25
+ * half-length h apart (they split at h), so s is at most ~3.2 of their spacing, and a cell holds at most ~62 of one
26
+ * front. A front closer set than the step leaves is drawn with a hole past this many.
27
+ */
28
+ export const WATER_PARTICLE_RUN_LIMIT: 96;
29
+ /**
30
+ * Steepness classes a cell counts its runs in: half octaves of |a|/r below 0.1, the steepest a splash makes, the last
31
+ * everything flatter. A run's class is its front's, the same in every cell it reaches. The cut pass reads a cell's
32
+ * classes and total as vectors, written out for ten (WaterParticleCrowd).
33
+ */
34
+ export const WATER_PARTICLE_CROWD_BINS: 10;
35
+ /** Words a bucket's crowd takes, as the weigh pass counts it: its runs by steepness class, then all of them. */
36
+ export const WATER_PARTICLE_CROWD_WORDS: number;
37
+ /**
38
+ * Words the nest, cut and mark passes keep per bucket: the most runs a point under it reads at finer levels and its own
39
+ * and the coarser ones; how many steepness classes its points keep, the steepest first, within
40
+ * {@link WATER_PARTICLE_CROWD_KEEP}, and within the gather budget; and a slot of the frame's table of cut fronts.
41
+ */
42
+ export const WATER_PARTICLE_NEST_WORDS: 4;
43
+ /** Slots of the cut fronts' table a front's tag is looked for in, from its own: at most an eighth of them hold one. */
44
+ export const WATER_PARTICLE_FRONT_PROBES: 8;
45
+ /**
46
+ * Runs a crowded point keeps: the steepest, class by class, as many as fit. A run a crowd cannot keep at any of its
47
+ * cells dooms its particles (WATER_PARTICLE_STRUCT's `fading`): they fade and die as packets below the drawing threshold
48
+ * do, so the weakest go first and nothing doomed comes back. The surface sampler's gather budget above this holds the
49
+ * doomed while they fade; a run past the budget itself, as where fresh fronts arrive faster than doomed ones fade, is
50
+ * cut: it is not drawn and dies at its next step, and so does all of its front, which a cut would otherwise leave in
51
+ * pieces no cell counted. The steepest class is always kept: a fresh splash is drawn, though points where more of those
52
+ * cross than the budget holds then lose some.
53
+ */
54
+ export const WATER_PARTICLE_CROWD_KEEP: 48;
53
55
  /** The step's settings: one immediate per entry point. */
54
56
  export const WATER_PARTICLE_STEP_STRUCT: WebGPUStruct;
55
57
  /** The pool's limits for the frame's finalize. */
@@ -71,81 +73,91 @@ export const shader_water_particles_total: ComputeShader;
71
73
  * which this frame's binning does not visit, so the ring's bound is added to the body's own here.
72
74
  */
73
75
  export const shader_water_particles_emit: ComputeShader;
76
+ /**
77
+ * Words the frame's clear writes per bucket of the table: its count, its largest |a|, its crowd and its nest, four to a
78
+ * thread (the table is a power of two of at least {@link WATER_PARTICLE_TABLE_MIN} buckets, so each array is whole vec4s).
79
+ */
80
+ export const WATER_PARTICLE_CLEAR_WORDS: number;
74
81
  /**
75
82
  * The live count, clamped to capacity (emitters append past it), and the frame's hash table size: twice the
76
83
  * entries the particles can take, a power of two, at least ${WATER_PARTICLE_TABLE_MIN}; and the command that clears
77
- * that much of the table, a thread a bucket.
84
+ * that much of the table, a thread every four words, folded.
78
85
  */
79
86
  export const shader_water_particles_finalize: ComputeShader;
80
87
  /**
81
- * Zero the frame's table, as far as finalize sized it: each bucket's count, largest |a| and crowd. A frame pays for the
82
- * table its particles take, not for the pool's capacity; the buckets past it are never read.
88
+ * Clear the frame's table, as far as finalize sized it: each bucket's count, largest |a| and crowd, its points let keep
89
+ * and draw every steepness class until the cut pass says otherwise, and its slot of the cut fronts' table. A thread
90
+ * every four words, the words of each array in a row, so neighbouring threads write neighbouring words; a bucket's nest
91
+ * is its four. A frame pays for the table its particles take, not for the pool's capacity; the buckets past it are
92
+ * never read.
83
93
  */
84
94
  export const shader_water_particles_clear: ComputeShader;
85
95
  /**
86
- * Where each front's run of particles begins: 1 at a particle not of the front before it, else 0. A front keeps its
87
- * particles in a row and in order — a ring is emitted whole, a split puts its three in its place, the dead leave no
88
- * gap — so the inclusive scan of these numbers each run from 1. A mirror image follows its packet in the row: it
89
- * breaks its front's run there, as a death does, and is a front of its own.
96
+ * Two words a particle: its front's neighbours β before and after it round the front (water_particle_linked), or none,
97
+ * from the particles {@link WATER_PARTICLE_LINK_REACH} places either side of it. A pair is linked from both ends or
98
+ * neither, so each draws the other's side of their meeting or neither does, and their windows sum to one. And three
99
+ * more: the cells its support overlaps, which every pass after reads rather than works out again.
90
100
  */
91
- export const shader_water_particles_fronts: ComputeShader;
101
+ export const shader_water_particles_links: ComputeShader;
92
102
  /**
93
- * Two words a run: its first particle, and the share its crowd leaves it, none yet (the share pass lowers it).
103
+ * Each run of a body simulated this frame counted into every cell it is drawn in, by its steepness class
104
+ * ({@link WATER_PARTICLE_CROWD_WORDS}): how crowded the cell is, for the cut pass to keep its steepest by. And its level
105
+ * to its body's: a point reads a cell of every level its body has.
94
106
  */
95
- export const shader_water_particles_runs: ComputeShader;
107
+ export const shader_water_particles_weigh: ComputeShader;
96
108
  /**
97
- * Two words a particle: its run, and how the frame draws it ({@link chunk_water_particle}'s water_particle_group): 1 as
98
- * itself, 0 not at all, 3^g for the middle of a whole front's group of 3^g, drawn as one packet.
109
+ * Each run of a body simulated this frame, its cells weighed: the runs a point of the cell it is drawn in reads at that
110
+ * level and the coarser ones, raised onto the cell over it at every coarser level its body has, so a cell knows the most
111
+ * its points read where finer levels hold runs under it.
99
112
  */
100
- export const shader_water_particles_groups: ComputeShader;
113
+ export const shader_water_particles_nest: ComputeShader;
101
114
  /**
102
- * Each packet drawn of a body simulated this frame adds its steepness to every cell its support overlaps: how crowded
103
- * a cell is, for the share pass to thin it by. Per bucket ({@link WATER_PARTICLE_CROWD_WORDS}) the sum, the largest
104
- * front and complement of a front entered, which are each other's complements only where one front alone was, and the
105
- * entries. And its level to its body's: a point reads a cell of every level its body has.
115
+ * How many steepness classes each cell's points keep, the steepest first: as many as keep its most crowded point within
116
+ * {@link WATER_PARTICLE_CROWD_KEEP} runs, over its own cell and the coarser ones over it, class by class, and what finer
117
+ * levels add under it (the nest pass's most, less what its own and coarser cells hold), counted as the steepest, since a
118
+ * run sits finer the younger it is; and as many as keep it within the gather budget. Never fewer than one. Each run
119
+ * lowers its cell's bucket to what it finds.
106
120
  */
107
- export const shader_water_particles_weigh: ComputeShader;
121
+ export const shader_water_particles_cut: ComputeShader;
108
122
  /**
109
- * Each packet drawn of a body simulated this frame, its cells weighed: what a point of each of its cells reads at its
110
- * level and the coarser ones, entries and summed steepness, raised onto the cell over it at every coarser level its
111
- * body has, so a cell knows its most crowded point where finer levels hold packets under it; and its entry counted
112
- * among its cell's by its key (water_particle_crowd_bin), for the share pass to cap a crowd by.
123
+ * Each particle of a body simulated this frame whose steepness class some cell it reaches cannot draw within the gather
124
+ * budget, or that an earlier frame cut, puts its front's tag in the frame's table of cut fronts: the first free slot of
125
+ * {@link WATER_PARTICLE_FRONT_PROBES} from its front's own, or the one already holding it. Its front's particles are
126
+ * alike and β apart, so every one of them then finds the tag, and the front is cut whole.
113
127
  */
114
- export const shader_water_particles_nest: ComputeShader;
128
+ export const shader_water_particles_mark: ComputeShader;
129
+ /**
130
+ * What each crowd leaves of a body simulated this frame, particle by particle: a particle whose steepness class some
131
+ * cell it reaches does not keep is doomed, to fade from its next step and die (chunk_water_particle_step), and is drawn
132
+ * as it is until then; one whose front is in the frame's table of cut fronts (the mark pass) is not drawn, here or
133
+ * anywhere, and dies at its next step. So a crowd loses its flattest runs, and never by a lot or an order the particles
134
+ * arrive in. A frame that does not step decides the same again: nothing it reads has changed. One word a particle:
135
+ * whether it is drawn.
136
+ */
137
+ export const shader_water_particles_keep: ComputeShader;
115
138
  /**
116
- * Each packet drawn its share of the most crowded of its cells, lowered onto its run: a run is thinned whole, by the most
117
- * crowded cell any of its packets is in, so a front is never holed. A cell is crowded where its most crowded point (one
118
- * of it at its level and the coarser ones, or one under it the nest pass raised) reads more than
119
- * {@link WATER_PARTICLE_CELL_SHARE} entries, and a packet's share there is that many times its steepness over the summed
120
- * steepness that point reads. Where that point would read more than the gather budget, the cell keeps no more of it
121
- * than its own steepness's part: its keys' octaves dropped from the top until the rest fit
122
- * ({@link WATER_PARTICLE_CROWD_BINS}). A cell only one front reaches does not count.
123
- */
124
- export const shader_water_particles_share: ComputeShader;
125
- /**
126
- * Enter each packet drawn of a body simulated this frame in every hash cell its support overlaps: count it into the
127
- * cell's bucket, keep its slot there, raise the bucket's largest |a| to its own, and mark its level on its body. One
128
- * atomic each: no compare-exchange loop a crowded bucket would serialize. A paused body's particles take no slot:
129
- * nothing draws them this frame.
130
- *
131
- * Where cells are crowded (the share pass), a run is drawn by the share its most crowded cell leaves it and its
132
- * front's lot: one decision for all its packets and all their cells, so neither a front nor the surface across cells
133
- * is holed, and it does not change with the order particles arrive in. One left out takes no slot.
139
+ * Enter each drawn run of a body simulated this frame in every cell it is drawn in, by its first particle: count it into
140
+ * the cell's bucket, keep its slot there, raise the bucket's largest |a| to its own, and mark its level on its body. One
141
+ * atomic each: no compare-exchange loop a crowded bucket would serialize. A paused body's particles take no slot, nor
142
+ * does one its crowd does not draw: nothing draws them this frame.
134
143
  */
135
144
  export const shader_water_particles_bin: ComputeShader;
136
- /** Each entry to its bucket's range, in arrival order, at the height its crowd leaves it; the rank pass orders it. */
145
+ /**
146
+ * Each run's entry to its bucket's range, in arrival order; the rank pass orders it. A run is its first particle and its
147
+ * front's drawn neighbours after it, one by one, while their supports overlap the cell, at most
148
+ * {@link WATER_PARTICLE_RUN_LIMIT}; an end is open where the front has no drawn neighbour beyond it.
149
+ */
137
150
  export const shader_water_particles_scatter: ComputeShader;
138
151
  /**
139
- * Order every bucket by particle index then cell, so a gather that runs out of budget drops the same
152
+ * Order every bucket by its runs' first particles then cells, so a gather that runs out of budget drops the same
140
153
  * entries every frame (the particle array keeps its order from frame to frame). A bucket of more than
141
154
  * ${WATER_PARTICLE_RANK_LIMIT} keeps its arrival order: a fixed budget of comparisons per entry.
142
155
  */
143
156
  export const shader_water_particles_rank: ComputeShader;
144
157
  /**
145
- * Each body's bound per level: the largest of count × max |a| over the buckets its particles are in, which is
146
- * at least the bucket's Σ|a|. Every particle that reaches a point is in that point's cell's bucket, and neither
147
- * its height nor its horizontal displacement exceeds |a|, so the bound holds everywhere; a hash collision only
148
- * adds to it.
158
+ * Each body's bound per level: the largest of count × max |a| over the buckets its runs are in, which is at least the
159
+ * bucket's Σ|a|. Every run that reaches a point is in that point's cell's bucket, and neither its height nor its
160
+ * horizontal displacement exceeds |a|, so the bound holds everywhere; a hash collision only adds to it.
149
161
  */
150
162
  export const shader_water_particles_bounds: ComputeShader;
151
163
  import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
@@ -1 +1 @@
1
- {"version":3,"file":"shader_water_particles.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/shader_water_particles.js"],"names":[],"mappings":"AA0BA,uFAAuF;AACvF,uDAGE;AAEF,+DAA+D;AAC/D,8DAGE;AAEF,oFAAoF;AACpF,yDAGE;AAEF,0DAA0D;AAC1D,4CAA6C;AAE7C,gFAAgF;AAChF,uCAAwC;AAExC,uFAAuF;AACvF,2CAA4C;AAE5C;;;;;;;;;;;;;;;;;;GAkBG;AACH,2CAA4C;AAE5C;;;;;GAKG;AACH,0CAA2C;AAE3C;;;GAGG;AACH,2CAA4C;AAE5C;;;;GAIG;AACH,+CAAuE;AAEvE,8EAA8E;AAC9E,gDAAiD;AAUjD,0DAA0D;AAC1D,sDAAqH;AAErH,kDAAkD;AAClD,wDAA0H;AAuF1H,0DACyB;AAUzB;;;;GAIG;AACH,yDA4B+E;AAQ/E,0EAA0E;AAC1E,yDAOiD;AAYjD;;;;;;GAMG;AACH,wDAyC0C;AAS1C;;;;GAIG;AACH,4DAaiD;AASjD;;;GAGG;AACH,yDAWsC;AA6FtC;;;;;GAKG;AACH,0DAQ4D;AAQ5D;;GAEG;AACH,wDAY+E;AAS/E;;;GAGG;AACH,0DAc4D;AAW5D;;;;;GAKG;AACH,yDAuBkE;AAYlE;;;;;GAKG;AACH,wDAwCkE;AAalE;;;;;;;;GAQG;AACH,yDAoDkE;AAclE;;;;;;;;;GASG;AACH,uDA6BkE;AAWlE,sHAAsH;AACtH,2DAuBkE;AAWlE;;;;GAIG;AACH,wDAgCkE;AAWlE;;;;;GAKG;AACH,0DAuBkE;6BAp2BrC,sCAAsC;8BAJrC,kCAAkC"}
1
+ {"version":3,"file":"shader_water_particles.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/water/surface/particles/shader_water_particles.js"],"names":[],"mappings":"AA2BA,uFAAuF;AACvF,uDAGE;AAEF,+DAA+D;AAC/D,8DAGE;AAEF,oFAAoF;AACpF,yDAGE;AAEF,0DAA0D;AAC1D,4CAA6C;AAE7C,gFAAgF;AAChF,uCAAwC;AAExC,uFAAuF;AACvF,2CAA4C;AAE5C;;;;;;GAMG;AACH,0CAA2C;AAE3C;;;;;;GAMG;AACH,0CAA2C;AAE3C;;;;GAIG;AACH,2CAA4C;AAE5C,gHAAgH;AAChH,gDAAwE;AAExE;;;;GAIG;AACH,0CAA2C;AAE3C,uHAAuH;AACvH,4CAA6C;AAE7C;;;;;;;;GAQG;AACH,2CAA4C;AAU5C,0DAA0D;AAC1D,sDAAqH;AAErH,kDAAkD;AAClD,wDAA0H;AAuF1H,0DACyB;AAUzB;;;;GAIG;AACH,yDA4B+E;AAQ/E,0EAA0E;AAC1E,yDAOiD;AAYjD;;;;;;GAMG;AACH,wDAyC0C;AAS1C;;;GAGG;AACH,gDAAqG;AAErG;;;;GAIG;AACH,4DAciD;AASjD;;;;;;GAMG;AACH,yDAkBsC;AAkHtC;;;;;GAKG;AACH,yDAwBkE;AAYlE;;;;GAIG;AACH,yDAqBsE;AAatE;;;;GAIG;AACH,wDAiCsE;AAatE;;;;;;GAMG;AACH,uDA6EsE;AAUtE;;;;;GAKG;AACH,wDA2BuE;AAWvE;;;;;;;GAOG;AACH,wDAiCuE;AA0BvE;;;;;GAKG;AACH,uDA6B4E;AAY5E;;;;GAIG;AACH,2DAsCuE;AAWvE;;;;GAIG;AACH,wDA8BuE;AAYvE;;;;GAIG;AACH,0DAqBuE;6BAl/B1C,sCAAsC;8BAJrC,kCAAkC"}