@woosh/meep-engine 3.41.0 → 3.43.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 (384) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/editor/selection/editor_pick.d.ts.map +1 -1
  4. package/editor/selection/editor_pick.js +2 -1
  5. package/editor/tools/TransformToolV2.d.ts.map +1 -1
  6. package/editor/tools/TransformToolV2.js +7 -1
  7. package/editor/tools/engine/ToolEngine.d.ts.map +1 -1
  8. package/editor/tools/engine/ToolEngine.js +10 -0
  9. package/editor/tools/v2/TransformControls.d.ts.map +1 -1
  10. package/editor/tools/v2/TransformControls.js +7 -20
  11. package/editor/tools/v2/handle/gizmo_drag_plane.d.ts.map +1 -1
  12. package/editor/tools/v2/handle/gizmo_drag_plane.js +4 -0
  13. package/editor/view/ecs/EntityEditor.d.ts.map +1 -1
  14. package/editor/view/ecs/EntityEditor.js +3 -1
  15. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  16. package/editor/view/node-graph/NodeGraphView.js +28 -12
  17. package/package.json +91 -96
  18. package/samples/engine/first-scene/index.html +4 -1
  19. package/samples/engine/first-scene/main.js +14 -9
  20. package/src/core/binary/utf8/utf8_decode.js +3 -3
  21. package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.d.ts.map +1 -1
  22. package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +112 -113
  23. package/src/core/bvh2/bvh3/ebvh_nodes_sort_sah_local4.js +2 -2
  24. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +14 -14
  25. package/src/core/collection/RingBuffer.d.ts.map +1 -1
  26. package/src/core/collection/RingBuffer.js +4 -0
  27. package/src/core/collection/array/array_contains_duplicates.d.ts.map +1 -1
  28. package/src/core/collection/array/array_contains_duplicates.js +2 -1
  29. package/src/core/collection/array/array_copy.d.ts.map +1 -1
  30. package/src/core/collection/array/array_copy.js +23 -0
  31. package/src/core/collection/array/typed/sparse_typed_array_hash.d.ts +2 -2
  32. package/src/core/collection/array/typed/sparse_typed_array_hash.d.ts.map +1 -1
  33. package/src/core/collection/array/typed/sparse_typed_array_hash.js +9 -8
  34. package/src/core/collection/array/typed/uint16_array_hash.d.ts +2 -2
  35. package/src/core/collection/array/typed/uint16_array_hash.js +4 -4
  36. package/src/core/collection/array/typed/uint8_array_hash.d.ts +2 -2
  37. package/src/core/collection/array/typed/uint8_array_hash.js +4 -4
  38. package/src/core/collection/array/weightedRandomFromArray.d.ts +1 -0
  39. package/src/core/collection/array/weightedRandomFromArray.d.ts.map +1 -1
  40. package/src/core/collection/array/weightedRandomFromArray.js +9 -1
  41. package/src/core/collection/heap/BinaryHeap.d.ts.map +1 -1
  42. package/src/core/collection/heap/BinaryHeap.js +4 -0
  43. package/src/core/collection/list/List.d.ts.map +1 -1
  44. package/src/core/collection/list/List.js +4 -2
  45. package/src/core/collection/set/ArraySet.js +1 -1
  46. package/src/core/collection/set/HashSet.d.ts +1 -1
  47. package/src/core/collection/set/HashSet.d.ts.map +1 -1
  48. package/src/core/collection/set/HashSet.js +4 -2
  49. package/src/core/debug/matchers/IsEqual.js +1 -1
  50. package/src/core/debug/matchers/IsIterableContaining.d.ts.map +1 -1
  51. package/src/core/debug/matchers/IsIterableContaining.js +61 -74
  52. package/src/core/events/signal/SignalBinding.js +101 -101
  53. package/src/core/function/extractFunctionBody.js +13 -13
  54. package/src/core/function/objectsEqual.d.ts.map +1 -1
  55. package/src/core/function/objectsEqual.js +15 -14
  56. package/src/core/geom/3d/frustum/frustum3_compute_closest_point.d.ts.map +1 -1
  57. package/src/core/geom/3d/frustum/frustum3_compute_closest_point.js +207 -172
  58. package/src/core/geom/3d/gjk/gjk_epa_penetration.d.ts.map +1 -1
  59. package/src/core/geom/3d/gjk/gjk_epa_penetration.js +5 -4
  60. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.d.ts.map +1 -1
  61. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.js +8 -2
  62. package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts +20 -0
  63. package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts.map +1 -1
  64. package/src/core/geom/3d/triangle/tri3_ray_intersection.js +182 -0
  65. package/src/core/math/noise/curl_noise_3dt.d.ts.map +1 -1
  66. package/src/core/math/noise/curl_noise_3dt.js +20 -10
  67. package/src/core/math/noise/sdnoise.d.ts +16 -5
  68. package/src/core/math/noise/sdnoise.d.ts.map +1 -1
  69. package/src/core/math/noise/sdnoise.js +43 -9
  70. package/src/core/math/spline/spline3_hermite_nearest_point.d.ts +16 -1
  71. package/src/core/math/spline/spline3_hermite_nearest_point.d.ts.map +1 -1
  72. package/src/core/math/spline/spline3_hermite_nearest_point.js +44 -3
  73. package/src/engine/Engine.d.ts.map +1 -1
  74. package/src/engine/Engine.js +6 -2
  75. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +9 -0
  76. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  77. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +26 -0
  78. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  79. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +2 -0
  80. package/src/engine/control/first-person/abilities/AbilitySet.d.ts.map +1 -1
  81. package/src/engine/control/first-person/abilities/AbilitySet.js +9 -0
  82. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
  83. package/src/engine/control/first-person/abilities/LedgeGrab.js +6 -0
  84. package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -1
  85. package/src/engine/control/first-person/abilities/Slide.js +1 -0
  86. package/src/engine/control/first-person/abilities/WallRun.d.ts +4 -1
  87. package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -1
  88. package/src/engine/control/first-person/abilities/WallRun.js +13 -1
  89. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts +1 -1
  90. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts.map +1 -1
  91. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.js +6 -5
  92. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts +3 -3
  93. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts.map +1 -1
  94. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.js +9 -8
  95. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -1
  96. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +13 -4
  97. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  98. package/src/engine/ecs/EntityManager.js +18 -15
  99. package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.d.ts.map +1 -1
  100. package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.js +2 -1
  101. package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescriptionTable.d.ts.map +1 -1
  102. package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescriptionTable.js +1 -0
  103. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
  104. package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +3 -0
  105. package/src/engine/ecs/parent/EntityNode.js +3 -3
  106. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  107. package/src/engine/ecs/speaker/VoiceSystem.js +4 -0
  108. package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +5 -5
  109. package/src/engine/ecs/storage/binary/BinarySerializationRegistry.d.ts.map +1 -1
  110. package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +3 -2
  111. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.js +1 -1
  112. package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.d.ts.map +1 -1
  113. package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.js +8 -1
  114. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  115. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +8 -0
  116. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  117. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +5 -2
  118. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.d.ts.map +1 -1
  119. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +3 -0
  120. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts.map +1 -1
  121. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +1 -0
  122. package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +1 -1
  123. package/src/engine/ecs/terrain/tiles/TerrainTile.d.ts.map +1 -1
  124. package/src/engine/ecs/terrain/tiles/TerrainTile.js +13 -1
  125. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
  126. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +1 -0
  127. package/src/engine/graphics/ecs/light/LightSerializationAdapter.d.ts.map +1 -1
  128. package/src/engine/graphics/ecs/light/LightSerializationAdapter.js +13 -1
  129. package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.d.ts +5 -0
  130. package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.d.ts.map +1 -0
  131. package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.js +27 -0
  132. package/src/engine/graphics/ecs/water/Water.d.ts +11 -0
  133. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  134. package/src/engine/graphics/ecs/water/Water.js +17 -0
  135. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.d.ts.map +1 -1
  136. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.js +3 -1
  137. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.d.ts +9 -0
  138. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.d.ts.map +1 -0
  139. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.js +24 -0
  140. package/src/engine/graphics/ecs/water/WaterWaves.d.ts +30 -9
  141. package/src/engine/graphics/ecs/water/WaterWaves.d.ts.map +1 -1
  142. package/src/engine/graphics/ecs/water/WaterWaves.js +41 -9
  143. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts.map +1 -1
  144. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.js +30 -26
  145. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.d.ts +6 -0
  146. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.d.ts.map +1 -0
  147. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.js +22 -0
  148. package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.d.ts.map +1 -1
  149. package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.js +3 -5
  150. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts +20 -0
  151. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts.map +1 -1
  152. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +36 -0
  153. package/src/engine/graphics3/WaterSystem.d.ts +12 -3
  154. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  155. package/src/engine/graphics3/WaterSystem.js +78 -46
  156. package/src/engine/input/devices/PointerDevice.d.ts.map +1 -1
  157. package/src/engine/input/devices/PointerDevice.js +29 -4
  158. package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.d.ts +1 -0
  159. package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.d.ts.map +1 -1
  160. package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.js +14 -3
  161. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  162. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.d.ts.map +1 -1
  163. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +12 -3
  164. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.d.ts.map +1 -1
  165. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +8 -2
  166. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts +19 -0
  167. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts.map +1 -1
  168. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js +41 -2
  169. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.d.ts.map +1 -1
  170. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.js +9 -3
  171. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.d.ts.map +1 -1
  172. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.js +26 -10
  173. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +3 -6
  174. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -1
  175. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +22 -9
  176. package/src/engine/ui/DraggableAspect.d.ts +5 -1
  177. package/src/engine/ui/DraggableAspect.d.ts.map +1 -1
  178. package/src/engine/ui/DraggableAspect.js +61 -4
  179. package/src/format/image/avif/heif/ItemProperty.d.ts +1 -1
  180. package/src/format/image/avif/heif/ItemProperty.js +1 -1
  181. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts.map +1 -1
  182. package/src/format/image/png/chunk/png_chunk_decode_iTXt.js +17 -6
  183. package/src/shade/device/mock/SoftwareGPUDevice.d.ts +2 -4
  184. package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
  185. package/src/shade/device/mock/SoftwareGPUDevice.js +20 -13
  186. package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts.map +1 -1
  187. package/src/shade/playground/skinned_blas_refit/sweep_views.js +2 -1
  188. package/src/shade/playground/vgeo_runtime/README.md +5 -4
  189. package/src/shade/playground/water_refraction/README.md +10 -11
  190. package/src/shade/playground/water_refraction/main.js +9 -8
  191. package/src/shade/playground/water_refraction/world.js +1 -1
  192. package/src/shade/playground/water_surface/README.md +43 -0
  193. package/src/shade/playground/water_surface/index.html +30 -0
  194. package/src/shade/playground/water_surface/main.d.ts +2 -0
  195. package/src/shade/playground/water_surface/main.d.ts.map +1 -0
  196. package/src/shade/playground/water_surface/main.js +154 -0
  197. package/src/shade/playground/water_surface/world.d.ts +44 -0
  198. package/src/shade/playground/water_surface/world.d.ts.map +1 -0
  199. package/src/shade/playground/water_surface/world.js +160 -0
  200. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  201. package/src/shade/renderer/Renderer.js +6 -5
  202. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  203. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +5 -0
  204. package/src/shade/renderer/atmosphere/GPUSky.d.ts +12 -0
  205. package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
  206. package/src/shade/renderer/atmosphere/GPUSky.js +162 -147
  207. package/src/shade/renderer/binding/BufferBinding.js +2 -2
  208. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  209. package/src/shade/renderer/buffer/table/GPUTypedTable.js +5 -3
  210. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts +10 -3
  211. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts.map +1 -1
  212. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.js +17 -9
  213. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +3 -0
  214. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +1 -1
  215. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +16 -0
  216. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +2 -0
  217. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +1 -1
  218. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +11 -0
  219. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts +1 -1
  220. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts.map +1 -1
  221. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.js +9 -3
  222. package/src/shade/renderer/geometry/util/geometry_simplify_redundant_topology.d.ts.map +1 -1
  223. package/src/shade/renderer/geometry/util/geometry_simplify_redundant_topology.js +2 -2
  224. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  225. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +85 -0
  226. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  227. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +12 -6
  228. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
  229. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +7 -0
  230. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -1
  231. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +3 -1
  232. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.d.ts.map +1 -1
  233. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +10 -3
  234. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  235. package/src/shade/renderer/particles/DESIGN.md +13 -9
  236. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +1 -1
  237. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +1 -1
  238. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  239. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +3 -2
  240. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  241. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +3 -2
  242. package/src/shade/renderer/scene/GPUSceneContext.d.ts +9 -1
  243. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  244. package/src/shade/renderer/scene/GPUSceneContext.js +23 -1
  245. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +2 -1
  246. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.d.ts +13 -0
  247. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.d.ts.map +1 -0
  248. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.js +42 -0
  249. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.d.ts +15 -0
  250. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.d.ts.map +1 -0
  251. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.js +39 -0
  252. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  253. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +2 -0
  254. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +4 -1
  255. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  256. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +74 -3
  257. package/src/shade/renderer/volumetrics/NOTES.md +1023 -957
  258. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts +5 -4
  259. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts.map +1 -1
  260. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.js +5 -4
  261. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +1 -1
  262. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +1 -1
  263. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +1 -1
  264. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +1 -1
  265. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +41 -0
  266. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -0
  267. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +112 -0
  268. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +9 -23
  269. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  270. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +18 -126
  271. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +22 -0
  272. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +1 -0
  273. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +228 -0
  274. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  275. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +0 -53
  276. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +15 -0
  277. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  278. package/src/shade/renderer/water/GPUWaterRenderer.js +110 -30
  279. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +16 -8
  280. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  281. package/src/shade/renderer/water/medium/GPUWaterBodies.js +31 -26
  282. package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts +0 -1
  283. package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts.map +1 -1
  284. package/src/shade/renderer/water/medium/shader_water_meshlets.js +1 -39
  285. package/src/shade/renderer/water/shader_water.d.ts +0 -1
  286. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  287. package/src/shade/renderer/water/shader_water.js +201 -72
  288. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts +70 -0
  289. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -0
  290. package/src/shade/renderer/water/surface/GPUWaterSurface.js +199 -0
  291. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts +5 -2
  292. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts.map +1 -1
  293. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js +32 -12
  294. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +23 -0
  295. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -0
  296. package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +227 -0
  297. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +65 -11
  298. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
  299. package/src/shade/renderer/water/surface/graph_water_tessellation.js +163 -28
  300. package/src/shade/renderer/water/surface/lod/WATER_LOD.d.ts +51 -0
  301. package/src/shade/renderer/water/surface/lod/WATER_LOD.d.ts.map +1 -0
  302. package/src/shade/renderer/water/surface/lod/WATER_LOD.js +95 -0
  303. package/src/shade/renderer/water/surface/lod/chunk_water_lod.d.ts +10 -0
  304. package/src/shade/renderer/water/surface/lod/chunk_water_lod.d.ts.map +1 -0
  305. package/src/shade/renderer/water/surface/lod/chunk_water_lod.js +127 -0
  306. package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.d.ts +17 -0
  307. package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.d.ts.map +1 -0
  308. package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.js +246 -0
  309. package/src/shade/renderer/water/surface/lod/shader_water_lod.d.ts +118 -0
  310. package/src/shade/renderer/water/surface/lod/shader_water_lod.d.ts.map +1 -0
  311. package/src/shade/renderer/water/surface/lod/shader_water_lod.js +727 -0
  312. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts +60 -0
  313. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -0
  314. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +274 -0
  315. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts +17 -0
  316. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts.map +1 -0
  317. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js +57 -0
  318. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts +43 -0
  319. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -0
  320. package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +268 -0
  321. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts +20 -0
  322. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -0
  323. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +239 -0
  324. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts +153 -0
  325. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts.map +1 -0
  326. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +874 -0
  327. package/src/shade/renderer/water/surface/shader_water_cull.d.ts +42 -0
  328. package/src/shade/renderer/water/surface/shader_water_cull.d.ts.map +1 -0
  329. package/src/shade/renderer/water/surface/shader_water_cull.js +269 -0
  330. package/src/shade/renderer/water/surface/shader_water_waves_combine.d.ts +15 -0
  331. package/src/shade/renderer/water/surface/shader_water_waves_combine.d.ts.map +1 -0
  332. package/src/shade/renderer/water/surface/shader_water_waves_combine.js +73 -0
  333. package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts +11 -0
  334. package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts.map +1 -0
  335. package/src/shade/renderer/water/surface/shader_water_waves_derive.js +78 -0
  336. package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.d.ts +35 -0
  337. package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.d.ts.map +1 -0
  338. package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.js +103 -0
  339. package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.d.ts +22 -0
  340. package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.d.ts.map +1 -0
  341. package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.js +57 -0
  342. package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.d.ts +22 -0
  343. package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.d.ts.map +1 -0
  344. package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.js +25 -0
  345. package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.d.ts +14 -0
  346. package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.d.ts.map +1 -0
  347. package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.js +48 -0
  348. package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.d.ts +23 -0
  349. package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.d.ts.map +1 -0
  350. package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.js +169 -0
  351. package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.d.ts +26 -0
  352. package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.d.ts.map +1 -0
  353. package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.js +161 -0
  354. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  355. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +29 -9
  356. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  357. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +14 -3
  358. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts +0 -28
  359. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts.map +0 -1
  360. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.js +0 -86
  361. package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.d.ts +0 -29
  362. package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.d.ts.map +0 -1
  363. package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.js +0 -44
  364. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts +0 -4
  365. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts.map +0 -1
  366. package/src/shade/renderer/water/medium/shader_water_bodies_derive.js +0 -32
  367. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts +0 -25
  368. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts.map +0 -1
  369. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.js +0 -128
  370. package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts +0 -9
  371. package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts.map +0 -1
  372. package/src/shade/renderer/water/surface/chunk_water_tessellation.js +0 -144
  373. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts +0 -13
  374. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts.map +0 -1
  375. package/src/shade/renderer/water/surface/chunk_water_wave.js +0 -40
  376. package/src/shade/renderer/water/surface/shader_water_tiles.d.ts +0 -4
  377. package/src/shade/renderer/water/surface/shader_water_tiles.d.ts.map +0 -1
  378. package/src/shade/renderer/water/surface/shader_water_tiles.js +0 -123
  379. package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts +0 -6
  380. package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts.map +0 -1
  381. package/src/shade/renderer/water/surface/shader_water_wave_batch.js +0 -85
  382. package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts +0 -6
  383. package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts.map +0 -1
  384. package/src/shade/renderer/water/surface/shader_water_wave_domain.js +0 -83
