@woosh/meep-engine 3.69.0 → 3.70.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 (398) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/package.json +1 -1
  4. package/src/core/bvh8/build/BVH8Converter.d.ts +16 -0
  5. package/src/core/bvh8/build/BVH8Converter.d.ts.map +1 -1
  6. package/src/core/bvh8/build/BVH8Converter.js +64 -37
  7. package/src/core/bvh8/build/bvh8_assign_slots_greedy.d.ts +25 -0
  8. package/src/core/bvh8/build/bvh8_assign_slots_greedy.d.ts.map +1 -0
  9. package/src/core/bvh8/build/bvh8_assign_slots_greedy.js +68 -0
  10. package/src/core/bvh8/build/bvh8_from_proxy.d.ts.map +1 -1
  11. package/src/core/bvh8/build/bvh8_from_proxy.js +2 -33
  12. package/src/core/bvh8/build/bvh8_node_fit_slots.d.ts +22 -0
  13. package/src/core/bvh8/build/bvh8_node_fit_slots.d.ts.map +1 -0
  14. package/src/core/bvh8/build/bvh8_node_fit_slots.js +115 -0
  15. package/src/core/bvh8/bvh8_depth.d.ts +8 -0
  16. package/src/core/bvh8/bvh8_depth.d.ts.map +1 -0
  17. package/src/core/bvh8/bvh8_depth.js +39 -0
  18. package/src/core/math/complex/complex_fft_radix2.d.ts +19 -0
  19. package/src/core/math/complex/complex_fft_radix2.d.ts.map +1 -0
  20. package/src/core/math/complex/complex_fft_radix2.js +71 -0
  21. package/src/engine/graphics3/GPUFluidSystem.d.ts +17 -4
  22. package/src/engine/graphics3/GPUFluidSystem.d.ts.map +1 -1
  23. package/src/engine/graphics3/GPUFluidSystem.js +113 -16
  24. package/src/engine/physics/cloth/playground/wind_main.js +7 -6
  25. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +2 -2
  26. package/src/engine/physics/cloth/wind/AbstractClothWind.js +2 -2
  27. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +3 -3
  28. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
  29. package/src/engine/physics/cloth/wind/ClothFluidWind.js +7 -9
  30. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.d.ts +10 -10
  31. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.d.ts.map +1 -1
  32. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.js +14 -22
  33. package/src/engine/physics/fluid/FluidAtmosphere.d.ts +16 -2
  34. package/src/engine/physics/fluid/FluidAtmosphere.d.ts.map +1 -1
  35. package/src/engine/physics/fluid/FluidAtmosphere.js +17 -3
  36. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.d.ts +1 -2
  37. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.d.ts.map +1 -1
  38. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.js +1 -2
  39. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.d.ts +8 -5
  40. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.d.ts.map +1 -1
  41. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.js +60 -17
  42. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts +1 -1
  43. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +1 -1
  44. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts +33 -47
  45. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
  46. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +38 -176
  47. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.d.ts +8 -11
  48. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.d.ts.map +1 -1
  49. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.js +13 -24
  50. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationUpgrader_0_1.d.ts +16 -0
  51. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationUpgrader_0_1.d.ts.map +1 -0
  52. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationUpgrader_0_1.js +35 -0
  53. package/src/engine/physics/fluid/fluid_apply_atmosphere.d.ts +1 -1
  54. package/src/engine/physics/fluid/fluid_apply_atmosphere.js +1 -1
  55. package/src/engine/physics/fluid/turbulence/FLUID_TURBULENCE_TILE.d.ts +28 -0
  56. package/src/engine/physics/fluid/turbulence/FLUID_TURBULENCE_TILE.d.ts.map +1 -0
  57. package/src/engine/physics/fluid/turbulence/FLUID_TURBULENCE_TILE.js +29 -0
  58. package/src/engine/physics/fluid/turbulence/fluid_atmosphere_velocity_at.d.ts +16 -0
  59. package/src/engine/physics/fluid/turbulence/fluid_atmosphere_velocity_at.d.ts.map +1 -0
  60. package/src/engine/physics/fluid/turbulence/fluid_atmosphere_velocity_at.js +49 -0
  61. package/src/engine/physics/fluid/turbulence/fluid_turbulence_inverse_tile_size.d.ts +11 -0
  62. package/src/engine/physics/fluid/turbulence/fluid_turbulence_inverse_tile_size.d.ts.map +1 -0
  63. package/src/engine/physics/fluid/turbulence/fluid_turbulence_inverse_tile_size.js +18 -0
  64. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_data.d.ts +25 -0
  65. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_data.d.ts.map +1 -0
  66. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_data.js +65 -0
  67. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_generate.d.ts +56 -0
  68. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_generate.d.ts.map +1 -0
  69. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_generate.js +313 -0
  70. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_sample.d.ts +16 -0
  71. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_sample.d.ts.map +1 -0
  72. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_sample.js +69 -0
  73. package/src/generation/foliage/mesh/branch_ring_triangulate.d.ts +1 -1
  74. package/src/generation/foliage/mesh/branch_ring_triangulate.js +1 -1
  75. package/src/shade/playground/bvh_repro/README.md +8 -6
  76. package/src/shade/playground/bvh_repro/index.html +125 -124
  77. package/src/shade/playground/bvh_repro/main.js +259 -254
  78. package/src/shade/playground/foliage_wind/foliage_world.d.ts.map +1 -1
  79. package/src/shade/playground/foliage_wind/foliage_world.js +7 -4
  80. package/src/shade/playground/grass_surfaces/main.js +3 -2
  81. package/src/shade/playground/particle_ecs/bonfire_wind.d.ts +23 -13
  82. package/src/shade/playground/particle_ecs/bonfire_wind.d.ts.map +1 -1
  83. package/src/shade/playground/particle_ecs/bonfire_wind.js +30 -33
  84. package/src/shade/playground/skinned_blas_refit/README.md +26 -14
  85. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts +14 -9
  86. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
  87. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +126 -127
  88. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +95 -95
  89. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts +9 -1
  90. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
  91. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +146 -135
  92. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts +6 -6
  93. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts.map +1 -1
  94. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.js +148 -134
  95. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.d.ts +11 -8
  96. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.d.ts.map +1 -1
  97. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +342 -202
  98. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts +12 -13
  99. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
  100. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +136 -116
  101. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts +4 -4
  102. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts.map +1 -1
  103. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +255 -249
  104. package/src/shade/playground/water_surface/main.js +6 -3
  105. package/src/shade/renderer/animation/GPUAnimationManager.js +2 -2
  106. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  107. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +7 -8
  108. package/src/shade/renderer/fluid/FLUID_FAR_FIELD_STRUCT.d.ts +111 -0
  109. package/src/shade/renderer/fluid/FLUID_FAR_FIELD_STRUCT.d.ts.map +1 -0
  110. package/src/shade/renderer/fluid/FLUID_FAR_FIELD_STRUCT.js +162 -0
  111. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +37 -8
  112. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts.map +1 -1
  113. package/src/shade/renderer/fluid/GPUFluidCascade.js +149 -47
  114. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +10 -3
  115. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
  116. package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +69 -10
  117. package/src/shade/renderer/fluid/chunk_fluid_far_field.d.ts +19 -0
  118. package/src/shade/renderer/fluid/chunk_fluid_far_field.d.ts.map +1 -0
  119. package/src/shade/renderer/fluid/chunk_fluid_far_field.js +43 -0
  120. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.d.ts +10 -9
  121. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.d.ts.map +1 -1
  122. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.js +14 -12
  123. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.d.ts +3 -2
  124. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.d.ts.map +1 -1
  125. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.js +7 -5
  126. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.d.ts +17 -9
  127. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.d.ts.map +1 -1
  128. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.js +58 -18
  129. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts +23 -11
  130. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts.map +1 -1
  131. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.js +371 -335
  132. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.d.ts.map +1 -1
  133. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.js +2 -1
  134. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.d.ts.map +1 -1
  135. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.js +109 -108
  136. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.d.ts +5 -3
  137. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.d.ts.map +1 -1
  138. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.js +24 -12
  139. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.d.ts +6 -2
  140. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.d.ts.map +1 -1
  141. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.js +10 -5
  142. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts +20 -21
  143. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts.map +1 -1
  144. package/src/shade/renderer/fluid/mac/FluidMacPasses.js +453 -427
  145. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -1
  146. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +2 -1
  147. package/src/shade/renderer/fluid/publish/FluidWindPublish.d.ts +13 -5
  148. package/src/shade/renderer/fluid/publish/FluidWindPublish.d.ts.map +1 -1
  149. package/src/shade/renderer/fluid/publish/FluidWindPublish.js +20 -10
  150. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.d.ts +2 -2
  151. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.js +2 -2
  152. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts +5 -3
  153. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts.map +1 -1
  154. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.js +147 -142
  155. package/src/shade/renderer/fluid/query/GPUFluidQueries.js +2 -2
  156. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  157. package/src/shade/renderer/geometry/GPUGeometryManager.js +5 -7
  158. package/src/shade/renderer/geometry/MeshletGeometry.d.ts +4 -1
  159. package/src/shade/renderer/geometry/MeshletGeometry.d.ts.map +1 -1
  160. package/src/shade/renderer/geometry/MeshletGeometry.js +4 -1
  161. package/src/shade/renderer/geometry/MeshletGeometrySerializationAdapter.d.ts +20 -0
  162. package/src/shade/renderer/geometry/MeshletGeometrySerializationAdapter.d.ts.map +1 -1
  163. package/src/shade/renderer/geometry/MeshletGeometrySerializationAdapter.js +35 -3
  164. package/src/shade/renderer/geometry/blas_from_meshlets.d.ts +9 -3
  165. package/src/shade/renderer/geometry/blas_from_meshlets.d.ts.map +1 -1
  166. package/src/shade/renderer/geometry/blas_from_meshlets.js +16 -30
  167. package/src/shade/renderer/geometry/bvh/BLAS8_REFIT_TARGET_STRUCT.d.ts +14 -0
  168. package/src/shade/renderer/geometry/bvh/BLAS8_REFIT_TARGET_STRUCT.d.ts.map +1 -0
  169. package/src/shade/renderer/geometry/bvh/BLAS8_REFIT_TARGET_STRUCT.js +33 -0
  170. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts +18 -21
  171. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts.map +1 -1
  172. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.js +78 -158
  173. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +18 -39
  174. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  175. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +39 -398
  176. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts +6 -7
  177. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts.map +1 -1
  178. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js +5 -7
  179. package/src/shade/renderer/geometry/bvh/bvh8_build_for_meshlets.d.ts +36 -0
  180. package/src/shade/renderer/geometry/bvh/bvh8_build_for_meshlets.d.ts.map +1 -0
  181. package/src/shade/renderer/geometry/bvh/bvh8_build_for_meshlets.js +179 -0
  182. package/src/shade/renderer/geometry/bvh/meshlet_batch_to_clustered_bvh.d.ts +30 -0
  183. package/src/shade/renderer/geometry/bvh/meshlet_batch_to_clustered_bvh.d.ts.map +1 -0
  184. package/src/shade/renderer/geometry/bvh/meshlet_batch_to_clustered_bvh.js +207 -0
  185. package/src/shade/renderer/geometry/bvh/shader_blas8_refit_batch.d.ts +52 -0
  186. package/src/shade/renderer/geometry/bvh/shader_blas8_refit_batch.d.ts.map +1 -0
  187. package/src/shade/renderer/geometry/bvh/shader_blas8_refit_batch.js +464 -0
  188. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts +12 -0
  189. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  190. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +37 -0
  191. package/src/shade/renderer/geometry/sdf/bake/shader_mesh_sdf_classify.d.ts.map +1 -1
  192. package/src/shade/renderer/geometry/sdf/bake/shader_mesh_sdf_classify.js +4 -4
  193. package/src/shade/renderer/geometry/sdf/bake/shader_mesh_sdf_evaluate.d.ts.map +1 -1
  194. package/src/shade/renderer/geometry/sdf/bake/shader_mesh_sdf_evaluate.js +2 -2
  195. package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts.map +1 -1
  196. package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.js +2 -2
  197. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts.map +1 -1
  198. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +4 -4
  199. package/src/shade/renderer/geometry/sdf/surface/shader_mesh_surface_trace.d.ts.map +1 -1
  200. package/src/shade/renderer/geometry/sdf/surface/shader_mesh_surface_trace.js +2 -2
  201. package/src/shade/renderer/geometry/sr_create_group_RTX.d.ts.map +1 -1
  202. package/src/shade/renderer/geometry/sr_create_group_RTX.js +4 -4
  203. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts.map +1 -1
  204. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +1 -0
  205. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  206. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +1 -0
  207. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts.map +1 -1
  208. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +372 -376
  209. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts +9 -10
  210. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts.map +1 -1
  211. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.js +10 -11
  212. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.d.ts +2 -2
  213. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.js +2 -2
  214. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts +12 -8
  215. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts.map +1 -1
  216. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.js +109 -60
  217. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_mesh_sdf.js +2 -2
  218. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_mesh_surfaces.js +2 -2
  219. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUFFER_LAYOUT.d.ts +2 -2
  220. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUFFER_LAYOUT.js +70 -70
  221. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUILD_SETTINGS_STRUCT.d.ts +6 -7
  222. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUILD_SETTINGS_STRUCT.d.ts.map +1 -1
  223. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUILD_SETTINGS_STRUCT.js +6 -7
  224. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts +3 -3
  225. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +3 -3
  226. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.js +1 -1
  227. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts +2 -2
  228. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +3 -3
  229. package/src/shade/renderer/gpu_primitive/bvh8/BVH8_TREE_BUFFER_LAYOUT.d.ts +69 -0
  230. package/src/shade/renderer/gpu_primitive/bvh8/BVH8_TREE_BUFFER_LAYOUT.d.ts.map +1 -0
  231. package/src/shade/renderer/gpu_primitive/bvh8/BVH8_TREE_BUFFER_LAYOUT.js +89 -0
  232. package/src/shade/renderer/gpu_primitive/bvh8/bvh8_encode_from_bvh2.d.ts +41 -0
  233. package/src/shade/renderer/gpu_primitive/bvh8/bvh8_encode_from_bvh2.d.ts.map +1 -0
  234. package/src/shade/renderer/gpu_primitive/bvh8/bvh8_encode_from_bvh2.js +348 -0
  235. package/src/shade/renderer/gpu_primitive/bvh8/check_bvh8_tree.d.ts +34 -0
  236. package/src/shade/renderer/gpu_primitive/bvh8/check_bvh8_tree.d.ts.map +1 -0
  237. package/src/shade/renderer/gpu_primitive/bvh8/check_bvh8_tree.js +291 -0
  238. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_assign.d.ts +31 -0
  239. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_assign.d.ts.map +1 -0
  240. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_assign.js +175 -0
  241. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_depth.d.ts +27 -0
  242. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_depth.d.ts.map +1 -0
  243. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_depth.js +48 -0
  244. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_gather.d.ts +26 -0
  245. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_gather.d.ts.map +1 -0
  246. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_gather.js +118 -0
  247. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_node.d.ts +22 -0
  248. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_node.d.ts.map +1 -0
  249. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_node.js +143 -0
  250. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_sums.d.ts +36 -0
  251. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_sums.d.ts.map +1 -0
  252. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_sums.js +97 -0
  253. package/src/shade/renderer/gpu_primitive/bvh8/graph_bvh8_encode_from_bvh2.d.ts +49 -0
  254. package/src/shade/renderer/gpu_primitive/bvh8/graph_bvh8_encode_from_bvh2.d.ts.map +1 -0
  255. package/src/shade/renderer/gpu_primitive/bvh8/graph_bvh8_encode_from_bvh2.js +265 -0
  256. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_assign.d.ts +37 -0
  257. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_assign.d.ts.map +1 -0
  258. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_assign.js +109 -0
  259. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count.d.ts +15 -0
  260. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count.d.ts.map +1 -0
  261. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count.js +85 -0
  262. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count_single_workgroup.d.ts +26 -0
  263. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count_single_workgroup.d.ts.map +1 -0
  264. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count_single_workgroup.js +200 -0
  265. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_parents.d.ts +19 -0
  266. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_parents.d.ts.map +1 -0
  267. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_parents.js +81 -0
  268. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_write.d.ts +14 -0
  269. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_write.d.ts.map +1 -0
  270. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_write.js +101 -0
  271. package/src/shade/renderer/gpu_primitive/bvh8/verify_gpu_bvh8_encode.d.ts +19 -0
  272. package/src/shade/renderer/gpu_primitive/bvh8/verify_gpu_bvh8_encode.d.ts.map +1 -0
  273. package/src/shade/renderer/gpu_primitive/bvh8/verify_gpu_bvh8_encode.js +361 -0
  274. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -1
  275. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +5 -6
  276. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  277. package/src/shade/renderer/lightmap/GPULightMap.js +1 -0
  278. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  279. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +1 -0
  280. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
  281. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +1 -0
  282. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +8 -4
  283. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  284. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +60 -33
  285. package/src/shade/renderer/scene/verify_gpu_tlas_build.d.ts +6 -6
  286. package/src/shade/renderer/scene/verify_gpu_tlas_build.d.ts.map +1 -1
  287. package/src/shade/renderer/scene/verify_gpu_tlas_build.js +23 -53
  288. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_INODE_STRUCT.d.ts +3 -1
  289. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_INODE_STRUCT.d.ts.map +1 -1
  290. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_INODE_STRUCT.js +5 -3
  291. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_MAX_DEPTH.d.ts +28 -0
  292. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_MAX_DEPTH.d.ts.map +1 -0
  293. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_MAX_DEPTH.js +29 -0
  294. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_grid.d.ts +25 -0
  295. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_grid.d.ts.map +1 -0
  296. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_grid.js +97 -0
  297. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_intersect.d.ts +8 -0
  298. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_intersect.d.ts.map +1 -1
  299. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_intersect.js +23 -14
  300. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_slot_distances.d.ts +36 -0
  301. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_slot_distances.d.ts.map +1 -0
  302. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_slot_distances.js +222 -0
  303. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_direction_rcp.d.ts +20 -0
  304. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_direction_rcp.d.ts.map +1 -0
  305. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_direction_rcp.js +30 -0
  306. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_tree_read.d.ts +30 -0
  307. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_tree_read.d.ts.map +1 -0
  308. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_tree_read.js +91 -0
  309. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_waiting_slots.d.ts +23 -0
  310. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_waiting_slots.d.ts.map +1 -0
  311. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_waiting_slots.js +40 -0
  312. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_nearest.d.ts +22 -0
  313. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_nearest.d.ts.map +1 -1
  314. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_nearest.js +121 -70
  315. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_occluded.d.ts +13 -1
  316. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_occluded.d.ts.map +1 -1
  317. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_occluded.js +117 -61
  318. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest.d.ts +21 -0
  319. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest.d.ts.map +1 -1
  320. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest.js +111 -72
  321. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +1 -2
  322. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -1
  323. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +83 -54
  324. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_occluded.d.ts +14 -0
  325. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_occluded.d.ts.map +1 -1
  326. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_occluded.js +92 -60
  327. package/src/shade/renderer/shader/chunk/sdf/chunk_point_query_blas_nearest.d.ts +22 -0
  328. package/src/shade/renderer/shader/chunk/sdf/chunk_point_query_blas_nearest.d.ts.map +1 -1
  329. package/src/shade/renderer/shader/chunk/sdf/chunk_point_query_blas_nearest.js +153 -106
  330. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_point_query_nearest.d.ts +21 -0
  331. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_point_query_nearest.d.ts.map +1 -1
  332. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_point_query_nearest.js +115 -74
  333. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.d.ts +5 -2
  334. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.d.ts.map +1 -1
  335. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.js +89 -63
  336. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_query_distance.d.ts +15 -0
  337. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_query_distance.d.ts.map +1 -1
  338. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_query_distance.js +108 -63
  339. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast.d.ts +14 -0
  340. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast.d.ts.map +1 -1
  341. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast.js +94 -60
  342. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts.map +1 -1
  343. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.js +4 -4
  344. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +2 -2
  345. package/src/shade/renderer/water/query/shader_water_surface_query.d.ts.map +1 -1
  346. package/src/shade/renderer/water/query/shader_water_surface_query.js +227 -227
  347. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -1
  348. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +7 -4
  349. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +2 -2
  350. package/src/shade/renderer/wind/GPUSceneWind.d.ts +36 -4
  351. package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
  352. package/src/shade/renderer/wind/GPUSceneWind.js +150 -4
  353. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts +9 -3
  354. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts.map +1 -1
  355. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.js +13 -3
  356. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +6 -6
  357. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +6 -6
  358. package/src/shade/renderer/wind/chunk_fluid_turbulence.d.ts +39 -0
  359. package/src/shade/renderer/wind/chunk_fluid_turbulence.d.ts.map +1 -0
  360. package/src/shade/renderer/wind/chunk_fluid_turbulence.js +63 -0
  361. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +10 -7
  362. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
  363. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +34 -11
  364. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +2 -2
  365. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +2 -2
  366. package/src/shade/renderer/wind/wind_field_add_resources.d.ts +6 -4
  367. package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
  368. package/src/shade/renderer/wind/wind_field_add_resources.js +9 -6
  369. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.d.ts +0 -18
  370. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.d.ts.map +0 -1
  371. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.js +0 -50
  372. package/src/shade/renderer/geometry/bvh/bvh2_derive_topology.d.ts +0 -23
  373. package/src/shade/renderer/geometry/bvh/bvh2_derive_topology.d.ts.map +0 -1
  374. package/src/shade/renderer/geometry/bvh/bvh2_derive_topology.js +0 -87
  375. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.d.ts +0 -42
  376. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.d.ts.map +0 -1
  377. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.js +0 -141
  378. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.d.ts +0 -21
  379. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.d.ts.map +0 -1
  380. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.js +0 -75
  381. package/src/shade/renderer/geometry/meshlet_batch_to_bvh.d.ts +0 -17
  382. package/src/shade/renderer/geometry/meshlet_batch_to_bvh.d.ts.map +0 -1
  383. package/src/shade/renderer/geometry/meshlet_batch_to_bvh.js +0 -247
  384. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_query_blas_occlusion.d.ts +0 -7
  385. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_query_blas_occlusion.d.ts.map +0 -1
  386. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_query_blas_occlusion.js +0 -226
  387. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mask_visibility_via_rays.d.ts +0 -8
  388. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mask_visibility_via_rays.d.ts.map +0 -1
  389. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mask_visibility_via_rays.js +0 -45
  390. package/src/shade/renderer/shader/chunk/light/sample/chunk_ray_sample_light.d.ts +0 -3
  391. package/src/shade/renderer/shader/chunk/light/sample/chunk_ray_sample_light.d.ts.map +0 -1
  392. package/src/shade/renderer/shader/chunk/light/sample/chunk_ray_sample_light.js +0 -105
  393. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_distance.d.ts +0 -6
  394. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_distance.d.ts.map +0 -1
  395. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_distance.js +0 -86
  396. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast_traversal_count.d.ts +0 -2
  397. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast_traversal_count.d.ts.map +0 -1
  398. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast_traversal_count.js +0 -136
