@woosh/meep-engine 3.56.0 → 3.57.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 (625) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/DUPLICATION_REVIEW_2026_10_24.md +1072 -0
  4. package/src/core/binary/BitSet.js +1 -1
  5. package/src/core/binary/FLOAT16_MAX.d.ts +2 -0
  6. package/src/core/binary/FLOAT16_MAX.d.ts.map +1 -0
  7. package/src/core/binary/FLOAT16_MAX.js +1 -0
  8. package/src/core/binary/base58/base58_encode.js +2 -2
  9. package/src/core/binary/type/TypeBuilder.js +1 -1
  10. package/src/core/bvh2/bvh3/BVH.js +1 -1
  11. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.d.ts.map +1 -1
  12. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.js +7 -3
  13. package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.d.ts.map +1 -1
  14. package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.js +5 -1
  15. package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.d.ts.map +1 -1
  16. package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +195 -246
  17. package/src/core/collection/CuckooFilter.js +1 -1
  18. package/src/core/collection/array/isArrayEqual.d.ts.map +1 -1
  19. package/src/core/collection/array/isArrayEqual.js +33 -58
  20. package/src/core/collection/array/typed/array_buffer_hash.d.ts.map +1 -1
  21. package/src/core/collection/array/typed/array_buffer_hash.js +41 -39
  22. package/src/core/collection/array/typed/float32_array_hash.js +38 -38
  23. package/src/core/collection/array/typed/uint16_array_hash.d.ts +2 -1
  24. package/src/core/collection/array/typed/uint16_array_hash.d.ts.map +1 -1
  25. package/src/core/collection/array/typed/uint16_array_hash.js +30 -29
  26. package/src/core/collection/array/typed/uint32_array_hash.d.ts +2 -1
  27. package/src/core/collection/array/typed/uint32_array_hash.d.ts.map +1 -1
  28. package/src/core/collection/array/typed/uint32_array_hash.js +21 -20
  29. package/src/core/collection/array/typed/uint8_array_hash.d.ts +2 -1
  30. package/src/core/collection/array/typed/uint8_array_hash.d.ts.map +1 -1
  31. package/src/core/collection/array/typed/uint8_array_hash.js +37 -36
  32. package/src/core/collection/array/typed/uint_array_for_count.js +2 -2
  33. package/src/core/collection/list/List.d.ts.map +1 -1
  34. package/src/core/collection/list/List.js +3 -19
  35. package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
  36. package/src/core/collection/table/RowFirstTable.js +4 -28
  37. package/src/core/debug/matchers/DescribeAs.d.ts.map +1 -1
  38. package/src/core/debug/matchers/DescribeAs.js +62 -64
  39. package/src/core/function/FunctionCompiler.js +4 -4
  40. package/src/core/function/objectsEqual.d.ts.map +1 -1
  41. package/src/core/function/objectsEqual.js +3 -2
  42. package/src/core/geom/2d/bvh/BVH2D.d.ts.map +1 -1
  43. package/src/core/geom/2d/bvh/BVH2D.js +4 -3
  44. package/src/core/geom/2d/convex-hull/convex_hull_fixed_count_2d_relaxation.d.ts +5 -2
  45. package/src/core/geom/2d/convex-hull/convex_hull_fixed_count_2d_relaxation.d.ts.map +1 -1
  46. package/src/core/geom/2d/convex-hull/convex_hull_fixed_count_2d_relaxation.js +49 -11
  47. package/src/core/geom/2d/hash-grid/shg_query_elements_circle.d.ts.map +1 -1
  48. package/src/core/geom/2d/hash-grid/shg_query_elements_circle.js +122 -159
  49. package/src/core/geom/2d/hash-grid/shg_query_elements_line.d.ts.map +1 -1
  50. package/src/core/geom/2d/hash-grid/shg_query_elements_line.js +8 -5
  51. package/src/core/geom/2d/polygon/polygon2_rasterize_coverage.d.ts +18 -0
  52. package/src/core/geom/2d/polygon/polygon2_rasterize_coverage.d.ts.map +1 -0
  53. package/src/core/geom/2d/polygon/polygon2_rasterize_coverage.js +97 -0
  54. package/src/core/geom/2d/r-tree/StaticR2Tree.js +2 -2
  55. package/src/core/geom/2d/triangle/tri2_rasterize_coverage.d.ts +21 -0
  56. package/src/core/geom/2d/triangle/tri2_rasterize_coverage.d.ts.map +1 -0
  57. package/src/core/geom/2d/triangle/tri2_rasterize_coverage.js +54 -0
  58. package/src/core/geom/3d/aabb/aabb3_build_frustum.d.ts.map +1 -1
  59. package/src/core/geom/3d/aabb/aabb3_build_frustum.js +20 -53
  60. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.d.ts +1 -1
  61. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.d.ts.map +1 -1
  62. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.js +11 -42
  63. package/src/core/geom/3d/atlas/pack/atlas_pack_charts.d.ts.map +1 -1
  64. package/src/core/geom/3d/atlas/pack/atlas_pack_charts.js +30 -32
  65. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.d.ts.map +1 -1
  66. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.js +1 -5
  67. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.d.ts.map +1 -1
  68. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.js +1 -15
  69. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts.map +1 -1
  70. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +105 -116
  71. package/src/core/geom/3d/line/line3_compute_segment_point_distance_sqr.d.ts.map +1 -1
  72. package/src/core/geom/3d/line/line3_compute_segment_point_distance_sqr.js +36 -54
  73. package/src/core/geom/3d/plane/plane3_compute_intersection_objects.d.ts +5 -10
  74. package/src/core/geom/3d/plane/plane3_compute_intersection_objects.d.ts.map +1 -1
  75. package/src/core/geom/3d/plane/plane3_compute_intersection_objects.js +20 -82
  76. package/src/core/geom/3d/plane/plane3_slerp.d.ts.map +1 -1
  77. package/src/core/geom/3d/plane/plane3_slerp.js +87 -102
  78. package/src/core/geom/3d/polygon/polygon3_compute_normal.d.ts +12 -0
  79. package/src/core/geom/3d/polygon/polygon3_compute_normal.d.ts.map +1 -1
  80. package/src/core/geom/3d/polygon/polygon3_compute_normal.js +107 -60
  81. package/src/core/geom/3d/ray/ray3_compute_closest_point.d.ts.map +1 -1
  82. package/src/core/geom/3d/ray/ray3_compute_closest_point.js +37 -43
  83. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
  84. package/src/core/geom/3d/shape/ConvexHullShape3D.js +5 -16
  85. package/src/core/geom/3d/shape/MeshShape3D.js +2 -56
  86. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  87. package/src/core/geom/3d/shape/TransformedShape3D.js +10 -7
  88. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  89. package/src/core/geom/3d/shape/UnionShape3D.js +9 -3
  90. package/src/core/geom/3d/shape/json/shape_to_type.js +2 -2
  91. package/src/core/geom/3d/sphere/harmonics/SH3_COEFFICIENTS.js +17 -17
  92. package/src/core/geom/3d/tetrahedra/TetrahedralMesh.d.ts.map +1 -1
  93. package/src/core/geom/3d/tetrahedra/TetrahedralMesh.js +6 -2
  94. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts.map +1 -1
  95. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +3 -2
  96. package/src/core/geom/3d/tetrahedra/tetrahedron_contains_point.d.ts +20 -2
  97. package/src/core/geom/3d/tetrahedra/tetrahedron_contains_point.d.ts.map +1 -1
  98. package/src/core/geom/3d/tetrahedra/tetrahedron_contains_point.js +52 -37
  99. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_face_normals.d.ts.map +1 -1
  100. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_face_normals.js +40 -56
  101. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts.map +1 -1
  102. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +251 -260
  103. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -1
  104. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +104 -113
  105. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_resolve_t_junctions.d.ts.map +1 -1
  106. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_resolve_t_junctions.js +227 -238
  107. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  108. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +15 -24
  109. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.d.ts.map +1 -1
  110. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.js +31 -115
  111. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_fuse_duplicate_edges.d.ts.map +1 -1
  112. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_fuse_duplicate_edges.js +142 -150
  113. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.d.ts.map +1 -1
  114. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.js +151 -194
  115. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_incenter.d.ts.map +1 -1
  116. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_incenter.js +60 -85
  117. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_distance_field.d.ts.map +1 -1
  118. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_distance_field.js +156 -171
  119. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path.d.ts.map +1 -1
  120. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path.js +8 -44
  121. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
  122. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +2 -7
  123. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts.map +1 -1
  124. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +3 -2
  125. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_segment_penetrates_surface.d.ts.map +1 -1
  126. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_segment_penetrates_surface.js +128 -133
  127. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.d.ts +8 -14
  128. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.d.ts.map +1 -1
  129. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.js +36 -82
  130. package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts.map +1 -1
  131. package/src/core/geom/3d/triangle/tri3_ray_intersection.js +7 -144
  132. package/src/core/geom/ConicRay.d.ts.map +1 -1
  133. package/src/core/geom/ConicRay.js +230 -237
  134. package/src/core/localization/LocaleDataset.d.ts +6 -0
  135. package/src/core/localization/LocaleDataset.d.ts.map +1 -1
  136. package/src/core/localization/LocaleDataset.js +48 -37
  137. package/src/core/localization/LocalizationEngine.d.ts.map +1 -1
  138. package/src/core/localization/LocalizationEngine.js +3 -2
  139. package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -1
  140. package/src/core/math/lookup/ParameterLookupTable.js +3 -1
  141. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -1
  142. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +330 -400
  143. package/src/core/math/spline/spline3_hermite_nearest_point.d.ts +16 -0
  144. package/src/core/math/spline/spline3_hermite_nearest_point.d.ts.map +1 -1
  145. package/src/core/math/spline/spline3_hermite_nearest_point.js +134 -167
  146. package/src/core/model/DebouncedObservedBoolean.d.ts +1 -2
  147. package/src/core/model/DebouncedObservedBoolean.d.ts.map +1 -1
  148. package/src/core/model/DebouncedObservedBoolean.js +1 -1
  149. package/src/core/model/node-graph/node/NodeInstance.d.ts.map +1 -1
  150. package/src/core/model/node-graph/node/NodeInstance.js +2 -7
  151. package/src/core/model/node-graph/node/parameter/NodeParameterDescription.js +1 -1
  152. package/src/core/model/object/optional_equality.d.ts +3 -3
  153. package/src/core/model/object/optional_equality.d.ts.map +1 -1
  154. package/src/core/model/object/optional_equality.js +10 -27
  155. package/src/core/model/object/write_property.js +1 -1
  156. package/src/core/model/reactive/evaluation/MultiPredicateEvaluator.js +2 -2
  157. package/src/core/primitives/strings/string_compute_byte_size.d.ts +3 -3
  158. package/src/core/primitives/strings/string_compute_byte_size.d.ts.map +1 -1
  159. package/src/core/primitives/strings/string_compute_byte_size.js +8 -21
  160. package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
  161. package/src/core/process/executor/ConcurrentExecutor.js +14 -2
  162. package/src/engine/achievements/gateway/StorageAchievementGateway.d.ts +6 -3
  163. package/src/engine/achievements/gateway/StorageAchievementGateway.d.ts.map +1 -1
  164. package/src/engine/achievements/gateway/StorageAchievementGateway.js +31 -75
  165. package/src/engine/asset/loaders/SVGAssetLoader.d.ts.map +1 -1
  166. package/src/engine/asset/loaders/SVGAssetLoader.js +33 -31
  167. package/src/engine/control/first-person/math/criticallyDampedSpring.d.ts.map +1 -1
  168. package/src/engine/control/first-person/math/criticallyDampedSpring.js +3 -14
  169. package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
  170. package/src/engine/ecs/EntityComponentDataset.js +4 -1
  171. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.d.ts +0 -2
  172. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.d.ts.map +1 -1
  173. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.js +3 -3
  174. package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.js +2 -2
  175. package/src/engine/graphics/sh3/path_tracer/geometry/sort_triangles_by_distance_to_point.js +1 -1
  176. package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min_indices.js +1 -1
  177. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  178. package/src/engine/graphics3/WaterSystem.js +2 -1
  179. package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts.map +1 -1
  180. package/src/engine/graphics3/prefab/prefab_skin_frame.js +1 -12
  181. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts +1 -1
  182. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
  183. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +141 -137
  184. package/src/engine/input/ecs/systems/InputControllerSystem.d.ts.map +1 -1
  185. package/src/engine/input/ecs/systems/InputControllerSystem.js +13 -3
  186. package/src/engine/input/ecs/systems/InputSystem.d.ts.map +1 -1
  187. package/src/engine/input/ecs/systems/InputSystem.js +2 -1
  188. package/src/engine/intelligence/behavior/composite/ParallelBehavior.d.ts +1 -1
  189. package/src/engine/intelligence/behavior/composite/ParallelBehavior.d.ts.map +1 -1
  190. package/src/engine/intelligence/behavior/composite/ParallelBehavior.js +4 -1
  191. package/src/engine/intelligence/behavior/decorator/InvertStatusBehavior.d.ts.map +1 -1
  192. package/src/engine/intelligence/behavior/decorator/InvertStatusBehavior.js +3 -1
  193. package/src/engine/intelligence/behavior/decorator/RepeatBehavior.d.ts.map +1 -1
  194. package/src/engine/intelligence/behavior/decorator/RepeatBehavior.js +3 -1
  195. package/src/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.d.ts.map +1 -1
  196. package/src/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.js +39 -33
  197. package/src/engine/intelligence/behavior/util/ConditionalBehavior.d.ts +5 -0
  198. package/src/engine/intelligence/behavior/util/ConditionalBehavior.d.ts.map +1 -1
  199. package/src/engine/intelligence/behavior/util/ConditionalBehavior.js +93 -75
  200. package/src/engine/intelligence/behavior/util/RotationBehavior.d.ts.map +1 -1
  201. package/src/engine/intelligence/behavior/util/RotationBehavior.js +79 -76
  202. package/src/engine/intelligence/blackboard/BlackboardStack.d.ts +1 -0
  203. package/src/engine/intelligence/blackboard/BlackboardStack.d.ts.map +1 -1
  204. package/src/engine/intelligence/blackboard/BlackboardStack.js +159 -123
  205. package/src/engine/intelligence/mcts/StateNode.d.ts.map +1 -1
  206. package/src/engine/intelligence/mcts/StateNode.js +366 -364
  207. package/src/engine/intelligence/resource/ResourceAllocationSolver.js +1 -1
  208. package/src/engine/navigation/ecs/components/Path.d.ts.map +1 -1
  209. package/src/engine/navigation/ecs/components/Path.js +2 -1
  210. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts.map +1 -1
  211. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +5 -2
  212. package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -1
  213. package/src/engine/physics/body/SolverBodyState.js +2 -6
  214. package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
  215. package/src/engine/physics/ccd/linear_sweep.js +3 -16
  216. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  217. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +2 -16
  218. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +13 -1
  219. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  220. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +15 -4
  221. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  222. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  223. package/src/engine/physics/inertia/locked_inverse_inertia.d.ts +12 -0
  224. package/src/engine/physics/inertia/locked_inverse_inertia.d.ts.map +1 -0
  225. package/src/engine/physics/inertia/locked_inverse_inertia.js +22 -0
  226. package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
  227. package/src/engine/physics/integration/integrate_velocity.js +3 -18
  228. package/src/engine/physics/mls-mpm/MLS_MPM.d.ts +1 -0
  229. package/src/engine/physics/mls-mpm/MLS_MPM.d.ts.map +1 -1
  230. package/src/engine/physics/mls-mpm/MLS_MPM.js +5 -4
  231. package/src/engine/physics/narrowphase/convex_decomposition.d.ts.map +1 -1
  232. package/src/engine/physics/narrowphase/convex_decomposition.js +7 -16
  233. package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
  234. package/src/engine/physics/vehicle/RaycastVehicle.js +15 -5
  235. package/src/engine/save/StorageBackedList.d.ts +5 -0
  236. package/src/engine/save/StorageBackedList.d.ts.map +1 -1
  237. package/src/engine/save/StorageBackedList.js +161 -144
  238. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  239. package/src/engine/simulation/Ticker.js +394 -391
  240. package/src/engine/sound/simulation/probe/AcousticProbeField.d.ts.map +1 -1
  241. package/src/engine/sound/simulation/probe/AcousticProbeField.js +6 -19
  242. package/src/engine/sound/simulation/probe/probe_edge_visible.d.ts +15 -0
  243. package/src/engine/sound/simulation/probe/probe_edge_visible.d.ts.map +1 -1
  244. package/src/engine/sound/simulation/probe/probe_edge_visible.js +59 -41
  245. package/src/engine/sound/simulation/probe/probe_refine_connectivity.d.ts.map +1 -1
  246. package/src/engine/sound/simulation/probe/probe_refine_connectivity.js +164 -181
  247. package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.d.ts.map +1 -1
  248. package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.js +20 -5
  249. package/src/format/image/avif/av1/decode/Av1FrameContext.d.ts.map +1 -1
  250. package/src/format/image/avif/av1/decode/Av1FrameContext.js +3 -10
  251. package/src/format/image/avif/av1/decode/reconstruct.d.ts +20 -0
  252. package/src/format/image/avif/av1/decode/reconstruct.d.ts.map +1 -1
  253. package/src/format/image/avif/av1/decode/reconstruct.js +22 -9
  254. package/src/format/image/avif/av1/encode/choose_restoration.js +2 -18
  255. package/src/format/image/avif/av1/encode/quantise.d.ts.map +1 -1
  256. package/src/format/image/avif/av1/encode/quantise.js +1 -55
  257. package/src/format/image/avif/av1/filter/loop_restoration.d.ts +9 -0
  258. package/src/format/image/avif/av1/filter/loop_restoration.d.ts.map +1 -1
  259. package/src/format/image/avif/av1/filter/loop_restoration.js +1 -1
  260. package/src/format/texture/basis/transcode/etc1s_to_bc7.js +2 -33
  261. package/src/format/texture/basis/transcode/fit_endpoints.d.ts +11 -0
  262. package/src/format/texture/basis/transcode/fit_endpoints.d.ts.map +1 -1
  263. package/src/format/texture/basis/transcode/fit_endpoints.js +1 -1
  264. package/src/format/texture/basis/uastc/uastc_decode_block.d.ts.map +1 -1
  265. package/src/format/texture/basis/uastc/uastc_decode_block.js +2 -19
  266. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +220 -0
  267. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +172 -0
  268. package/src/generation/foliage/FOLIAGE_DESIGN.md +165 -15
  269. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +158 -0
  270. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +248 -0
  271. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +694 -0
  272. package/src/generation/foliage/analysis/CrownOpacity.d.ts +118 -0
  273. package/src/generation/foliage/analysis/CrownOpacity.d.ts.map +1 -0
  274. package/src/generation/foliage/analysis/CrownOpacity.js +182 -0
  275. package/src/generation/foliage/analysis/crown_opacity_frames.d.ts +10 -0
  276. package/src/generation/foliage/analysis/crown_opacity_frames.d.ts.map +1 -0
  277. package/src/generation/foliage/analysis/crown_opacity_frames.js +132 -0
  278. package/src/generation/foliage/analysis/crown_opacity_measure.d.ts +51 -0
  279. package/src/generation/foliage/analysis/crown_opacity_measure.d.ts.map +1 -0
  280. package/src/generation/foliage/analysis/crown_opacity_measure.js +649 -0
  281. package/src/generation/foliage/analysis/foliage_measure_leaf_area.d.ts +66 -0
  282. package/src/generation/foliage/analysis/foliage_measure_leaf_area.d.ts.map +1 -0
  283. package/src/generation/foliage/analysis/foliage_measure_leaf_area.js +192 -0
  284. package/src/generation/foliage/analysis/tree_crown_opacity.d.ts +27 -0
  285. package/src/generation/foliage/analysis/tree_crown_opacity.d.ts.map +1 -0
  286. package/src/generation/foliage/analysis/tree_crown_opacity.js +58 -0
  287. package/src/generation/foliage/animation/build_tree_wind_rig.d.ts +3 -2
  288. package/src/generation/foliage/animation/build_tree_wind_rig.d.ts.map +1 -1
  289. package/src/generation/foliage/animation/build_tree_wind_rig.js +12 -30
  290. package/src/generation/foliage/animation/tree_wind_bend_limit.d.ts +12 -0
  291. package/src/generation/foliage/animation/tree_wind_bend_limit.d.ts.map +1 -0
  292. package/src/generation/foliage/animation/tree_wind_bend_limit.js +13 -0
  293. package/src/generation/foliage/asset/TreeAsset.d.ts +5 -0
  294. package/src/generation/foliage/asset/TreeAsset.d.ts.map +1 -1
  295. package/src/generation/foliage/asset/TreeAsset.js +6 -0
  296. package/src/generation/foliage/asset/generate_tree.d.ts.map +1 -1
  297. package/src/generation/foliage/asset/generate_tree.js +23 -6
  298. package/src/generation/foliage/config/{BranchLevelConfig.d.ts → BranchGeneratorConfig.d.ts} +61 -75
  299. package/src/generation/foliage/config/BranchGeneratorConfig.d.ts.map +1 -0
  300. package/src/generation/foliage/config/{BranchLevelConfig.js → BranchGeneratorConfig.js} +83 -126
  301. package/src/generation/foliage/config/BranchSpawnRule.d.ts +118 -0
  302. package/src/generation/foliage/config/BranchSpawnRule.d.ts.map +1 -0
  303. package/src/generation/foliage/config/BranchSpawnRule.js +217 -0
  304. package/src/generation/foliage/config/FoliageCardType.d.ts +1 -1
  305. package/src/generation/foliage/config/FoliageCardType.js +2 -2
  306. package/src/generation/foliage/config/FoliageConfig.d.ts +23 -45
  307. package/src/generation/foliage/config/FoliageConfig.d.ts.map +1 -1
  308. package/src/generation/foliage/config/FoliageConfig.js +47 -93
  309. package/src/generation/foliage/config/FoliageMaterialConfig.d.ts +12 -20
  310. package/src/generation/foliage/config/FoliageMaterialConfig.d.ts.map +1 -1
  311. package/src/generation/foliage/config/FoliageMaterialConfig.js +261 -279
  312. package/src/generation/foliage/config/FoliageSpawnRule.d.ts +77 -0
  313. package/src/generation/foliage/config/FoliageSpawnRule.d.ts.map +1 -0
  314. package/src/generation/foliage/config/FoliageSpawnRule.js +135 -0
  315. package/src/generation/foliage/config/FoliageTileContent.d.ts +9 -0
  316. package/src/generation/foliage/config/FoliageTileContent.d.ts.map +1 -0
  317. package/src/generation/foliage/config/FoliageTileContent.js +12 -0
  318. package/src/generation/foliage/config/LeafApexShape.d.ts +12 -0
  319. package/src/generation/foliage/config/LeafApexShape.d.ts.map +1 -0
  320. package/src/generation/foliage/config/LeafApexShape.js +17 -0
  321. package/src/generation/foliage/config/LeafArchitecture.d.ts +155 -0
  322. package/src/generation/foliage/config/LeafArchitecture.d.ts.map +1 -0
  323. package/src/generation/foliage/config/LeafArchitecture.js +288 -0
  324. package/src/generation/foliage/config/LeafBaseShape.d.ts +14 -0
  325. package/src/generation/foliage/config/LeafBaseShape.d.ts.map +1 -0
  326. package/src/generation/foliage/config/LeafBaseShape.js +21 -0
  327. package/src/generation/foliage/config/LeafLobation.d.ts +10 -0
  328. package/src/generation/foliage/config/LeafLobation.d.ts.map +1 -0
  329. package/src/generation/foliage/config/LeafLobation.js +14 -0
  330. package/src/generation/foliage/config/PhyllotaxisMode.d.ts +11 -0
  331. package/src/generation/foliage/config/PhyllotaxisMode.d.ts.map +1 -1
  332. package/src/generation/foliage/config/PhyllotaxisMode.js +36 -0
  333. package/src/generation/foliage/config/ShootBudZone.d.ts +105 -0
  334. package/src/generation/foliage/config/ShootBudZone.d.ts.map +1 -0
  335. package/src/generation/foliage/config/ShootBudZone.js +219 -0
  336. package/src/generation/foliage/config/ShootGrowthConfig.d.ts +84 -0
  337. package/src/generation/foliage/config/ShootGrowthConfig.d.ts.map +1 -0
  338. package/src/generation/foliage/config/ShootGrowthConfig.js +146 -0
  339. package/src/generation/foliage/config/ShootSystemRule.d.ts +144 -0
  340. package/src/generation/foliage/config/ShootSystemRule.d.ts.map +1 -0
  341. package/src/generation/foliage/config/ShootSystemRule.js +316 -0
  342. package/src/generation/foliage/config/TreeLODConfig.d.ts +1 -1
  343. package/src/generation/foliage/config/TreeLODConfig.js +1 -1
  344. package/src/generation/foliage/config/TreeSpeciesConfig.d.ts +40 -8
  345. package/src/generation/foliage/config/TreeSpeciesConfig.d.ts.map +1 -1
  346. package/src/generation/foliage/config/TreeSpeciesConfig.js +124 -68
  347. package/src/generation/foliage/config/TreeWindConfig.d.ts +23 -10
  348. package/src/generation/foliage/config/TreeWindConfig.d.ts.map +1 -1
  349. package/src/generation/foliage/config/TreeWindConfig.js +34 -25
  350. package/src/generation/foliage/index.d.ts +19 -2
  351. package/src/generation/foliage/index.js +63 -44
  352. package/src/generation/foliage/material/FoliageAtlasCutout.d.ts +59 -0
  353. package/src/generation/foliage/material/FoliageAtlasCutout.d.ts.map +1 -0
  354. package/src/generation/foliage/material/FoliageAtlasCutout.js +93 -0
  355. package/src/generation/foliage/material/compute_foliage_variant_atlas_layout.d.ts +26 -0
  356. package/src/generation/foliage/material/compute_foliage_variant_atlas_layout.d.ts.map +1 -0
  357. package/src/generation/foliage/material/compute_foliage_variant_atlas_layout.js +63 -0
  358. package/src/generation/foliage/material/foliage_atlas_cutout.d.ts +34 -0
  359. package/src/generation/foliage/material/foliage_atlas_cutout.d.ts.map +1 -0
  360. package/src/generation/foliage/material/foliage_atlas_cutout.js +174 -0
  361. package/src/generation/foliage/material/foliage_tile.d.ts +110 -0
  362. package/src/generation/foliage/material/foliage_tile.d.ts.map +1 -0
  363. package/src/generation/foliage/material/foliage_tile.js +286 -0
  364. package/src/generation/foliage/material/leaf_geometry.d.ts +103 -0
  365. package/src/generation/foliage/material/leaf_geometry.d.ts.map +1 -0
  366. package/src/generation/foliage/material/leaf_geometry.js +528 -0
  367. package/src/generation/foliage/material/make_foliage_material.d.ts +13 -33
  368. package/src/generation/foliage/material/make_foliage_material.d.ts.map +1 -1
  369. package/src/generation/foliage/material/make_foliage_material.js +356 -605
  370. package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts +39 -4
  371. package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts.map +1 -1
  372. package/src/generation/foliage/mesh/foliage_collect_attachments.js +637 -569
  373. package/src/generation/foliage/mesh/interpolate_ring_skin_weights4.d.ts +48 -0
  374. package/src/generation/foliage/mesh/interpolate_ring_skin_weights4.d.ts.map +1 -0
  375. package/src/generation/foliage/mesh/interpolate_ring_skin_weights4.js +232 -0
  376. package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
  377. package/src/generation/foliage/mesh/tree_mesh_build_bark.js +1023 -1049
  378. package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts +9 -2
  379. package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts.map +1 -1
  380. package/src/generation/foliage/mesh/tree_mesh_build_foliage.js +467 -454
  381. package/src/generation/foliage/presets/make_tree_species_preset.d.ts.map +1 -1
  382. package/src/generation/foliage/presets/make_tree_species_preset.js +1648 -870
  383. package/src/generation/foliage/skeleton/ShootFrameworkHash.d.ts +35 -0
  384. package/src/generation/foliage/skeleton/ShootFrameworkHash.d.ts.map +1 -0
  385. package/src/generation/foliage/skeleton/ShootFrameworkHash.js +129 -0
  386. package/src/generation/foliage/skeleton/ShootGirth.d.ts +51 -0
  387. package/src/generation/foliage/skeleton/ShootGirth.d.ts.map +1 -0
  388. package/src/generation/foliage/skeleton/ShootGirth.js +212 -0
  389. package/src/generation/foliage/skeleton/ShootLightField.d.ts +73 -0
  390. package/src/generation/foliage/skeleton/ShootLightField.d.ts.map +1 -0
  391. package/src/generation/foliage/skeleton/ShootLightField.js +197 -0
  392. package/src/generation/foliage/skeleton/TreeSkeleton.d.ts +106 -3
  393. package/src/generation/foliage/skeleton/TreeSkeleton.d.ts.map +1 -1
  394. package/src/generation/foliage/skeleton/TreeSkeleton.js +217 -39
  395. package/src/generation/foliage/skeleton/flare_lobe_phase_offset.d.ts +13 -0
  396. package/src/generation/foliage/skeleton/flare_lobe_phase_offset.d.ts.map +1 -0
  397. package/src/generation/foliage/skeleton/flare_lobe_phase_offset.js +16 -0
  398. package/src/generation/foliage/skeleton/foliage_card_density.d.ts +71 -0
  399. package/src/generation/foliage/skeleton/foliage_card_density.d.ts.map +1 -0
  400. package/src/generation/foliage/skeleton/foliage_card_density.js +101 -0
  401. package/src/generation/foliage/skeleton/foliage_senescence.d.ts +101 -0
  402. package/src/generation/foliage/skeleton/foliage_senescence.d.ts.map +1 -0
  403. package/src/generation/foliage/skeleton/foliage_senescence.js +149 -0
  404. package/src/generation/foliage/skeleton/foliage_unit_cards.d.ts +76 -0
  405. package/src/generation/foliage/skeleton/foliage_unit_cards.d.ts.map +1 -0
  406. package/src/generation/foliage/skeleton/foliage_unit_cards.js +95 -0
  407. package/src/generation/foliage/skeleton/shoot_demography.d.ts +22 -0
  408. package/src/generation/foliage/skeleton/shoot_demography.d.ts.map +1 -0
  409. package/src/generation/foliage/skeleton/shoot_demography.js +96 -0
  410. package/src/generation/foliage/skeleton/shoot_geometry.d.ts +66 -0
  411. package/src/generation/foliage/skeleton/shoot_geometry.d.ts.map +1 -0
  412. package/src/generation/foliage/skeleton/shoot_geometry.js +109 -0
  413. package/src/generation/foliage/skeleton/shoot_systems_simulate.d.ts +166 -0
  414. package/src/generation/foliage/skeleton/shoot_systems_simulate.d.ts.map +1 -0
  415. package/src/generation/foliage/skeleton/shoot_systems_simulate.js +588 -0
  416. package/src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.d.ts +28 -12
  417. package/src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.d.ts.map +1 -1
  418. package/src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.js +137 -102
  419. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts +112 -0
  420. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts.map +1 -0
  421. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.js +408 -0
  422. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.d.ts.map +1 -1
  423. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.js +208 -206
  424. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts +5 -2
  425. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts.map +1 -1
  426. package/src/generation/foliage/skeleton/tree_skeleton_grow.js +2048 -1871
  427. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts +17 -0
  428. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts.map +1 -0
  429. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.js +231 -0
  430. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_motion.d.ts +14 -0
  431. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_motion.d.ts.map +1 -0
  432. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_motion.js +26 -0
  433. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_parents.d.ts +10 -0
  434. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_parents.d.ts.map +1 -0
  435. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_parents.js +20 -0
  436. package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts.map +1 -1
  437. package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +4 -1
  438. package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts +1 -0
  439. package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts.map +1 -1
  440. package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +98 -86
  441. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +263 -0
  442. package/src/shade/descriptor/WebGPUExtensionType.d.ts +17 -0
  443. package/src/shade/descriptor/WebGPUExtensionType.d.ts.map +1 -1
  444. package/src/shade/descriptor/WebGPUExtensionType.js +31 -1
  445. package/src/shade/playground/foliage_wind/FoliageRigOverlay.d.ts +37 -0
  446. package/src/shade/playground/foliage_wind/FoliageRigOverlay.d.ts.map +1 -0
  447. package/src/shade/playground/foliage_wind/FoliageRigOverlay.js +491 -0
  448. package/src/shade/playground/foliage_wind/foliage_world.d.ts.map +1 -1
  449. package/src/shade/playground/foliage_wind/foliage_world.js +600 -602
  450. package/src/shade/playground/foliage_wind/index.html +6 -0
  451. package/src/shade/playground/foliage_wind/main.js +14 -0
  452. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  453. package/src/shade/renderer/animation/GPUAnimationManager.js +2 -1
  454. package/src/shade/renderer/animation/foliage/FoliageWindJoint.d.ts +2 -1
  455. package/src/shade/renderer/animation/foliage/FoliageWindJoint.d.ts.map +1 -1
  456. package/src/shade/renderer/animation/foliage/FoliageWindJoint.js +2 -1
  457. package/src/shade/renderer/animation/foliage/chunk_foliage_wind_step.d.ts.map +1 -1
  458. package/src/shade/renderer/animation/foliage/chunk_foliage_wind_step.js +4 -2
  459. package/src/shade/renderer/buffer/table/GPUTypedTable.js +1 -1
  460. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  461. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +403 -401
  462. package/src/shade/renderer/camera/OrbitalCameraController.d.ts +1 -62
  463. package/src/shade/renderer/camera/OrbitalCameraController.d.ts.map +1 -1
  464. package/src/shade/renderer/camera/OrbitalCameraController.js +1 -374
  465. package/src/shade/renderer/deferred/indirect/chunk_lpv_2d_cache_sample_irradiance.d.ts.map +1 -1
  466. package/src/shade/renderer/deferred/indirect/chunk_lpv_2d_cache_sample_irradiance.js +3 -0
  467. package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.d.ts.map +1 -1
  468. package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.js +6 -1
  469. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.js +1 -1
  470. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +2 -2
  471. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts.map +1 -1
  472. package/src/shade/renderer/fluid/GPUFluidCascade.js +6 -3
  473. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +361 -0
  474. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts.map +1 -1
  475. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.js +335 -241
  476. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.d.ts.map +1 -1
  477. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.js +108 -101
  478. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.d.ts.map +1 -1
  479. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.js +69 -67
  480. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts +7 -6
  481. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts.map +1 -1
  482. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.js +341 -287
  483. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts +6 -4
  484. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts.map +1 -1
  485. package/src/shade/renderer/fluid/mac/FluidMacPasses.js +427 -400
  486. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts +10 -5
  487. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts.map +1 -1
  488. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.js +532 -190
  489. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.d.ts.map +1 -1
  490. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.js +231 -237
  491. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts +2 -2
  492. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -1
  493. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +282 -245
  494. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts +1 -3
  495. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts.map +1 -1
  496. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.js +139 -109
  497. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts +6 -6
  498. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts.map +1 -1
  499. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.js +257 -222
  500. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts +8 -7
  501. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts.map +1 -1
  502. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.js +119 -92
  503. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts +6 -9
  504. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts.map +1 -1
  505. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.js +229 -181
  506. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +17 -7
  507. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts.map +1 -1
  508. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.js +634 -621
  509. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts +8 -6
  510. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts.map +1 -1
  511. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.js +166 -149
  512. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts +8 -6
  513. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts.map +1 -1
  514. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.js +219 -183
  515. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts.map +1 -1
  516. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.js +142 -122
  517. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +674 -663
  518. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +1 -1
  519. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  520. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +63 -29
  521. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts.map +1 -1
  522. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.js +77 -87
  523. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/meshopt_clusterizer.d.ts.map +1 -1
  524. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/meshopt_clusterizer.js +4 -3
  525. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts +11 -11
  526. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
  527. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +17 -19
  528. package/src/shade/renderer/global_illumination/lpv/graph_bake_irradiance_lookup_2d.js +4 -4
  529. package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_mesh_interpolate_radiance_via_atlas.d.ts.map +1 -1
  530. package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_mesh_interpolate_radiance_via_atlas.js +5 -1
  531. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  532. package/src/shade/renderer/loader/gltf/load_gltf.js +11 -35
  533. package/src/shade/renderer/loader/usd/load_usd.d.ts.map +1 -1
  534. package/src/shade/renderer/loader/usd/load_usd.js +6 -19
  535. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
  536. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +199 -193
  537. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts.map +1 -1
  538. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.js +151 -143
  539. package/src/shade/renderer/postprocess/bloom/chunk_karis_blur4x4_sample.d.ts.map +1 -1
  540. package/src/shade/renderer/postprocess/bloom/chunk_karis_blur4x4_sample.js +11 -5
  541. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts.map +1 -1
  542. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +6 -18
  543. package/src/shade/renderer/postprocess/gtao/GTAO.js +1 -1
  544. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  545. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +3 -5
  546. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +1 -1
  547. package/src/shade/renderer/postprocess/nss/chunk_nss_luma_derivative.d.ts.map +1 -1
  548. package/src/shade/renderer/postprocess/nss/chunk_nss_luma_derivative.js +7 -3
  549. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
  550. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +4 -2
  551. package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.d.ts.map +1 -1
  552. package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +4 -1
  553. package/src/shade/renderer/postprocess/ssr/downsample_karis.d.ts.map +1 -1
  554. package/src/shade/renderer/postprocess/ssr/downsample_karis.js +6 -3
  555. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -1
  556. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +4 -3
  557. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts.map +1 -1
  558. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.js +4 -1
  559. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
  560. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +4 -2
  561. package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap.d.ts.map +1 -1
  562. package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap.js +35 -39
  563. package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap_inv.d.ts.map +1 -1
  564. package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap_inv.js +20 -17
  565. package/src/shade/renderer/postprocess/taa/shader_taa.d.ts.map +1 -1
  566. package/src/shade/renderer/postprocess/taa/shader_taa.js +6 -3
  567. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  568. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +3 -1
  569. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +1 -1
  570. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.js +2 -2
  571. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +1 -1
  572. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts.map +1 -1
  573. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.js +92 -83
  574. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +1 -1
  575. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  576. package/src/shade/renderer/shader/ShaderDescriptor.js +12 -4
  577. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts.map +1 -1
  578. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.js +294 -286
  579. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_interpolate_probe_irradiance8.js +5 -5
  580. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe.d.ts.map +1 -1
  581. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe.js +5 -3
  582. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe_irradiance.d.ts.map +1 -1
  583. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe_irradiance.js +9 -6
  584. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_sh3_at.d.ts.map +1 -1
  585. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_sh3_at.js +33 -38
  586. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  587. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +690 -675
  588. package/src/shade/renderer/shader/type/WebGPUArray.d.ts +3 -0
  589. package/src/shade/renderer/shader/type/WebGPUArray.d.ts.map +1 -1
  590. package/src/shade/renderer/shader/type/WebGPUArray.js +185 -167
  591. package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
  592. package/src/shade/renderer/shader/type/WebGPUStruct.js +461 -455
  593. package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.d.ts.map +1 -1
  594. package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.js +335 -211
  595. package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.d.ts.map +1 -1
  596. package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.js +329 -221
  597. package/src/shade/renderer/shader/type/type_has_f16.d.ts +12 -0
  598. package/src/shade/renderer/shader/type/type_has_f16.d.ts.map +1 -0
  599. package/src/shade/renderer/shader/type/type_has_f16.js +66 -0
  600. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  601. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +16 -2
  602. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts.map +1 -1
  603. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js +5 -2
  604. package/src/shade/renderer/water/shader_water_avboit.js +1 -1
  605. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  606. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +260 -23
  607. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts +6 -7
  608. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  609. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +269 -69
  610. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  611. package/src/shade/wgsl/validate_wgsl_source.js +27 -1
  612. package/src/view/controller/controls/ListController.d.ts.map +1 -1
  613. package/src/view/controller/controls/ListController.js +118 -113
  614. package/src/view/controller/controls/Vector1Control.js +97 -97
  615. package/src/view/elements/image/SvgImageView.d.ts +1 -0
  616. package/src/view/elements/image/SvgImageView.d.ts.map +1 -1
  617. package/src/view/elements/image/SvgImageView.js +92 -90
  618. package/src/view/minimap/dom/MinimapTerrainView.d.ts +1 -0
  619. package/src/view/minimap/dom/MinimapTerrainView.d.ts.map +1 -1
  620. package/src/view/minimap/dom/MinimapTerrainView.js +151 -147
  621. package/src/view/tooltip/gml/TooltipParser.js +2 -2
  622. package/src/engine/network/PriorityFetch.d.ts +0 -59
  623. package/src/engine/network/PriorityFetch.d.ts.map +0 -1
  624. package/src/engine/network/PriorityFetch.js +0 -193
  625. package/src/generation/foliage/config/BranchLevelConfig.d.ts.map +0 -1
