@woosh/meep-engine 3.64.1 → 3.65.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 (324) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/build/bundle-worker-image-decoder.js +1 -1
  3. package/build/bundle-worker-terrain.js +1 -1
  4. package/package.json +1 -1
  5. package/src/core/binary/BinaryBuffer.d.ts +5 -0
  6. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  7. package/src/core/binary/BinaryBuffer.js +39 -5
  8. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts +65 -6
  9. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts.map +1 -1
  10. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +451 -101
  11. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +4 -2
  12. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -1
  13. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +4 -2
  14. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts +8 -1
  15. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts.map +1 -1
  16. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +45 -10
  17. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
  18. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +237 -119
  19. package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts +143 -0
  20. package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts.map +1 -0
  21. package/src/engine/graphics/ecs/grass/GrassSpecies.js +189 -0
  22. package/src/engine/graphics/ecs/grass/GrassSurface.d.ts +25 -0
  23. package/src/engine/graphics/ecs/grass/GrassSurface.d.ts.map +1 -0
  24. package/src/engine/graphics/ecs/grass/GrassSurface.js +32 -0
  25. package/src/engine/graphics/ecs/grass/GroundCover.d.ts +68 -0
  26. package/src/engine/graphics/ecs/grass/GroundCover.d.ts.map +1 -0
  27. package/src/engine/graphics/ecs/grass/GroundCover.js +85 -0
  28. package/src/engine/graphics3/GrassSurfaceSystem.d.ts +153 -0
  29. package/src/engine/graphics3/GrassSurfaceSystem.d.ts.map +1 -0
  30. package/src/engine/graphics3/GrassSurfaceSystem.js +1076 -0
  31. package/src/engine/graphics3/GroundCoverSystem.d.ts +33 -0
  32. package/src/engine/graphics3/GroundCoverSystem.d.ts.map +1 -0
  33. package/src/engine/graphics3/GroundCoverSystem.js +58 -0
  34. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  35. package/src/engine/network/NetworkSession.js +372 -110
  36. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  37. package/src/engine/network/orchestrator/NetworkPeer.js +6 -1
  38. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  39. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +9 -2
  40. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  41. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +325 -140
  42. package/src/engine/network/sim/SimActionExecutor.d.ts +4 -1
  43. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
  44. package/src/engine/network/sim/SimActionExecutor.js +65 -9
  45. package/src/engine/network/state/PredictionHistory.d.ts.map +1 -1
  46. package/src/engine/network/state/PredictionHistory.js +6 -1
  47. package/src/engine/network/time/AdaptiveRenderDelay.d.ts +25 -14
  48. package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -1
  49. package/src/engine/network/time/AdaptiveRenderDelay.js +38 -20
  50. package/src/engine/network/time/RenderPlayout.d.ts +23 -3
  51. package/src/engine/network/time/RenderPlayout.d.ts.map +1 -1
  52. package/src/engine/network/time/RenderPlayout.js +40 -4
  53. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  54. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +5 -1
  55. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -1
  56. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +27 -1
  57. package/src/shade/device/shader/ShaderModuleCompiler.d.ts +2 -0
  58. package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
  59. package/src/shade/device/shader/ShaderModuleCompiler.js +25 -2
  60. package/src/shade/playground/grass_surfaces/index.html +75 -0
  61. package/src/shade/playground/grass_surfaces/main.d.ts +2 -0
  62. package/src/shade/playground/grass_surfaces/main.d.ts.map +1 -0
  63. package/src/shade/playground/grass_surfaces/main.js +593 -0
  64. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts +62 -0
  65. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts.map +1 -0
  66. package/src/shade/playground/grass_surfaces/read_grass_surfaces.js +188 -0
  67. package/src/shade/playground/probe_clipmap_box/README.md +5 -1
  68. package/src/shade/playground/probe_clipmap_box/index.html +12 -0
  69. package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -1
  70. package/src/shade/playground/probe_clipmap_box/main.js +15 -0
  71. package/src/shade/playground/probe_clipmap_box/scene.d.ts +8 -1
  72. package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -1
  73. package/src/shade/playground/probe_clipmap_box/scene.js +74 -6
  74. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  75. package/src/shade/renderer/Renderer.js +47 -43
  76. package/src/shade/renderer/extension/ViewTextures.d.ts +12 -5
  77. package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
  78. package/src/shade/renderer/extension/ViewTextures.js +19 -5
  79. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +3 -1
  80. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
  81. package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +6 -1
  82. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +7 -0
  83. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
  84. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +10 -0
  85. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +7 -1
  86. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  87. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +46 -15
  88. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts +3 -2
  89. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts.map +1 -1
  90. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js +3 -2
  91. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts +22 -0
  92. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts.map +1 -0
  93. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js +247 -0
  94. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +50 -0
  95. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  96. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +101 -0
  97. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +2 -1
  98. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
  99. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +2 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +8 -0
  101. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
  102. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +12 -0
  103. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +12 -6
  104. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +35 -29
  106. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.d.ts.map +1 -1
  107. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.js +4 -2
  108. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.d.ts.map +1 -1
  109. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.js +6 -4
  110. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.d.ts.map +1 -1
  111. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.js +2 -1
  112. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts +6 -5
  113. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts.map +1 -1
  114. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.js +15 -14
  115. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.d.ts.map +1 -1
  116. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.js +4 -2
  117. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +19 -2
  118. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  119. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +128 -10
  120. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +19 -1
  121. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  122. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +27 -2
  123. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +19 -11
  124. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -1
  125. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +35 -11
  126. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  127. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +3 -1
  128. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts +40 -0
  129. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts.map +1 -0
  130. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js +174 -0
  131. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.d.ts +4 -4
  132. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.js +10 -10
  133. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts +31 -0
  134. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts.map +1 -0
  135. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.js +54 -0
  136. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +8 -4
  137. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
  138. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +10 -21
  139. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +7 -2
  140. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -1
  141. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +33 -29
  142. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts +28 -0
  143. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts.map +1 -0
  144. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.js +138 -0
  145. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +13 -9
  146. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
  147. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +18 -11
  148. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +1 -1
  149. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
  150. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +4 -2
  151. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
  152. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +2 -3
  153. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +5 -3
  154. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
  155. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +15 -30
  156. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -1
  157. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  158. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +4 -2
  159. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +11 -0
  160. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
  161. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +29 -2
  162. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts +40 -0
  163. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts.map +1 -0
  164. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.js +126 -0
  165. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts +36 -0
  166. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts.map +1 -0
  167. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.js +221 -0
  168. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts +40 -0
  169. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts.map +1 -0
  170. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.js +86 -0
  171. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts +135 -0
  172. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts.map +1 -0
  173. package/src/shade/renderer/grass/blade/GPUGrassBlades.js +676 -0
  174. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts +145 -0
  175. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts.map +1 -0
  176. package/src/shade/renderer/grass/blade/GRASS_BLADE.js +179 -0
  177. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts +63 -0
  178. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts.map +1 -0
  179. package/src/shade/renderer/grass/blade/chunk_grass_blade.js +244 -0
  180. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts +58 -0
  181. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts.map +1 -0
  182. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.js +174 -0
  183. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts +25 -0
  184. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts.map +1 -0
  185. package/src/shade/renderer/grass/blade/grass_blade_id_draw.js +133 -0
  186. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts +80 -0
  187. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts.map +1 -0
  188. package/src/shade/renderer/grass/blade/grass_blade_mechanics.js +92 -0
  189. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts +29 -0
  190. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts.map +1 -0
  191. package/src/shade/renderer/grass/blade/grass_blade_resolve.js +175 -0
  192. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts +14 -0
  193. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts.map +1 -0
  194. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.js +45 -0
  195. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts +61 -0
  196. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts.map +1 -0
  197. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.js +340 -0
  198. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts +46 -0
  199. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts.map +1 -0
  200. package/src/shade/renderer/grass/blade/shader_grass_cell_count.js +280 -0
  201. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts +60 -0
  202. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts.map +1 -0
  203. package/src/shade/renderer/grass/population/chunk_grass_population.js +171 -0
  204. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts +99 -0
  205. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts.map +1 -0
  206. package/src/shade/renderer/grass/press/GPUGrassPress.js +436 -0
  207. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts +179 -0
  208. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts.map +1 -0
  209. package/src/shade/renderer/grass/press/GRASS_PRESS.js +217 -0
  210. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts +65 -0
  211. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts.map +1 -0
  212. package/src/shade/renderer/grass/press/chunk_grass_press.js +296 -0
  213. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +31 -0
  214. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -0
  215. package/src/shade/renderer/grass/press/shader_grass_press_mark.js +169 -0
  216. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts +27 -0
  217. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts.map +1 -0
  218. package/src/shade/renderer/grass/press/shader_grass_press_stamp.js +183 -0
  219. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts +193 -0
  220. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts.map +1 -0
  221. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.js +1253 -0
  222. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts +211 -0
  223. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts.map +1 -0
  224. package/src/shade/renderer/grass/surface/GRASS_SURFACE.js +241 -0
  225. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts +82 -0
  226. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts.map +1 -0
  227. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.js +111 -0
  228. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts +39 -0
  229. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts.map +1 -0
  230. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.js +85 -0
  231. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts +29 -0
  232. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts.map +1 -0
  233. package/src/shade/renderer/grass/surface/chunk_grass_directory.js +112 -0
  234. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts +27 -0
  235. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts.map +1 -0
  236. package/src/shade/renderer/grass/surface/chunk_grass_slot.js +50 -0
  237. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts +21 -0
  238. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts.map +1 -0
  239. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.js +41 -0
  240. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts +32 -0
  241. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts.map +1 -0
  242. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.js +136 -0
  243. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts +37 -0
  244. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts.map +1 -0
  245. package/src/shade/renderer/grass/surface/chunk_grass_surfel.js +85 -0
  246. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts +25 -0
  247. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts.map +1 -0
  248. package/src/shade/renderer/grass/surface/chunk_grass_tile.js +52 -0
  249. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts +23 -0
  250. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts.map +1 -0
  251. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.js +87 -0
  252. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts +43 -0
  253. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -0
  254. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +265 -0
  255. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts +13 -0
  256. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts.map +1 -0
  257. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.js +49 -0
  258. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts +62 -0
  259. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts.map +1 -0
  260. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.js +162 -0
  261. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts +40 -0
  262. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts.map +1 -0
  263. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.js +155 -0
  264. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts +19 -0
  265. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts.map +1 -0
  266. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.js +58 -0
  267. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts +30 -0
  268. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts.map +1 -0
  269. package/src/shade/renderer/grass/surface/shader_grass_surface_want.js +251 -0
  270. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts +21 -0
  271. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts.map +1 -0
  272. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.js +75 -0
  273. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  274. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +4 -23
  275. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts +12 -0
  276. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts.map +1 -0
  277. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.js +29 -0
  278. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  279. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +22 -0
  280. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  281. package/src/shade/renderer/scene/GPUSceneContext.js +3 -0
  282. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts +27 -0
  283. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts.map +1 -0
  284. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.js +38 -0
  285. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts +28 -0
  286. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts.map +1 -0
  287. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.js +58 -0
  288. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
  289. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +8 -0
  290. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +37 -0
  291. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -0
  292. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +148 -0
  293. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts +20 -0
  294. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts.map +1 -0
  295. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js +169 -0
  296. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +18 -0
  297. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -1
  298. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +28 -0
  299. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts +13 -0
  300. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts.map +1 -0
  301. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js +22 -0
  302. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  303. package/src/shade/renderer/water/GPUWaterRenderer.js +4 -0
  304. package/src/shade/renderer/wind/GPUSceneWind.d.ts +52 -5
  305. package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
  306. package/src/shade/renderer/wind/GPUSceneWind.js +164 -8
  307. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +3 -1
  308. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -1
  309. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +3 -1
  310. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -1
  311. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
  312. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +18 -13
  313. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts +13 -0
  314. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts.map +1 -0
  315. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.js +23 -0
  316. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +1 -0
  317. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -1
  318. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +6 -1
  319. package/src/shade/renderer/wind/wind_field_add_resources.d.ts +11 -0
  320. package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
  321. package/src/shade/renderer/wind/wind_field_add_resources.js +15 -0
  322. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +1 -1
  323. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  324. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