@@ -32,11 +32,12 @@ export const GPU_FLUID_SYSTEM_TICK_CAP: number;
32
32
  * new Entity().add(new Transform64()).add(new GPUFluidComponent()).build(dataset);
33
33
  * ```
34
34
  *
35
- * ## The CPU half: {@link far_field}
35
+ * ## The CPU half: {@link far_field} and {@link far_field_at}
36
36
  *
37
37
  * The far field in m/s, synchronously, from {@link FluidEffectorsSystem}'s fold: deterministic, the
38
38
  * same headless as on a device, and still air with no `FluidEffectorsSystem`. Gameplay reads this,
39
- * never the fluid (§6).
39
+ * never the fluid (§6). `far_field` is its mean; `far_field_at` is the far field at a point, its
40
+ * turbulence included, as every GPU reader of the wind field takes it beyond the cascades.
40
41
  *
41
42
  * ## The CPU half: {@link request}, a lattice of the wind, asynchronously
42
43
  *
@@ -58,8 +59,8 @@ export const GPU_FLUID_SYSTEM_TICK_CAP: number;
58
59
  * most 4 batches (a frame's requests each) in flight; a frame's requests past that are dropped,
59
60
  * with the status. Measured latency: see the proposal (§12). Rows are freed after delivery or a
60
61
  * drop. A device restart drops what was in flight; requests not yet recorded go to the new device.
61
- * - **Headless** (no scene context at the update): answered from {@link far_field} at the next
62
- * {@link update}, every point the far field.
62
+ * - **Headless** (no scene context at the update): answered from {@link far_field_at} at the next
63
+ * {@link update}, every point the far field there.
63
64
  *
64
65
  * At steady state nothing is allocated per request.
65
66
  *
@@ -168,6 +169,18 @@ export class GPUFluidSystem extends System<any> {
168
169
  * @param {Float64Array|Float32Array|number[]} out receives `[x, y, z]`
169
170
  */
170
171
  far_field(out: Float64Array | Float32Array | number[]): void;
172
+ /**
173
+ * The far field now at a world point, m/s: its mean plus its turbulence there, `u + σ·T((x − o) ⊙ S⁻¹)`,
174
+ * as every GPU reader of the wind field takes it where no cascade holds the point
175
+ * (`fluid_atmosphere_velocity_at`). Synchronous and deterministic, with or without a device; the mean
176
+ * alone ({@link far_field}) with no turbulence. Allocates nothing once the turbulence tile exists.
177
+ *
178
+ * @param {Float64Array|Float32Array|number[]} out receives `[x, y, z]`
179
+ * @param {number} x world metres
180
+ * @param {number} y
181
+ * @param {number} z
182
+ */
183
+ far_field_at(out: Float64Array | Float32Array | number[], x: number, y: number, z: number): void;
171
184
  /**
172
185
  * What became of each request, by handle: a `GPUReadbackStatus`. `Pending` from {@link request}
173
186
  * until the apply point ({@link update}) that answers it, `Delivered` (the lattice is in its
@@ -1 +1 @@
1
- {"version":3,"file":"GPUFluidSystem.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/GPUFluidSystem.js"],"names":[],"mappings":"AAyCA;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,wCAFU,MAAM,CAE2B;AAmG3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkGG;AACH;IAEI;;;;;OAKG;IACH,iCAFW,OAAO,gDAAgD,EAAE,eAAe,QAMlF;IAyID;;;OAGG;IACH,sBAHW,OAAO,qBAAqB,EAAE,cAAc,SAC5C,OAAO,qCAAqC,EAAE,KAAK,EAU7D;IAnJD,gEAAgD;IAEhD,oOAME;IA6IF;;OAEG;IACH,iEAEC;IAED;;;;;OAKG;IACH,qBAEC;IAED;;;;;OAKG;IACH,kCAEC;IAED;;;;;OAKG;IACH,+BAEC;IAED;;;;;OAKG;IACH,iCAEC;IAED;;;;;;OAMG;IACH,eAFW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,QAQ5C;IAED;;;;;;;;;;OAUG;IACH,yBAEC;IAED;;;;;OAKG;IACH,+BAEC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,eAbW,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,WACN,MAAM,WACN,MAAM,WACN,MAAM,UACN,YAAY,iBACZ,MAAM,GACJ,MAAM,CA+ClB;IAmMD,2CAOC;IAED,4CAaC;IA4DD;;;;OAIG;IACH,gBAJW,iBAAiB,aACjB,WAAW,UACX,MAAM,QAOhB;IAED;;;;OAIG;IACH,kBAJW,iBAAiB,aACjB,WAAW,UACX,MAAM,QAiBhB;IAqiBD;;;;;OAKG;IACH,eAFW,YAAY,QAetB;IAkKL;;;;;;;OAOG;IACH,2BAFU,OAAO,CAEwB;;CAVxC;AAYD;;;GAGG;AACH;IAII;;OAEG;IACH,oBAFW,cAAc,EAMxB;IADG,uBAAoB;CAkB3B;8BA1kDY,OAAO,+CAA+C,EAAE,eAAe;2BACvE,OAAO,gDAAgD,EAAE,YAAY;oCACrE,OAAO,oDAAoD,EAAE,qBAAqB;kCAClF,OAAO,kEAAkE,EAAE,mBAAmB;kCAC9F,OAAO,2DAA2D,EAAE,mBAAmB;8BACvF,OAAO,6CAA6C,EAAE,eAAe;uBAjC3D,kBAAkB;4BACb,iCAAiC;kCAWtD,2CAA2C;wCARV,iDAAiD;4CAf7C,iDAAiD;8BAiB/D,uCAAuC;yBAJ5C,4BAA4B;0BAC3B,6BAA6B;qCARlB,oDAAoD;gCADzD,uDAAuD;gCAE5B,qDAAqD;gCAJhF,mDAAmD"}
1
+ {"version":3,"file":"GPUFluidSystem.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/GPUFluidSystem.js"],"names":[],"mappings":"AA0CA;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,wCAFU,MAAM,CAE2B;AAiH3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmGG;AACH;IAEI;;;;;OAKG;IACH,iCAFW,OAAO,gDAAgD,EAAE,eAAe,QAMlF;IAkJD;;;OAGG;IACH,sBAHW,OAAO,qBAAqB,EAAE,cAAc,SAC5C,OAAO,qCAAqC,EAAE,KAAK,EAU7D;IA5JD,gEAAgD;IAEhD,oOAME;IAsJF;;OAEG;IACH,iEAEC;IAED;;;;;OAKG;IACH,qBAEC;IAED;;;;;OAKG;IACH,kCAEC;IAED;;;;;OAKG;IACH,+BAEC;IAED;;;;;OAKG;IACH,iCAEC;IAED;;;;;;OAMG;IACH,eAFW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,QAQ5C;IAED;;;;;;;;;;OAUG;IACH,kBALW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,KAClC,MAAM,KACN,MAAM,KACN,MAAM,QAIhB;IAED;;;;;;;;;;OAUG;IACH,yBAEC;IAED;;;;;OAKG;IACH,+BAEC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,eAbW,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,WACN,MAAM,WACN,MAAM,WACN,MAAM,UACN,YAAY,iBACZ,MAAM,GACJ,MAAM,CA+ClB;IA+ND,2CAOC;IAED,4CAaC;IA4DD;;;;OAIG;IACH,gBAJW,iBAAiB,aACjB,WAAW,UACX,MAAM,QAOhB;IAED;;;;OAIG;IACH,kBAJW,iBAAiB,aACjB,WAAW,UACX,MAAM,QAiBhB;IAqiBD;;;;;OAKG;IACH,eAFW,YAAY,QAetB;IA+LL;;;;;;;OAOG;IACH,2BAFU,OAAO,CAEwB;;CAVxC;AAYD;;;GAGG;AACH;IAII;;OAEG;IACH,oBAFW,cAAc,EAMxB;IADG,uBAAoB;CAkB3B;8BA1qDY,OAAO,+CAA+C,EAAE,eAAe;2BACvE,OAAO,gDAAgD,EAAE,YAAY;oCACrE,OAAO,oDAAoD,EAAE,qBAAqB;kCAClF,OAAO,kEAAkE,EAAE,mBAAmB;kCAC9F,OAAO,2DAA2D,EAAE,mBAAmB;8BACvF,OAAO,6CAA6C,EAAE,eAAe;uBAlC3D,kBAAkB;4BACb,iCAAiC;kCAWtD,2CAA2C;wCARV,iDAAiD;4CAf7C,iDAAiD;8BAiB/D,uCAAuC;yBAJ5C,4BAA4B;0BAC3B,6BAA6B;qCARlB,oDAAoD;gCADzD,uDAAuD;gCAE5B,qDAAqD;gCAJhF,mDAAmD"}
@@ -27,6 +27,7 @@ import {
27
27
  } from "../physics/fluid/ecs/GPUFluidComponent.js";
28
28
  import { fluid_effector_record_create } from "../physics/fluid/effector/record/fluid_effector_record_create.js";
29
29
  import { FLUID_ATMOSPHERE_WORDS, FluidAtmosphere } from "../physics/fluid/FluidAtmosphere.js";
30
+ import { fluid_atmosphere_velocity_at } from "../physics/fluid/turbulence/fluid_atmosphere_velocity_at.js";
30
31
  import { fluid_obstacle_record_create } from "../physics/fluid/obstacle/fluid_obstacle_record_create.js";
31
32
  import {
32
33
  FLUID_OBSTACLE_PLANES_CHANGED,
@@ -154,6 +155,20 @@ class ObstacleEntry {
154
155
  held = false;
155
156
  }
156
157
 
158
+ /**
159
+ * Point `i` of `n` along an axis of a request's box: `mix(min, max, i / (n − 1))`, or `min` for one
160
+ * point, as the device's gather places it.
161
+ *
162
+ * @param {number} min
163
+ * @param {number} max
164
+ * @param {number} i
165
+ * @param {number} n
166
+ * @returns {number}
167
+ */
168
+ function request_axis_point(min, max, i, n) {
169
+ return n > 1 ? min + (max - min) * (i / (n - 1)) : min;
170
+ }
171
+
157
172
  /**
158
173
  * # The GPU wind fluid of a scene
159
174
  *
@@ -172,11 +187,12 @@ class ObstacleEntry {
172
187
  * new Entity().add(new Transform64()).add(new GPUFluidComponent()).build(dataset);
173
188
  * ```