@@ -1,400 +1,427 @@
1
- import { assert } from "../../../../core/assert.js";
2
- import { isPowerOfTwo } from "../../../../core/math/isPowerOfTwo.js";
3
- import { GRID_TILE_SIZE } from "../../shader/chunk/grid/chunk_grid_tile_window.js";
4
- import { fluid_cascade_window_place, fluid_cascade_window_value } from "../fluid_cascade_window.js";
5
- import { FLUID_CASCADE_DEVIATION_CELLS } from "../coupling/chunk_fluid_cascade_epilogue.js";
6
- import { FLUID_MAC_STEP_STRUCT } from "./FLUID_MAC_STEP_STRUCT.js";
7
- import { shader_fluid_mac_advect_correct } from "./shader_fluid_mac_advect_correct.js";
8
- import { shader_fluid_mac_advect_predict } from "./shader_fluid_mac_advect_predict.js";
9
- import { shader_fluid_mac_curl } from "./shader_fluid_mac_curl.js";
10
- import { shader_fluid_mac_divergence } from "./shader_fluid_mac_divergence.js";
11
- import { shader_fluid_mac_gradient } from "./shader_fluid_mac_gradient.js";
12
- import { shader_fluid_cascade_ghosts } from "../coupling/shader_fluid_cascade_ghosts.js";
13
- import { FLUID_CASCADE_GHOST_DEPTH } from "../coupling/FLUID_CASCADE_GHOSTS.js";
14
-
15
- /**
16
- * @typedef {import("../../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext} ShadeGPUCommandContext
17
- * @typedef {import("./FluidMacVelocitySet.js").FluidMacVelocitySet} FluidMacVelocitySet
18
- * @typedef {{u: GPUTextureView, v: GPUTextureView, w: GPUTextureView}} FluidMacVelocityViews a MAC
19
- * velocity field's three component views: a {@link FluidMacVelocitySet}'s, or a frame graph's
20
- * transient textures'
21
- * @typedef {{uniform: GPUBuffer, u: GPUTextureView, v: GPUTextureView, w: GPUTextureView, pressure: GPUBuffer}} FluidCascadeParentBindings
22
- * what a step reads of its parent beyond its window: `uniform`, the parent as
23
- * {@link FLUID_CASCADE_PARENT_STRUCT}; `u`, `v`, `w`, its persistent faces; `pressure`, its pressure.
24
- * A far-field parent binds stand-ins it never reads.
25
- * @typedef {{u: GPUTextureView, v: GPUTextureView, w: GPUTextureView, pressure: GPUBuffer}} FluidCascadeGhostBindings
26
- * a step's ghosts (`shader_fluid_cascade_ghosts`): `u`, `v`, `w`, the velocity shells, transient
27
- * `r32float` textures of each face lattice grown by `FLUID_CASCADE_GHOST_DEPTH` on every side;
28
- * `pressure`, the pressure ghosts over the window grown by one cell.
29
- */
30
-
31
- /**
32
- * Records the MAC passes of one cascade's step (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §8): the
33
- * advection (predict, then correct), the right-hand side of the pressure solve, and the gradient
34
- * subtraction that writes the step's end velocity. The pressure solve between the last two is not
35
- * here.
36
- *
37
- * One instance a cascade. {@link place} puts its window, {@link set_step} sets a step's h, dt and far
38
- * field, and each `record_*` records into the encoder a frame-graph pass hands its callback. Each
39
- * record serialises the step's parameters into a transient uniform of its own (pooled by the
40
- * encoder), so a step recorded later in the frame cannot change what an earlier one reads.
41
- *
42
- * The step's order and what moves between the passes, A the cascade's persistent velocity:
43
- *
44
- * record_ghosts(encoder, parent, G) parent → G (the step's ghosts)
45
- * record_curl(encoder, A, solid, C) A → C, the confinement force (with confinement)
46
- * record_advect(encoder, A, F, B, solid, forcing, C, parent, G) A → F (predict), A + F + C + forcing → B (correct)
47
- * record_divergence(encoder, B, solid, rhs) B → rhs = div/dt
48
- * (the pressure solve: rhs → pressure, its ghosts G)
49
- * record_gradient(encoder, B, pressure, solid, A, G) B + pressure → A
50
- *
51
- * so A is the only velocity a cascade keeps between steps, and F and B are transients. Beyond the
52
- * window, the advection reads the step's ghosts of the parent's faces and the gradient those of its
53
- * pressure ({@link FluidCascadeGhostBindings}), each written once a step from the parent
54
- * ({@link FluidCascadeParentBindings}).
55
- *
56
- * Every pass dispatches `(nx / 8, ny / 8, nz / 4)` workgroups, the ghosts `ceil((n + 1 + 2·depth) / 4)`
57
- * on each axis, a texel of the largest shell an invocation. Nothing here allocates once placed:
58
- * the parameters, bindings and dispatch arguments are retained and rewritten in place.
59
- */
60
- export class FluidMacPasses {
61
- /**
62
- * Offer the compute pipelines the MAC step passes dispatch — see {@link PipelineEnquiry}.
63
- *
64
- * @param {import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} enquiry
65
- */
66
- static enquirePipelines(enquiry) {
67
- enquiry.compute.push(
68
- shader_fluid_mac_advect_correct.pipeline,
69
- shader_fluid_mac_advect_predict.pipeline,
70
- shader_fluid_mac_curl.pipeline,
71
- shader_fluid_mac_divergence.pipeline,
72
- shader_fluid_mac_gradient.pipeline,
73
- shader_fluid_cascade_ghosts.pipeline,
74
- );
75
- }
76
-
77
- /** The value of {@link FLUID_MAC_STEP_STRUCT}, rewritten in place. */
78
- #step = {
79
- cells: fluid_cascade_window_value(),
80
- faces_u: fluid_cascade_window_value(),
81
- faces_v: fluid_cascade_window_value(),
82
- faces_w: fluid_cascade_window_value(),
83
- far_velocity: new Float32Array(3),
84
- dt_over_h: 0,
85
- far_velocity_end: new Float32Array(3),
86
- rhs_scale: 0,
87
- keep: 1,
88
- deviation_limit: 0,
89
- band: 0,
90
- confinement_dt: 0,
91
- };
92
-
93
- #placed = false;
94
- #stepped = false;
95
-
96
- #curl = {
97
- encoder: null,
98
- bindings: { step: null, source_u: null, source_v: null, source_w: null, solid: null, confinement: null },
99
- group_count_x: 1, group_count_y: 1, group_count_z: 1,
100
- };
101
-
102
- #predict = {
103
- encoder: null,
104
- bindings: {
105
- step: null, parent: null, source_u: null, source_v: null, source_w: null, parent_u: null, parent_v: null, parent_w: null,
106
- ghost_u: null, ghost_v: null, ghost_w: null,
107
- solid: null, forward_u: null, forward_v: null, forward_w: null,
108
- },
109
- group_count_x: 1, group_count_y: 1, group_count_z: 1,
110
- };
111
-
112
- #correct = {
113
- encoder: null,
114
- bindings: {
115
- step: null, parent: null, source_u: null, source_v: null, source_w: null, forward_u: null, forward_v: null, forward_w: null,
116
- parent_u: null, parent_v: null, parent_w: null, ghost_u: null, ghost_v: null, ghost_w: null,
117
- solid: null, forcing: null, confinement: null, out_u: null, out_v: null, out_w: null,
118
- },
119
- group_count_x: 1, group_count_y: 1, group_count_z: 1,
120
- };
121
-
122
- #divergence = {
123
- encoder: null,
124
- bindings: { step: null, velocity_u: null, velocity_v: null, velocity_w: null, solid: null, rhs: null },
125
- group_count_x: 1, group_count_y: 1, group_count_z: 1,
126
- };
127
-
128
- #ghosts = {
129
- encoder: null,
130
- bindings: {
131
- step: null, parent: null, parent_u: null, parent_v: null, parent_w: null, parent_pressure: null,
132
- ghost_u: null, ghost_v: null, ghost_w: null, ghost_pressure: null,
133
- },
134
- group_count_x: 1, group_count_y: 1, group_count_z: 1,
135
- };
136
-
137
- #gradient = {
138
- encoder: null,
139
- bindings: {
140
- step: null, velocity_u: null, velocity_v: null, velocity_w: null, pressure: null, ghost_pressure: null,
141
- solid: null, out_u: null, out_v: null, out_w: null,
142
- },
143
- group_count_x: 1, group_count_y: 1, group_count_z: 1,
144
- };
145
-
146
- /**
147
- * Where the cascade's window is.
148
- *
149
- * @param {ArrayLike<number>} resolution cells on each axis, each a power of two, at least 8, 8, 4
150
- * @param {ArrayLike<number>} corner the world cell at window-local (0, 0, 0)
151
- */
152
- place(resolution, corner) {
153
- for (let i = 0; i < 3; i++) {
154
- assert.isNonNegativeInteger(resolution[i], 'resolution');
155
- assert.ok(isPowerOfTwo(resolution[i]), 'resolution is a power of two on each axis');
156
- assert.greaterThanOrEqual(resolution[i], GRID_TILE_SIZE[i], 'resolution holds a whole tile on each axis');
157
- assert.isInteger(corner[i], 'corner');
158
- }
159
-
160
- const step = this.#step;
161
-
162
- fluid_cascade_window_place(step.cells, corner, resolution, -1);
163
- fluid_cascade_window_place(step.faces_u, corner, resolution, 0);
164
- fluid_cascade_window_place(step.faces_v, corner, resolution, 1);
165
- fluid_cascade_window_place(step.faces_w, corner, resolution, 2);
166
-
167
- const x = resolution[0] / GRID_TILE_SIZE[0];
168
- const y = resolution[1] / GRID_TILE_SIZE[1];
169
- const z = resolution[2] / GRID_TILE_SIZE[2];
170
-
171
- for (const pass of [this.#curl, this.#predict, this.#correct, this.#divergence, this.#gradient]) {
172
- pass.group_count_x = x;
173
- pass.group_count_y = y;
174
- pass.group_count_z = z;
175
- }
176
-
177
- // the ghosts: a texel of the largest shell an invocation
178
- const ghosts = this.#ghosts;
179
- ghosts.group_count_x = Math.ceil((resolution[0] + 1 + 2 * FLUID_CASCADE_GHOST_DEPTH) / 4);
180
- ghosts.group_count_y = Math.ceil((resolution[1] + 1 + 2 * FLUID_CASCADE_GHOST_DEPTH) / 4);
181
- ghosts.group_count_z = Math.ceil((resolution[2] + 1 + 2 * FLUID_CASCADE_GHOST_DEPTH) / 4);
182
-
183
- this.#placed = true;
184
- }
185
-
186
- /**
187
- * The step about to be recorded, from `t₀` to `t₁` (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §6, §8).
188
- *
189
- * @param {number} h cell size, m
190
- * @param {number} dt time step, s
191
- * @param {ArrayLike<number>} far_velocity `v_far(t₀)`, m/s: what the velocity the step starts from
192
- * is a deviation from
193
- * @param {ArrayLike<number>} far_velocity_end `v_far(t₁)`, m/s
194
- * @param {number} keep `e^(−(Λ(t₁) − Λ(t₀)))`, in [0, 1]
195
- * @param {boolean} band whether the faces of rows 2..5 relax toward the parent
196
- * @param {number} confinement the vorticity confinement's strength ε, per second, ≥ 0: 0 for none,
197
- * and then {@link record_curl} is not recorded for the step
198
- */
199
- set_step(h, dt, far_velocity, far_velocity_end, keep, band, confinement) {
200
- assert.isFinite(h, 'h'); assert.greaterThan(h, 0, 'h');
201
- assert.isFinite(dt, 'dt'); assert.greaterThan(dt, 0, 'dt');
202
- assert.isFinite(keep, 'keep');
203
- assert.greaterThanOrEqual(keep, 0, 'keep');
204
- assert.lessThanOrEqual(keep, 1, 'keep');
205
- assert.isBoolean(band, 'band');
206
- assert.isFinite(confinement, 'confinement');
207
- assert.greaterThanOrEqual(confinement, 0, 'confinement');
208
-
209
- const step = this.#step;
210
-
211
- step.dt_over_h = dt / h;
212
- step.rhs_scale = 1 / (h * dt);
213
- step.keep = keep;
214
- step.deviation_limit = FLUID_CASCADE_DEVIATION_CELLS * h / dt;
215
- step.band = band ? 1 : 0;
216
- step.confinement_dt = confinement * dt;
217
-
218
- for (let i = 0; i < 3; i++) {
219
- assert.isFinite(far_velocity[i], 'far_velocity');
220
- assert.isFinite(far_velocity_end[i], 'far_velocity_end');
221
-
222
- step.far_velocity[i] = far_velocity[i];
223
- step.far_velocity_end[i] = far_velocity_end[i];
224
- }
225
-
226
- this.#stepped = true;
227
- }
228
-
229
- /**
230
- * @param {ShadeGPUCommandContext} encoder
231
- * @returns {GPUBuffer}
232
- */
233
- #uniform(encoder) {
234
- assert.ok(this.#placed, 'placed before recording');
235
- assert.ok(this.#stepped, 'a step set before recording');
236
-
237
- return encoder.allocateTransientValueBuffer(FLUID_MAC_STEP_STRUCT, this.#step, GPUBufferUsage.UNIFORM);
238
- }
239
-
240
- /**
241
- * The step's vorticity confinement, pass 1 (`shader_fluid_mac_curl`): the curl of the persistent
242
- * velocity and the force it makes in every cell, for the correct pass. Recorded only for a step whose
243
- * confinement is not 0, before {@link record_advect}.
244
- *
245
- * @param {ShadeGPUCommandContext} encoder
246
- * @param {FluidMacVelocityViews} source the persistent velocity, toroidal; read
247
- * @param {GPUBuffer} solid the window-local solid flags, `array<u32>`, bit 0
248
- * @param {GPUBuffer} confinement written, `array<f32>` of 3·N cells, window-local
249
- */
250
- record_curl(encoder, source, solid, confinement) {
251
- assert.greaterThan(this.#step.confinement_dt, 0, 'a step with confinement');
252
-
253
- const pass = this.#curl;
254
- const b = pass.bindings;
255
- b.step = this.#uniform(encoder);
256
- b.source_u = source.u; b.source_v = source.v; b.source_w = source.w;
257
- b.solid = solid;
258
- b.confinement = confinement;
259
- pass.encoder = encoder;
260
-
261
- shader_fluid_mac_curl.dispatch(pass);
262
-
263
- pass.encoder = null;
264
- b.confinement = null;
265
- }
266
-
267
- /**
268
- * MacCormack advection of the persistent velocity by itself: predict into `forward`, then correct
269
- * into `out`, which adds the step's confinement and the tick's forcing.
270
- *
271
- * @param {ShadeGPUCommandContext} encoder
272
- * @param {FluidMacVelocityViews} source the persistent velocity, toroidal; read
273
- * @param {FluidMacVelocityViews} forward a transient, window-local; written, then read
274
- * @param {FluidMacVelocityViews} out a transient, window-local; written
275
- * @param {GPUBuffer} solid the window-local solid flags, `array<u32>`: bit 0 solid, bit 1
276
- * (`FLUID_FORCED_FLAG`) forcing written for the cell's faces
277
- * @param {GPUBuffer} forcing the tick's forcing, `array<f32>` over the three face lattices
278
- * (`shader_fluid_mac_advect_correct`); read only where `solid` says it was written
279
- * @param {GPUBuffer} confinement what {@link record_curl} wrote for the step; read only when the
280
- * step's confinement is not 0
281
- * @param {FluidCascadeParentBindings} parent what lies beyond the window, past its ghosts
282
- * @param {FluidCascadeGhostBindings} ghosts the step's ghosts, written by {@link record_ghosts}
283
- */
284
- record_advect(encoder, source, forward, out, solid, forcing, confinement, parent, ghosts) {
285
- assert.notEqual(source, forward, 'source and forward are different sets');
286
- assert.notEqual(source, out, 'source and out are different sets');
287
- assert.notEqual(forward, out, 'forward and out are different sets');
288
-
289
- const step = this.#uniform(encoder);
290
-
291
- const predict = this.#predict;
292
- const p = predict.bindings;
293
- p.step = step;
294
- p.parent = parent.uniform;
295
- p.source_u = source.u; p.source_v = source.v; p.source_w = source.w;
296
- p.parent_u = parent.u; p.parent_v = parent.v; p.parent_w = parent.w;
297
- p.ghost_u = ghosts.u; p.ghost_v = ghosts.v; p.ghost_w = ghosts.w;
298
- p.solid = solid;
299
- p.forward_u = forward.u; p.forward_v = forward.v; p.forward_w = forward.w;
300
- predict.encoder = encoder;
301
-
302
- shader_fluid_mac_advect_predict.dispatch(predict);
303
-
304
- const correct = this.#correct;
305
- const c = correct.bindings;
306
- c.step = step;
307
- c.parent = parent.uniform;
308
- c.source_u = source.u; c.source_v = source.v; c.source_w = source.w;
309
- c.forward_u = forward.u; c.forward_v = forward.v; c.forward_w = forward.w;
310
- c.parent_u = parent.u; c.parent_v = parent.v; c.parent_w = parent.w;
311
- c.ghost_u = ghosts.u; c.ghost_v = ghosts.v; c.ghost_w = ghosts.w;
312
- c.solid = solid;
313
- c.forcing = forcing;
314
- c.confinement = confinement;
315
- c.out_u = out.u; c.out_v = out.v; c.out_w = out.w;
316
- correct.encoder = encoder;
317
-
318
- shader_fluid_mac_advect_correct.dispatch(correct);
319
-
320
- predict.encoder = null;
321
- correct.encoder = null;
322
- c.forcing = null;
323
- c.confinement = null;
324
- }
325
-
326
- /**
327
- * The step's ghosts (`shader_fluid_cascade_ghosts`): the parent's identity read at every face of the
328
- * velocity shells and its pressure at every cell one past the window, once, for the step's passes.
329
- *
330
- * @param {ShadeGPUCommandContext} encoder
331
- * @param {FluidCascadeParentBindings} parent
332
- * @param {FluidCascadeGhostBindings} ghosts written
333
- */
334
- record_ghosts(encoder, parent, ghosts) {
335
- const pass = this.#ghosts;
336
- const b = pass.bindings;
337
- b.step = this.#uniform(encoder);
338
- b.parent = parent.uniform;
339
- b.parent_u = parent.u; b.parent_v = parent.v; b.parent_w = parent.w;
340
- b.parent_pressure = parent.pressure;
341
- b.ghost_u = ghosts.u; b.ghost_v = ghosts.v; b.ghost_w = ghosts.w;
342
- b.ghost_pressure = ghosts.pressure;
343
- pass.encoder = encoder;
344
-
345
- shader_fluid_cascade_ghosts.dispatch(pass);
346
-
347
- pass.encoder = null;
348
- }
349
-
350
- /**
351
- * The right-hand side of the pressure solve, `div/dt` at every cell, 0 in solid cells.
352
- *
353
- * @param {ShadeGPUCommandContext} encoder
354
- * @param {FluidMacVelocityViews} velocity the advected velocity, window-local; read
355
- * @param {GPUBuffer} solid the window-local solid flags, `array<u32>`, bit 0
356
- * @param {GPUBuffer} rhs written, `array<f32>` of N cells, window-local, x fastest
357
- */
358
- record_divergence(encoder, velocity, solid, rhs) {
359
- const pass = this.#divergence;
360
- const b = pass.bindings;
361
- b.step = this.#uniform(encoder);
362
- b.velocity_u = velocity.u; b.velocity_v = velocity.v; b.velocity_w = velocity.w;
363
- b.solid = solid;
364
- b.rhs = rhs;
365
- pass.encoder = encoder;
366
-
367
- shader_fluid_mac_divergence.dispatch(pass);
368
-
369
- pass.encoder = null;
370
- }
371
-
372
- /**
373
- * The pressure gradient taken from the advected velocity, into the persistent velocity.
374
- *
375
- * @param {ShadeGPUCommandContext} encoder
376
- * @param {FluidMacVelocityViews} velocity the advected velocity, window-local; read
377
- * @param {GPUBuffer} pressure kinematic pressure, m²/s², `array<f32>` of N cells, toroidal; read
378
- * @param {GPUBuffer} solid the window-local solid flags, `array<u32>`, bit 0
379
- * @param {FluidMacVelocityViews} out the persistent velocity, toroidal; written
380
- * @param {FluidCascadeGhostBindings} ghosts the step's ghosts: `pressure` is the pressure beyond the window
381
- */
382
- record_gradient(encoder, velocity, pressure, solid, out, ghosts) {
383
- assert.notEqual(velocity, out, 'velocity and out are different sets');
384
- assert.notEqual(pressure, ghosts.pressure, 'the ghosts are not the cascade\'s pressure');
385
-
386
- const pass = this.#gradient;
387
- const b = pass.bindings;
388
- b.step = this.#uniform(encoder);
389
- b.velocity_u = velocity.u; b.velocity_v = velocity.v; b.velocity_w = velocity.w;
390
- b.pressure = pressure;
391
- b.ghost_pressure = ghosts.pressure;
392
- b.solid = solid;
393
- b.out_u = out.u; b.out_v = out.v; b.out_w = out.w;
394
- pass.encoder = encoder;
395
-
396
- shader_fluid_mac_gradient.dispatch(pass);
397
-
398
- pass.encoder = null;
399
- }
400
- }
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { isPowerOfTwo } from "../../../../core/math/isPowerOfTwo.js";
3
+ import { GRID_TILE_SIZE } from "../../shader/chunk/grid/chunk_grid_tile_window.js";
4
+ import { fluid_cascade_window_place, fluid_cascade_window_value } from "../fluid_cascade_window.js";
5
+ import { FLUID_CASCADE_DEVIATION_CELLS } from "../coupling/chunk_fluid_cascade_epilogue.js";
6
+ import { FLUID_MAC_STEP_STRUCT } from "./FLUID_MAC_STEP_STRUCT.js";
7
+ import { shader_fluid_mac_advect_correct } from "./shader_fluid_mac_advect_correct.js";
8
+ import { shader_fluid_mac_advect_predict } from "./shader_fluid_mac_advect_predict.js";
9
+ import { shader_fluid_mac_curl } from "./shader_fluid_mac_curl.js";
10
+ import { shader_fluid_mac_divergence } from "./shader_fluid_mac_divergence.js";
11
+ import { shader_fluid_mac_gradient } from "./shader_fluid_mac_gradient.js";
12
+ import { shader_fluid_cascade_ghosts } from "../coupling/shader_fluid_cascade_ghosts.js";
13
+ import { FLUID_CASCADE_GHOST_DEPTH } from "../coupling/FLUID_CASCADE_GHOSTS.js";
14
+
15
+ /**
16
+ * @typedef {import("../../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext} ShadeGPUCommandContext
17
+ * @typedef {import("./FluidMacVelocitySet.js").FluidMacVelocitySet} FluidMacVelocitySet
18
+ * @typedef {{u: GPUTextureView, v: GPUTextureView, w: GPUTextureView}} FluidMacVelocityViews a MAC
19
+ * velocity field's three component views: a {@link FluidMacVelocitySet}'s, or a frame graph's
20
+ * transient textures'
21
+ * @typedef {{uniform: GPUBuffer, u: GPUTextureView, v: GPUTextureView, w: GPUTextureView, pressure: GPUBuffer}} FluidCascadeParentBindings
22
+ * what a step reads of its parent beyond its window: `uniform`, the parent as
23
+ * {@link FLUID_CASCADE_PARENT_STRUCT}; `u`, `v`, `w`, its persistent faces; `pressure`, its pressure.
24
+ * A far-field parent binds stand-ins it never reads.
25
+ * @typedef {{u: GPUTextureView, v: GPUTextureView, w: GPUTextureView, pressure: GPUBuffer}} FluidCascadeGhostBindings
26
+ * a step's ghosts (`shader_fluid_cascade_ghosts`): `u`, `v`, `w`, the velocity shells, transient
27
+ * `r32float` textures of each face lattice grown by `FLUID_CASCADE_GHOST_DEPTH` on every side;
28
+ * `pressure`, the pressure ghosts over the window grown by one cell.
29
+ */
30
+
31
+ /**
32
+ * Records the MAC passes of one cascade's step (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §8): the
33
+ * advection (predict, then correct), the right-hand side of the pressure solve, and the gradient
34
+ * subtraction that writes the step's end velocity. The pressure solve between the last two is not
35
+ * here.
36
+ *
37
+ * One instance a cascade. {@link place} puts its window, {@link set_step} sets a step's h, dt and far
38
+ * field, and each `record_*` records into the encoder a frame-graph pass hands its callback. Each
39
+ * record serialises the step's parameters into a transient uniform of its own (pooled by the
40
+ * encoder), so a step recorded later in the frame cannot change what an earlier one reads.
41
+ *
42
+ * The step's order and what moves between the passes, A the cascade's persistent velocity:
43
+ *
44
+ * record_ghosts(encoder, parent, G) parent → G (the step's ghosts)
45
+ * record_curl(encoder, A, solid, C) A → C, the confinement force (with confinement)
46
+ * record_advect(encoder, A, F, B, solid, forcing, C, parent, G) A → F (predict), A + F + C + forcing → B (correct)
47
+ * record_divergence(encoder, B, solid, rhs, words) B → rhs = div/dt, solid → level 0 words
48
+ * (the pressure solve: rhs → pressure, its ghosts G)
49
+ * record_gradient(encoder, B, pressure, solid, A, G) B + pressure → A
50
+ *
51
+ * so A is the only velocity a cascade keeps between steps, and F and B are transients. Beyond the
52
+ * window, the advection reads the step's ghosts of the parent's faces and the gradient those of its
53
+ * pressure ({@link FluidCascadeGhostBindings}), each written once a step from the parent
54
+ * ({@link FluidCascadeParentBindings}).
55
+ *
56
+ * Every pass dispatches `(nx / 8, ny / 8, nz / 4)` workgroups, the ghosts `ceil((n + 1 + 2·depth) / 4)`
57
+ * on each axis, a texel of the largest shell an invocation. Nothing here allocates once placed:
58
+ * the parameters, bindings and dispatch arguments are retained and rewritten in place.
59
+ */
60
+ export class FluidMacPasses {
61
+ /**
62
+ * Offer the compute pipelines the MAC step passes dispatch — see {@link PipelineEnquiry}.
63
+ *
64
+ * @param {import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} enquiry
65
+ */
66
+ static enquirePipelines(enquiry) {
67
+ enquiry.compute.push(
68
+ shader_fluid_mac_advect_correct.pipeline,
69
+ shader_fluid_mac_advect_predict.pipeline,
70
+ shader_fluid_mac_curl.pipeline,
71
+ shader_fluid_mac_divergence.pipeline,
72
+ shader_fluid_mac_gradient.pipeline,
73
+ shader_fluid_cascade_ghosts.pipeline,
74
+ );
75
+ }
76
+
77
+ /** The value of {@link FLUID_MAC_STEP_STRUCT}, rewritten in place. */
78
+ #step = {
79
+ cells: fluid_cascade_window_value(),
80
+ faces_u: fluid_cascade_window_value(),
81
+ faces_v: fluid_cascade_window_value(),
82
+ faces_w: fluid_cascade_window_value(),
83
+ far_velocity: new Float32Array(3),
84
+ dt_over_h: 0,
85
+ far_velocity_end: new Float32Array(3),
86
+ rhs_scale: 0,
87
+ keep: 1,
88
+ deviation_limit: 0,
89
+ band: 0,
90
+ confinement_dt: 0,
91
+ };
92
+
93
+ #placed = false;
94
+ #stepped = false;
95
+
96
+ /** Stand-in words buffer when {@link record_divergence} is called without an explicit words buffer. */
97
+ #stand_in_device = null;
98
+ #stand_in_words = null;
99
+
100
+ #curl = {
101
+ encoder: null,
102
+ bindings: { step: null, source_u: null, source_v: null, source_w: null, solid: null, confinement: null },
103
+ group_count_x: 1, group_count_y: 1, group_count_z: 1,
104
+ };
105
+
106
+ #predict = {
107
+ encoder: null,
108
+ bindings: {
109
+ step: null, source_u: null, source_v: null, source_w: null,
110
+ ghost_u: null, ghost_v: null, ghost_w: null,
111
+ solid: null, forward_u: null, forward_v: null, forward_w: null,
112
+ },
113
+ group_count_x: 1, group_count_y: 1, group_count_z: 1,
114
+ };
115
+
116
+ #correct = {
117
+ encoder: null,
118
+ bindings: {
119
+ step: null, parent: null, source_u: null, source_v: null, source_w: null, forward_u: null, forward_v: null, forward_w: null,
120
+ parent_u: null, parent_v: null, parent_w: null, ghost_u: null, ghost_v: null, ghost_w: null,
121
+ solid: null, forcing: null, confinement: null, out_u: null, out_v: null, out_w: null,
122
+ },
123
+ group_count_x: 1, group_count_y: 1, group_count_z: 1,
124
+ };
125
+
126
+ #divergence = {
127
+ encoder: null,
128
+ bindings: { step: null, velocity_u: null, velocity_v: null, velocity_w: null, solid: null, rhs: null, words: null },
129
+ group_count_x: 1, group_count_y: 1, group_count_z: 1,
130
+ };
131
+
132
+ #ghosts = {
133
+ encoder: null,
134
+ bindings: {
135
+ step: null, parent: null, parent_u: null, parent_v: null, parent_w: null, parent_pressure: null,
136
+ ghost_u: null, ghost_v: null, ghost_w: null, ghost_pressure: null,
137
+ },
138
+ group_count_x: 1, group_count_y: 1, group_count_z: 1,
139
+ };
140
+
141
+ #gradient = {
142
+ encoder: null,
143
+ bindings: {
144
+ step: null, velocity_u: null, velocity_v: null, velocity_w: null, pressure: null, ghost_pressure: null,
145
+ solid: null, out_u: null, out_v: null, out_w: null,
146
+ },
147
+ group_count_x: 1, group_count_y: 1, group_count_z: 1,
148
+ };
149
+
150
+ /**
151
+ * Where the cascade's window is.
152
+ *
153
+ * @param {ArrayLike<number>} resolution cells on each axis, each a power of two, at least 8, 8, 4
154
+ * @param {ArrayLike<number>} corner the world cell at window-local (0, 0, 0)
155
+ */
156
+ place(resolution, corner) {
157
+ for (let i = 0; i < 3; i++) {
158
+ assert.isNonNegativeInteger(resolution[i], 'resolution');
159
+ assert.ok(isPowerOfTwo(resolution[i]), 'resolution is a power of two on each axis');
160
+ assert.greaterThanOrEqual(resolution[i], GRID_TILE_SIZE[i], 'resolution holds a whole tile on each axis');
161
+ assert.isInteger(corner[i], 'corner');
162
+ }
163
+
164
+ const step = this.#step;
165
+
166
+ fluid_cascade_window_place(step.cells, corner, resolution, -1);
167
+ fluid_cascade_window_place(step.faces_u, corner, resolution, 0);
168
+ fluid_cascade_window_place(step.faces_v, corner, resolution, 1);
169
+ fluid_cascade_window_place(step.faces_w, corner, resolution, 2);
170
+
171
+ const x = resolution[0] / GRID_TILE_SIZE[0];
172
+ const y = resolution[1] / GRID_TILE_SIZE[1];
173
+ const z = resolution[2] / GRID_TILE_SIZE[2];
174
+
175
+ for (const pass of [this.#curl, this.#predict, this.#correct, this.#divergence, this.#gradient]) {
176
+ pass.group_count_x = x;
177
+ pass.group_count_y = y;
178
+ pass.group_count_z = z;
179
+ }
180
+
181
+ // the ghosts: a texel of the largest shell an invocation
182
+ const ghosts = this.#ghosts;
183
+ ghosts.group_count_x = Math.ceil((resolution[0] + 1 + 2 * FLUID_CASCADE_GHOST_DEPTH) / 4);
184
+ ghosts.group_count_y = Math.ceil((resolution[1] + 1 + 2 * FLUID_CASCADE_GHOST_DEPTH) / 4);
185
+ ghosts.group_count_z = Math.ceil((resolution[2] + 1 + 2 * FLUID_CASCADE_GHOST_DEPTH) / 4);
186
+
187
+ this.#placed = true;
188
+ }
189
+
190
+ /**
191
+ * The step about to be recorded, from `t₀` to `t₁` (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §6, §8).
192
+ *
193
+ * @param {number} h cell size, m
194
+ * @param {number} dt time step, s
195
+ * @param {ArrayLike<number>} far_velocity `v_far(t₀)`, m/s: what the velocity the step starts from
196
+ * is a deviation from
197
+ * @param {ArrayLike<number>} far_velocity_end `v_far(t₁)`, m/s
198
+ * @param {number} keep `e^(−(Λ(t₁) − Λ(t₀)))`, in [0, 1]
199
+ * @param {boolean} band whether the faces of rows 2..5 relax toward the parent
200
+ * @param {number} confinement the vorticity confinement's strength ε, per second, ≥ 0: 0 for none,
201
+ * and then {@link record_curl} is not recorded for the step
202
+ */
203
+ set_step(h, dt, far_velocity, far_velocity_end, keep, band, confinement) {
204
+ assert.isFinite(h, 'h'); assert.greaterThan(h, 0, 'h');
205
+ assert.isFinite(dt, 'dt'); assert.greaterThan(dt, 0, 'dt');
206
+ assert.isFinite(keep, 'keep');
207
+ assert.greaterThanOrEqual(keep, 0, 'keep');
208
+ assert.lessThanOrEqual(keep, 1, 'keep');
209
+ assert.isBoolean(band, 'band');
210
+ assert.isFinite(confinement, 'confinement');
211
+ assert.greaterThanOrEqual(confinement, 0, 'confinement');
212
+
213
+ const step = this.#step;
214
+
215
+ step.dt_over_h = dt / h;
216
+ step.rhs_scale = 1 / (h * dt);
217
+ step.keep = keep;
218
+ step.deviation_limit = FLUID_CASCADE_DEVIATION_CELLS * h / dt;
219
+ step.band = band ? 1 : 0;
220
+ step.confinement_dt = confinement * dt;
221
+
222
+ for (let i = 0; i < 3; i++) {
223
+ assert.isFinite(far_velocity[i], 'far_velocity');
224
+ assert.isFinite(far_velocity_end[i], 'far_velocity_end');
225
+
226
+ step.far_velocity[i] = far_velocity[i];
227
+ step.far_velocity_end[i] = far_velocity_end[i];
228
+ }
229
+
230
+ this.#stepped = true;
231
+ }
232
+
233
+ /**
234
+ * @param {ShadeGPUCommandContext} encoder
235
+ * @returns {GPUBuffer}
236
+ */
237
+ #uniform(encoder) {
238
+ assert.ok(this.#placed, 'placed before recording');
239
+ assert.ok(this.#stepped, 'a step set before recording');
240
+
241
+ return encoder.allocateTransientValueBuffer(FLUID_MAC_STEP_STRUCT, this.#step, GPUBufferUsage.UNIFORM);
242
+ }
243
+
244
+ /**
245
+ * The step's vorticity confinement, pass 1 (`shader_fluid_mac_curl`): the curl of the persistent
246
+ * velocity and the force it makes in every cell, for the correct pass. Recorded only for a step whose
247
+ * confinement is not 0, before {@link record_advect}.
248
+ *
249
+ * @param {ShadeGPUCommandContext} encoder
250
+ * @param {FluidMacVelocityViews} source the persistent velocity, toroidal; read
251
+ * @param {GPUBuffer} solid the window-local solid flags, `array<u32>`, bit 0
252
+ * @param {GPUBuffer} confinement written, `array<f32>` of 3·N cells, window-local
253
+ */
254
+ record_curl(encoder, source, solid, confinement) {
255
+ assert.greaterThan(this.#step.confinement_dt, 0, 'a step with confinement');
256
+
257
+ const pass = this.#curl;
258
+ const b = pass.bindings;
259
+ b.step = this.#uniform(encoder);
260
+ b.source_u = source.u; b.source_v = source.v; b.source_w = source.w;
261
+ b.solid = solid;
262
+ b.confinement = confinement;
263
+ pass.encoder = encoder;
264
+
265
+ shader_fluid_mac_curl.dispatch(pass);
266
+
267
+ pass.encoder = null;
268
+ b.confinement = null;
269
+ }
270
+
271
+ /**
272
+ * MacCormack advection of the persistent velocity by itself: predict into `forward`, then correct
273
+ * into `out`, which adds the step's confinement and the tick's forcing.
274
+ *
275
+ * @param {ShadeGPUCommandContext} encoder
276
+ * @param {FluidMacVelocityViews} source the persistent velocity, toroidal; read
277
+ * @param {FluidMacVelocityViews} forward a transient, window-local; written, then read
278
+ * @param {FluidMacVelocityViews} out a transient, window-local; written
279
+ * @param {GPUBuffer} solid the window-local solid flags, `array<u32>`: bit 0 solid, bit 1
280
+ * (`FLUID_FORCED_FLAG`) forcing written for the cell's faces
281
+ * @param {GPUBuffer} forcing the tick's forcing, `array<f32>` over the three face lattices
282
+ * (`shader_fluid_mac_advect_correct`); read only where `solid` says it was written
283
+ * @param {GPUBuffer} confinement what {@link record_curl} wrote for the step; read only when the
284
+ * step's confinement is not 0
285
+ * @param {FluidCascadeParentBindings} parent what the relaxation band reads on rows 2..5
286
+ * @param {FluidCascadeGhostBindings} ghosts the step's ghosts, written by {@link record_ghosts}
287
+ */
288
+ record_advect(encoder, source, forward, out, solid, forcing, confinement, parent, ghosts) {
289
+ assert.notEqual(source, forward, 'source and forward are different sets');
290
+ assert.notEqual(source, out, 'source and out are different sets');
291
+ assert.notEqual(forward, out, 'forward and out are different sets');
292
+
293
+ const step = this.#uniform(encoder);
294
+
295
+ const predict = this.#predict;
296
+ const p = predict.bindings;
297
+ p.step = step;
298
+ p.source_u = source.u; p.source_v = source.v; p.source_w = source.w;
299
+ p.ghost_u = ghosts.u; p.ghost_v = ghosts.v; p.ghost_w = ghosts.w;
300
+ p.solid = solid;
301
+ p.forward_u = forward.u; p.forward_v = forward.v; p.forward_w = forward.w;
302
+ predict.encoder = encoder;
303
+
304
+ shader_fluid_mac_advect_predict.dispatch(predict);
305
+
306
+ const correct = this.#correct;
307
+ const c = correct.bindings;
308
+ c.step = step;
309
+ c.parent = parent.uniform;
310
+ c.source_u = source.u; c.source_v = source.v; c.source_w = source.w;
311
+ c.forward_u = forward.u; c.forward_v = forward.v; c.forward_w = forward.w;
312
+ c.parent_u = parent.u; c.parent_v = parent.v; c.parent_w = parent.w;
313
+ c.ghost_u = ghosts.u; c.ghost_v = ghosts.v; c.ghost_w = ghosts.w;
314
+ c.solid = solid;
315
+ c.forcing = forcing;
316
+ c.confinement = confinement;
317
+ c.out_u = out.u; c.out_v = out.v; c.out_w = out.w;
318
+ correct.encoder = encoder;
319
+
320
+ shader_fluid_mac_advect_correct.dispatch(correct);
321
+
322
+ predict.encoder = null;
323
+ correct.encoder = null;
324
+ c.forcing = null;
325
+ c.confinement = null;
326
+ }
327
+
328
+ /**
329
+ * The step's ghosts (`shader_fluid_cascade_ghosts`): the parent's identity read at every face of the
330
+ * velocity shells and its pressure at every cell one past the window, once, for the step's passes.
331
+ *
332
+ * @param {ShadeGPUCommandContext} encoder
333
+ * @param {FluidCascadeParentBindings} parent
334
+ * @param {FluidCascadeGhostBindings} ghosts written
335
+ */
336
+ record_ghosts(encoder, parent, ghosts) {
337
+ const pass = this.#ghosts;
338
+ const b = pass.bindings;
339
+ b.step = this.#uniform(encoder);
340
+ b.parent = parent.uniform;
341
+ b.parent_u = parent.u; b.parent_v = parent.v; b.parent_w = parent.w;
342
+ b.parent_pressure = parent.pressure;
343
+ b.ghost_u = ghosts.u; b.ghost_v = ghosts.v; b.ghost_w = ghosts.w;
344
+ b.ghost_pressure = ghosts.pressure;
345
+ pass.encoder = encoder;
346
+
347
+ shader_fluid_cascade_ghosts.dispatch(pass);
348
+
349
+ pass.encoder = null;
350
+ }
351
+
352
+ /**
353
+ * @param {GPUDevice} device
354
+ * @param {number} size
355
+ * @returns {GPUBuffer}
356
+ */
357
+ #ensure_stand_in_words(device, size) {
358
+ if (this.#stand_in_device === device && this.#stand_in_words !== null && this.#stand_in_words.size === size) {
359
+ return this.#stand_in_words;
360
+ }
361
+
362
+ this.#stand_in_words?.destroy();
363
+ this.#stand_in_device = device;
364
+ this.#stand_in_words = device.createBuffer({
365
+ label: 'Fluid / MAC / stand-in words',
366
+ size,
367
+ usage: GPUBufferUsage.STORAGE,
368
+ });
369
+
370
+ return this.#stand_in_words;
371
+ }
372
+
373
+ /**
374
+ * The right-hand side and finest-level weight words of the pressure solve, `div/dt` at every cell,
375
+ * 0 in solid cells.
376
+ *
377
+ * @param {ShadeGPUCommandContext} encoder
378
+ * @param {FluidMacVelocityViews} velocity the advected velocity, window-local; read
379
+ * @param {GPUBuffer} solid the window-local solid flags, `array<u32>`, bit 0
380
+ * @param {GPUBuffer} rhs written, `array<f32>` of N cells, window-local, x fastest
381
+ * @param {GPUBuffer} [words] written, `array<u32>` of N cells, the finest level's weight words
382
+ */
383
+ record_divergence(encoder, velocity, solid, rhs, words = null) {
384
+ const pass = this.#divergence;
385
+ const b = pass.bindings;
386
+ b.step = this.#uniform(encoder);
387
+ b.velocity_u = velocity.u; b.velocity_v = velocity.v; b.velocity_w = velocity.w;
388
+ b.solid = solid;
389
+ b.rhs = rhs;
390
+ b.words = words ?? this.#ensure_stand_in_words(encoder.device, rhs.size);
391
+ pass.encoder = encoder;
392
+
393
+ shader_fluid_mac_divergence.dispatch(pass);
394
+
395
+ pass.encoder = null;
396
+ b.words = null;
397
+ }
398
+
399
+ /**
400
+ * The pressure gradient taken from the advected velocity, into the persistent velocity.
401
+ *
402
+ * @param {ShadeGPUCommandContext} encoder
403
+ * @param {FluidMacVelocityViews} velocity the advected velocity, window-local; read
404
+ * @param {GPUBuffer} pressure kinematic pressure, m²/s², `array<f32>` of N cells, toroidal; read
405
+ * @param {GPUBuffer} solid the window-local solid flags, `array<u32>`, bit 0
406
+ * @param {FluidMacVelocityViews} out the persistent velocity, toroidal; written
407
+ * @param {FluidCascadeGhostBindings} ghosts the step's ghosts: `pressure` is the pressure beyond the window
408
+ */
409
+ record_gradient(encoder, velocity, pressure, solid, out, ghosts) {
410
+ assert.notEqual(velocity, out, 'velocity and out are different sets');
411
+ assert.notEqual(pressure, ghosts.pressure, 'the ghosts are not the cascade\'s pressure');
412
+
413
+ const pass = this.#gradient;
414
+ const b = pass.bindings;
415
+ b.step = this.#uniform(encoder);
416
+ b.velocity_u = velocity.u; b.velocity_v = velocity.v; b.velocity_w = velocity.w;
417
+ b.pressure = pressure;
418
+ b.ghost_pressure = ghosts.pressure;
419
+ b.solid = solid;
420
+ b.out_u = out.u; b.out_v = out.v; b.out_w = out.w;
421
+ pass.encoder = encoder;
422
+
423
+ shader_fluid_mac_gradient.dispatch(pass);
424
+
425
+ pass.encoder = null;
426
+ }
427
+ }