@@ -0,0 +1,436 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
3
+ import { FLUID_OBSTACLE_TABLE } from "../../fluid/forcing/FLUID_DATABASE_SPEC.js";
4
+ import {
5
+ GRASS_PRESS_FIELD_WORDS,
6
+ GRASS_PRESS_JOBS_COMMAND,
7
+ GRASS_PRESS_JOBS_TILES,
8
+ GRASS_PRESS_JOBS_WORDS,
9
+ GRASS_PRESS_TICKS_PER_SECOND,
10
+ GRASS_PRESS_TILE_CELLS,
11
+ GRASS_PRESS_WINDOW_CELLS,
12
+ GRASS_PRESS_WINDOW_STRUCT
13
+ } from "./GRASS_PRESS.js";
14
+ import { GRASS_PRESS_MARK_WORKGROUP_SIZE, shader_grass_press_mark } from "./shader_grass_press_mark.js";
15
+ import { shader_grass_press_stamp } from "./shader_grass_press_stamp.js";
16
+
17
+ /**
18
+ * @typedef {import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} FrameGraph
19
+ * @typedef {import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
20
+ * @typedef {import("../../fluid/forcing/GPUFluidForcing.js").GPUFluidForcing} GPUFluidForcing
21
+ * @typedef {import("../../GraphicsContext.js").GraphicsContext} GraphicsContext
22
+ * @typedef {import("../../view/GPUViewContext.js").GPUViewContext} GPUViewContext
23
+ */
24
+
25
+ /**
26
+ * The frame's tile jobs: the command and the tiles' counts cleared, the rest written before it is read.
27
+ */
28
+ const JOBS_DESCRIPTOR = BufferResourceDescriptor.from(
29
+ GRASS_PRESS_JOBS_WORDS * 4,
30
+ GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT,
31
+ GRASS_PRESS_JOBS_COMMAND * 4, (GRASS_PRESS_JOBS_TILES - GRASS_PRESS_JOBS_COMMAND) * 4,
32
+ );
33
+
34
+ // words of GRASS_PRESS_WINDOW_STRUCT, from its layout
35
+ const WINDOW_CORNER = GRASS_PRESS_WINDOW_STRUCT.get('corner').offset >>> 2;
36
+ const WINDOW_SPACING = GRASS_PRESS_WINDOW_STRUCT.get('spacing').offset >>> 2;
37
+ const WINDOW_NOW = GRASS_PRESS_WINDOW_STRUCT.get('now').offset >>> 2;
38
+ const WINDOW_PREVIOUS = GRASS_PRESS_WINDOW_STRUCT.get('previous').offset >>> 2;
39
+ const WINDOW_STAMPED = GRASS_PRESS_WINDOW_STRUCT.get('stamped').offset >>> 2;
40
+ const WINDOW_ROW_COUNT = GRASS_PRESS_WINDOW_STRUCT.get('row_count').offset >>> 2;
41
+
42
+ /**
43
+ * The press field on the device (`GRASS_PRESS.js`): the field, its window and clock, and the passes that
44
+ * write it from the scene's fluid obstacles.
45
+ *
46
+ * Each frame: {@link update} once, with the scene's clock; then {@link graph_stamp} for every view that
47
+ * reads the field, before the pass that reads it, which reads the resource it answers with and takes the
48
+ * window from {@link bind}.
49
+ *
50
+ * The obstacles are the GPU fluid's: the rows of its forcing's obstacle table, whose database the passes
51
+ * bind. While a scene has no fluid, or its fluid no obstacle, nothing is stamped and the field keeps what
52
+ * it holds.
53
+ *
54
+ * The field has one window, which follows the first view a frame stamps for. It lies where that view
55
+ * looks: about the eye for a view that looks straight down, and ahead of it, the eye on its near edge, for
56
+ * one that looks level, moved along the way the view looks over the ground by that much of half its side.
57
+ */
58
+ export class GPUGrassPress {
59
+
60
+ /**
61
+ * Offer the pipelines the field's passes run — see {@link PipelineEnquiry}.
62
+ *
63
+ * @param {PipelineEnquiry} enquiry
64
+ */
65
+ static enquirePipelines(enquiry) {
66
+ enquiry.compute.push(shader_grass_press_mark.pipeline);
67
+ enquiry.compute.push(shader_grass_press_stamp.pipeline);
68
+ }
69
+
70
+ /**
71
+ * Whether obstacles press grass. While false nothing is stamped and nothing reads as pressed.
72
+ * @type {boolean}
73
+ */
74
+ enabled = true;
75
+
76
+ /**
77
+ * A cell's side, metres: how fine the edge of a press is. The window is
78
+ * `GRASS_PRESS_WINDOW_CELLS` of them a side. Changing it empties the field.
79
+ * @type {number}
80
+ */
81
+ spacing = 0.125;
82
+
83
+ /** @type {GPUDevice} */
84
+ #device;
85
+
86
+ /** @type {GPUBuffer|null} the field */
87
+ #field = null;
88
+
89
+ /** @type {BufferResourceDescriptor|null} */
90
+ #field_descriptor = null;
91
+
92
+ /** @type {GPUBuffer|null} the window and clock, `GRASS_PRESS_WINDOW_STRUCT` */
93
+ #window_buffer = null;
94
+
95
+ #window = new ArrayBuffer(GRASS_PRESS_WINDOW_STRUCT.size);
96
+ #window_i32 = new Int32Array(this.#window);
97
+ #window_u32 = new Uint32Array(this.#window);
98
+ #window_f32 = new Float32Array(this.#window);
99
+
100
+ /**
101
+ * The spacing the field's cells were written at.
102
+ * @type {number}
103
+ */
104
+ #field_spacing = 0;
105
+
106
+ /**
107
+ * The obstacle table's rows, as the device holds them, and how many.
108
+ * @type {Uint32Array}
109
+ */
110
+ #rows = new Uint32Array(64);
111
+ #row_count = 0;
112
+
113
+ /** @type {GPUBuffer|null} */
114
+ #rows_buffer = null;
115
+
116
+ /**
117
+ * The forcing the rows were listed from, and its version of its sets then.
118
+ * @type {GPUFluidForcing|null}
119
+ */
120
+ #listed = null;
121
+ #listed_version = -1;
122
+
123
+ /**
124
+ * The graph the frame's stamp was recorded on, and the field as that graph knows it.
125
+ * @type {FrameGraph|null}
126
+ */
127
+ #stamped_graph = null;
128
+ #field_resource = -1;
129
+
130
+ /**
131
+ * Whether a view has been stamped for since the last {@link update}.
132
+ * @type {boolean}
133
+ */
134
+ #stamped = false;
135
+
136
+ /**
137
+ * Seconds of the clock past its whole ticks, and the ticks, wrapped to 32 bits.
138
+ */
139
+ #tick_fraction = 0;
140
+ #ticks = 0;
141
+
142
+ /**
143
+ * The clock at the last frame a view was stamped for.
144
+ * @type {number}
145
+ */
146
+ #stamped_ticks = 0;
147
+
148
+ /**
149
+ * @param {GraphicsContext} graphics
150
+ */
151
+ constructor(graphics) {
152
+ assert.defined(graphics, 'graphics');
153
+ assert.equal(graphics.isGraphicsContext, true, 'graphics.isGraphicsContext !== true');
154
+
155
+ this.#device = graphics.device;
156
+ }
157
+
158
+ /**
159
+ * The field on the device. Null before the first {@link update}, and replaced when {@link spacing}
160
+ * changes.
161
+ *
162
+ * @returns {GPUBuffer|null}
163
+ */
164
+ get field_buffer() {
165
+ return this.#field;
166
+ }
167
+
168
+ /**
169
+ * The window and clock on the device. Null before the first {@link update}.
170
+ *
171
+ * @returns {GPUBuffer|null}
172
+ */
173
+ get window_buffer() {
174
+ return this.#window_buffer;
175
+ }
176
+
177
+ /**
178
+ * Begin a frame: move the press's clock on, and make the field if there is none or its cells have
179
+ * another size than {@link spacing}, which leaves it with no press.
180
+ *
181
+ * @param {number} time_delta_seconds how far the scene's clock has moved since the last call
182
+ */
183
+ update(time_delta_seconds) {
184
+ assert.isNumber(time_delta_seconds, 'time_delta_seconds');
185
+ assert.greaterThanOrEqual(time_delta_seconds, 0, 'time_delta_seconds');
186
+ assert.greaterThan(this.spacing, 0, 'spacing');
187
+
188
+ const device = this.#device;
189
+
190
+ if (this.#field === null || this.#field_spacing !== this.spacing) {
191
+ this.#field?.destroy();
192
+
193
+ // made zeroed: no cell holds a press
194
+ this.#field = device.createBuffer({
195
+ label: "grass / press field",
196
+ size: GRASS_PRESS_FIELD_WORDS * 4,
197
+ // copied from by whoever reads the field back off the device
198
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
199
+ });
200
+
201
+ this.#field_descriptor = BufferResourceDescriptor.fromBuffer(this.#field);
202
+ this.#field_spacing = this.spacing;
203
+ }
204
+
205
+ if (this.#window_buffer === null) {
206
+ this.#window_buffer = device.createBuffer({
207
+ label: "grass / press window",
208
+ size: GRASS_PRESS_WINDOW_STRUCT.size,
209
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
210
+ });
211
+ }
212
+
213
+ const moved = this.#tick_fraction + time_delta_seconds * GRASS_PRESS_TICKS_PER_SECOND;
214
+ const whole = Math.floor(moved);
215
+
216
+ this.#tick_fraction = moved - whole;
217
+
218
+ const u32 = this.#window_u32;
219
+
220
+ u32[WINDOW_PREVIOUS] = this.#ticks;
221
+
222
+ this.#ticks = (this.#ticks + whole) >>> 0;
223
+
224
+ u32[WINDOW_NOW] = this.#ticks;
225
+
226
+ this.#stamped = false;
227
+ this.#stamped_graph = null;
228
+ this.#field_resource = -1;
229
+ }
230
+
231
+ /**
232
+ * Record the frame's stamp, and answer with the field as a resource of `graph` for the passes that
233
+ * read it.
234
+ *
235
+ * The first call of a frame puts the window about its view, lists the fluid's obstacles by the
236
+ * window's tiles, and writes the cells under them. Later calls, other views', record nothing and
237
+ * answer with the same field.
238
+ *
239
+ * Nothing is stamped while the field is off, or `forcing` is null or holds no obstacle.
240
+ *
241
+ * @param {object} options
242
+ * @param {FrameGraph} options.graph
243
+ * @param {GPUViewContext} options.view the view the window follows; its scene is the obstacles' scene
244
+ * @param {GPUFluidForcing|null} options.forcing the scene's GPU fluid forcing, whose obstacle table is read
245
+ * @returns {number} the field, a resource of `graph`
246
+ */
247
+ graph_stamp({ graph, view, forcing }) {
248
+ assert.defined(graph, 'graph');
249
+ assert.defined(view, 'view');
250
+ assert.notNull(this.#field, 'field: update() comes first');
251
+
252
+ if (this.#stamped_graph === graph) {
253
+ return this.#field_resource;
254
+ }
255
+
256
+ this.#stamped_graph = graph;
257
+ this.#field_resource = graph.import_resource("grass press field", this.#field_descriptor, this.#field);
258
+
259
+ if (this.#stamped) {
260
+ // another graph of the same frame: the field as it is
261
+ return this.#field_resource;
262
+ }
263
+
264
+ this.#stamped = true;
265
+
266
+ // a contact goes on from the stamp before this one, however many frames of the clock went by unstamped
267
+ this.#window_u32[WINDOW_STAMPED] = this.#stamped_ticks;
268
+ this.#stamped_ticks = this.#ticks;
269
+
270
+ // the window: whole tiles about a point half its side ahead of the eye, as far as the view looks level
271
+ const eye = view.camera.camera.transform;
272
+ const tile_side = this.spacing * GRASS_PRESS_TILE_CELLS;
273
+ const half = GRASS_PRESS_WINDOW_CELLS / GRASS_PRESS_TILE_CELLS / 2;
274
+
275
+ // the way a camera looks is its third axis
276
+ const looks = Math.hypot(eye[8], eye[9], eye[10]);
277
+ const ahead = looks > 0 ? half * tile_side / looks : 0;
278
+
279
+ const i32 = this.#window_i32;
280
+
281
+ i32[WINDOW_CORNER] = (Math.floor((eye.translation_x + eye[8] * ahead) / tile_side) - half) * GRASS_PRESS_TILE_CELLS;
282
+ i32[WINDOW_CORNER + 1] = (Math.floor((eye.translation_z + eye[10] * ahead) / tile_side) - half) * GRASS_PRESS_TILE_CELLS;
283
+
284
+ let row_count = 0;
285
+
286
+ if (this.enabled && forcing !== null && forcing !== undefined) {
287
+ row_count = this.#list_rows(forcing);
288
+ }
289
+
290
+ this.#window_u32[WINDOW_ROW_COUNT] = row_count;
291
+
292
+ // a field that is off reads as one with no cells
293
+ this.#window_f32[WINDOW_SPACING] = this.enabled ? this.spacing : 0;
294
+
295
+ this.#device.queue.writeBuffer(this.#window_buffer, 0, this.#window);
296
+
297
+ if (row_count === 0) {
298
+ return this.#field_resource;
299
+ }
300
+
301
+ const scene = view.scene;
302
+ const database = forcing.database;
303
+
304
+ graph.push_scope("grass press");
305
+
306
+ const mark_data = {};
307
+
308
+ const mark_pass = graph.add("mark tiles", mark_data, (data, resources, context) => {
309
+ if (database.has_pending_upload) {
310
+ // rows the fluid has not sent yet: it sends them only in a frame that steps
311
+ database.update(context.encoder);
312
+ }
313
+
314
+ shader_grass_press_mark.dispatch({
315
+ encoder: context.encoder,
316
+ group_count_x: Math.ceil(row_count / GRASS_PRESS_MARK_WORKGROUP_SIZE),
317
+ bindings: {
318
+ grass_press_window: this.#window_buffer,
319
+ press_rows: this.#rows_buffer,
320
+ fluid_database: database.buffer,
321
+ scene_database: scene.scene_database_buffer,
322
+ press_jobs: resources.get(data.jobs),
323
+ grass_press: resources.get(data.field),
324
+ },
325
+ });
326
+ });
327
+
328
+ mark_data.jobs = mark_pass.create("press jobs", JOBS_DESCRIPTOR);
329
+ mark_data.field = mark_pass.write(this.#field_resource);
330
+
331
+ const stamp_data = {};
332
+
333
+ const stamp_pass = graph.add("stamp cells", stamp_data, (data, resources, context) => {
334
+ const jobs = resources.get(data.jobs);
335
+
336
+ shader_grass_press_stamp.dispatchIndirect({
337
+ encoder: context.encoder,
338
+ command: jobs,
339
+ bindings: {
340
+ grass_press_window: this.#window_buffer,
341
+ press_jobs: jobs,
342
+ fluid_database: database.buffer,
343
+ scene_database: scene.scene_database_buffer,
344
+ grass_press: resources.get(data.field),
345
+ },
346
+ });
347
+ });
348
+
349
+ stamp_data.jobs = stamp_pass.read(mark_data.jobs);
350
+ // the field is not the graph's own, so the pass is kept whether or not anything reads it this frame
351
+ stamp_data.field = stamp_pass.write(mark_data.field);
352
+
353
+ graph.pop_scope();
354
+
355
+ this.#field_resource = stamp_data.field;
356
+
357
+ return this.#field_resource;
358
+ }
359
+
360
+ /**
361
+ * The forcing's obstacle rows, listed again and sent to the device only when its sets have changed.
362
+ *
363
+ * @param {GPUFluidForcing} forcing
364
+ * @returns {number} how many
365
+ */
366
+ #list_rows(forcing) {
367
+ if (this.#listed === forcing && this.#listed_version === forcing.sets_version) {
368
+ return this.#row_count;
369
+ }
370
+
371
+ this.#listed = forcing;
372
+ this.#listed_version = forcing.sets_version;
373
+
374
+ const count = forcing.obstacle_count;
375
+
376
+ this.#row_count = count;
377
+
378
+ if (count === 0) {
379
+ return 0;
380
+ }
381
+
382
+ if (this.#rows.length < count) {
383
+ this.#rows = new Uint32Array(Math.max(count, 2 * this.#rows.length));
384
+ }
385
+
386
+ const rows = this.#rows;
387
+ const occupancy = forcing.database.get(FLUID_OBSTACLE_TABLE).occupancy;
388
+
389
+ let n = 0;
390
+
391
+ for (let row = occupancy.nextSetBit(0); row !== -1; row = occupancy.nextSetBit(row + 1)) {
392
+ rows[n++] = row;
393
+ }
394
+
395
+ if (this.#rows_buffer === null || this.#rows_buffer.size < rows.byteLength) {
396
+ this.#rows_buffer?.destroy();
397
+
398
+ this.#rows_buffer = this.#device.createBuffer({
399
+ label: "grass / press rows",
400
+ size: rows.byteLength,
401
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
402
+ });
403
+ }
404
+
405
+ this.#device.queue.writeBuffer(this.#rows_buffer, 0, rows, 0, n);
406
+
407
+ return n;
408
+ }
409
+
410
+ /**
411
+ * Put the field's window and clock into a dispatch's bindings as `grass_press_window`, which
412
+ * `chunk_grass_press` reads. The field itself, `grass_press`, is the resource {@link graph_stamp}
413
+ * answered with.
414
+ *
415
+ * @param {Object} bindings
416
+ */
417
+ bind(bindings) {
418
+ bindings.grass_press_window = this.#window_buffer;
419
+ }
420
+
421
+ /**
422
+ * Let go of everything on the device. The field's presses go with it.
423
+ */
424
+ destroy() {
425
+ this.#field?.destroy();
426
+ this.#field = null;
427
+ this.#field_descriptor = null;
428
+ this.#window_buffer?.destroy();
429
+ this.#window_buffer = null;
430
+ this.#rows_buffer?.destroy();
431
+ this.#rows_buffer = null;
432
+ this.#listed = null;
433
+ this.#stamped_graph = null;
434
+ this.#field_resource = -1;
435
+ }
436
+ }
@@ -0,0 +1,179 @@
1
+ /**
2
+ * The press field: where obstacles have pressed grass down, kept on the device.
3
+ *
4
+ * The ground is cut into square **cells** over the world's x and z, `spacing` metres a side. An obstacle
5
+ * over a cell leaves a **press** in it: the heights the obstacle spans on the vertical line through the
6
+ * cell's middle, its velocity over the ground there, and when. A blade leans as far as a press leaves it no
7
+ * room to stand, and from the press's time on stands back up (`chunk_grass_press`). Nothing sweeps the
8
+ * field: a cell is written only while an obstacle is over it.
9
+ *
10
+ * **A cell remembers two presses**, which together are its **state**: the *latest*, and the *deepest* of
11
+ * the contact the latest is part of, a contact being the stamps of the field, one after another, in which
12
+ * something is over the cell. Both are needed. Whatever rolls or steps over a cell leaves it rim last, so the latest
13
+ * press of a contact is too high to hold anything down; and whatever comes down on a cell and then lingers
14
+ * above it holds the grass as low as it lingers long after how low it first came has been stood back up
15
+ * from. A blade is held by whichever of the two holds it further.
16
+ *
17
+ * It is exact for something that comes down on a cell and goes. Where it lingers higher than it has been
18
+ * and then goes, what is remembered is how low it first came and how it left, not how it lingered.
19
+ *
20
+ * **A cell keeps the state it had before its last stamp** beside the one it has, so that a blade can be
21
+ * drawn as it was a frame ago: for a cell stamped this frame that is the other state, and for any other
22
+ * cell the one it has.
23
+ *
24
+ * The field holds the cells of a **window**, `GRASS_PRESS_WINDOW_CELLS` a side, about a view. A cell has
25
+ * one place in the field wherever the window is, its coordinates wrapped by the window's side, and a
26
+ * place says which cell it holds, so a place the window has moved away from and come back to with
27
+ * another cell is never read as that cell's. The window's side, a tile's and the tiles' count are powers
28
+ * of two, so that wrapping is a mask.
29
+ *
30
+ * Each frame the obstacles over the window are listed by the **tiles** they stand over
31
+ * (`shader_grass_press_mark`), `GRASS_PRESS_TILE_CELLS` cells a side, and every cell of every tile that
32
+ * has an obstacle is written by a thread of its own (`shader_grass_press_stamp`).
33
+ *
34
+ * **A tile remembers when an obstacle was last near it**, one word, at the front of the field. Most grass
35
+ * is nowhere near a press, and a blade whose tile was last near an obstacle too long ago for any press to
36
+ * still show reads that word and none of its cells.
37
+ *
38
+ * Times are 32-bit ticks of the press's clock: a press is read rightly for 2³¹ ticks after it was made,
39
+ * 24 days.
40
+ *
41
+ * What is ground of a grass surface presses nothing: the grass on it stands on it, and other obstacles
42
+ * stand on it too. An obstacle that stands in for ground and is not to flatten the grass about it is made
43
+ * a member of the surface.
44
+ */
45
+ /**
46
+ * Cells along a tile's side, as a power of two.
47
+ *
48
+ * @type {number}
49
+ */
50
+ export const GRASS_PRESS_TILE_CELLS_LOG2: number;
51
+ /**
52
+ * Cells along a tile's side.
53
+ *
54
+ * @type {number}
55
+ */
56
+ export const GRASS_PRESS_TILE_CELLS: number;
57
+ /**
58
+ * Tiles along the window's side, as a power of two.
59
+ *
60
+ * @type {number}
61
+ */
62
+ export const GRASS_PRESS_WINDOW_TILES_LOG2: number;
63
+ /**
64
+ * Tiles along the window's side.
65
+ *
66
+ * @type {number}
67
+ */
68
+ export const GRASS_PRESS_WINDOW_TILES: number;
69
+ /**
70
+ * Cells along the window's side, as a power of two.
71
+ *
72
+ * @type {number}
73
+ */
74
+ export const GRASS_PRESS_WINDOW_CELLS_LOG2: number;
75
+ /**
76
+ * Cells along the window's side.
77
+ *
78
+ * @type {number}
79
+ */
80
+ export const GRASS_PRESS_WINDOW_CELLS: number;
81
+ /**
82
+ * Obstacles a tile lists at most: what a cell's thread walks. A tile more obstacles stand over is
83
+ * pressed by the first that many to list themselves.
84
+ *
85
+ * @type {number}
86
+ */
87
+ export const GRASS_PRESS_TILE_CANDIDATES: number;
88
+ /**
89
+ * Steps of the press's clock in a second.
90
+ *
91
+ * @type {number}
92
+ */
93
+ export const GRASS_PRESS_TICKS_PER_SECOND: number;
94
+ /**
95
+ * Words a press takes.
96
+ *
97
+ * @type {number}
98
+ */
99
+ export const GRASS_PRESS_WORDS: number;
100
+ /** Press word: when, in ticks of the press's clock. */
101
+ export const GRASS_PRESS_TIME: 0;
102
+ /** Press word: the lowest height of the obstacle on the cell's line, the bits of a `f32`. */
103
+ export const GRASS_PRESS_BOTTOM: 1;
104
+ /** Press word: the highest, the bits of a `f32`. */
105
+ export const GRASS_PRESS_TOP: 2;
106
+ /** Press word: the obstacle's velocity along x and along z at the foot of its span, two half floats. */
107
+ export const GRASS_PRESS_VELOCITY: 3;
108
+ /**
109
+ * Words a state takes: whose press the latest is, the latest, and the deepest of its contact.
110
+ *
111
+ * @type {number}
112
+ */
113
+ export const GRASS_PRESS_STATE_WORDS: number;
114
+ /** State word: the `transforms` row of the latest press's obstacle, plus one; 0 for a state that holds nothing. */
115
+ export const GRASS_PRESS_STATE_NODE: 0;
116
+ /** State word: the first of the latest press's. */
117
+ export const GRASS_PRESS_STATE_LATEST: 1;
118
+ /** State word: the first of the deepest press's. */
119
+ export const GRASS_PRESS_STATE_DEEPEST: number;
120
+ /**
121
+ * Words a cell takes in the field: its tag, and its two states.
122
+ *
123
+ * @type {number}
124
+ */
125
+ export const GRASS_PRESS_CELL_WORDS: number;
126
+ /**
127
+ * Cell word: the cell's tag. Its low {@link GRASS_PRESS_TAG_CURRENT_SHIFT} bits say which cell this is,
128
+ * `grass_press_page`; the bits above which state is the cell's, 1 or 2, the other being the one it had
129
+ * before its last stamp, or 0 for a cell nothing has pressed.
130
+ */
131
+ export const GRASS_PRESS_CELL_TAG: 0;
132
+ /**
133
+ * Where in a cell's tag the number of its state is: above the page.
134
+ *
135
+ * @type {number}
136
+ */
137
+ export const GRASS_PRESS_TAG_CURRENT_SHIFT: number;
138
+ /** Cell word: the first of state 1's; state 2's follow. */
139
+ export const GRASS_PRESS_CELL_STATES: 1;
140
+ /**
141
+ * Field word: the first of the window's tiles' words, one a tile, by the tile's place among the window's.
142
+ * The clock's time when an obstacle last stood within a cell of the tile; 0 for never, a time of 0 being
143
+ * written as 1.
144
+ */
145
+ export const GRASS_PRESS_FIELD_TILES: 0;
146
+ /** Field word: the first of the cells'. */
147
+ export const GRASS_PRESS_FIELD_CELLS: number;
148
+ /**
149
+ * Words in the field.
150
+ *
151
+ * @type {number}
152
+ */
153
+ export const GRASS_PRESS_FIELD_WORDS: number;
154
+ /**
155
+ * Words of the frame's tile jobs (`shader_grass_press_mark` writes them, `shader_grass_press_stamp` reads
156
+ * them): the stamp's indirect dispatch, three words and one unused; then for each of the window's tiles how
157
+ * many obstacles listed themselves; then the tiles that have any, in the order they were first listed;
158
+ * then each tile's list, `GRASS_PRESS_TILE_CANDIDATES` rows of the fluid's obstacle table.
159
+ */
160
+ export const GRASS_PRESS_JOBS_COMMAND: 0;
161
+ export const GRASS_PRESS_JOBS_COUNTS: 4;
162
+ export const GRASS_PRESS_JOBS_TILES: number;
163
+ export const GRASS_PRESS_JOBS_LISTS: number;
164
+ export const GRASS_PRESS_JOBS_WORDS: number;
165
+ /**
166
+ * The press field's window and clock, as every pass that touches the field reads them.
167
+ *
168
+ * - `corner`: the window's first cell along x and along z, a multiple of `GRASS_PRESS_TILE_CELLS`.
169
+ * - `spacing`: a cell's side in metres. Zero while there is no field: nothing is pressed.
170
+ * - `now`, `previous`: the press's clock at this frame and at the frame before, in ticks.
171
+ * - `stamped`: the clock when the field was stamped the time before this one. It is `previous` where
172
+ * every frame of the clock stamps, and earlier where frames went by unstamped.
173
+ * - `row_count`: obstacle rows the frame lists, for the pass that marks tiles.
174
+ *
175
+ * @type {WebGPUStruct}
176
+ */
177
+ export const GRASS_PRESS_WINDOW_STRUCT: WebGPUStruct;
178
+ import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
179
+ //# sourceMappingURL=GRASS_PRESS.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GRASS_PRESS.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/grass/press/GRASS_PRESS.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH;;;;GAIG;AACH,0CAFU,MAAM,CAE6B;AAE7C;;;;GAIG;AACH,qCAFU,MAAM,CAEuD;AAEvE;;;;GAIG;AACH,4CAFU,MAAM,CAE+B;AAE/C;;;;GAIG;AACH,uCAFU,MAAM,CAE2D;AAE3E;;;;GAIG;AACH,4CAFU,MAAM,CAEyF;AAEzG;;;;GAIG;AACH,uCAFU,MAAM,CAE2D;AAE3E;;;;;GAKG;AACH,0CAFU,MAAM,CAE8B;AAE9C;;;;GAIG;AACH,2CAFU,MAAM,CAEiC;AAEjD;;;;GAIG;AACH,gCAFU,MAAM,CAEmB;AAEnC,uDAAuD;AACvD,iCAAkC;AAElC,6FAA6F;AAC7F,mCAAoC;AAEpC,oDAAoD;AACpD,gCAAiC;AAEjC,wGAAwG;AACxG,qCAAsC;AAEtC;;;;GAIG;AACH,sCAFU,MAAM,CAEiD;AAEjE,mHAAmH;AACnH,uCAAwC;AAExC,mDAAmD;AACnD,yCAA0C;AAE1C,oDAAoD;AACpD,+CAAsF;AAEtF;;;;GAIG;AACH,qCAFU,MAAM,CAEsD;AAEtE;;;;GAIG;AACH,qCAAsC;AAEtC;;;;GAIG;AACH,4CAFU,MAAM,CAEgC;AAEhD,2DAA2D;AAC3D,wCAAyC;AAEzC;;;;GAIG;AACH,wCAAyC;AAEzC,2CAA2C;AAC3C,6CAA+F;AAE/F;;;;GAIG;AACH,sCAFU,MAAM,CAEwG;AAExH;;;;;GAKG;AACH,yCAA0C;AAE1C,wCAAyC;AAEzC,4CAA8F;AAE9F,4CAA6F;AAE7F,4CAA2H;AAE3H;;;;;;;;;;;GAWG;AACH,wCAFU,YAAY,CASC;6BAvNM,mCAAmC"}