174
189
  *
175
- * ## The CPU half: {@link far_field}
190
+ * ## The CPU half: {@link far_field} and {@link far_field_at}
176
191
  *
177
192
  * The far field in m/s, synchronously, from {@link FluidEffectorsSystem}'s fold: deterministic, the
178
193
  * same headless as on a device, and still air with no `FluidEffectorsSystem`. Gameplay reads this,
179
- * never the fluid (§6).
194
+ * never the fluid (§6). `far_field` is its mean; `far_field_at` is the far field at a point, its
195
+ * turbulence included, as every GPU reader of the wind field takes it beyond the cascades.
180
196
  *
181
197
  * ## The CPU half: {@link request}, a lattice of the wind, asynchronously
182
198
  *
@@ -198,8 +214,8 @@ class ObstacleEntry {
198
214
  * most 4 batches (a frame's requests each) in flight; a frame's requests past that are dropped,
199
215
  * with the status. Measured latency: see the proposal (§12). Rows are freed after delivery or a
200
216
  * drop. A device restart drops what was in flight; requests not yet recorded go to the new device.
201
- * - **Headless** (no scene context at the update): answered from {@link far_field} at the next
202
- * {@link update}, every point the far field.
217
+ * - **Headless** (no scene context at the update): answered from {@link far_field_at} at the next
218
+ * {@link update}, every point the far field there.
203
219
  *
204
220
  * At steady state nothing is allocated per request.
205
221
  *
@@ -370,6 +386,15 @@ export class GPUFluidSystem extends System {
370
386
  #bounds = new Float64Array(6);
371
387
  #far = new Float64Array(3);
372
388
 
389
+ /** The turbulence `σ` last written into the wind field with no domain. */
390
+ #wind_sigma = 0;
391
+
392
+ /** Scratch for an atmosphere's turbulence offset. */
393
+ #turbulence_offset = new Float64Array(3);
394
+
395
+ /** The atmosphere a tick steps against, its turbulence carried back to the tick. */
396
+ #tick_atmosphere = new Float64Array(FLUID_ATMOSPHERE_WORDS);
397
+
373
398
  /*
374
399
  The read API: per handle, the request's box and counts, its target, and its status.
375
400
  */
@@ -478,6 +503,21 @@ export class GPUFluidSystem extends System {
478
503
  out[2] = atmosphere[FluidAtmosphere.VELOCITY_Z];
479
504
  }
480
505
 
506
+ /**
507
+ * The far field now at a world point, m/s: its mean plus its turbulence there, `u + σ·T((x − o) ⊙ S⁻¹)`,
508
+ * as every GPU reader of the wind field takes it where no cascade holds the point
509
+ * (`fluid_atmosphere_velocity_at`). Synchronous and deterministic, with or without a device; the mean
510
+ * alone ({@link far_field}) with no turbulence. Allocates nothing once the turbulence tile exists.
511
+ *
512
+ * @param {Float64Array|Float32Array|number[]} out receives `[x, y, z]`
513
+ * @param {number} x world metres
514
+ * @param {number} y
515
+ * @param {number} z
516
+ */
517
+ far_field_at(out, x, y, z) {
518
+ fluid_atmosphere_velocity_at(out, this.#read_atmosphere(), 0, x, y, z);
519
+ }
520
+
481
521
  /**
482
522
  * What became of each request, by handle: a `GPUReadbackStatus`. `Pending` from {@link request}
483
523
  * until the apply point ({@link update}) that answers it, `Delivered` (the lattice is in its
@@ -646,26 +686,38 @@ export class GPUFluidSystem extends System {
646
686
  return;
647
687
  }
648
688
 
649
- // headless: every point the far field
689
+ // headless: every point the far field there, at the points the device would gather
650
690
  const far = this.#far;
651
-
652
- this.far_field(far);
691
+ const atmosphere = this.#read_atmosphere();
653
692
 
654
693
  const asked = this.#asked;
655
694
  const counts = this.#request_counts;
695
+ const box = this.#request_box;
656
696
 
657
697
  for (let i = 0; i < this.#asked_count; i++) {
658
698
  const h = asked[i];
659
699
  const target = this.#request_targets[h];
660
- const points = counts[3 * h] * counts[3 * h + 1] * counts[3 * h + 2];
700
+ const nx = counts[3 * h], ny = counts[3 * h + 1], nz = counts[3 * h + 2];
661
701
 
662
702
  let at = this.#request_offsets[h];
663
703
 
664
- for (let p = 0; p < points; p++, at += FLUID_QUERY_SAMPLE_FLOATS) {
665
- target[at] = far[0];
666
- target[at + 1] = far[1];
667
- target[at + 2] = far[2];
668
- target[at + 3] = 0;
704
+ for (let k = 0; k < nz; k++) {
705
+ const z = request_axis_point(box[6 * h + 2], box[6 * h + 5], k, nz);
706
+
707
+ for (let j = 0; j < ny; j++) {
708
+ const y = request_axis_point(box[6 * h + 1], box[6 * h + 4], j, ny);
709
+
710
+ for (let p = 0; p < nx; p++, at += FLUID_QUERY_SAMPLE_FLOATS) {
711
+ const x = request_axis_point(box[6 * h], box[6 * h + 3], p, nx);
712
+
713
+ fluid_atmosphere_velocity_at(far, atmosphere, 0, x, y, z);
714
+
715
+ target[at] = far[0];
716
+ target[at + 1] = far[1];
717
+ target[at + 2] = far[2];
718
+ target[at + 3] = 0;
719
+ }
720
+ }
669
721
  }
670
722
 
671
723
  this.#settle(h, GPUReadbackStatus.Delivered);
@@ -740,6 +792,22 @@ export class GPUFluidSystem extends System {
740
792
  this.#queries = null;
741
793
  }
742
794
 
795
+ /**
796
+ * The turbulence's offset in an atmosphere record, into {@link #turbulence_offset}.
797
+ *
798
+ * @param {Float64Array} atmosphere
799
+ * @returns {Float64Array}
800
+ */
801
+ #read_turbulence_offset(atmosphere) {
802
+ const out = this.#turbulence_offset;
803
+
804
+ out[0] = atmosphere[FluidAtmosphere.TURBULENCE_OFFSET_X];
805
+ out[1] = atmosphere[FluidAtmosphere.TURBULENCE_OFFSET_Y];
806
+ out[2] = atmosphere[FluidAtmosphere.TURBULENCE_OFFSET_Z];
807
+
808
+ return out;
809
+ }
810
+
743
811
  /**
744
812
  * The far field and its terms, into {@link #atmosphere}; still air at time 0 with no effectors
745
813
  * system.
@@ -1556,16 +1624,39 @@ export class GPUFluidSystem extends System {
1556
1624
  anchor[1] = transform.translation_y;
1557
1625
  anchor[2] = transform.translation_z;
1558
1626
 
1627
+ const wind = context.wind;
1628
+ const sigma = atmosphere[FluidAtmosphere.TURBULENCE_SIGMA];
1629
+
1630
+ // the tile, before any pass binds it
1631
+ if (sigma !== 0) {
1632
+ this.#read_turbulence_offset(atmosphere);
1633
+ wind.set_turbulence(sigma, this.#turbulence_offset, atmosphere[FluidAtmosphere.TURBULENCE_LENGTH]);
1634
+ }
1635
+
1636
+ const tick_atmosphere = this.#tick_atmosphere;
1637
+ tick_atmosphere.set(atmosphere);
1638
+
1559
1639
  for (let tick = first_tick; tick <= tick_now; tick++) {
1640
+ // every tick steps against the far field at the end of the frame's last, its eddies
1641
+ // carried back by the mean to where the tick left them, so a frame of several ticks
1642
+ // advances them as one tick at a time does
1643
+ const behind = (tick_now - tick) * dt;
1644
+
1645
+ tick_atmosphere[FluidAtmosphere.TURBULENCE_OFFSET_X] = atmosphere[FluidAtmosphere.TURBULENCE_OFFSET_X] - atmosphere[FluidAtmosphere.VELOCITY_X] * behind;
1646
+ tick_atmosphere[FluidAtmosphere.TURBULENCE_OFFSET_Y] = atmosphere[FluidAtmosphere.TURBULENCE_OFFSET_Y] - atmosphere[FluidAtmosphere.VELOCITY_Y] * behind;
1647
+ tick_atmosphere[FluidAtmosphere.TURBULENCE_OFFSET_Z] = atmosphere[FluidAtmosphere.TURBULENCE_OFFSET_Z] - atmosphere[FluidAtmosphere.VELOCITY_Z] * behind;
1648
+
1560
1649
  stack.record_tick({
1561
1650
  graph,
1562
1651
  tick,
1563
1652
  dt,
1564
1653
  anchor,
1565
- atmosphere,
1654
+ atmosphere: tick_atmosphere,
1566
1655
  atmosphere_offset: 0,
1567
1656
  forcing: this.#forcing,
1568
1657
  vorticity_confinement: domain.component.vorticity_confinement,
1658
+ // always the wind's: a cascade may still hold turbulence the far field has let go of
1659
+ turbulence: wind.turbulence,
1569
1660
  });
1570
1661
  }
1571
1662
  }
@@ -1583,25 +1674,31 @@ export class GPUFluidSystem extends System {
1583
1674
  }
1584
1675
 
1585
1676
  /**
1586
- * With no domain, the wind field is the far field alone: written when it changes.
1677
+ * With no domain, the wind field is the far field alone: written when it changes, which with
1678
+ * turbulence is every frame, the mean carrying the eddies.
1587
1679
  *
1588
1680
  * @param {GPUSceneContext} context
1589
1681
  */
1590
1682
  #publish_far_field(context) {
1591
1683
  const far = this.#far;
1592
1684
  const written = this.#wind_far;
1685
+ const atmosphere = this.#read_atmosphere();
1686
+ const sigma = atmosphere[FluidAtmosphere.TURBULENCE_SIGMA];
1593
1687
 
1594
1688
  this.far_field(far);
1595
1689
 
1596
- if (far[0] === written[0] && far[1] === written[1] && far[2] === written[2]) {
1690
+ if (far[0] === written[0] && far[1] === written[1] && far[2] === written[2] && sigma === 0 && this.#wind_sigma === 0) {
1597
1691
  return;
1598
1692
  }
1599
1693
 
1600
1694
  const wind = context.wind;
1601
1695
 
1602
1696
  wind.set_far_velocity(far);
1697
+ wind.set_turbulence(sigma, this.#read_turbulence_offset(atmosphere), atmosphere[FluidAtmosphere.TURBULENCE_LENGTH]);
1603
1698
  wind.update();
1604
1699
 
1700
+ this.#wind_sigma = sigma;
1701
+
1605
1702
  written[0] = far[0];
1606
1703
  written[1] = far[1];
1607
1704
  written[2] = far[2];
@@ -34,7 +34,7 @@ import { build_wind_tunnel, place_wind_post } from "./wind_build.js";
34
34
  * scene would use. The global acts as a scene's do: `FluidEffectorsSystem` folds
35
35
  * it into the far field once a step, the field is brought to that far field
36
36
  * (`fluid_apply_atmosphere`), and the cloth reads the same far field outside the
37
- * volume — one wind, gust included (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md G2).
37
+ * volume — one wind, turbulence included (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md G2).
38
38
  * That is §10's whole argument — this engine already has something better than a
39
39
  * wind zone — put where it can be watched instead of read.
40
40
  *
@@ -56,7 +56,7 @@ import { build_wind_tunnel, place_wind_post } from "./wind_build.js";
56
56
  * shedding street — it is a steady deficit, and the free corner moves twelve
57
57
  * times as far per step with the post as without rather than fluttering.
58
58
  *
59
- * And **"far field only"** is §10's fallback: the global's wind and its gust,
59
+ * And **"far field only"** is §10's fallback: the global's wind and its turbulence,
60
60
  * uniform over the whole banner, read through the same interface. It costs one
61
61
  * sample for the whole cloth instead of one per particle, which the readout
62
62
  * shows as the sample time dropping by a factor of twenty-five.
@@ -245,10 +245,11 @@ function step_once() {
245
245
  tunnel.effector.wind[1] = 0;
246
246
  tunnel.effector.wind[2] = Math.cos(angle) * control.speed;
247
247
 
248
- // The gust is the global's, so the far field carries it inside the volume
249
- // and outside alike.
250
- tunnel.effector.gust = control.gust;
251
- tunnel.effector.gust_period = 1.6;
248
+ // The turbulence is the global's, read where the cloth hangs outside the
249
+ // volume; the CPU fluid inside takes the mean. The slider is its rms, and its
250
+ // strongest eddies (4.05·L) go by every 1.6 s.
251
+ tunnel.effector.turbulence_intensity = control.speed > 0 ? control.gust / control.speed : 0;
252
+ tunnel.effector.turbulence_length = control.speed > 0 ? control.speed * 1.6 / 4.05 : tunnel.effector.turbulence_length;
252
253
 
253
254
  // 1. The air. The far field folded, then a real fluid step brought to it,
254
255
  // with the post's wake in it — what `FluidSystem` does for a scene.
@@ -30,12 +30,12 @@
30
30
  * they read the same bytes of it.
31
31
  *
32
32
  * **The clock is the scene's** (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §12,
33
- * G2). The far field's gust is integrated once a tick by `FluidEffectorsSystem`,
33
+ * G2). The far field is integrated once a tick by `FluidEffectorsSystem`,
34
34
  * so a cloth steps in the weather of the tick it is advanced on — and a worker
35
35
  * cloth is advanced from the tick its registration is acknowledged, not the tick
36
36
  * it was linked (`MEASUREMENTS.md` §39, §57). So the gate holds for cloths
37
37
  * registered on the same tick under both systems, and for any registration
38
- * under a time-invariant wind; under a gust, a cloth the worker registers later
38
+ * under a time-invariant wind; under a varying one, a cloth the worker registers later
39
39
  * steps in later weather. And the GPU wind arrives when the GPU answers, so two
40
40
  * runs of a scene need not read the same air at all: run-to-run repeatability
41
41
  * under the GPU wind is given up (F4). `MEASUREMENTS.md` §69.
@@ -30,12 +30,12 @@
30
30
  * they read the same bytes of it.
31
31
  *
32
32
  * **The clock is the scene's** (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §12,
33
- * G2). The far field's gust is integrated once a tick by `FluidEffectorsSystem`,
33
+ * G2). The far field is integrated once a tick by `FluidEffectorsSystem`,
34
34
  * so a cloth steps in the weather of the tick it is advanced on — and a worker
35
35
  * cloth is advanced from the tick its registration is acknowledged, not the tick
36
36
  * it was linked (`MEASUREMENTS.md` §39, §57). So the gate holds for cloths
37
37
  * registered on the same tick under both systems, and for any registration
38
- * under a time-invariant wind; under a gust, a cloth the worker registers later
38
+ * under a time-invariant wind; under a varying one, a cloth the worker registers later
39
39
  * steps in later weather. And the GPU wind arrives when the GPU answers, so two
40
40
  * runs of a scene need not read the same air at all: run-to-run repeatability
41
41
  * under the GPU wind is given up (F4). `MEASUREMENTS.md` §69.
@@ -15,9 +15,9 @@
15
15
  * (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §6). So this is the one source a
16
16
  * CPU-fluid scene needs rather than a thing to switch between: a banner inside
17
17
  * a wind tunnel volume reads the tunnel, the same banner carried outside reads
18
- * the prevailing weather and its gust, and the cloth never learns which
19
- * happened. The gust runs on the scene's clock (G2), so `sample`'s `time` is not
20
- * read.
18
+ * the prevailing weather and its turbulence where it hangs, and the cloth never
19
+ * learns which happened. The far field runs on the scene's clock (G2), so
20
+ * `sample`'s `time` is not read.
21
21
  *
22
22
  * ## Two units problems, and they are the reason this class exists at all
23
23
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ClothFluidWind.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/wind/ClothFluidWind.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH;IAmCI;;;;OAIG;IACH,uBAJW,OAAO,yCAAyC,EAAE,oBAAoB,EAWhF;IA7CD;;;;OAIG;IACH,oBAAY;IAEZ;;;;OAIG;IACH,qBAAwD;IAExD;;;;OAIG;IACH,qBAAkB;IAElB;;;OAGG;IACH,iBAAc;IAEd;;;OAGG;IACH,gBAAY;IAgBZ;;;OAGG;IACH,wFAEC;CAkHJ;kCArOiC,wBAAwB"}
1
+ {"version":3,"file":"ClothFluidWind.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/wind/ClothFluidWind.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH;IAmCI;;;;OAIG;IACH,uBAJW,OAAO,yCAAyC,EAAE,oBAAoB,EAWhF;IA7CD;;;;OAIG;IACH,oBAAY;IAEZ;;;;OAIG;IACH,qBAAwD;IAExD;;;;OAIG;IACH,qBAAkB;IAElB;;;OAGG;IACH,iBAAc;IAEd;;;OAGG;IACH,gBAAY;IAgBZ;;;OAGG;IACH,wFAEC;CA+GJ;kCAnOiC,wBAAwB"}
@@ -4,6 +4,7 @@ import { FluidComponent } from "../../fluid/ecs/FluidComponent.js";
4
4
  import { fluid_sample_domain_bounds } from "../../fluid/ecs/fluid_sample_domain_bounds.js";
5
5
  import { fluid_sample_velocity_world_mps } from "../../fluid/ecs/fluid_sample_velocity_world_mps.js";
6
6
  import { AbstractClothWind } from "./AbstractClothWind.js";
7
+ import { fluid_atmosphere_velocity_at } from "../../fluid/turbulence/fluid_atmosphere_velocity_at.js";
7
8
 
8
9
  /**
9
10
  * # The air, read out of the CPU fluid simulation that is already running
@@ -22,9 +23,9 @@ import { AbstractClothWind } from "./AbstractClothWind.js";
22
23
  * (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §6). So this is the one source a
23
24
  * CPU-fluid scene needs rather than a thing to switch between: a banner inside
24
25
  * a wind tunnel volume reads the tunnel, the same banner carried outside reads
25
- * the prevailing weather and its gust, and the cloth never learns which
26
- * happened. The gust runs on the scene's clock (G2), so `sample`'s `time` is not
27
- * read.
26
+ * the prevailing weather and its turbulence where it hangs, and the cloth never
27
+ * learns which happened. The far field runs on the scene's clock (G2), so
28
+ * `sample`'s `time` is not read.
28
29
  *
29
30
  * ## Two units problems, and they are the reason this class exists at all
30
31
  *
@@ -201,7 +202,7 @@ export class ClothFluidWind extends AbstractClothWind {
201
202
  * @param {number} y
202
203
  * @param {number} z
203
204
  * @param {number} time not read: a field's velocities are a snapshot of this
204
- * tick, and the far field's gust runs on the scene clock
205
+ * tick, and the far field runs on the scene clock
205
206
  * @returns {Float64Array|number[]}
206
207
  */
207
208
  sample(out, x, y, z, time) {
@@ -224,11 +225,8 @@ export class ClothFluidWind extends AbstractClothWind {
224
225
  return out;
225
226
  }
226
227
 
227
- const atmosphere = this.__atmosphere;
228
-
229
- out[0] = atmosphere[FluidAtmosphere.VELOCITY_X];
230
- out[1] = atmosphere[FluidAtmosphere.VELOCITY_Y];
231
- out[2] = atmosphere[FluidAtmosphere.VELOCITY_Z];
228
+ // the far field there, its turbulence included
229
+ fluid_atmosphere_velocity_at(out, this.__atmosphere, 0, x, y, z);
232
230
 
233
231
  return out;
234
232
  }
@@ -10,8 +10,8 @@ export const CLOTH_GPU_FLUID_WIND_AXIS_LIMIT: number;
10
10
  *
11
11
  * GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §12: the default source for a scene with the GPU wind —
12
12
  * an adapter over `GPUFluidSystem`'s CPU read API, so cloth reads the same wind particles, water and
13
- * volumetrics do: the fluid's cascades around its domain, its far field (`GlobalFluidEffector`s and
14
- * their gust) everywhere else.
13
+ * volumetrics do: the fluid's cascades around its domain, its far field (`GlobalFluidEffector`s, their
14
+ * mean wind and its turbulence) everywhere else.
15
15
  *