@@ -1,6 +1,6 @@
1
1
  import { assert } from "../../core/assert.js";
2
2
  import Water from "../graphics/ecs/water/Water.js";
3
- import WaterWaves from "../graphics/ecs/water/WaterWaves.js";
3
+ import WaterWaves, { WATER_WAVES_SHORE_REFLECTION_DEFAULT } from "../graphics/ecs/water/WaterWaves.js";
4
4
  import { System } from "../ecs/System.js";
5
5
  import { EventType } from "../ecs/EventType.js";
6
6
  import { Transform64 } from "../ecs/transform/Transform64.js";
@@ -12,21 +12,32 @@ import { ResourceAccessKind } from "../../core/model/ResourceAccessKind.js";
12
12
  import { ResourceAccessSpecification } from "../../core/model/ResourceAccessSpecification.js";
13
13
  import { GPUWaterRenderer } from "../../shade/renderer/water/GPUWaterRenderer.js";
14
14
  import { GPUWaterBodies } from "../../shade/renderer/water/medium/GPUWaterBodies.js";
15
- import { GPUWaterWaveSimulation } from "../../shade/renderer/water/surface/GPUWaterWaveSimulation.js";
15
+ import { GPUWaterSurface } from "../../shade/renderer/water/surface/GPUWaterSurface.js";
16
16
  import { FramePhase } from "../../shade/renderer/extension/FramePhase.js";