16
16
  * `ClothWorld` makes one by itself while the scene has a domain and nothing was assigned to its
17
17
  * `wind` (`ClothWorld#wind`); assigning one is the same source, made by hand:
@@ -23,23 +23,23 @@ export const CLOTH_GPU_FLUID_WIND_AXIS_LIMIT: number;
23
23
  * The GPU's answer is a frame or more late, so cloth reads **lattices**: the wind on a grid over a
24
24
  * box padded around each cloth, asked for ahead and interpolated when it lands.
25
25
  *
26
- * - **{@link begin}**, once a tick, takes the far field and swaps in the lattices delivered since the
27
- * last tick. A lattice no cloth read during the last tick is let go; one only {@link sample} read
26
+ * - **{@link begin}**, once a tick, swaps in the lattices delivered since the last tick. A lattice no cloth read during the last tick is let go; one only {@link sample} read
28
27
  * (a sleeping cloth's wake test) is asked for again over its own box, so a banner asleep inside it
29
28
  * still notices a gust.
30
29
  * - **{@link varies}** answers whether a delivered lattice covers the cloth's box — then the cloth
31
30
  * samples per particle — and asks for the box padded by {@link padding}, unless a request in flight
32
31
  * already covers it: one request at a time per cloth, a new lattice as fast as they land.
33
32
  * - **{@link sample}** interpolates the newest delivered lattice holding the point
34
- * (`scs3d_sample_linear3_strided`, x fastest, four floats a point), or answers the far field.
33
+ * (`scs3d_sample_linear3_strided`, x fastest, four floats a point), or answers the far field there
34
+ * (`GPUFluidSystem#far_field_at`).
35
35
  *
36
- * Before the first delivery, and wherever no lattice reaches, the air is the far field: uniform, so
37
- * a cloth costs one sample.
36
+ * Before the first delivery, and wherever no lattice reaches, the air is the far field, which a cloth
37
+ * samples once: its mean, and its turbulence where the cloth asks.
38
38
  *
39
39
  * ## Clocks
40
40
  *
41
- * The far field's gust runs on the scene's clock (G2, `GlobalFluidEffector#advance`), not the
42
- * cloth's age: `sample`'s `time` is not read. Lattices arrive when the GPU answers, so two runs of a
41
+ * The far field runs on the scene's clock (G2, `FluidEffectorsSystem`'s fold), not the cloth's
42
+ * age: `sample`'s `time` is not read. Lattices arrive when the GPU answers, so two runs of a
43
43
  * scene need not read the same air (F4, accepted): the parity gate of the worker against the inline
44
44
  * system holds for cloths registered on the same tick and for a time-invariant wind
45
45
  * (`WorkerClothSystem.spec.js`).
@@ -58,7 +58,7 @@ export const CLOTH_GPU_FLUID_WIND_AXIS_LIMIT: number;
58
58
  export class ClothGPUFluidWind extends AbstractClothWind {
59
59
  /**
60
60
  * @param {import("../../../graphics3/GPUFluidSystem.js").GPUFluidSystem} fluid the scene's GPU
61
- * fluid: its `far_field`, `request` and `status`
61
+ * fluid: its `far_field_at`, `request` and `status`
62
62
  */
63
63
  constructor(fluid: import("../../../graphics3/GPUFluidSystem.js").GPUFluidSystem);
64
64
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ClothGPUFluidWind.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/wind/ClothGPUFluidWind.js"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,8CAFU,MAAM,CAEkC;AAuDlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH;IAyCI;;;OAGG;IACH,mBAHW,OAAO,sCAAsC,EAAE,cAAc,EAUvE;IAlDD;;;;;OAKG;IACH,SAFU,MAAM,CAEF;IAEd;;;;;OAKG;IACH,SAFU,MAAM,CAEF;IAsCd;;;OAGG;IACH,2EAEC;IAED;;;OAGG;IACH,4BAEC;IAED;;;OAGG;IACH,4BAEC;;CAwPJ;kCArbiC,wBAAwB"}
1
+ {"version":3,"file":"ClothGPUFluidWind.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/wind/ClothGPUFluidWind.js"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,8CAFU,MAAM,CAEkC;AAuDlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH;IAuCI;;;OAGG;IACH,mBAHW,OAAO,sCAAsC,EAAE,cAAc,EAUvE;IAhDD;;;;;OAKG;IACH,SAFU,MAAM,CAEF;IAEd;;;;;OAKG;IACH,SAFU,MAAM,CAEF;IAoCd;;;OAGG;IACH,2EAEC;IAED;;;OAGG;IACH,4BAEC;IAED;;;OAGG;IACH,4BAEC;;CAkPJ;kCA7aiC,wBAAwB"}
@@ -69,8 +69,8 @@ function lattice_covers(lattice, min_x, min_y, min_z, max_x, max_y, max_z) {
69
69
  *
70
70
  * GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §12: the default source for a scene with the GPU wind —
71
71
  * an adapter over `GPUFluidSystem`'s CPU read API, so cloth reads the same wind particles, water and
72
- * volumetrics do: the fluid's cascades around its domain, its far field (`GlobalFluidEffector`s and
73
- * their gust) everywhere else.
72
+ * volumetrics do: the fluid's cascades around its domain, its far field (`GlobalFluidEffector`s, their
73
+ * mean wind and its turbulence) everywhere else.
74
74
  *