17
17
  import { RenderExtension } from "../../shade/renderer/extension/RenderExtension.js";
18
18
  import { SceneColor } from "../../shade/renderer/extension/SceneColor.js";
19
19
  import { m4_invert } from "../../core/geom/3d/mat4/m4_invert.js";
20
20
  import { generate_record_writer } from "../../shade/renderer/buffer/table/serde/generate_record_writer.js";
21
21
  import { WATER_WAVE_IMPULSE_LIMIT, WATER_WAVE_RECORD_STRUCT } from "../../shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js";
22
+ import { WATER_SPECTRUM_BAND_COUNT } from "../../shade/renderer/water/surface/spectrum/WATER_SPECTRUM.js";
22
23
 
23
- const WIND_WRITER = generate_record_writer(WATER_WAVE_RECORD_STRUCT, ['forcing', 'unresolved_variance']);
24
+ // Only the authored fields: a whole-record write would undo what the GPU derives into the row.
25
+ const AUTHORED_WRITER = generate_record_writer(WATER_WAVE_RECORD_STRUCT, ['wind', 'upwind_fetch', 'node', 'geometry', 'simulate_hidden']);
24
26
  const IMPULSE_WRITER = generate_record_writer(WATER_WAVE_RECORD_STRUCT, ['impulses', 'impulse_count']);
27
+ /** The WaterWaves fields a body's row follows. */
28
+ const WAVE_FIELDS = ['windSpeed', 'windDirection', 'upwindFetch', 'shoreReflection'];
29
+ /** A splash's world-to-local matrix: rain can splash hundreds of times a second. */
30
+ const SPLASH_INVERSE = new Float64Array(16);
25
31
 
26
32
  /**
27
33
  * Registers [Water, MeshletGeometry, Transform64] in the scene's existing GPU database. Authored
28
34
  * edits queue writes; idle frames never walk bodies. Transform rows follow the same change events
29
35
  * and GPU hierarchy as shaded geometry. Water does not enter the opaque mesh table or its TLAS.
36
+ *
37
+ * Every body has a surface row (WATER_SURFACE_SIMULATION_PLAN_2026_10_06.md §6.1): its wind from an
38
+ * optional {@link WaterWaves}, its queued splashes, and what the GPU derives from them each frame. The GPU culls
39
+ * every body against the frame's view before simulating; a hidden body is paused unless
40
+ * {@link Water#simulateWhenHidden} (WATER_SURFACE_DISTANCE_LOD_PROPOSAL_2026_10_06.md §3).
30
41
  */