75
75
  * `ClothWorld` makes one by itself while the scene has a domain and nothing was assigned to its
76
76
  * `wind` (`ClothWorld#wind`); assigning one is the same source, made by hand:
@@ -82,23 +82,23 @@ function lattice_covers(lattice, min_x, min_y, min_z, max_x, max_y, max_z) {
82
82
  * The GPU's answer is a frame or more late, so cloth reads **lattices**: the wind on a grid over a
83
83
  * box padded around each cloth, asked for ahead and interpolated when it lands.
84
84
  *
85
- * - **{@link begin}**, once a tick, takes the far field and swaps in the lattices delivered since the
86
- * last tick. A lattice no cloth read during the last tick is let go; one only {@link sample} read
85
+ * - **{@link begin}**, once a tick, swaps in the lattices delivered since the last tick. A lattice no cloth read during the last tick is let go; one only {@link sample} read
87
86
  * (a sleeping cloth's wake test) is asked for again over its own box, so a banner asleep inside it
88
87
  * still notices a gust.
89
88
  * - **{@link varies}** answers whether a delivered lattice covers the cloth's box — then the cloth
90
89
  * samples per particle — and asks for the box padded by {@link padding}, unless a request in flight
91
90
  * already covers it: one request at a time per cloth, a new lattice as fast as they land.
92
91
  * - **{@link sample}** interpolates the newest delivered lattice holding the point
93
- * (`scs3d_sample_linear3_strided`, x fastest, four floats a point), or answers the far field.
92
+ * (`scs3d_sample_linear3_strided`, x fastest, four floats a point), or answers the far field there
93
+ * (`GPUFluidSystem#far_field_at`).
94
94
  *
95
- * Before the first delivery, and wherever no lattice reaches, the air is the far field: uniform, so
96
- * a cloth costs one sample.
95
+ * Before the first delivery, and wherever no lattice reaches, the air is the far field, which a cloth
96
+ * samples once: its mean, and its turbulence where the cloth asks.
97
97
  *
98
98
  * ## Clocks
99
99
  *
100
- * The far field's gust runs on the scene's clock (G2, `GlobalFluidEffector#advance`), not the
101
- * cloth's age: `sample`'s `time` is not read. Lattices arrive when the GPU answers, so two runs of a
100
+ * The far field runs on the scene's clock (G2, `FluidEffectorsSystem`'s fold), not the cloth's
101
+ * age: `sample`'s `time` is not read. Lattices arrive when the GPU answers, so two runs of a
102
102
  * scene need not read the same air (F4, accepted): the parity gate of the worker against the inline
103
103
  * system holds for cloths registered on the same tick and for a time-invariant wind
104
104
  * (`WorkerClothSystem.spec.js`).
@@ -135,8 +135,6 @@ export class ClothGPUFluidWind extends AbstractClothWind {
135
135
  /** @type {import("../../../graphics3/GPUFluidSystem.js").GPUFluidSystem} */
136
136
  #fluid;
137
137
 
138
- /** The far field this tick. */
139
- #far = new Float64Array(3);
140
138
 
141
139
  /** Delivered lattices, oldest first. @type {ClothWindLattice[]} */
142
140
  #current = [];
@@ -157,7 +155,7 @@ export class ClothGPUFluidWind extends AbstractClothWind {
157
155
 
158
156
  /**
159
157
  * @param {import("../../../graphics3/GPUFluidSystem.js").GPUFluidSystem} fluid the scene's GPU
160
- * fluid: its `far_field`, `request` and `status`
158
+ * fluid: its `far_field_at`, `request` and `status`
161
159
  */
162
160
  constructor(fluid) {
163
161
  super();
@@ -193,14 +191,12 @@ export class ClothGPUFluidWind extends AbstractClothWind {
193
191
  }
194
192
 
195
193
  /**
196
- * @param {number} time not read: the gust runs on the scene clock
194
+ * @param {number} time not read: the far field runs on the scene clock
197
195
  * @param {EntityComponentDataset} ecd not read
198
196
  */
199
197
  begin(time, ecd) {
200
198
  const fluid = this.#fluid;
201
199
 
202
- fluid.far_field(this.#far);
203
-
204
200
  // the last tick's reads decide what stays
205
201
  const current = this.#current;
206
202
  let kept = 0;
@@ -403,24 +399,20 @@ export class ClothGPUFluidWind extends AbstractClothWind {
403
399
 
404
400
  /**
405
401
  * The air at a world point, m/s: the newest delivered lattice holding it, interpolated, or the far
406
- * field.
402
+ * field there (`GPUFluidSystem#far_field_at`), its turbulence included.
407
403
  *
408
404
  * @param {Float64Array|number[]} out
409
405
  * @param {number} x
410
406
  * @param {number} y
411
407
  * @param {number} z
412
- * @param {number} time not read: the gust runs on the scene clock
408
+ * @param {number} time not read: the far field runs on the scene clock
413
409
  * @returns {Float64Array|number[]}
414
410
  */
415
411
  sample(out, x, y, z, time) {
416
412
  const lattice = this.#containing(x, y, z);
417
413
 
418
414
  if (lattice === null) {
419
- const far = this.#far;
420
-
421
- out[0] = far[0];
422
- out[1] = far[1];
423
- out[2] = far[2];
415
+ this.#fluid.far_field_at(out, x, y, z);
424
416
 
425
417
  return out;
426
418
  }
@@ -9,8 +9,8 @@
9
9
  * ({@link fluid_apply_atmosphere }).
10
10
  *
11
11
  * - `TIME`: seconds the effectors system has integrated, at the end of its last tick.
12
- * - `VELOCITY_*`: the far field `v_far = u + g`: `u` relaxes toward the globals'
13
- * drag-weighted mean wind at `DRAG`, and `g` is the sum of their gusts, unfiltered.
12
+ * - `VELOCITY_*`: `u`, the far field's mean: it relaxes toward the globals' drag-weighted
13
+ * mean wind at `DRAG`. Where a reader takes the far field as one vector, this is it.
14
14
  * - `LAMBDA`: `Λ = ∫ D dt`, so air left to the far field over an interval keeps
15
15
  * `e^(−ΔΛ)` of its deviation from it, however `D` varied.
16
16
  * - `FORCED_*`: `P`, the velocity the summed body force has given air the atmosphere
@@ -20,6 +20,15 @@
20
20
  * `F` and `D` varied. Not part of the far field: a term inside CPU fields only.
21
21
  * - `FORCE_*`: `F`, the sum of the globals' body forces, this tick.
22
22
  * - `DRAG`: `D`, the sum of the globals' drags, this tick.
23
+ * - `TURBULENCE_OFFSET_*`: `o = ∫ u dt`, how far the mean has carried the turbulence since the
24
+ * first tick, WORLD units, integrated exactly tick by tick.
25
+ * - `TURBULENCE_SIGMA`: `σ`, the turbulence's rms on each axis, `intensity · |u|`, WORLD units per
26
+ * second; 0 is none.
27
+ * - `TURBULENCE_LENGTH`: `L`, its length scale, WORLD units.
28
+ *
29
+ * The far field at a point `x` is `u + σ·T((x − o) ⊙ S⁻¹)` ({@link fluid_atmosphere_velocity_at }),
30
+ * `T` the unit-rms turbulence tile and `S` its size in the world for `L`. Not part of CPU fields,
31
+ * which take `u` alone.
23
32
  */
24
33
  export type FluidAtmosphere = number;
25
34
  export namespace FluidAtmosphere {
@@ -35,6 +44,11 @@ export namespace FluidAtmosphere {
35
44
  let FORCE_Y: number;
36
45
  let FORCE_Z: number;
37
46
  let DRAG: number;
47
+ let TURBULENCE_OFFSET_X: number;
48
+ let TURBULENCE_OFFSET_Y: number;
49
+ let TURBULENCE_OFFSET_Z: number;
50
+ let TURBULENCE_SIGMA: number;
51
+ let TURBULENCE_LENGTH: number;
38
52
  }
39
53
  /**
40
54
  * Words in an atmosphere record.
@@ -1 +1 @@
1
- {"version":3,"file":"FluidAtmosphere.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/fluid/FluidAtmosphere.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;8BAwBU,MAAM;;;;;;;;;;;;;;;AAiBhB;;;GAGG;AACH,qCAFU,MAAM,CAEyB;;;;;;;;;;;;mCAc/B,MAAM;;;;;;;;;;;;;;;;;;;;AAchB;;;GAGG;AACH,2CAFU,MAAM,CAE8B"}
1
+ {"version":3,"file":"FluidAtmosphere.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/fluid/FluidAtmosphere.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAiCU,MAAM;;;;;;;;;;;;;;;;;;;;AAsBhB;;;GAGG;AACH,qCAFU,MAAM,CAEyB;;;;;;;;;;;;mCAc/B,MAAM;;;;;;;;;;;;;;;;;;;;AAchB;;;GAGG;AACH,2CAFU,MAAM,CAE8B"}