31
42
  export class WaterSystem extends System {
32
43
  dependencies = [Water, MeshletGeometry, Transform64];
@@ -35,11 +46,13 @@ export class WaterSystem extends System {
35
46
  #scene;
36
47
  #context = null;
37
48
  #renderer = new GPUWaterRenderer();
38
- #waves = new GPUWaterWaveSimulation();
49
+ #waves = new GPUWaterSurface();
39
50
  #bodies = new GPUWaterBodies();
40
51
  #entries = new Map();
41
52
  #dirty = new Set();
42
53
  #impulses = new Set();
54
+ // bodies with wind: while there is none, the shared band tiles are not animated
55
+ #windy = new Set();
43
56
  #extensions = [];
44
57
  #time = 0;
45
58
  get settings() { return this.#renderer.settings; }
@@ -60,9 +73,8 @@ export class WaterSystem extends System {
60
73
  this.#waves.onInputsConsumed.add(context => {
61
74
  if (context !== this.#context) { return; }
62
75
  for (const entry of this.#impulses) {
63
- entry.staged.length = 0;
64
- if (entry.impulses.length !== 0) { this.#dirty.add(entry); }
65
- else { this.#impulses.delete(entry); }
76
+ entry.staged.impulse_count = 0;
77
+ if (entry.queue.length === 0) { this.#impulses.delete(entry); }
66
78
  }
67
79
  });
68
80
  this.#renderer.bodies = this.#bodies;
@@ -87,8 +99,10 @@ export class WaterSystem extends System {
87
99
  }
88
100
 
89
101
  link(water, geometry, transform, entity) {
90
- const entry = { water, geometry, transform, entity, context: null, row: -1, wave: -1, waves: null,
91
- impulses: [], staged: [], wave_record: null };
102
+ // queue: splashes not yet staged, four numbers each (local x, z, radius, kick); staged: the batch on the
103
+ // GPU row until a submitted frame spends it
104
+ const entry = { water, geometry, transform, entity, context: null, row: -1, wave: -1, waves: null, queue: [],
105
+ staged: { impulses: Array.from({ length: WATER_WAVE_IMPULSE_LIMIT }, () => new Float64Array(4)), impulse_count: 0 } };
92
106
  const dataset = this.entityManager.dataset;
93
107
  entry.changed = () => this.#dirty.add(entry);
94
108
  entry.world = () => entry.context?.rows.mark_world(entity);
@@ -109,11 +123,9 @@ export class WaterSystem extends System {
109
123
  }
110
124
 
111
125
  #watch_waves(entry) {
112
- entry.waves?.windSpeed.onChanged.remove(entry.changed);
113
- entry.waves?.windDirection.onChanged.remove(entry.changed);
126
+ if (entry.waves != null) { for (const field of WAVE_FIELDS) { entry.waves[field].onChanged.remove(entry.changed); } }
114
127
  entry.waves = this.entityManager.dataset.getComponent(entry.entity, WaterWaves);
115
- entry.waves?.windSpeed.onChanged.add(entry.changed);
116
- entry.waves?.windDirection.onChanged.add(entry.changed);
128
+ if (entry.waves != null) { for (const field of WAVE_FIELDS) { entry.waves[field].onChanged.add(entry.changed); } }
117
129
  }
118
130
 
119
131
  unlink(water, geometry, transform, entity) {
@@ -121,8 +133,7 @@ export class WaterSystem extends System {
121
133
  if (entry === undefined) { return; }
122
134
  const dataset = this.entityManager.dataset;
123
135
  water.onChanged.remove(entry.changed);
124
- entry.waves?.windSpeed.onChanged.remove(entry.changed);
125
- entry.waves?.windDirection.onChanged.remove(entry.changed);
136
+ if (entry.waves != null) { for (const field of WAVE_FIELDS) { entry.waves[field].onChanged.remove(entry.changed); } }
126
137
  dataset.removeEntityEventListener(entity, TRANSFORM64_EVENT_CHANGE, entry.world);
127
138
  dataset.removeEntityEventListener(entity, TRANSFORM_ATTACHMENT_EVENT_CHANGE, entry.local);
128
139
  dataset.removeEntityEventListener(entity, EventType.ComponentAdded, entry.components);
@@ -132,6 +143,7 @@ export class WaterSystem extends System {
132
143
  entry.context.rows.release(entity);
133
144
  }
134
145
  this.#entries.delete(entity); this.#dirty.delete(entry); this.#impulses.delete(entry);
146
+ this.#windy.delete(entry); this.#waves.windy = this.#windy.size > 0;
135
147
  this.#renderer.body_count--;
136
148
  if (entry.context !== null) { this.#renderer.meshlet_capacity -= entry.geometry.meshlets.count; }
137
149
  }
@@ -144,14 +156,34 @@ export class WaterSystem extends System {
144
156
  this.#context = context;
145
157
  // Device replacement is the only whole-scene rebuild; ordinary frames drain edits.
146
158
  for (const entry of this.#entries.values()) {
147
- entry.context = null; entry.row = -1; entry.wave = -1; entry.wave_record = null;
148
- entry.impulses.unshift(...entry.staged); entry.staged.length = 0;
159
+ entry.context = null; entry.row = -1; entry.wave = -1;
160
+ // a batch the old context never spent goes back to the front of the queue
161
+ const staged = [];
162
+ for (let i = 0; i < entry.staged.impulse_count; i++) { staged.push(...entry.staged.impulses[i]); }
163
+ entry.queue.unshift(...staged); entry.staged.impulse_count = 0;
149
164
  this.#dirty.add(entry);
150
165
  }
151
166
  this.#renderer.meshlet_capacity = 0;
152
167
  }
153
168
  for (const entry of this.#dirty) { this.#write(entry, context); }
154
169
  this.#dirty.clear();
170
+ for (const entry of this.#impulses) { this.#stage(entry, context); }
171
+ }
172
+
173
+ /** Top up a body's batch on its surface row from its queue, up to the row's limit. */
174
+ #stage(entry, context) {
175
+ const staged = entry.staged, queue = entry.queue;
176
+ if (entry.wave === -1 || queue.length === 0 || staged.impulse_count === WATER_WAVE_IMPULSE_LIMIT) { return; }
177
+ const taken = Math.min(queue.length / 4, WATER_WAVE_IMPULSE_LIMIT - staged.impulse_count);
178
+ for (let i = 0; i < taken; i++) {
179
+ const impulse = staged.impulses[staged.impulse_count++];
180
+ for (let c = 0; c < 4; c++) { impulse[c] = queue[4 * i + c]; }
181
+ }
182
+ queue.copyWithin(0, 4 * taken);
183
+ queue.length -= 4 * taken;
184
+ this.#waves.splashed = true;
185
+ for (let i = staged.impulse_count; i < WATER_WAVE_IMPULSE_LIMIT; i++) { staged.impulses[i].fill(0); }
186
+ context.scene_database.get('water_waves').set_fields(entry.wave, staged, IMPULSE_WRITER);
155
187
  }
156
188
 
157
189
  #write(entry, context) {
@@ -163,54 +195,54 @@ export class WaterSystem extends System {
163
195
  entry.context = context;
164
196
  this.#renderer.meshlet_capacity += entry.geometry.meshlets.count;
165
197
  }
166
- if (entry.wave !== -1 || entry.waves != null || entry.impulses.length !== 0) {
167
- const bounds = entry.geometry.bounding_box;
168
- if (entry.wave === -1) {
169
- entry.wave_record = { extent: [bounds[0], bounds[2], bounds[3], bounds[5]],
170
- forcing: [1, 0, 0, 0], impulses: Array.from({ length: WATER_WAVE_IMPULSE_LIMIT }, () => [0, 0, 0, 0]),
171
- node: entry.entity + 1, geometry: context.geometries.getAddress(entry.geometry),
172
- unresolved_variance: 0, impulse_count: 0, first_write: 1, displacement_bounds: [0, 0] };
173
- entry.wave = waves.add(entry.wave_record);
174
- }
175
- const wind = Math.max(0, entry.waves?.windSpeed.getValue() ?? 0);
176
- const direction = entry.waves?.windDirection.getValue() ?? 0;
177
- // Patch only authored fields: a full write would restore GPU-consumed impulses/reset flags.
178
- waves.set_fields(entry.wave, { forcing: [Math.cos(direction), Math.sin(direction), 0.02 * wind * wind, 0.5 * wind],
179
- unresolved_variance: wind > 0 ? 0.003 + 0.00512 * wind : 0 }, WIND_WRITER);
180
- if (entry.impulses.length !== 0) {
181
- entry.staged.push(...entry.impulses.splice(0, WATER_WAVE_IMPULSE_LIMIT - entry.staged.length));
182
- const impulses = entry.staged.slice();
183
- const count = impulses.length;
184
- while (impulses.length < WATER_WAVE_IMPULSE_LIMIT) { impulses.push([0, 0, 0, 0]); }
185
- waves.set_fields(entry.wave, { impulses, impulse_count: count }, IMPULSE_WRITER);
186
- }
198
+ const geometry = context.geometries.getAddress(entry.geometry);
199
+ if (entry.wave === -1) {
200
+ entry.wave = waves.add({ wind: [1, 0, 0, WATER_WAVES_SHORE_REFLECTION_DEFAULT], upwind_fetch: 0,
201
+ impulses: Array.from({ length: WATER_WAVE_IMPULSE_LIMIT }, () => [0, 0, 0, 0]), impulse_count: 0,
202
+ node: entry.entity + 1, geometry, simulate_hidden: 0, derived_for: [-1, -1],
203
+ weights: new Array(WATER_SPECTRUM_BAND_COUNT).fill(0), slope_variance: 0,
204
+ wind_from: [0, 0], wind_to: [0, 0], wind_blend: 1, displacement_bounds: [0, 0, 0, 0], particle_levels: 0 });
187
205
  }
206
+ const waves_component = entry.waves;
207
+ const speed = Math.max(0, waves_component?.windSpeed.getValue() ?? 0);
208
+ const direction = waves_component?.windDirection.getValue() ?? 0;
209
+ const reflection = Math.min(1, Math.max(0, waves_component?.shoreReflection.getValue() ?? WATER_WAVES_SHORE_REFLECTION_DEFAULT));
210
+ waves.set_fields(entry.wave, { wind: [Math.cos(direction), Math.sin(direction), speed, reflection],
211
+ upwind_fetch: Math.max(0, waves_component?.upwindFetch.getValue() ?? 0), node: entry.entity + 1, geometry,
212
+ simulate_hidden: entry.water.simulateWhenHidden.getValue() ? 1 : 0 }, AUTHORED_WRITER);
213
+ if (speed > 0) { this.#windy.add(entry); } else { this.#windy.delete(entry); }
214
+ this.#waves.windy = this.#windy.size > 0;
188
215
  const water = entry.water;
189
- const record = { geometry: context.geometries.getAddress(entry.geometry), node: entry.entity + 1,
216
+ const record = { geometry, node: entry.entity + 1,
190
217
  dirty: 1,
191
- wave: entry.wave === -1 ? 0xffffffff : entry.wave, ior: Math.max(1, water.ior.getValue()),
218
+ wave: entry.wave, ior: Math.max(1, water.ior.getValue()),
192
219
  roughness: Math.min(1, Math.max(0, water.roughness.getValue())), medium: water.medium.to_gpu_record(),
193
220
  backscattering: [0, 0, 0, 0], extinction: [0, 0, 0, 0], diffuse_transmittance: 0 };
194
221
  if (entry.row === -1) { entry.row = bodies.add(record); } else { bodies.set(entry.row, record); }
195
222
  }
196
223
 
197
- /** World-space radius and velocity kick; position is interpreted in the CPU-owned pose. */
224
+ /**
225
+ * A splash at a world position: rings of wave particles of the given world radius (half their wavelength)
226
+ * whose height is the given vertical velocity kick, m/s, over the time a crest takes to cross them. The
227
+ * position is interpreted in the CPU-owned pose; queued on the CPU and spent on the GPU, sixteen a body a frame.
228
+ */
198
229
  splash(entity, position, radius, strength) {
199
230
  const entry = this.#entries.get(entity); assert.defined(entry, 'water entity');
200
231
  assert.greaterThan(radius, 0, 'radius'); assert.isFinite(radius, 'radius'); assert.isFinite(strength, 'strength');
201
232
  for (let i = 0; i < 3; i++) { assert.isFinite(position[i], `position[${i}]`); }
202
- const inverse = new Float64Array(16);
233
+ const inverse = SPLASH_INVERSE;
203
234
  assert.ok(m4_invert(inverse, entry.transform), 'water transform is singular');
204
235
  const x = inverse[0] * position[0] + inverse[4] * position[1] + inverse[8] * position[2] + inverse[12];
205
236
  const z = inverse[2] * position[0] + inverse[6] * position[1] + inverse[10] * position[2] + inverse[14];
206
- entry.impulses.push([x, z, radius, strength]); this.#impulses.add(entry); this.#dirty.add(entry);
237
+ entry.queue.push(x, z, radius, strength); this.#impulses.add(entry);
207
238
  }
208
239
 
209
240
  record_surface(frame) {
210
- const scene = frame.view.scene;
241
+ const view = frame.view, scene = view.scene;
211
242
  if (scene.scene !== this.#scene) { return; }
212
- this.#waves.record({ graph: frame.graph, device: this.#graphics.renderer.graphics.device, scene });
213
- this.#bodies.record({ graph: frame.graph, scene });
243
+ this.#waves.record({ graph: frame.graph, device: this.#graphics.renderer.graphics.device, scene, time: this.#time,
244
+ view: { camera: view.camera.gpu_buffer, projection: view.camera.camera.projection_matrix, height: view.resolution[1] },
245
+ pixels: this.#renderer.settings.tessellation_pixels });
214
246
  }
215
247
  record(frame) {
216
248
  const inspection = this.#renderer.inspect(frame.graph, frame.view, frame.resolution);
@@ -1 +1 @@
1
- {"version":3,"file":"PointerDevice.d.ts","sourceRoot":"","sources":["../../../../../src/engine/input/devices/PointerDevice.js"],"names":[],"mappings":"AA2NA;;;;;GAKG;AACH,mDAJW,OAAO,SACP,UAAU,GAAC,KAAK,WAChB,OAAO,QAejB;AAED;;;;;GAKG;AACH;IAuFI;;;;OAIG;IACH,wBAHW,WAAW,EA+BrB;IAtHD;;;;OAIG;IACH,mBAFU,OAAO,CAEQ;IAEzB;;OAEG;IACH;;;QAGI;;;;;;WAMG;;;QAGH;;WAEG;;;;;;;;;MASL;IAeF;;;OAGG;IACH,kBAAkB;IAElB;;;;OAIG;IACH,kBAFU,iBAAiB,EAAE,CAEL;IAExB;;;OAGG;IACH,yCAEC;IAED;;;OAGG;IACH,0CAEC;IAED;;;OAGG;IACH,2CAEC;IAyID;;;OAGG;IACH,oBAFY,OAAO,CAIlB;IAED;;;OAGG;IACH,4BAsBC;IAED,0BAEC;IAED;;;;OAIG;IACH,qCAHW,OAAO,SACP,UAAU,GAAC,KAAK,QAI1B;IAED,cAiCC;IAED,aA4BC;;CACJ;oBAnkBmB,+BAA+B;mBADhC,uCAAuC;kCAOxB,wBAAwB"}
1
+ {"version":3,"file":"PointerDevice.d.ts","sourceRoot":"","sources":["../../../../../src/engine/input/devices/PointerDevice.js"],"names":[],"mappings":"AAgPA;;;;;GAKG;AACH,mDAJW,OAAO,SACP,UAAU,GAAC,KAAK,WAChB,OAAO,QAejB;AAED;;;;;GAKG;AACH;IAyFI;;;;OAIG;IACH,wBAHW,WAAW,EA+BrB;IAtHD;;;;OAIG;IACH,mBAFU,OAAO,CAEQ;IAEzB;;OAEG;IACH;;;QAGI;;;;;;WAMG;;;QAGH;;WAEG;;;;;;;;;MASL;IAeF;;;OAGG;IACH,kBAAkB;IAElB;;;;OAIG;IACH,kBAFU,iBAAiB,EAAE,CAEL;IAExB;;;OAGG;IACH,yCAEC;IAED;;;OAGG;IACH,0CAEC;IAED;;;OAGG;IACH,2CAEC;IA2ID;;;OAGG;IACH,oBAFY,OAAO,CAIlB;IAED;;;OAGG;IACH,4BAsBC;IAED,0BAEC;IAED;;;;OAIG;IACH,qCAHW,OAAO,SACP,UAAU,GAAC,KAAK,QAI1B;IAED,cAiCC;IAED,aA4BC;;CACJ;oBA5lBmB,+BAA+B;mBADhC,uCAAuC;kCAOxB,wBAAwB"}
@@ -20,6 +20,7 @@ import { suppressContextMenu } from "./mouse/suppressContextMenu.js";
20
20
  * @param {number} [options.maxDistance] in pixels
21
21
  * @param {number} [options.maxDelay] Maximum delay between down and up events in seconds
22
22
  * @param {Signal} options.signal
23
+ * @returns {(id?:number)=>void} clears pending candidates without emitting a tap
23
24
  */
24
25
  function observeTap({
25
26
  up,
@@ -139,6 +140,16 @@ function observeTap({
139
140
  }
140
141
 
141
142
  down.add(handleDown);
143
+
144
+ return id => {
145
+ if (id !== undefined) {
146
+ reset(id);
147
+ return;
148
+ }
149
+ active.clear();
150
+ up.remove(handleUp);
151
+ move.remove(handleMove);
152
+ };
142
153
  }
143
154
 
144
155
  /**
@@ -149,6 +160,7 @@ function observeTap({
149
160
  * @param {Signal} dragStart
150
161
  * @param {Signal} dragEnd
151
162
  * @param {Signal} drag
163
+ * @returns {()=>void} removes pending gesture observations without emitting a drag end
152
164
  */
153
165
  function observeDrag(up, down, move, dragStart, dragEnd, drag) {
154
166
  const origin = new Vector2();
@@ -188,7 +200,8 @@ function observeDrag(up, down, move, dragStart, dragEnd, drag) {
188
200
 
189
201
  lastDragPosition.copy(origin);
190
202
  dragStart.send2(origin, event);
191
- handleDrag(position, event);
203
+ // A start consumer can stop the device and remove this gesture before motion is delivered.
204
+ if (up.contains(handleDragEnd)) handleDrag(position, event);
192
205
  }
193
206
 
194
207
  const lastDragPosition = new Vector2();
@@ -214,6 +227,14 @@ function observeDrag(up, down, move, dragStart, dragEnd, drag) {
214
227
  }
215
228
 
216
229
  down.add(handleDown);
230
+
231
+ return () => {
232
+ // Overlapping presses can register these owned observations more than once.
233
+ while (up.remove(noDrag)) {}
234
+ while (up.remove(handleDragEnd)) {}
235
+ while (move.remove(handleDragStart)) {}
236
+ while (move.remove(handleDrag)) {}
237
+ };
217
238
  }
218
239
 
219
240
 
@@ -245,6 +266,8 @@ export function readPositionFromMouseEvent(result, event, source = event.target)
245
266
  * @copyright Company Named Limited (c) 2026
246
267
  */
247
268
  export class PointerDevice {
269
+ #resetTap;
270
+ #resetDrag;
248
271
 
249
272
  /**
250
273
  * Current live position of the pointer
@@ -355,14 +378,14 @@ export class PointerDevice {
355
378
  // `globalUp`, not `up`, for the same reason observeDrag below uses it: `up` only fires for
356
379
  // a release over the element, so a press that lifted one pixel outside the canvas was
357
380
  // never resolved and never reset - the candidate simply sat in the map.
358
- observeTap({
381
+ this.#resetTap = observeTap({
359
382
  up: this.on.globalUp,
360
383
  down: this.on.down,
361
384
  move: this.on.move,
362
385
  maxDistance: 10,
363
386
  signal: this.on.tap
364
387
  });
365
- observeDrag(this.on.globalUp, this.on.down, this.on.move, this.on.dragStart, this.on.dragEnd, this.on.drag);
388
+ this.#resetDrag = observeDrag(this.on.globalUp, this.on.down, this.on.move, this.on.dragStart, this.on.dragEnd, this.on.drag);
366
389
 
367
390
  }
368
391
 
@@ -424,7 +447,9 @@ export class PointerDevice {
424
447
  * every button for the same reason. The pointer was the one device of the three that did not,
425
448
  * with `PointerEvents.Cancel` sitting unused in the event table as the tell.
426
449
  */
427
- #releaseAllButtons = () => {
450
+ #releaseAllButtons = event => {
451
+ this.#resetTap(event?.type === PointerEvents.Cancel ? event.pointerId : undefined);
452
+ this.#resetDrag();
428
453
  const buttons = this.buttons;
429
454
 
430
455
  for (let i = 0; i < buttons.length; i++) {
@@ -2,6 +2,7 @@
2
2
  * Picks a random behavior to execute.
3
3
  * The selection is done during initialization, and that selected behavior will then run to completion.
4
4
  * NOTE: Weights are relative, so they don't need to add up to any specific value.
5
+ * If every weight is zero, no child runs and the selector fails.
5
6
  *
6
7
  * @example
7
8
  * const behavior = WeightedRandomBehavior.from([
@@ -1 +1 @@
1
- {"version":3,"file":"WeightedRandomBehavior.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/intelligence/behavior/selector/WeightedRandomBehavior.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;GAaG;AACH;IAkEI;;;;OAIG;IACH,sBAHW,8BAAyB,EAAE,GACzB,sBAAsB,CAUlC;;IA7ED;;;;OAIG;IACH,mBAAgB;IAEhB;;;;OAIG;IACH,iBAA+B;IAE/B;;;;OAIG;IACH,mBAAuB;IAEvB;;;OAGG;IACH,iBAFW,MAAM,QAIhB;IAED;;;OAGG;IACH,sBAFW,8BAAyB,EAAE,QAcrC;IAED;;;OAGG;IACH,cAFW,8BAAyB,QAanC;IAiBD,iBAYC;IAkBD,6BAEC;CACJ;yBAnIwB,gBAAgB;gCACT,sBAAsB"}
1
+ {"version":3,"file":"WeightedRandomBehavior.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/intelligence/behavior/selector/WeightedRandomBehavior.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;GAcG;AACH;IAkEI;;;;OAIG;IACH,sBAHW,8BAAyB,EAAE,GACzB,sBAAsB,CAUlC;;IA7ED;;;;OAIG;IACH,mBAAgB;IAEhB;;;;OAIG;IACH,iBAA+B;IAE/B;;;;OAIG;IACH,mBAAuB;IAEvB;;;OAGG;IACH,iBAFW,MAAM,QAIhB;IAED;;;OAGG;IACH,sBAFW,8BAAyB,EAAE,QAcrC;IAED;;;OAGG;IACH,cAFW,8BAAyB,QAanC;IAiBD,iBAiBC;IAsBD,6BAEC;CACJ;yBA9IwB,gBAAgB;gCAET,sBAAsB"}
@@ -2,12 +2,14 @@ import { assert } from "../../../../core/assert.js";
2
2
  import { weightedRandomFromArray } from "../../../../core/collection/array/weightedRandomFromArray.js";
3
3
  import { seededRandom } from "../../../../core/math/random/seededRandom.js";
4
4
  import { Behavior } from "../Behavior.js";
5
+ import { BehaviorStatus } from "../BehaviorStatus.js";
5
6
  import { WeightedElement } from "./WeightedElement.js";
6
7
 
7
8
  /**
8
9
  * Picks a random behavior to execute.
9
10
  * The selection is done during initialization, and that selected behavior will then run to completion.
10
11
  * NOTE: Weights are relative, so they don't need to add up to any specific value.
12
+ * If every weight is zero, no child runs and the selector fails.
11
13
  *
12
14
  * @example
13
15
  * const behavior = WeightedRandomBehavior.from([
@@ -106,6 +108,11 @@ export class WeightedRandomBehavior extends Behavior {
106
108
  */
107
109
  const weightedElement = weightedRandomFromArray(this.__elements, this.__random, WeightedElement.getWeight);
108
110
 
111
+ if (weightedElement === undefined) {
112
+ this.__selected = undefined;
113
+ return;
114
+ }
115
+
109
116
  const selected = weightedElement.data;
110
117
 
111
118
  assert.equal(selected.isBehavior, true, 'selected.isBehavior !== true');
@@ -118,18 +125,22 @@ export class WeightedRandomBehavior extends Behavior {
118
125
 
119
126
  this.__select();
120
127
 
121
- this.__selected.initialize(context);
128
+ if (this.__selected !== undefined) {
129
+ this.__selected.initialize(context);
130
+ }
122
131
  }
123
132
 
124
133
  finalize() {
125
134
  super.finalize();
126
135
 
127
- this.__selected.finalize();
136
+ if (this.__selected !== undefined) {
137
+ this.__selected.finalize();
138
+ }
128
139
 
129
140
  this.__selected = undefined;
130
141
  }
131
142
 
132
143
  tick(timeDelta) {
133
- return this.__selected.tick(timeDelta);
144
+ return this.__selected === undefined ? BehaviorStatus.Failed : this.__selected.tick(timeDelta);
134
145
  }
135
146
  }
@@ -66,11 +66,11 @@ export class FluidObstacleSystem extends System<any> {
66
66
  /**
67
67
  * @param {FluidComponent} fluid
68
68
  */
69
- static "__#426@#refresh_masks"(fluid: FluidComponent): void;
69
+ static "__#430@#refresh_masks"(fluid: FluidComponent): void;
70
70
  /**
71
71
  * @param {FluidComponent} fluid
72
72
  */
73
- static "__#426@#clear_field"(fluid: FluidComponent): void;
73
+ static "__#430@#clear_field"(fluid: FluidComponent): void;
74
74
  /**
75
75
  * Mark every cell of `fluid` whose centre lies within `inflation` of the
76
76
  * posed shape as solid. Iteration is clipped to the shape's world AABB
@@ -82,7 +82,7 @@ export class FluidObstacleSystem extends System<any> {
82
82
  * @param {number} inflation world-units SDF threshold
83
83
  * @param {Float64Array} point length-3 scratch
84
84
  */
85
- static "__#426@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
85
+ static "__#430@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
86
86
  /**
87
87
  * Write the obstacle's translation velocity onto every face of every cell
88
88
  * it voxelized — the moving-wall boundary condition. Runs AFTER the mask
@@ -102,7 +102,7 @@ export class FluidObstacleSystem extends System<any> {
102
102
  * @param {number} wvy
103
103
  * @param {number} wvz
104
104
  */
105
- static "__#426@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
105
+ static "__#430@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
106
106
  constructor();
107
107
  dependencies: (typeof FluidObstacle)[];
108
108
  components_used: (ResourceAccessSpecification<typeof Transform64> | ResourceAccessSpecification<typeof RigidBody> | ResourceAccessSpecification<typeof Collider> | ResourceAccessSpecification<typeof FluidComponent> | ResourceAccessSpecification<typeof FluidObstacle>)[];
@@ -1 +1 @@
1
- {"version":3,"file":"v3_grid_advect_maccormack_velocity.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,4DAbW,YAAY,EAAE,WACd,YAAY,EAAE,aACd,YAAY,aACZ,YAAY,aACZ,YAAY,mBACZ,YAAY,EAAE,SAEd,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,UAAU,QAgHpB"}
1
+ {"version":3,"file":"v3_grid_advect_maccormack_velocity.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,4DAbW,YAAY,EAAE,WACd,YAAY,EAAE,aACd,YAAY,aACZ,YAAY,aACZ,YAAY,mBACZ,YAAY,EAAE,SAEd,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,UAAU,QAuHpB"}
@@ -1,7 +1,7 @@
1
1
  import { v3_grid_limit8_at_indices } from "./v3_grid_limit8_at_indices.js";
2
2
  import { assert } from "../../../../core/assert.js";
3
3
  import { clamp } from "../../../../core/math/clamp.js";
4
- import { scs3d_sample_linear3 } from "../../../graphics/texture/3d/scs3d_sample_linear3.js";
4
+ import { scs3d_sample_linear3_array } from "../../../graphics/texture/3d/scs3d_sample_linear3.js";
5
5
 
6
6
  /*
7
7
  * COLLOCATED VARIANT. FluidSimulator transports through the MAC (staggered-grid) kernels in the sibling
@@ -76,6 +76,7 @@ export function v3_grid_advect_maccormack_velocity(outputs, sources, carrier_x,
76
76
  const last_y = res_y - 1;
77
77
  const last_z = res_z - 1;
78
78
  const sample = scratch_sample;
79
+ const position = scratch_position;
79
80
 
80
81
  // ─── pass 1: forward SL step into the scratch trio ──────────────────────
81
82
  for (let z = 0; z < res_z; z++) {
@@ -93,7 +94,10 @@ export function v3_grid_advect_maccormack_velocity(outputs, sources, carrier_x,
93
94
  const s_x = x - carrier_x[c] * time_delta;
94
95
  const s_y = y - carrier_y[c] * time_delta;
95
96
  const s_z = z - carrier_z[c] * time_delta;
96
- scs3d_sample_linear3(sample, src_x, src_y, src_z, res_x, res_y, res_z, s_x, s_y, s_z);
97
+ position[0] = s_x;
98
+ position[1] = s_y;
99
+ position[2] = s_z;
100
+ scs3d_sample_linear3_array(sample, src_x, src_y, src_z, res_x, res_y, res_z, position, 0);
97
101
  fwd_x[c] = sample[0];
98
102
  fwd_y[c] = sample[1];
99
103
  fwd_z[c] = sample[2];
@@ -119,7 +123,10 @@ export function v3_grid_advect_maccormack_velocity(outputs, sources, carrier_x,
119
123
  const vy = carrier_y[c] * time_delta;
120
124
  const vz = carrier_z[c] * time_delta;
121
125
 
122
- scs3d_sample_linear3(sample, fwd_x, fwd_y, fwd_z, res_x, res_y, res_z, x + vx, y + vy, z + vz);
126
+ position[0] = x + vx;
127
+ position[1] = y + vy;
128
+ position[2] = z + vz;
129
+ scs3d_sample_linear3_array(sample, fwd_x, fwd_y, fwd_z, res_x, res_y, res_z, position, 0);
123
130
  const corr_x = fwd_x[c] + 0.5 * (src_x[c] - sample[0]);
124
131
  const corr_y = fwd_y[c] + 0.5 * (src_y[c] - sample[1]);
125
132
  const corr_z = fwd_z[c] + 0.5 * (src_z[c] - sample[2]);
@@ -160,3 +167,5 @@ export function v3_grid_advect_maccormack_velocity(outputs, sources, carrier_x,
160
167
 
161
168
  /** Module-static sample destination — avoids per-cell allocation. */
162
169
  const scratch_sample = new Float32Array(3);
170
+ /** Continuous coordinates passed to the sampler during this synchronous typed-array sweep. */
171
+ const scratch_position = new Float64Array(3);
@@ -1 +1 @@
1
- {"version":3,"file":"v3_grid_advect_sl_velocity.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,oDAdW,YAAY,EAAE,WACd,YAAY,EAAE,aAEd,YAAY,aACZ,YAAY,aACZ,YAAY,SACZ,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,UAAU,QA+DpB"}
1
+ {"version":3,"file":"v3_grid_advect_sl_velocity.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,oDAdW,YAAY,EAAE,WACd,YAAY,EAAE,aAEd,YAAY,aACZ,YAAY,aACZ,YAAY,SACZ,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,UAAU,QAmEpB"}
@@ -1,5 +1,5 @@
1
1
  import { assert } from "../../../../core/assert.js";
2
- import { scs3d_sample_linear3 } from "../../../graphics/texture/3d/scs3d_sample_linear3.js";
2
+ import { scs3d_sample_linear3_array } from "../../../graphics/texture/3d/scs3d_sample_linear3.js";
3
3
 
4
4
  /*
5
5
  * COLLOCATED VARIANT. FluidSimulator transports through the MAC (staggered-grid) kernels in the sibling
@@ -72,6 +72,7 @@ export function v3_grid_advect_sl_velocity(outputs, sources, carrier_x, carrier_
72
72
 
73
73
  const slice_size = res_x * res_y;
74
74
  const sample = scratch_sample;
75
+ const position = scratch_position;
75
76
 
76
77
  for (let z = 0; z < res_z; z++) {
77
78
  const z_off = z * slice_size;
@@ -94,7 +95,10 @@ export function v3_grid_advect_sl_velocity(outputs, sources, carrier_x, carrier_
94
95
  const s_y = y - carrier_y[c] * time_delta;
95
96
  const s_z = z - carrier_z[c] * time_delta;
96
97
 
97
- scs3d_sample_linear3(sample, src_x, src_y, src_z, res_x, res_y, res_z, s_x, s_y, s_z);
98
+ position[0] = s_x;
99
+ position[1] = s_y;
100
+ position[2] = s_z;
101
+ scs3d_sample_linear3_array(sample, src_x, src_y, src_z, res_x, res_y, res_z, position, 0);
98
102
  out_x[c] = sample[0];
99
103
  out_y[c] = sample[1];
100
104
  out_z[c] = sample[2];
@@ -105,3 +109,5 @@ export function v3_grid_advect_sl_velocity(outputs, sources, carrier_x, carrier_
105
109
 
106
110
  /** Module-static sample destination — avoids per-cell allocation. */
107
111
  const scratch_sample = new Float32Array(3);
112
+ /** Continuous coordinates passed to the sampler during this synchronous typed-array sweep. */
113
+ const scratch_position = new Float64Array(3);
@@ -27,4 +27,23 @@
27
27
  * @return {number}
28
28
  */
29
29
  export function v3_grid_sample_scalar_masked(data: Float32Array, solid: Uint8Array, res_x: number, res_y: number, res_z: number, x: number, y: number, z: number, fallback: number): number;
30
+ /**
31
+ * {@link v3_grid_sample_scalar_masked} with `[x, y, z, fallback]` read from a reusable operand record
32
+ * and the sample written into `out`. No continuous number crosses the call boundary, including the
33
+ * result, so a per-cell caller does not need this sampler to be inlined to avoid numeric boxes.
34
+ *
35
+ * The operands are read before any output write; `out` may overlap `operands` or `data`. Float64
36
+ * operands preserve the scalar form's coordinate and fallback precision.
37
+ *
38
+ * @param {Float32Array|Float64Array|number[]} out
39
+ * @param {number} out_offset
40
+ * @param {Float32Array} data
41
+ * @param {Uint8Array} solid
42
+ * @param {number} res_x
43
+ * @param {number} res_y
44
+ * @param {number} res_z
45
+ * @param {Float64Array} operands `[x, y, z, fallback]`
46
+ * @param {number} operands_offset
47
+ */
48
+ export function v3_grid_sample_scalar_masked_array(out: Float32Array | Float64Array | number[], out_offset: number, data: Float32Array, solid: Uint8Array, res_x: number, res_y: number, res_z: number, operands: Float64Array, operands_offset: number): void;
30
49
  //# sourceMappingURL=v3_grid_sample_scalar_masked.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"v3_grid_sample_scalar_masked.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,mDAXW,YAAY,SACZ,UAAU,SACV,MAAM,SACN,MAAM,SACN,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,YACN,MAAM,GACL,MAAM,CA+DjB"}
1
+ {"version":3,"file":"v3_grid_sample_scalar_masked.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,mDAXW,YAAY,SACZ,UAAU,SACV,MAAM,SACN,MAAM,SACN,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,YACN,MAAM,GACL,MAAM,CAYjB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wDAVW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,cAClC,MAAM,QACN,YAAY,SACZ,UAAU,SACV,MAAM,SACN,MAAM,SACN,MAAM,YACN,YAAY,mBACZ,MAAM,QAqEhB"}
@@ -1,5 +1,8 @@
1
1
  import { clamp } from "../../../../core/math/clamp.js";
2
2
 
3
+ const scratch_operands = new Float64Array(4);
4
+ const scratch_sample = new Float64Array(1);
5
+
3
6
  /**
4
7
  * Trilinearly sample a cell-centered scalar at a fractional position,
5
8
  * EXCLUDING solid cells from the interpolation: solid taps contribute zero
@@ -29,6 +32,41 @@ import { clamp } from "../../../../core/math/clamp.js";
29
32
  * @return {number}
30
33
  */
31
34
  export function v3_grid_sample_scalar_masked(data, solid, res_x, res_y, res_z, x, y, z, fallback) {
35
+ const operands = scratch_operands;
36
+ operands[0] = x;
37
+ operands[1] = y;
38
+ operands[2] = z;
39
+ operands[3] = fallback;
40
+
41
+ v3_grid_sample_scalar_masked_array(scratch_sample, 0, data, solid, res_x, res_y, res_z, operands, 0);
42
+
43
+ return scratch_sample[0];
44
+ }
45
+
46
+ /**
47
+ * {@link v3_grid_sample_scalar_masked} with `[x, y, z, fallback]` read from a reusable operand record
48
+ * and the sample written into `out`. No continuous number crosses the call boundary, including the
49
+ * result, so a per-cell caller does not need this sampler to be inlined to avoid numeric boxes.
50
+ *
51
+ * The operands are read before any output write; `out` may overlap `operands` or `data`. Float64
52
+ * operands preserve the scalar form's coordinate and fallback precision.
53
+ *
54
+ * @param {Float32Array|Float64Array|number[]} out
55
+ * @param {number} out_offset
56
+ * @param {Float32Array} data
57
+ * @param {Uint8Array} solid
58
+ * @param {number} res_x
59
+ * @param {number} res_y
60
+ * @param {number} res_z
61
+ * @param {Float64Array} operands `[x, y, z, fallback]`
62
+ * @param {number} operands_offset
63
+ */
64
+ export function v3_grid_sample_scalar_masked_array(out, out_offset, data, solid, res_x, res_y, res_z, operands, operands_offset) {
65
+ const x = operands[operands_offset];
66
+ const y = operands[operands_offset + 1];
67
+ const z = operands[operands_offset + 2];
68
+ const fallback = operands[operands_offset + 3];
69
+
32
70
  const x_max = res_x - 1;
33
71
  const y_max = res_y - 1;
34
72
  const z_max = res_z - 1;
@@ -80,7 +118,8 @@ export function v3_grid_sample_scalar_masked(data, solid, res_x, res_y, res_z, x
80
118
 
81
119
  const total = w000 + w100 + w010 + w110 + w001 + w101 + w011 + w111;
82
120
  if (total <= 0) {
83
- return fallback;
121
+ out[out_offset] = fallback;
122
+ return;
84
123
  }
85
124
 
86
125
  const sum = w000 * data[c000] + w100 * data[c100]
@@ -88,5 +127,5 @@ export function v3_grid_sample_scalar_masked(data, solid, res_x, res_y, res_z, x
88
127
  + w001 * data[c001] + w101 * data[c101]
89
128
  + w011 * data[c011] + w111 * data[c111];
90
129
 
91
- return sum / total;
130
+ out[out_offset] = sum / total;
92
131
  }
@@ -1 +1 @@
1
- {"version":3,"file":"v3_mac_advect_scalar.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_mac_advect_scalar.js"],"names":[],"mappings":"AAiCA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,gDAXW,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,UAAU,QA4CpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wDAZW,YAAY,SACZ,YAAY,mBACZ,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,UAAU,QA8GpB"}
1
+ {"version":3,"file":"v3_mac_advect_scalar.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_mac_advect_scalar.js"],"names":[],"mappings":"AAmCA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,gDAXW,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,UAAU,QAgDpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wDAZW,YAAY,SACZ,YAAY,mBACZ,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,YAAY,SACZ,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,UAAU,QA8GpB"}