@woosh/meep-engine 2.156.0 → 2.158.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 (695) hide show
  1. package/README.md +1 -3
  2. package/editor/view/ecs/components/common/AutoCanvasView.js +100 -53
  3. package/editor/view/ecs/components/common/TextController.js +59 -0
  4. package/editor/view/node-graph/NodeGraphCamera.js +90 -0
  5. package/editor/view/node-graph/NodeGraphEditorView.js +121 -22
  6. package/editor/view/node-graph/NodeGraphSelection.js +89 -0
  7. package/editor/view/node-graph/NodeGraphView.js +669 -453
  8. package/editor/view/node-graph/NodeView.js +211 -135
  9. package/editor/view/node-graph/actions/ConnectionCreateAction.js +53 -0
  10. package/editor/view/node-graph/actions/ConnectionDeleteAction.js +36 -0
  11. package/editor/view/node-graph/actions/NodeDeleteAction.js +88 -0
  12. package/editor/view/node-graph/actions/NodeParameterSetAction.js +52 -0
  13. package/editor/view/node-graph/actions/NodesMoveAction.js +41 -0
  14. package/editor/view/node-graph/actions/SelectionSetAction.js +60 -0
  15. package/editor/view/node-graph/connection_wire_geometry.js +107 -0
  16. package/package.json +1 -1
  17. package/samples/generation/SampleGenerator0.js +8 -1
  18. package/src/core/binary/reinterpret_float32_as_uint32.d.ts +7 -0
  19. package/src/core/binary/reinterpret_float32_as_uint32.d.ts.map +1 -0
  20. package/src/core/binary/reinterpret_float32_as_uint32.js +13 -0
  21. package/src/core/binary/reinterpret_uint32_as_float32.d.ts +7 -0
  22. package/src/core/binary/reinterpret_uint32_as_float32.d.ts.map +1 -0
  23. package/src/core/binary/reinterpret_uint32_as_float32.js +14 -0
  24. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_incremental.d.ts.map +1 -1
  25. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_incremental.js +1 -3
  26. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.d.ts +12 -0
  27. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.d.ts.map +1 -0
  28. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.js +92 -0
  29. package/src/core/bvh8/BVH8.d.ts +127 -0
  30. package/src/core/bvh8/BVH8.d.ts.map +1 -0
  31. package/src/core/bvh8/BVH8.js +436 -0
  32. package/src/core/bvh8/NOTES.md +63 -0
  33. package/src/core/bvh8/build/BVH8Converter.d.ts +59 -0
  34. package/src/core/bvh8/build/BVH8Converter.d.ts.map +1 -0
  35. package/src/core/bvh8/build/BVH8Converter.js +588 -0
  36. package/src/core/bvh8/build/NodeProxy.d.ts +66 -0
  37. package/src/core/bvh8/build/NodeProxy.d.ts.map +1 -0
  38. package/src/core/bvh8/build/NodeProxy.js +308 -0
  39. package/src/core/bvh8/build/TriangleCluster.d.ts +29 -0
  40. package/src/core/bvh8/build/TriangleCluster.d.ts.map +1 -0
  41. package/src/core/bvh8/build/TriangleCluster.js +123 -0
  42. package/src/core/bvh8/build/aabb3_compute_merge_cost.d.ts +8 -0
  43. package/src/core/bvh8/build/aabb3_compute_merge_cost.d.ts.map +1 -0
  44. package/src/core/bvh8/build/aabb3_compute_merge_cost.js +29 -0
  45. package/src/core/bvh8/build/aabb3_from_triangle_by_index.d.ts +10 -0
  46. package/src/core/bvh8/build/aabb3_from_triangle_by_index.d.ts.map +1 -0
  47. package/src/core/bvh8/build/aabb3_from_triangle_by_index.js +18 -0
  48. package/src/core/bvh8/build/bvh8_build_for_geometry.d.ts +10 -0
  49. package/src/core/bvh8/build/bvh8_build_for_geometry.d.ts.map +1 -0
  50. package/src/core/bvh8/build/bvh8_build_for_geometry.js +303 -0
  51. package/src/core/bvh8/build/bvh8_from_proxy.d.ts +9 -0
  52. package/src/core/bvh8/build/bvh8_from_proxy.d.ts.map +1 -0
  53. package/src/core/bvh8/build/bvh8_from_proxy.js +256 -0
  54. package/src/core/bvh8/build/byte.d.ts +7 -0
  55. package/src/core/bvh8/build/byte.d.ts.map +1 -0
  56. package/src/core/bvh8/build/byte.js +10 -0
  57. package/src/core/bvh8/build/encode_bounds_e.d.ts +9 -0
  58. package/src/core/bvh8/build/encode_bounds_e.d.ts.map +1 -0
  59. package/src/core/bvh8/build/encode_bounds_e.js +12 -0
  60. package/src/core/bvh8/bvh8_convert_to_dot.d.ts +11 -0
  61. package/src/core/bvh8/bvh8_convert_to_dot.d.ts.map +1 -0
  62. package/src/core/bvh8/bvh8_convert_to_dot.js +133 -0
  63. package/src/core/bvh8/bvh8_count_primitives.d.ts +22 -0
  64. package/src/core/bvh8/bvh8_count_primitives.d.ts.map +1 -0
  65. package/src/core/bvh8/bvh8_count_primitives.js +98 -0
  66. package/src/core/bvh8/bvh8_geometry_validate.d.ts +16 -0
  67. package/src/core/bvh8/bvh8_geometry_validate.d.ts.map +1 -0
  68. package/src/core/bvh8/bvh8_geometry_validate.js +149 -0
  69. package/src/core/bvh8/bvh8_geometry_validate_indirect.d.ts +16 -0
  70. package/src/core/bvh8/bvh8_geometry_validate_indirect.d.ts.map +1 -0
  71. package/src/core/bvh8/bvh8_geometry_validate_indirect.js +177 -0
  72. package/src/core/bvh8/bvh8_get_node_bounds.d.ts +9 -0
  73. package/src/core/bvh8/bvh8_get_node_bounds.d.ts.map +1 -0
  74. package/src/core/bvh8/bvh8_get_node_bounds.js +35 -0
  75. package/src/core/bvh8/bvh8_get_node_child_bounds.d.ts +10 -0
  76. package/src/core/bvh8/bvh8_get_node_child_bounds.d.ts.map +1 -0
  77. package/src/core/bvh8/bvh8_get_node_child_bounds.js +53 -0
  78. package/src/core/bvh8/bvh8_node_child_surface_area.d.ts +9 -0
  79. package/src/core/bvh8/bvh8_node_child_surface_area.d.ts.map +1 -0
  80. package/src/core/bvh8/bvh8_node_child_surface_area.js +18 -0
  81. package/src/core/bvh8/bvh8_node_count_triangles.d.ts +8 -0
  82. package/src/core/bvh8/bvh8_node_count_triangles.d.ts.map +1 -0
  83. package/src/core/bvh8/bvh8_node_count_triangles.js +28 -0
  84. package/src/core/bvh8/bvh8_quality.d.ts +8 -0
  85. package/src/core/bvh8/bvh8_quality.d.ts.map +1 -0
  86. package/src/core/bvh8/bvh8_quality.js +73 -0
  87. package/src/core/bvh8/bvh8_validate_structure.d.ts +15 -0
  88. package/src/core/bvh8/bvh8_validate_structure.d.ts.map +1 -0
  89. package/src/core/bvh8/bvh8_validate_structure.js +87 -0
  90. package/src/core/collection/Uint32MinHeap.d.ts +56 -0
  91. package/src/core/collection/Uint32MinHeap.d.ts.map +1 -0
  92. package/src/core/collection/Uint32MinHeap.js +109 -0
  93. package/src/core/collection/list/FilteredListProjection.js +1 -1
  94. package/src/{engine/physics/island → core/collection/union-find}/union_find.d.ts +8 -5
  95. package/src/core/collection/union-find/union_find.d.ts.map +1 -0
  96. package/src/{engine/physics/island → core/collection/union-find}/union_find.js +8 -5
  97. package/src/core/dom/isImageBitmap.d.ts +7 -0
  98. package/src/core/dom/isImageBitmap.d.ts.map +1 -0
  99. package/src/core/dom/isImageBitmap.js +12 -0
  100. package/src/core/function/frameThrottle.d.ts +8 -0
  101. package/src/core/function/frameThrottle.d.ts.map +1 -0
  102. package/src/core/function/frameThrottle.js +23 -0
  103. package/src/{engine/physics/narrowphase/clip_against_axis_uv.d.ts → core/geom/2d/polygon/polygon2_clip_axis_halfplane.d.ts} +3 -3
  104. package/src/core/geom/2d/polygon/polygon2_clip_axis_halfplane.d.ts.map +1 -0
  105. package/src/{engine/physics/narrowphase/clip_against_axis_uv.js → core/geom/2d/polygon/polygon2_clip_axis_halfplane.js} +51 -51
  106. package/src/{engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts → core/geom/3d/aabb/aabb3_transform_oriented_inverse.d.ts} +9 -7
  107. package/src/core/geom/3d/aabb/aabb3_transform_oriented_inverse.d.ts.map +1 -0
  108. package/src/{engine/physics/narrowphase/decomposition/aabb_world_to_local.js → core/geom/3d/aabb/aabb3_transform_oriented_inverse.js} +9 -7
  109. package/src/core/geom/3d/aabb/compute_triangle_group_aabb3.d.ts +12 -0
  110. package/src/core/geom/3d/aabb/compute_triangle_group_aabb3.d.ts.map +1 -0
  111. package/src/core/geom/3d/aabb/compute_triangle_group_aabb3.js +46 -0
  112. package/src/core/geom/3d/box/box3_projected_half_extent.d.ts +28 -0
  113. package/src/core/geom/3d/box/box3_projected_half_extent.d.ts.map +1 -0
  114. package/src/core/geom/3d/box/box3_projected_half_extent.js +35 -0
  115. package/src/core/geom/3d/frustum/read_cluster_frustum_corners.js +1 -1
  116. package/src/core/geom/3d/frustum/read_frustum_corner.d.ts +9 -0
  117. package/src/core/geom/3d/frustum/read_frustum_corner.d.ts.map +1 -0
  118. package/src/core/geom/3d/frustum/read_frustum_corner.js +14 -0
  119. package/src/core/geom/3d/gjk/gjk.d.ts.map +1 -0
  120. package/src/{engine/physics → core/geom/3d}/gjk/gjk.js +430 -372
  121. package/src/{engine/physics → core/geom/3d}/gjk/gjk_epa_penetration.d.ts +8 -5
  122. package/src/core/geom/3d/gjk/gjk_epa_penetration.d.ts.map +1 -0
  123. package/src/{engine/physics → core/geom/3d}/gjk/gjk_epa_penetration.js +520 -544
  124. package/src/{engine/physics → core/geom/3d}/gjk/minkowski_support.d.ts +5 -4
  125. package/src/core/geom/3d/gjk/minkowski_support.d.ts.map +1 -0
  126. package/src/{engine/physics → core/geom/3d}/gjk/minkowski_support.js +71 -70
  127. package/src/{engine/physics → core/geom/3d}/gjk/mpr.d.ts +3 -3
  128. package/src/core/geom/3d/gjk/mpr.d.ts.map +1 -0
  129. package/src/{engine/physics → core/geom/3d}/gjk/mpr.js +368 -362
  130. package/src/{engine/physics/integration/quat_integrate.d.ts → core/geom/3d/quaternion/quat3_integrate.d.ts} +2 -2
  131. package/src/core/geom/3d/quaternion/quat3_integrate.d.ts.map +1 -0
  132. package/src/{engine/physics/integration/quat_integrate.js → core/geom/3d/quaternion/quat3_integrate.js} +1 -1
  133. package/src/{engine/physics/narrowphase/PosedShape.d.ts → core/geom/3d/shape/PosedShape3D.d.ts} +26 -8
  134. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -0
  135. package/src/{engine/physics/narrowphase/PosedShape.js → core/geom/3d/shape/PosedShape3D.js} +60 -9
  136. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  137. package/src/core/geom/3d/shape/TransformedShape3D.js +15 -11
  138. package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts +1 -1
  139. package/src/core/geom/vec3/v3_quat3_apply_inverse.js +1 -1
  140. package/src/core/math/complex/complex_add.d.ts +1 -1
  141. package/src/core/math/complex/complex_add.d.ts.map +1 -1
  142. package/src/core/math/complex/complex_add.js +12 -3
  143. package/src/core/math/complex/complex_div.d.ts +1 -1
  144. package/src/core/math/complex/complex_div.d.ts.map +1 -1
  145. package/src/core/math/complex/complex_div.js +11 -4
  146. package/src/core/math/complex/complex_mul.d.ts +1 -1
  147. package/src/core/math/complex/complex_mul.d.ts.map +1 -1
  148. package/src/core/math/complex/complex_mul.js +10 -3
  149. package/src/core/math/complex/complex_sub.d.ts +1 -1
  150. package/src/core/math/complex/complex_sub.d.ts.map +1 -1
  151. package/src/core/math/complex/complex_sub.js +12 -3
  152. package/src/{engine/physics/fluid/solver/optimal_sor_omega.d.ts → core/math/linalg/sor_optimal_omega.d.ts} +4 -3
  153. package/src/core/math/linalg/sor_optimal_omega.d.ts.map +1 -0
  154. package/src/{engine/physics/fluid/solver/optimal_sor_omega.js → core/math/linalg/sor_optimal_omega.js} +4 -3
  155. package/src/core/math/lookup/ParameterLookupTable.d.ts +123 -0
  156. package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -0
  157. package/src/core/math/lookup/ParameterLookupTable.js +495 -0
  158. package/src/core/math/lookup/ParameterLookupTableFlags.d.ts +5 -0
  159. package/src/core/math/lookup/ParameterLookupTableFlags.d.ts.map +1 -0
  160. package/src/core/math/lookup/ParameterLookupTableFlags.js +6 -0
  161. package/src/core/math/physics/kinematics/computeInterceptPoint.d.ts.map +1 -0
  162. package/src/{engine/physics → core/math/physics/kinematics}/computeInterceptPoint.js +79 -79
  163. package/src/core/math/physics/mie/ri_air.d.ts.map +1 -1
  164. package/src/core/math/physics/mie/ri_air.js +1 -3
  165. package/src/core/math/physics/mie/ri_ammonium_sulfate.d.ts.map +1 -1
  166. package/src/core/math/physics/mie/ri_ammonium_sulfate.js +1 -3
  167. package/src/core/math/physics/mie/ri_brine.d.ts.map +1 -1
  168. package/src/core/math/physics/mie/ri_brine.js +1 -3
  169. package/src/core/math/physics/mie/ri_dust.d.ts.map +1 -1
  170. package/src/core/math/physics/mie/ri_dust.js +1 -3
  171. package/src/core/math/physics/mie/ri_pollen.d.ts.map +1 -1
  172. package/src/core/math/physics/mie/ri_pollen.js +1 -3
  173. package/src/core/math/physics/mie/ri_smoke.d.ts.map +1 -1
  174. package/src/core/math/physics/mie/ri_smoke.js +1 -3
  175. package/src/core/math/physics/mie/ri_soot.d.ts.map +1 -1
  176. package/src/core/math/physics/mie/ri_soot.js +1 -3
  177. package/src/core/math/physics/mie/ri_water.d.ts.map +1 -1
  178. package/src/core/math/physics/mie/ri_water.js +1 -3
  179. package/src/core/math/random/random_pick_weighted_index.d.ts +10 -0
  180. package/src/core/math/random/random_pick_weighted_index.d.ts.map +1 -0
  181. package/src/core/math/random/random_pick_weighted_index.js +26 -0
  182. package/src/core/model/node-graph/NodeGraph.d.ts +9 -0
  183. package/src/core/model/node-graph/NodeGraph.d.ts.map +1 -1
  184. package/src/core/model/node-graph/NodeGraph.js +38 -0
  185. package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts +23 -0
  186. package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts.map +1 -1
  187. package/src/core/model/node-graph/visual/NodeGraphVisualData.js +54 -0
  188. package/src/core/path/convertPathToURL.d.ts +9 -0
  189. package/src/core/path/convertPathToURL.d.ts.map +1 -0
  190. package/src/core/path/convertPathToURL.js +107 -0
  191. package/src/core/process/worker/WorkerBuilder.js +1 -1
  192. package/src/core/process/worker/extractTransferables.js +1 -1
  193. package/src/engine/animation/curve/draw/build_tangent_editor.d.ts.map +1 -1
  194. package/src/engine/animation/curve/draw/build_tangent_editor.js +8 -1
  195. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts.map +1 -1
  196. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.js +11 -5
  197. package/src/engine/asset/Asset.d.ts.map +1 -1
  198. package/src/engine/asset/Asset.js +16 -6
  199. package/src/engine/asset/AssetManager.d.ts +61 -52
  200. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  201. package/src/engine/asset/AssetManager.js +1411 -1045
  202. package/src/engine/asset/AssetRequest.d.ts +1 -1
  203. package/src/engine/asset/AssetRequest.d.ts.map +1 -1
  204. package/src/engine/asset/AssetRequest.js +1 -1
  205. package/src/engine/asset/AssetRequestScope.d.ts.map +1 -1
  206. package/src/engine/asset/AssetRequestScope.js +7 -0
  207. package/src/engine/asset/PendingAsset.d.ts +32 -1
  208. package/src/engine/asset/PendingAsset.d.ts.map +1 -1
  209. package/src/engine/asset/PendingAsset.js +108 -61
  210. package/src/engine/asset/loaders/ArrayBufferLoader.js +2 -2
  211. package/src/engine/asset/loaders/AssetLoader.d.ts.map +1 -1
  212. package/src/engine/asset/loaders/AssetLoader.js +19 -2
  213. package/src/engine/asset/loaders/GLTFAssetLoader.d.ts.map +1 -1
  214. package/src/engine/asset/loaders/GLTFAssetLoader.js +123 -114
  215. package/src/engine/asset/loaders/JavascriptAssetLoader.d.ts +1 -1
  216. package/src/engine/asset/loaders/JavascriptAssetLoader.d.ts.map +1 -1
  217. package/src/engine/asset/loaders/JavascriptAssetLoader.js +31 -47
  218. package/src/engine/asset/loaders/JsonAssetLoader.js +1 -1
  219. package/src/engine/asset/loaders/SVGAssetLoader.js +2 -2
  220. package/src/engine/asset/loaders/SoundAssetLoader.js +1 -1
  221. package/src/engine/asset/loaders/TextAssetLoader.js +2 -2
  222. package/src/{core → engine/asset/loaders}/font/FontAsset.d.ts +1 -1
  223. package/src/engine/asset/loaders/font/FontAsset.d.ts.map +1 -0
  224. package/src/{core → engine/asset/loaders}/font/FontAsset.js +21 -21
  225. package/src/{core → engine/asset/loaders}/font/FontAssetLoader.d.ts +1 -1
  226. package/src/engine/asset/loaders/font/FontAssetLoader.d.ts.map +1 -0
  227. package/src/{core → engine/asset/loaders}/font/FontAssetLoader.js +20 -20
  228. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +1 -1
  229. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
  230. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +11 -20
  231. package/src/engine/asset/loaders/texture/TextureAssetLoader.d.ts.map +1 -1
  232. package/src/engine/asset/loaders/texture/TextureAssetLoader.js +8 -2
  233. package/src/engine/asset/preloader/AssetPreloader.js +1 -1
  234. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts +1 -1
  235. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts.map +1 -1
  236. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.js +19 -22
  237. package/src/engine/graphics/FrameThrottle.d.ts +1 -7
  238. package/src/engine/graphics/FrameThrottle.d.ts.map +1 -1
  239. package/src/engine/graphics/FrameThrottle.js +2 -24
  240. package/src/{core/geom/3d/shape/util → engine/graphics/debug}/shape_to_visual_entity.d.ts +1 -1
  241. package/src/engine/graphics/debug/shape_to_visual_entity.d.ts.map +1 -0
  242. package/src/{core/geom/3d/shape/util → engine/graphics/debug}/shape_to_visual_entity.js +159 -159
  243. package/src/{core/geom/3d/tetrahedra → engine/graphics/debug}/visualize_tetrahedral_mesh.d.ts +1 -1
  244. package/src/engine/graphics/debug/visualize_tetrahedral_mesh.d.ts.map +1 -0
  245. package/src/{core/geom/3d/tetrahedra → engine/graphics/debug}/visualize_tetrahedral_mesh.js +46 -46
  246. package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.d.ts +1 -1
  247. package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.d.ts.map +1 -1
  248. package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.js +22 -32
  249. package/src/engine/graphics/ecs/trail2d/Trail2D.d.ts.map +1 -1
  250. package/src/engine/graphics/ecs/trail2d/Trail2D.js +21 -0
  251. package/src/engine/graphics/ecs/trail2d/Trail2DFlags.d.ts +1 -0
  252. package/src/engine/graphics/ecs/trail2d/Trail2DFlags.js +9 -1
  253. package/src/engine/graphics/particles/particular/engine/emitter/serde/ParameterLookupTableSerializationAdapter.d.ts.map +1 -1
  254. package/src/engine/graphics/particles/particular/engine/emitter/serde/ParameterLookupTableSerializationAdapter.js +2 -76
  255. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.d.ts.map +1 -1
  256. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +2 -427
  257. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTableFlags.d.ts +1 -4
  258. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTableFlags.d.ts.map +1 -1
  259. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTableFlags.js +2 -6
  260. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
  261. package/src/engine/graphics/render/forward_plus/read_frustum_corner.d.ts +1 -8
  262. package/src/engine/graphics/render/forward_plus/read_frustum_corner.d.ts.map +1 -1
  263. package/src/engine/graphics/render/forward_plus/read_frustum_corner.js +2 -14
  264. package/src/engine/graphics/sh3/path_tracer/geometry/compute_triangle_group_aabb3.d.ts +1 -11
  265. package/src/engine/graphics/sh3/path_tracer/geometry/compute_triangle_group_aabb3.d.ts.map +1 -1
  266. package/src/engine/graphics/sh3/path_tracer/geometry/compute_triangle_group_aabb3.js +2 -46
  267. package/src/engine/graphics/sh3/prototypeSH3Probe.js +1 -1
  268. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts +27 -0
  269. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts.map +1 -0
  270. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +81 -0
  271. package/src/engine/graphics/texture/isImageBitmap.d.ts +1 -6
  272. package/src/engine/graphics/texture/isImageBitmap.d.ts.map +1 -1
  273. package/src/engine/graphics/texture/isImageBitmap.js +2 -12
  274. package/src/{core/process/action → engine/intelligence/behavior/util}/AsynchronousDelayAction.d.ts +2 -2
  275. package/src/engine/intelligence/behavior/util/AsynchronousDelayAction.d.ts.map +1 -0
  276. package/src/{core/process/action → engine/intelligence/behavior/util}/AsynchronousDelayAction.js +55 -55
  277. package/src/engine/network/NetworkSession.d.ts +12 -1
  278. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  279. package/src/engine/network/NetworkSession.js +52 -1
  280. package/src/engine/network/README.md +45 -0
  281. package/src/engine/network/convertPathToURL.d.ts +1 -8
  282. package/src/engine/network/convertPathToURL.d.ts.map +1 -1
  283. package/src/engine/network/convertPathToURL.js +2 -107
  284. package/src/engine/network/core/quantize/quantize_float.d.ts.map +1 -1
  285. package/src/engine/network/core/quantize/quantize_float.js +7 -0
  286. package/src/engine/network/core/quantize/quantize_position.d.ts.map +1 -1
  287. package/src/engine/network/core/quantize/quantize_position.js +12 -1
  288. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  289. package/src/engine/network/orchestrator/NetworkPeer.js +15 -1
  290. package/src/engine/network/replication/Replicator.d.ts +8 -0
  291. package/src/engine/network/replication/Replicator.d.ts.map +1 -1
  292. package/src/engine/network/replication/Replicator.js +48 -0
  293. package/src/engine/network/transport/Channel.d.ts.map +1 -1
  294. package/src/engine/network/transport/Channel.js +46 -12
  295. package/src/engine/network/transport/ReliableCommandPipeline.d.ts +16 -0
  296. package/src/engine/network/transport/ReliableCommandPipeline.d.ts.map +1 -1
  297. package/src/engine/network/transport/ReliableCommandPipeline.js +29 -0
  298. package/src/engine/network/transport/adapters/NodeUDPTransport.d.ts.map +1 -1
  299. package/src/engine/network/transport/adapters/NodeUDPTransport.js +7 -1
  300. package/src/engine/network/transport/fragments/packet_size.d.ts +5 -5
  301. package/src/engine/network/transport/fragments/packet_size.d.ts.map +1 -1
  302. package/src/engine/network/transport/fragments/packet_size.js +5 -5
  303. package/src/engine/physics/BULLET_REVIEW.md +1 -1
  304. package/src/engine/physics/JOLT_REVIEW.md +2 -2
  305. package/src/engine/physics/PLAN.md +1094 -945
  306. package/src/engine/physics/RAPIER_REVIEW.md +2 -2
  307. package/src/engine/physics/body/BodyStorage.d.ts +2 -12
  308. package/src/engine/physics/body/BodyStorage.d.ts.map +1 -1
  309. package/src/engine/physics/body/BodyStorage.js +406 -452
  310. package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -1
  311. package/src/engine/physics/body/SolverBodyState.js +12 -3
  312. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +28 -3
  313. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -1
  314. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +60 -24
  315. package/src/engine/physics/broadphase/generate_pairs.d.ts +9 -5
  316. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
  317. package/src/engine/physics/broadphase/generate_pairs.js +52 -37
  318. package/src/engine/physics/ccd/linear_sweep.d.ts +15 -5
  319. package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
  320. package/src/engine/physics/ccd/linear_sweep.js +122 -40
  321. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  322. package/src/engine/physics/constraint/solve_constraints.js +830 -805
  323. package/src/engine/physics/contact/ManifoldStore.d.ts +91 -16
  324. package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
  325. package/src/engine/physics/contact/ManifoldStore.js +204 -60
  326. package/src/engine/physics/ecs/BodyKind.d.ts +7 -3
  327. package/src/engine/physics/ecs/BodyKind.d.ts.map +1 -1
  328. package/src/engine/physics/ecs/BodyKind.js +29 -25
  329. package/src/engine/physics/ecs/Collider.d.ts +7 -0
  330. package/src/engine/physics/ecs/Collider.d.ts.map +1 -1
  331. package/src/engine/physics/ecs/Collider.js +7 -0
  332. package/src/engine/physics/ecs/ColliderSerializationAdapter.js +1 -1
  333. package/src/engine/physics/ecs/PhysicsSystem.d.ts +110 -6
  334. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  335. package/src/engine/physics/ecs/PhysicsSystem.js +467 -45
  336. package/src/engine/physics/ecs/RigidBody.d.ts +20 -5
  337. package/src/engine/physics/ecs/RigidBody.d.ts.map +1 -1
  338. package/src/engine/physics/ecs/RigidBody.js +307 -286
  339. package/src/engine/physics/ecs/RigidBodyFlags.d.ts +6 -3
  340. package/src/engine/physics/ecs/RigidBodyFlags.d.ts.map +1 -1
  341. package/src/engine/physics/ecs/RigidBodyFlags.js +31 -28
  342. package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts +12 -4
  343. package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts.map +1 -1
  344. package/src/engine/physics/ecs/RigidBodySerializationAdapter.js +19 -5
  345. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.d.ts +10 -0
  346. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.d.ts.map +1 -0
  347. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.js +37 -0
  348. package/src/engine/physics/ecs/find_non_finite_physics_state.d.ts +28 -0
  349. package/src/engine/physics/ecs/find_non_finite_physics_state.d.ts.map +1 -0
  350. package/src/engine/physics/ecs/find_non_finite_physics_state.js +76 -0
  351. package/src/engine/physics/events/ContactEventBuffer.d.ts +11 -0
  352. package/src/engine/physics/events/ContactEventBuffer.d.ts.map +1 -1
  353. package/src/engine/physics/events/ContactEventBuffer.js +40 -0
  354. package/src/engine/physics/events/diff_manifolds.d.ts +30 -13
  355. package/src/engine/physics/events/diff_manifolds.d.ts.map +1 -1
  356. package/src/engine/physics/events/diff_manifolds.js +87 -50
  357. package/src/engine/physics/fluid/FluidField.d.ts +98 -26
  358. package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
  359. package/src/engine/physics/fluid/FluidField.js +684 -570
  360. package/src/engine/physics/fluid/FluidSimulator.d.ts +157 -6
  361. package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
  362. package/src/engine/physics/fluid/FluidSimulator.js +450 -83
  363. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +243 -0
  364. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +4 -3
  365. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts.map +1 -1
  366. package/src/engine/physics/fluid/ecs/FluidComponent.js +4 -3
  367. package/src/engine/physics/fluid/ecs/FluidObstacle.d.ts +72 -0
  368. package/src/engine/physics/fluid/ecs/FluidObstacle.d.ts.map +1 -0
  369. package/src/engine/physics/fluid/ecs/FluidObstacle.js +97 -0
  370. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +117 -0
  371. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts.map +1 -0
  372. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +348 -0
  373. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +3 -3
  374. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts +62 -12
  375. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
  376. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +135 -38
  377. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts.map +1 -1
  378. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +85 -38
  379. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts +27 -8
  380. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
  381. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +171 -68
  382. package/src/engine/physics/fluid/prototype.js +25 -1
  383. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.d.ts +42 -0
  384. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.d.ts.map +1 -0
  385. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.js +136 -0
  386. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.d.ts +37 -0
  387. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.d.ts.map +1 -0
  388. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +169 -0
  389. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.d.ts +36 -0
  390. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.d.ts.map +1 -0
  391. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +100 -0
  392. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts +6 -0
  393. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts.map +1 -1
  394. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.js +6 -0
  395. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts +7 -2
  396. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts.map +1 -1
  397. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.js +17 -12
  398. package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.d.ts +42 -0
  399. package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.d.ts.map +1 -0
  400. package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.js +131 -0
  401. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts +32 -22
  402. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts.map +1 -1
  403. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +43 -26
  404. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.d.ts +31 -0
  405. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.d.ts.map +1 -0
  406. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.js +77 -0
  407. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts +30 -0
  408. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts.map +1 -0
  409. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js +92 -0
  410. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts +26 -19
  411. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts.map +1 -1
  412. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +46 -42
  413. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts +38 -10
  414. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts.map +1 -1
  415. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +158 -75
  416. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +22 -17
  417. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -1
  418. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +108 -96
  419. package/src/engine/physics/fluid/solver/v3_mac_advect_maccormack_velocity.d.ts +42 -0
  420. package/src/engine/physics/fluid/solver/v3_mac_advect_maccormack_velocity.d.ts.map +1 -0
  421. package/src/engine/physics/fluid/solver/v3_mac_advect_maccormack_velocity.js +319 -0
  422. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.d.ts +53 -0
  423. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.d.ts.map +1 -0
  424. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.js +236 -0
  425. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.d.ts +46 -0
  426. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.d.ts.map +1 -0
  427. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.js +217 -0
  428. package/src/engine/physics/fluid/solver/v3_mac_apply_vorticity_confinement.d.ts +40 -0
  429. package/src/engine/physics/fluid/solver/v3_mac_apply_vorticity_confinement.d.ts.map +1 -0
  430. package/src/engine/physics/fluid/solver/v3_mac_apply_vorticity_confinement.js +165 -0
  431. package/src/engine/physics/fluid/solver/v3_mac_clip_trace.d.ts +44 -0
  432. package/src/engine/physics/fluid/solver/v3_mac_clip_trace.d.ts.map +1 -0
  433. package/src/engine/physics/fluid/solver/v3_mac_clip_trace.js +95 -0
  434. package/src/engine/physics/fluid/solver/v3_mac_compute_divergence.d.ts +38 -0
  435. package/src/engine/physics/fluid/solver/v3_mac_compute_divergence.d.ts.map +1 -0
  436. package/src/engine/physics/fluid/solver/v3_mac_compute_divergence.js +77 -0
  437. package/src/engine/physics/fluid/solver/v3_mac_compute_face_solid.d.ts +52 -0
  438. package/src/engine/physics/fluid/solver/v3_mac_compute_face_solid.d.ts.map +1 -0
  439. package/src/engine/physics/fluid/solver/v3_mac_compute_face_solid.js +131 -0
  440. package/src/engine/physics/fluid/solver/v3_mac_subtract_pressure_gradient.d.ts +38 -0
  441. package/src/engine/physics/fluid/solver/v3_mac_subtract_pressure_gradient.d.ts.map +1 -0
  442. package/src/engine/physics/fluid/solver/v3_mac_subtract_pressure_gradient.js +104 -0
  443. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +30 -1
  444. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
  445. package/src/engine/physics/inertia/world_inverse_inertia.js +160 -116
  446. package/src/engine/physics/integration/integrate_position.js +97 -97
  447. package/src/engine/physics/island/IslandBuilder.d.ts +49 -8
  448. package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -1
  449. package/src/engine/physics/island/IslandBuilder.js +93 -14
  450. package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
  451. package/src/engine/physics/narrowphase/box_box_manifold.js +683 -673
  452. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -1
  453. package/src/engine/physics/narrowphase/box_triangle_contact.js +899 -749
  454. package/src/engine/physics/narrowphase/capsule_contacts.d.ts +27 -0
  455. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
  456. package/src/engine/physics/narrowphase/capsule_contacts.js +624 -459
  457. package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts.map +1 -1
  458. package/src/engine/physics/narrowphase/capsule_triangle_contact.js +58 -38
  459. package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -1
  460. package/src/engine/physics/narrowphase/compute_penetration.js +369 -325
  461. package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts +3 -1
  462. package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts.map +1 -1
  463. package/src/engine/physics/narrowphase/convex_convex_manifold.js +568 -422
  464. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts +6 -3
  465. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts.map +1 -1
  466. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.js +66 -10
  467. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts +4 -1
  468. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -1
  469. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +97 -94
  470. package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +117 -117
  471. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  472. package/src/engine/physics/narrowphase/narrowphase_step.js +1738 -1739
  473. package/src/engine/physics/narrowphase/reduce_manifold_contacts.d.ts +14 -7
  474. package/src/engine/physics/narrowphase/reduce_manifold_contacts.d.ts.map +1 -1
  475. package/src/engine/physics/narrowphase/reduce_manifold_contacts.js +74 -69
  476. package/src/engine/physics/persistence/solver_caches.d.ts +20 -0
  477. package/src/engine/physics/persistence/solver_caches.d.ts.map +1 -0
  478. package/src/engine/physics/persistence/solver_caches.js +309 -0
  479. package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -1
  480. package/src/engine/physics/queries/overlap_shape.js +187 -184
  481. package/src/engine/physics/queries/raycast.d.ts +3 -2
  482. package/src/engine/physics/queries/raycast.d.ts.map +1 -1
  483. package/src/engine/physics/queries/raycast.js +37 -11
  484. package/src/engine/physics/queries/shape_cast.d.ts +18 -5
  485. package/src/engine/physics/queries/shape_cast.d.ts.map +1 -1
  486. package/src/engine/physics/queries/shape_cast.js +417 -393
  487. package/src/engine/physics/solver/solve_contacts.d.ts +22 -6
  488. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
  489. package/src/engine/physics/solver/solve_contacts.js +1482 -1338
  490. package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
  491. package/src/engine/physics/vehicle/RaycastVehicle.js +344 -339
  492. package/src/engine/ui/DraggableAspect.d.ts +12 -3
  493. package/src/engine/ui/DraggableAspect.d.ts.map +1 -1
  494. package/src/engine/ui/DraggableAspect.js +115 -83
  495. package/src/generation/COORDINATES.md +54 -0
  496. package/src/generation/GridTaskGroup.js +2 -2
  497. package/src/generation/REVIEW_01_ACTION_PLAN.md +628 -0
  498. package/src/generation/automata/CaveGeneratorCellularAutomata.d.ts +9 -1
  499. package/src/generation/automata/CaveGeneratorCellularAutomata.d.ts.map +1 -1
  500. package/src/generation/automata/CaveGeneratorCellularAutomata.js +79 -59
  501. package/src/generation/automata/CellularAutomata.d.ts +6 -3
  502. package/src/generation/automata/CellularAutomata.d.ts.map +1 -1
  503. package/src/generation/automata/CellularAutomata.js +22 -19
  504. package/src/generation/filtering/CellFilter.d.ts +17 -0
  505. package/src/generation/filtering/CellFilter.d.ts.map +1 -1
  506. package/src/generation/filtering/CellFilter.js +117 -77
  507. package/src/generation/filtering/CellFilterCellMatcher.d.ts.map +1 -1
  508. package/src/generation/filtering/CellFilterCellMatcher.js +2 -0
  509. package/src/generation/filtering/boolean/CellFilterLiteralBoolean.d.ts +5 -0
  510. package/src/generation/filtering/boolean/CellFilterLiteralBoolean.d.ts.map +1 -1
  511. package/src/generation/filtering/boolean/CellFilterLiteralBoolean.js +15 -0
  512. package/src/generation/filtering/core/CellFilterBinaryOperation.d.ts +0 -1
  513. package/src/generation/filtering/core/CellFilterBinaryOperation.d.ts.map +1 -1
  514. package/src/generation/filtering/core/CellFilterBinaryOperation.js +37 -50
  515. package/src/generation/filtering/core/CellFilterOperationTertiary.d.ts +0 -1
  516. package/src/generation/filtering/core/CellFilterOperationTertiary.d.ts.map +1 -1
  517. package/src/generation/filtering/core/CellFilterOperationTertiary.js +43 -59
  518. package/src/generation/filtering/core/CellFilterUnaryOperation.d.ts +0 -1
  519. package/src/generation/filtering/core/CellFilterUnaryOperation.d.ts.map +1 -1
  520. package/src/generation/filtering/core/CellFilterUnaryOperation.js +29 -33
  521. package/src/generation/filtering/numeric/CellFilterCache.d.ts +1 -0
  522. package/src/generation/filtering/numeric/CellFilterCache.d.ts.map +1 -1
  523. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.d.ts +3 -2
  524. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.d.ts.map +1 -1
  525. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.js +9 -35
  526. package/src/generation/filtering/numeric/complex/CellFilterCurvature.d.ts +0 -1
  527. package/src/generation/filtering/numeric/complex/CellFilterCurvature.d.ts.map +1 -1
  528. package/src/generation/filtering/numeric/complex/CellFilterCurvature.js +19 -43
  529. package/src/generation/filtering/numeric/complex/CellFilterFXAA.d.ts +0 -1
  530. package/src/generation/filtering/numeric/complex/CellFilterFXAA.d.ts.map +1 -1
  531. package/src/generation/filtering/numeric/complex/CellFilterFXAA.js +2 -6
  532. package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.d.ts.map +1 -1
  533. package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +9 -12
  534. package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.d.ts.map +1 -1
  535. package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +2 -1
  536. package/src/generation/filtering/numeric/complex/CellFilterSobel.d.ts +0 -1
  537. package/src/generation/filtering/numeric/complex/CellFilterSobel.d.ts.map +1 -1
  538. package/src/generation/filtering/numeric/complex/CellFilterSobel.js +2 -6
  539. package/src/generation/filtering/numeric/math/CellFilterInverseLerp.d.ts +5 -4
  540. package/src/generation/filtering/numeric/math/CellFilterInverseLerp.d.ts.map +1 -1
  541. package/src/generation/filtering/numeric/math/CellFilterInverseLerp.js +5 -4
  542. package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.d.ts +17 -0
  543. package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.d.ts.map +1 -0
  544. package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.js +42 -0
  545. package/src/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.d.ts.map +1 -1
  546. package/src/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.js +7 -1
  547. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.d.ts.map +1 -1
  548. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.js +7 -10
  549. package/src/generation/filtering/numeric/util/sampler_from_filter.d.ts.map +1 -1
  550. package/src/generation/filtering/numeric/util/sampler_from_filter.js +2 -1
  551. package/src/generation/grid/GridData.d.ts.map +1 -1
  552. package/src/generation/grid/GridData.js +14 -1
  553. package/src/generation/grid/actions/ContinuousGridCellAction.d.ts +10 -3
  554. package/src/generation/grid/actions/ContinuousGridCellAction.d.ts.map +1 -1
  555. package/src/generation/grid/actions/ContinuousGridCellAction.js +18 -3
  556. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainHeight.d.ts +11 -1
  557. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainHeight.d.ts.map +1 -1
  558. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainHeight.js +13 -3
  559. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainObstacle.d.ts +1 -1
  560. package/src/generation/grid/actions/ContinuousGridCellActionSetTerrainObstacle.js +2 -2
  561. package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.d.ts +1 -1
  562. package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.d.ts.map +1 -1
  563. package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.js +4 -6
  564. package/src/generation/grid/coords/grid_to_texel.d.ts +9 -0
  565. package/src/generation/grid/coords/grid_to_texel.d.ts.map +1 -0
  566. package/src/generation/grid/coords/grid_to_texel.js +10 -0
  567. package/src/generation/grid/coords/texel_to_grid.d.ts +9 -0
  568. package/src/generation/grid/coords/texel_to_grid.d.ts.map +1 -0
  569. package/src/generation/grid/coords/texel_to_grid.js +10 -0
  570. package/src/generation/grid/generation/GridTaskApplyActionToCells.d.ts +2 -2
  571. package/src/generation/grid/generation/GridTaskApplyActionToCells.d.ts.map +1 -1
  572. package/src/generation/grid/generation/GridTaskApplyActionToCells.js +10 -6
  573. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.d.ts.map +1 -1
  574. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +20 -21
  575. package/src/generation/grid/generation/GridTaskExecuteRuleTimes.d.ts +7 -0
  576. package/src/generation/grid/generation/GridTaskExecuteRuleTimes.d.ts.map +1 -1
  577. package/src/generation/grid/generation/GridTaskExecuteRuleTimes.js +18 -10
  578. package/src/generation/grid/generation/discrete/GridTaskCellularAutomata.d.ts.map +1 -1
  579. package/src/generation/grid/generation/discrete/GridTaskCellularAutomata.js +16 -7
  580. package/src/generation/grid/generation/discrete/GridTaskConnectRooms.d.ts +5 -3
  581. package/src/generation/grid/generation/discrete/GridTaskConnectRooms.d.ts.map +1 -1
  582. package/src/generation/grid/generation/discrete/GridTaskConnectRooms.js +26 -23
  583. package/src/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.d.ts.map +1 -1
  584. package/src/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.js +10 -1
  585. package/src/generation/grid/generation/grid/select/CellSupplierBestN.d.ts.map +1 -1
  586. package/src/generation/grid/generation/grid/select/CellSupplierBestN.js +4 -0
  587. package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts +15 -8
  588. package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts.map +1 -1
  589. package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +89 -92
  590. package/src/generation/markers/GridActionRuleSet.d.ts.map +1 -1
  591. package/src/generation/markers/GridActionRuleSet.js +10 -2
  592. package/src/generation/markers/GridCellActionPlaceMarker.d.ts +11 -0
  593. package/src/generation/markers/GridCellActionPlaceMarker.d.ts.map +1 -1
  594. package/src/generation/markers/GridCellActionPlaceMarker.js +20 -3
  595. package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts +3 -1
  596. package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts.map +1 -1
  597. package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +9 -2
  598. package/src/generation/markers/MarkerNode.d.ts +8 -3
  599. package/src/generation/markers/MarkerNode.d.ts.map +1 -1
  600. package/src/generation/markers/MarkerNode.js +12 -5
  601. package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +1 -1
  602. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.d.ts +1 -1
  603. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.d.ts.map +1 -1
  604. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.js +1 -1
  605. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.d.ts +1 -1
  606. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.d.ts.map +1 -1
  607. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.js +1 -1
  608. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.d.ts +1 -1
  609. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.d.ts.map +1 -1
  610. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.js +2 -2
  611. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorSequence.d.ts +1 -1
  612. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorSequence.d.ts.map +1 -1
  613. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorSequence.js +2 -2
  614. package/src/generation/markers/actions/probability/MarkerNodeActionSelectWeighted.d.ts.map +1 -1
  615. package/src/generation/markers/actions/probability/MarkerNodeActionSelectWeighted.js +6 -4
  616. package/src/generation/markers/actions/probability/MarkerNodeActionWeightedElement.d.ts.map +1 -1
  617. package/src/generation/markers/actions/probability/MarkerNodeActionWeightedElement.js +1 -3
  618. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.d.ts.map +1 -1
  619. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +12 -11
  620. package/src/generation/markers/matcher/MarkerNodeMatcherAnd.js +2 -2
  621. package/src/generation/markers/transform/MarkerNodeTransformer.d.ts +4 -1
  622. package/src/generation/markers/transform/MarkerNodeTransformer.d.ts.map +1 -1
  623. package/src/generation/markers/transform/MarkerNodeTransformer.js +4 -1
  624. package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.d.ts.map +1 -1
  625. package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.js +1 -3
  626. package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.d.ts +5 -0
  627. package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.d.ts.map +1 -1
  628. package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +15 -0
  629. package/src/generation/markers/transform/MarkerNodeTransformerRecordProperty.d.ts.map +1 -1
  630. package/src/generation/markers/transform/MarkerNodeTransformerRecordProperty.js +1 -3
  631. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.d.ts.map +1 -1
  632. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.js +2 -4
  633. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.d.ts.map +1 -1
  634. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.js +1 -3
  635. package/src/generation/placement/GridCellPlacementRule.d.ts.map +1 -1
  636. package/src/generation/placement/GridCellPlacementRule.js +1 -3
  637. package/src/generation/placement/action/GridCellActionWriteFilterToLayer.d.ts.map +1 -1
  638. package/src/generation/placement/action/GridCellActionWriteFilterToLayer.js +8 -10
  639. package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.d.ts.map +1 -1
  640. package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.js +6 -4
  641. package/src/generation/placement/action/random/weighted/WeightedGridCellAction.d.ts.map +1 -1
  642. package/src/generation/placement/action/random/weighted/WeightedGridCellAction.js +1 -3
  643. package/src/generation/rules/CellMatcher.d.ts +3 -1
  644. package/src/generation/rules/CellMatcher.d.ts.map +1 -1
  645. package/src/generation/rules/CellMatcher.js +3 -1
  646. package/src/generation/rules/CellMatcherFromFilter.d.ts.map +1 -1
  647. package/src/generation/rules/CellMatcherFromFilter.js +1 -3
  648. package/src/generation/rules/CellMatcherLayerBitMaskTest.d.ts.map +1 -1
  649. package/src/generation/rules/CellMatcherLayerBitMaskTest.js +6 -20
  650. package/src/generation/test_support/executeTaskTreeSync.d.ts +9 -0
  651. package/src/generation/test_support/executeTaskTreeSync.d.ts.map +1 -0
  652. package/src/generation/test_support/executeTaskTreeSync.js +78 -0
  653. package/src/generation/theme/TerrainLayerRuleAggregator.d.ts +2 -1
  654. package/src/generation/theme/TerrainLayerRuleAggregator.d.ts.map +1 -1
  655. package/src/generation/theme/TerrainLayerRuleAggregator.js +9 -6
  656. package/src/generation/theme/Theme.d.ts +1 -1
  657. package/src/generation/theme/Theme.d.ts.map +1 -1
  658. package/src/generation/theme/Theme.js +2 -2
  659. package/src/generation/theme/ThemeEngine.d.ts +3 -3
  660. package/src/generation/theme/ThemeEngine.d.ts.map +1 -1
  661. package/src/generation/theme/ThemeEngine.js +26 -16
  662. package/src/generation/theme/cell/CellProcessingRule.d.ts +3 -3
  663. package/src/generation/theme/cell/CellProcessingRule.d.ts.map +1 -1
  664. package/src/generation/theme/cell/CellProcessingRule.js +6 -10
  665. package/src/generation/theme/cell/CellProcessingRuleSet.d.ts +1 -1
  666. package/src/generation/theme/cell/CellProcessingRuleSet.d.ts.map +1 -1
  667. package/src/generation/theme/cell/CellProcessingRuleSet.js +2 -2
  668. package/src/view/common/ListView.js +1 -1
  669. package/src/view/elements/BottomLeftResizeHandleView.d.ts.map +1 -1
  670. package/src/view/elements/BottomLeftResizeHandleView.js +13 -5
  671. package/src/core/font/FontAsset.d.ts.map +0 -1
  672. package/src/core/font/FontAssetLoader.d.ts.map +0 -1
  673. package/src/core/geom/3d/shape/util/shape_to_visual_entity.d.ts.map +0 -1
  674. package/src/core/geom/3d/tetrahedra/visualize_tetrahedral_mesh.d.ts.map +0 -1
  675. package/src/core/process/action/AsynchronousDelayAction.d.ts.map +0 -1
  676. package/src/engine/physics/computeInterceptPoint.d.ts.map +0 -1
  677. package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts.map +0 -1
  678. package/src/engine/physics/gjk/gjk.d.ts.map +0 -1
  679. package/src/engine/physics/gjk/gjk_epa_penetration.d.ts.map +0 -1
  680. package/src/engine/physics/gjk/minkowski_support.d.ts.map +0 -1
  681. package/src/engine/physics/gjk/mpr.d.ts.map +0 -1
  682. package/src/engine/physics/integration/quat_integrate.d.ts.map +0 -1
  683. package/src/engine/physics/island/union_find.d.ts.map +0 -1
  684. package/src/engine/physics/narrowphase/PosedShape.d.ts.map +0 -1
  685. package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts.map +0 -1
  686. package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts.map +0 -1
  687. package/src/generation/grid/generation/discrete/layer/GridTaskDistanceToMarkers.d.ts +0 -21
  688. package/src/generation/grid/generation/discrete/layer/GridTaskDistanceToMarkers.d.ts.map +0 -1
  689. package/src/generation/grid/generation/discrete/layer/GridTaskDistanceToMarkers.js +0 -68
  690. package/src/generation/grid/generation/grid/GridTaskGridAlignedNodeGenerator.d.ts +0 -10
  691. package/src/generation/grid/generation/grid/GridTaskGridAlignedNodeGenerator.d.ts.map +0 -1
  692. package/src/generation/grid/generation/grid/GridTaskGridAlignedNodeGenerator.js +0 -17
  693. /package/src/{engine/physics → core/geom/3d}/gjk/NOTES.md +0 -0
  694. /package/src/{engine/physics → core/geom/3d}/gjk/gjk.d.ts +0 -0
  695. /package/src/{engine/physics → core/math/physics/kinematics}/computeInterceptPoint.d.ts +0 -0
@@ -1,12 +1,14 @@
1
1
  import { assert } from "../../../core/assert.js";
2
- import { optimal_sor_omega } from "./solver/optimal_sor_omega.js";
3
- import { v3_grid_apply_advection_forward } from "./solver/v3_grid_apply_advection_forward.js";
2
+ import { sor_optimal_omega } from "../../../core/math/linalg/sor_optimal_omega.js";
4
3
  import { v3_grid_apply_diffusion } from "./solver/v3_grid_apply_diffusion.js";
5
- import { v3_grid_apply_scalar_advection } from "./solver/v3_grid_apply_scalar_advection.js";
6
- import { v3_grid_compute_divergence } from "./solver/v3_grid_compute_divergence.js";
7
4
  import { v3_grid_solve_pressure } from "./solver/v3_grid_solve_pressure.js";
8
5
  import { v3_grid_solve_pressure_pcg } from "./solver/v3_grid_solve_pressure_pcg.js";
9
- import { v3_grid_subtract_pressure_gradient } from "./solver/v3_grid_subtract_pressure_gradient.js";
6
+ import { v3_mac_advect_maccormack_velocity } from "./solver/v3_mac_advect_maccormack_velocity.js";
7
+ import { v3_mac_advect_sl_velocity } from "./solver/v3_mac_advect_sl_velocity.js";
8
+ import { v3_mac_advect_sl_scalar } from "./solver/v3_mac_advect_scalar.js";
9
+ import { v3_mac_apply_vorticity_confinement } from "./solver/v3_mac_apply_vorticity_confinement.js";
10
+ import { v3_mac_compute_divergence } from "./solver/v3_mac_compute_divergence.js";
11
+ import { v3_mac_subtract_pressure_gradient } from "./solver/v3_mac_subtract_pressure_gradient.js";
10
12
 
11
13
  /**
12
14
  * Pressure solver selection. Both solve the same A·p = -div system over the
@@ -31,7 +33,34 @@ export const PressureSolver = {
31
33
  };
32
34
 
33
35
  /**
34
- * Cell-centered 3D Stable Fluids solver (Stam, 1999/2003).
36
+ * VELOCITY transport scheme selection. Passive scalars always use
37
+ * semi-Lagrangian transport regardless of this setting — gather-form
38
+ * MacCormack is non-conservative (the corrector re-adds roughly double the
39
+ * gather bias; measured 1.7x total dye mass in one second of a sealed
40
+ * vortex, independent of wall handling), and scalar conservation is a hard
41
+ * requirement, not a preference.
42
+ *
43
+ * - `"semi-lagrangian"` — first-order back-trace + trilinear gather (Stam
44
+ * 1999). Cheapest; strongly dissipative — a vortex loses half its kinetic
45
+ * energy per second at production settings (see quality.spec.js).
46
+ *
47
+ * - `"maccormack"` — unconditionally stable MacCormack (Selle et al. 2008):
48
+ * a forward and a backward semi-Lagrangian pass with error correction and
49
+ * a monotone min-max limiter. Second-order accurate in space and time.
50
+ * Allocates 3 additional face-lattice scratch buffers.
51
+ *
52
+ * @enum {string}
53
+ */
54
+ export const AdvectionScheme = {
55
+ SEMI_LAGRANGIAN: "semi-lagrangian",
56
+ MACCORMACK: "maccormack",
57
+ };
58
+
59
+ /**
60
+ * 3D incompressible-flow solver on a MAC (staggered) grid — Stam's stable-
61
+ * fluids step structure (1999/2003) with face-centered velocity (Harlow &
62
+ * Welch 1965), an exact discrete Helmholtz projection, and optional
63
+ * advection-reflection / MacCormack transport.
35
64
  *
36
65
  * Holds tuning knobs plus transient working memory (per-step velocity snapshots,
37
66
  * divergence, ping-pong scratch). None of that working memory carries information
@@ -41,12 +70,16 @@ export const PressureSolver = {
41
70
  * the field). Scratch is cached by cell-count so per-step allocation stays at zero.
42
71
  *
43
72
  * Per step:
44
- * 1. Apply external forces (effectors mutate field velocity).
73
+ * 1. Apply external forces (effectors mutate field velocity), then the
74
+ * optional exponential velocity damping.
45
75
  * 2. Diffuse velocity (viscosity; skipped when `velocity_diffusion_rate == 0`).
46
- * 3. Project (pressure solve + gradient subtract) to enforce ∇·v ≈ 0.
47
- * 4. Self-advect velocity (semi-Lagrangian back-trace).
48
- * 5. Project again (advection introduces small divergence).
49
- * 6. For each scalar attribute on the field: optionally diffuse, then advect.
76
+ * 3-5. Transport block either the Stam reference sequence
77
+ * project₁ advect project₂, or (default) the advection-reflection
78
+ * form of the same two projections (see {@link advection_reflection}).
79
+ * Advection itself is semi-Lagrangian or MacCormack per
80
+ * {@link advection_scheme}.
81
+ * 6. For each scalar attribute on the field: optionally diffuse, then
82
+ * advect (always semi-Lagrangian — see {@link AdvectionScheme}).
50
83
  *
51
84
  * Pressure is warm-started from the previous step's solution (`field.pressure`),
52
85
  * which converges much faster than starting from zero once the flow reaches a
@@ -69,6 +102,25 @@ export const PressureSolver = {
69
102
  */
70
103
  export const PRESSURE_ITERATIONS_FLOOR = 8;
71
104
 
105
+ /**
106
+ * Relative convergence tolerance handed to the MIC-PCG pressure solve: the
107
+ * solver stops as soon as `max|r| <= tolerance * max|−div|`. The iteration
108
+ * cap from {@link FluidSimulator#resolvePressureIterations} is sized for the
109
+ * cold-start worst case; warm-started production frames converge much
110
+ * earlier, and without a tolerance exit every warm frame would pay the full
111
+ * cold-start budget for no quality gain.
112
+ *
113
+ * 1e-3 sits below visual-fluids noticeability and below the collocated
114
+ * operator-mismatch floor that dominates post-projection divergence (see
115
+ * quality.spec.js) — iterating past it buys nothing visible.
116
+ *
117
+ * SOR has no equivalent exit: it never computes its residual (doing so would
118
+ * add a pass per sweep), so its cost is governed by the iteration count alone.
119
+ *
120
+ * @type {number}
121
+ */
122
+ export const PCG_RELATIVE_TOLERANCE = 1e-3;
123
+
72
124
  export class FluidSimulator {
73
125
 
74
126
  /**
@@ -97,6 +149,34 @@ export class FluidSimulator {
97
149
  */
98
150
  scalar_diffusion_iterations = 4;
99
151
 
152
+ /**
153
+ * Exponential velocity damping rate, per second. Each step multiplies the
154
+ * whole velocity field by `exp(-velocity_damping * dt)` right after
155
+ * effectors run. `0` (default) disables — no pass is made.
156
+ *
157
+ * Why it exists: the solver has no other dissipation mechanism that bounds
158
+ * energy under sustained forcing. Incompressible projection cannot oppose
159
+ * a uniform body force (a uniform field is divergence-free), so a bare
160
+ * `force` on a {@link GlobalFluidEffector} accelerates the fluid without
161
+ * limit — there is no terminal state. A small damping rate gives constant
162
+ * forcing a terminal velocity of approximately
163
+ * `acceleration / velocity_damping` and makes transient gusts decay back
164
+ * to calm.
165
+ *
166
+ * Relationship to {@link GlobalFluidEffector#drag}: the effector's drag
167
+ * is the same operation expressed as SCENE CONTENT — it relaxes toward a
168
+ * configurable ambient wind and travels with the effector entity. This
169
+ * knob is the SOLVER-level stability primitive: it exists even when no
170
+ * effectors are wired, and always relaxes toward zero. Use the effector
171
+ * for atmosphere design; use this to guarantee boundedness.
172
+ *
173
+ * The exponential form is frame-rate independent: two half-steps damp
174
+ * exactly as much as one full step.
175
+ *
176
+ * @type {number}
177
+ */
178
+ velocity_damping = 0;
179
+
100
180
  /**
101
181
  * Which pressure solver to use. `PressureSolver.SOR` (default) is the
102
182
  * baseline red-black Successive Over-Relaxation. `PressureSolver.MICPCG`
@@ -115,6 +195,80 @@ export class FluidSimulator {
115
195
  */
116
196
  pressure_solver = PressureSolver.SOR;
117
197
 
198
+ /**
199
+ * Vorticity-confinement strength ε, per second (Fedkiw et al. 2001). Each
200
+ * step deposits `ε·dt·(N × ω)` as a velocity increment, sharpening vortex
201
+ * cores that coarse grids and dissipative transport smear away. `0`
202
+ * (default) disables — no pass is made.
203
+ *
204
+ * Confinement ADDS energy by design; pair non-zero values with
205
+ * {@link velocity_damping} so gusts still decay. Visual-smoke territory
206
+ * starts around `ε ≈ 5–30` at 60 Hz (epsilon_dt 0.1–0.5).
207
+ *
208
+ * Cost when enabled: two extra O(N) passes (curl + force) using existing
209
+ * scratch — no allocations.
210
+ *
211
+ * @type {number}
212
+ */
213
+ vorticity_confinement = 0;
214
+
215
+ /**
216
+ * Which transport scheme advects VELOCITY — see {@link AdvectionScheme}
217
+ * (scalars are always semi-Lagrangian; see the enum docstring for why).
218
+ *
219
+ * **Default MacCormack.** On the MAC grid with solid-clipped traces it is
220
+ * measured long-horizon stable (sealed-vortex energy peaks at 0.96x its
221
+ * initial over 10 s, monotone decay thereafter) and retains dramatically
222
+ * more energy than first-order transport: 0.80 vs 0.53 KE after one
223
+ * second (quality.spec.js scenario 2b).
224
+ *
225
+ * Do NOT combine with {@link advection_reflection}: the energy-preserving
226
+ * reflection re-injects the corrector overshoots and the pair pumps
227
+ * energy without bound (10 s peak 3.7x — measured both with and without
228
+ * trace clipping). Reflection is the companion for SEMI_LAGRANGIAN.
229
+ *
230
+ * @type {string}
231
+ */
232
+ advection_scheme = AdvectionScheme.MACCORMACK;
233
+
234
+ /**
235
+ * Replace the plain "project → advect → project" sequence with the
236
+ * advection-reflection scheme (Zehnder, Narain, Thomaszewski 2018):
237
+ *
238
+ * ũ = advect(u, u, dt/2) — half-step self-advection
239
+ * u½ = project(ũ)
240
+ * û = 2·u½ − ũ — energy-preserving reflection
241
+ * u′ = advect(û, u½, dt/2) — transport the REFLECTED field
242
+ * along the PROJECTED one
243
+ * u₁ = project(u′)
244
+ *
245
+ * Same two pressure solves as the default double-projection Stam step,
246
+ * and two half-dt advections instead of one full-dt one — measured cost
247
+ * ~+70% of step() at 32×8×32 on the MAC lattices (each half-step pays the
248
+ * cross-component carrier sampling). The reflection replaces the
249
+ * energy-DISSIPATING first projection with an energy-PRESERVING
250
+ * reflection about the divergence-free subspace.
251
+ *
252
+ * With semi-Lagrangian advection this is measured stable (sealed-vortex
253
+ * kinetic energy never exceeds its initial over 10 s) while retaining
254
+ * visibly more swirl — peak vorticity 0.74 vs 0.68 after one second
255
+ * (quality.spec.js scenario 2b). Do NOT combine with MacCormack — the
256
+ * reflection re-injects the corrector overshoots (10 s energy peak
257
+ * 3.7x); see {@link advection_scheme}.
258
+ *
259
+ * Only consulted when {@link project_before_advection} is true — the
260
+ * scheme is defined around the mid-step projection. With
261
+ * `project_before_advection = false` this flag is ignored.
262
+ *
263
+ * Default OFF: the default velocity scheme is MacCormack, with which the
264
+ * reflection is unstable (see {@link advection_scheme}). Enable it when
265
+ * running SEMI_LAGRANGIAN velocity transport — that pairing is measured
266
+ * stable and retains visibly more swirl than plain SL.
267
+ *
268
+ * @type {boolean}
269
+ */
270
+ advection_reflection = false;
271
+
118
272
  /**
119
273
  * Run the pressure projection *before* self-advection in addition to after.
120
274
  *
@@ -178,13 +332,12 @@ export class FluidSimulator {
178
332
  pressure_iteration_scale = 0.25;
179
333
 
180
334
  // ────────────────────────────────────────────────────────────────────────────
181
- // Transient scratch — overwritten before read on every step. Cached by
182
- // cell-count so we don't allocate per step. Their value never crosses a step
183
- // boundary; if it did it would belong on the field (see `field.pressure`).
335
+ // Transient scratch — overwritten before read on every step. Cached and
336
+ // grown monotonically so we don't allocate per step. Their value never
337
+ // crosses a step boundary; if it did it would belong on the field (see
338
+ // `field.pressure`). Velocity-shaped buffers are sized per face lattice.
184
339
  // ────────────────────────────────────────────────────────────────────────────
185
340
 
186
- #scratch_cells = 0;
187
-
188
341
  /** @type {Float32Array|null} */ #prev_x = null;
189
342
  /** @type {Float32Array|null} */ #prev_y = null;
190
343
  /** @type {Float32Array|null} */ #prev_z = null;
@@ -200,23 +353,46 @@ export class FluidSimulator {
200
353
  /** @type {Float32Array|null} */ #pcg_As = null;
201
354
  /** @type {Float32Array|null} */ #pcg_precon = null;
202
355
 
356
+ // Auxiliary velocity trio (allocated lazily, face-lattice sized): the
357
+ // reflection scheme's ũ snapshot / carrier copy, and vorticity
358
+ // confinement's curl scratch — the uses never overlap in time.
359
+ /** @type {Float32Array|null} */ #aux_x = null;
360
+ /** @type {Float32Array|null} */ #aux_y = null;
361
+ /** @type {Float32Array|null} */ #aux_z = null;
362
+
363
+ // MacCormack forward-pass trio (allocated lazily, face-lattice sized).
364
+ // Deliberately separate from #aux: in the reflection path #aux holds the
365
+ // carrier during the very advection that needs this scratch.
366
+ /** @type {Float32Array|null} */ #mc_x = null;
367
+ /** @type {Float32Array|null} */ #mc_y = null;
368
+ /** @type {Float32Array|null} */ #mc_z = null;
369
+
203
370
  /**
204
- * Grow the cached scratch buffers if the requested size exceeds what's allocated.
205
- * Idempotent and monotonic never shrinks. Called at the top of {@link step} and
206
- * {@link project} so user code never has to think about it.
207
- * @param {number} cell_count
371
+ * Grow the cached scratch buffers to fit the field's lattices. The prev
372
+ * trio and the diffusion scratch are sized per FACE grid (the largest of
373
+ * which also covers every cell-count use); divergence and scalar scratch
374
+ * are cell-count. Idempotent and monotonic — never shrinks. Called at the
375
+ * top of {@link step} so user code never has to think about it.
376
+ * @param {FluidField} field
208
377
  */
209
- #ensure_scratch(cell_count) {
210
- if (this.#scratch_cells >= cell_count) {
211
- return;
378
+ #ensure_scratch(field) {
379
+ const res = field.getResolution();
380
+ const n_u = (res[0] + 1) * res[1] * res[2];
381
+ const n_v = res[0] * (res[1] + 1) * res[2];
382
+ const n_w = res[0] * res[1] * (res[2] + 1);
383
+ const n_cell = field.cellCount();
384
+ const n_face_max = Math.max(n_u, n_v, n_w);
385
+
386
+ if (this.#prev_x === null || this.#prev_x.length < n_u) this.#prev_x = new Float32Array(n_u);
387
+ if (this.#prev_y === null || this.#prev_y.length < n_v) this.#prev_y = new Float32Array(n_v);
388
+ if (this.#prev_z === null || this.#prev_z.length < n_w) this.#prev_z = new Float32Array(n_w);
389
+ if (this.#diffusion_scratch === null || this.#diffusion_scratch.length < n_face_max) {
390
+ this.#diffusion_scratch = new Float32Array(n_face_max);
212
391
  }
213
- this.#scratch_cells = cell_count;
214
- this.#prev_x = new Float32Array(cell_count);
215
- this.#prev_y = new Float32Array(cell_count);
216
- this.#prev_z = new Float32Array(cell_count);
217
- this.#divergence = new Float32Array(cell_count);
218
- this.#diffusion_scratch = new Float32Array(cell_count);
219
- this.#scalar_scratch = new Float32Array(cell_count);
392
+ if (this.#scalar_scratch === null || this.#scalar_scratch.length < n_cell) {
393
+ this.#scalar_scratch = new Float32Array(n_cell);
394
+ }
395
+ // #divergence is dtype-tracked separately by #ensure_divergence_matches.
220
396
  }
221
397
 
222
398
  /**
@@ -236,6 +412,72 @@ export class FluidSimulator {
236
412
  this.#pcg_precon = new Float32Array(cell_count);
237
413
  }
238
414
 
415
+ /**
416
+ * Lazily allocate the auxiliary velocity trio (face-lattice sized) used by
417
+ * the reflection scheme and vorticity confinement. Idempotent and
418
+ * monotonic.
419
+ * @param {FluidField} field
420
+ */
421
+ #ensure_aux_scratch(field) {
422
+ const res = field.getResolution();
423
+ const n_u = (res[0] + 1) * res[1] * res[2];
424
+ const n_v = res[0] * (res[1] + 1) * res[2];
425
+ const n_w = res[0] * res[1] * (res[2] + 1);
426
+ if (this.#aux_x === null || this.#aux_x.length < n_u) this.#aux_x = new Float32Array(n_u);
427
+ if (this.#aux_y === null || this.#aux_y.length < n_v) this.#aux_y = new Float32Array(n_v);
428
+ if (this.#aux_z === null || this.#aux_z.length < n_w) this.#aux_z = new Float32Array(n_w);
429
+ }
430
+
431
+ /**
432
+ * Lazily allocate the MacCormack forward-pass trio (face-lattice sized).
433
+ * Idempotent and monotonic.
434
+ * @param {FluidField} field
435
+ */
436
+ #ensure_mc_scratch(field) {
437
+ const res = field.getResolution();
438
+ const n_u = (res[0] + 1) * res[1] * res[2];
439
+ const n_v = res[0] * (res[1] + 1) * res[2];
440
+ const n_w = res[0] * res[1] * (res[2] + 1);
441
+ if (this.#mc_x === null || this.#mc_x.length < n_u) this.#mc_x = new Float32Array(n_u);
442
+ if (this.#mc_y === null || this.#mc_y.length < n_v) this.#mc_y = new Float32Array(n_v);
443
+ if (this.#mc_z === null || this.#mc_z.length < n_w) this.#mc_z = new Float32Array(n_w);
444
+ }
445
+
446
+ /**
447
+ * Advect the field's velocity from `sources` along the given carrier, into
448
+ * the field's velocity buffers, using the configured
449
+ * {@link advection_scheme}. The carrier may alias the field's own velocity
450
+ * arrays; sources must not.
451
+ *
452
+ * @param {FluidField} field
453
+ * @param {number[]} res
454
+ * @param {number} dt
455
+ * @param {Float32Array[]} sources `[src_u, src_v, src_w]` face grids
456
+ * @param {Float32Array[]} carrier `[car_u, car_v, car_w]` face grids
457
+ */
458
+ #advect_velocity(field, res, dt, sources, carrier) {
459
+ const outputs = [field.velocity_x, field.velocity_y, field.velocity_z];
460
+ if (this.advection_scheme === AdvectionScheme.MACCORMACK) {
461
+ this.#ensure_mc_scratch(field);
462
+ v3_mac_advect_maccormack_velocity(
463
+ outputs, sources, carrier,
464
+ [this.#mc_x, this.#mc_y, this.#mc_z],
465
+ res[0], res[1], res[2],
466
+ dt,
467
+ field.face_solid_x, field.face_solid_y, field.face_solid_z,
468
+ field.solid
469
+ );
470
+ } else {
471
+ v3_mac_advect_sl_velocity(
472
+ outputs, sources, carrier,
473
+ res[0], res[1], res[2],
474
+ dt,
475
+ field.face_solid_x, field.face_solid_y, field.face_solid_z,
476
+ field.solid
477
+ );
478
+ }
479
+ }
480
+
239
481
  /**
240
482
  * Re-allocate the divergence scratch buffer if its element type doesn't match
241
483
  * the field's pressure type. Lets `half_precision_pressure` on the field carry
@@ -282,31 +524,45 @@ export class FluidSimulator {
282
524
  * because tests and external code may need to project on demand (e.g., after
283
525
  * splatting an out-of-band impulse). `field.pressure` is read as the warm-start
284
526
  * initial guess and written with the new solution.
527
+ *
528
+ * Refreshes the field's solid-neighbour mask itself, so direct callers never
529
+ * have to remember invalidation after mutating solids. {@link step} refreshes
530
+ * the mask once for the whole step and uses the private no-recompute variant
531
+ * for both of its projections.
532
+ *
285
533
  * @param {FluidField} field
286
534
  */
287
535
  project(field) {
288
- this.#ensure_scratch(field.cellCount());
536
+ field.recomputeSolidNeighbourMask();
537
+ this.#project_with_current_mask(field);
538
+ }
539
+
540
+ /**
541
+ * Projection body — assumes the field's derived masks (cell neighbour
542
+ * mask, pressure diagonal, face pins) are already fresh.
543
+ *
544
+ * On the MAC layout this is an exact discrete Helmholtz projection: the
545
+ * face-difference divergence and the face gradient compose to exactly the
546
+ * 7-point Laplacian the solvers invert, so post-projection divergence is
547
+ * zero up to solver residual — including beside walls.
548
+ *
549
+ * @param {FluidField} field
550
+ */
551
+ #project_with_current_mask(field) {
289
552
  this.#ensure_divergence_matches(field);
290
553
 
291
554
  const res = field.getResolution();
292
- const solid = field.solid;
293
555
  const iterations = this.resolvePressureIterations(res[0], res[1], res[2]);
294
556
 
295
557
  if (iterations === 0) {
296
558
  return;
297
559
  }
298
560
 
299
- // Pre-bake the per-cell neighbourhood mask consumed by the pressure SOR
300
- // loop. One O(N) byte-pass amortized across `iterations` SOR sweeps;
301
- // saves six boundary checks plus six solid-neighbour checks per cell per
302
- // iteration. See FluidField.solid_neighbour_mask.
303
- field.recomputeSolidNeighbourMask();
304
-
305
- v3_grid_compute_divergence(
561
+ v3_mac_compute_divergence(
306
562
  this.#divergence,
307
563
  field.velocity_x, field.velocity_y, field.velocity_z,
308
564
  res[0], res[1], res[2],
309
- solid
565
+ field.solid
310
566
  );
311
567
 
312
568
  if (this.pressure_solver === PressureSolver.MICPCG) {
@@ -314,8 +570,8 @@ export class FluidSimulator {
314
570
  v3_grid_solve_pressure_pcg(
315
571
  field.pressure, this.#divergence,
316
572
  res[0], res[1], res[2],
317
- iterations,
318
- field.solid_neighbour_mask,
573
+ iterations, PCG_RELATIVE_TOLERANCE,
574
+ field.solid_neighbour_mask, field.pressure_diag,
319
575
  this.#pcg_r, this.#pcg_z, this.#pcg_s, this.#pcg_As, this.#pcg_precon
320
576
  );
321
577
  } else {
@@ -323,35 +579,47 @@ export class FluidSimulator {
323
579
  field.pressure, this.#divergence,
324
580
  res[0], res[1], res[2],
325
581
  iterations,
326
- optimal_sor_omega(res[0], res[1], res[2]),
327
- field.solid_neighbour_mask
582
+ sor_optimal_omega(res[0], res[1], res[2]),
583
+ field.solid_neighbour_mask, field.pressure_diag
328
584
  );
329
585
  }
330
586
 
331
- v3_grid_subtract_pressure_gradient(
587
+ v3_mac_subtract_pressure_gradient(
332
588
  field.velocity_x, field.velocity_y, field.velocity_z,
333
589
  field.pressure,
334
- res[0], res[1], res[2],
335
- field.solid_neighbour_mask
590
+ field.face_solid_x, field.face_solid_y, field.face_solid_z,
591
+ res[0], res[1], res[2]
336
592
  );
337
593
  }
338
594
 
339
595
  /**
340
- * Diffuse a single velocity component in-place, using `source_copy_buf` as the
341
- * "before" snapshot and `#diffusion_scratch` as the ping-pong scratch.
342
- * @param {Float32Array} component
596
+ * Diffuse a single velocity component (one face lattice) in-place, using
597
+ * `source_copy_buf` as the "before" snapshot and `#diffusion_scratch` as
598
+ * the ping-pong scratch. The face-pin mask plays the diffusion kernel's
599
+ * "solid" role: pinned faces are frozen and act as no-flux neighbours.
600
+ *
601
+ * The shared scratch buffers can be larger than this lattice (they are
602
+ * sized to the largest one); the kernel's internal whole-buffer copies
603
+ * require exact-length views.
604
+ *
605
+ * @param {Float32Array} component Face lattice, exact length.
343
606
  * @param {Float32Array} source_copy_buf
344
- * @param {number[]} res
345
- * @param {Uint8Array} solid
607
+ * @param {number} dim_x
608
+ * @param {number} dim_y
609
+ * @param {number} dim_z
610
+ * @param {Uint8Array} face_solid
346
611
  */
347
- #diffuse_velocity_component(component, source_copy_buf, res, solid) {
348
- source_copy_buf.set(component);
612
+ #diffuse_velocity_component(component, source_copy_buf, dim_x, dim_y, dim_z, face_solid) {
613
+ const n = component.length;
614
+ const copy = source_copy_buf.length === n ? source_copy_buf : source_copy_buf.subarray(0, n);
615
+ const scratch = this.#diffusion_scratch.length === n ? this.#diffusion_scratch : this.#diffusion_scratch.subarray(0, n);
616
+ copy.set(component);
349
617
  v3_grid_apply_diffusion(
350
- component, source_copy_buf, this.#diffusion_scratch,
351
- res[0], res[1], res[2],
618
+ component, copy, scratch,
619
+ dim_x, dim_y, dim_z,
352
620
  this.velocity_diffusion_rate,
353
621
  this.velocity_diffusion_iterations,
354
- solid
622
+ face_solid
355
623
  );
356
624
  }
357
625
 
@@ -385,46 +653,137 @@ export class FluidSimulator {
385
653
  const cell_count = field.cellCount();
386
654
  assert.greaterThan(cell_count, 0, "field has not been built");
387
655
 
388
- this.#ensure_scratch(cell_count);
656
+ this.#ensure_scratch(field);
389
657
 
390
658
  const res = field.getResolution();
659
+ const n_u = field.velocity_x.length;
660
+ const n_v = field.velocity_y.length;
661
+ const n_w = field.velocity_z.length;
391
662
 
392
663
  // 1. External forces.
393
664
  for (let i = 0; i < effectors.length; i++) {
394
665
  effectors[i].apply(field, time_delta, world_to_grid);
395
666
  }
396
667
 
668
+ // Refresh the pre-baked derived masks (cell neighbour mask, pressure
669
+ // diagonal, face pins) ONCE for the whole step — after effectors (a
670
+ // custom effector may splat solids), before anything that consumes
671
+ // them. Both projections below reuse them. Faces that just became
672
+ // pinned have their velocity zeroed here (static-wall default);
673
+ // already-pinned faces keep whatever boundary condition their solid's
674
+ // owner wrote (FluidObstacleSystem writes moving-wall velocities).
675
+ field.recomputeSolidNeighbourMask();
676
+
397
677
  const solid = field.solid;
398
678
 
399
- // 2. Velocity diffusion (viscosity). Cheap to skip when disabled.
400
- if (this.velocity_diffusion_rate > 0 && this.velocity_diffusion_iterations > 0) {
401
- this.#diffuse_velocity_component(field.velocity_x, this.#prev_x, res, solid);
402
- this.#diffuse_velocity_component(field.velocity_y, this.#prev_y, res, solid);
403
- this.#diffuse_velocity_component(field.velocity_z, this.#prev_z, res, solid);
679
+ // 1b. Velocity damping the solver's only energy sink under sustained
680
+ // forcing. Pinned faces are SKIPPED: their value is the wall's
681
+ // boundary condition, not fluid momentum.
682
+ if (this.velocity_damping > 0) {
683
+ const decay = Math.exp(-this.velocity_damping * time_delta);
684
+ const vu = field.velocity_x;
685
+ const vv = field.velocity_y;
686
+ const vw = field.velocity_z;
687
+ const pin_u = field.face_solid_x;
688
+ const pin_v = field.face_solid_y;
689
+ const pin_w = field.face_solid_z;
690
+ for (let i = 0; i < n_u; i++) {
691
+ if (pin_u[i] === 0) vu[i] *= decay;
692
+ }
693
+ for (let i = 0; i < n_v; i++) {
694
+ if (pin_v[i] === 0) vv[i] *= decay;
695
+ }
696
+ for (let i = 0; i < n_w; i++) {
697
+ if (pin_w[i] === 0) vw[i] *= decay;
698
+ }
699
+ }
700
+
701
+ // 1c. Vorticity confinement — an additional force term that sharpens
702
+ // vortex cores (see the knob's docstring). Needs the fresh face
703
+ // pins; uses the prev + aux trios and the diffusion scratch as
704
+ // working memory, all overwritten by later phases anyway.
705
+ if (this.vorticity_confinement > 0) {
706
+ this.#ensure_aux_scratch(field);
707
+ v3_mac_apply_vorticity_confinement(
708
+ field.velocity_x, field.velocity_y, field.velocity_z,
709
+ field.face_solid_x, field.face_solid_y, field.face_solid_z,
710
+ this.#prev_x, this.#prev_y, this.#prev_z,
711
+ this.#aux_x, this.#aux_y, this.#aux_z, this.#diffusion_scratch,
712
+ res[0], res[1], res[2],
713
+ this.vorticity_confinement * time_delta,
714
+ solid
715
+ );
404
716
  }
405
717
 
406
- // 3. Project to enforce incompressibility before advection. Skipping this
407
- // is a perf knob (~halves the pressure cost) at the price of advection
408
- // seeing a slightly-divergent input. See `project_before_advection`.
409
- if (this.project_before_advection) {
410
- this.project(field);
718
+ // 2. Velocity diffusion (viscosity). Cheap to skip when disabled. Each
719
+ // face lattice diffuses with its own dimensions; the face-pin masks
720
+ // make walls no-flux exactly like solid cells used to.
721
+ if (this.velocity_diffusion_rate > 0 && this.velocity_diffusion_iterations > 0) {
722
+ this.#diffuse_velocity_component(field.velocity_x, this.#prev_x, res[0] + 1, res[1], res[2], field.face_solid_x);
723
+ this.#diffuse_velocity_component(field.velocity_y, this.#prev_y, res[0], res[1] + 1, res[2], field.face_solid_y);
724
+ this.#diffuse_velocity_component(field.velocity_z, this.#prev_z, res[0], res[1], res[2] + 1, field.face_solid_z);
411
725
  }
412
726
 
413
- // 4. Self-advect velocity (semi-Lagrangian back-trace through the projected field).
414
- this.#prev_x.set(field.velocity_x);
415
- this.#prev_y.set(field.velocity_y);
416
- this.#prev_z.set(field.velocity_z);
727
+ // 3-5. Transport block: project + self-advect (+ optional reflection).
728
+ const prev = [this.#prev_x, this.#prev_y, this.#prev_z];
729
+
730
+ if (this.project_before_advection && this.advection_reflection) {
731
+ // Advection-reflection (Zehnder et al. 2018), half-step form — see
732
+ // the `advection_reflection` docstring. Same two projections as the
733
+ // plain path; two half-dt advections instead of one full-dt one.
734
+ const half_dt = 0.5 * time_delta;
735
+
736
+ // ũ = advect(u, u, dt/2)
737
+ this.#prev_x.set(field.velocity_x);
738
+ this.#prev_y.set(field.velocity_y);
739
+ this.#prev_z.set(field.velocity_z);
740
+ this.#advect_velocity(field, res, half_dt, prev, prev);
741
+
742
+ // Snapshot ũ.
743
+ this.#ensure_aux_scratch(field);
744
+ this.#aux_x.set(field.velocity_x);
745
+ this.#aux_y.set(field.velocity_y);
746
+ this.#aux_z.set(field.velocity_z);
747
+
748
+ // u½ = project(ũ)
749
+ this.#project_with_current_mask(field);
750
+
751
+ // û = 2·u½ − ũ — the reflection about the divergence-free subspace,
752
+ // per face lattice.
753
+ const ax = this.#aux_x, ay = this.#aux_y, az = this.#aux_z;
754
+ const fx = field.velocity_x, fy = field.velocity_y, fz = field.velocity_z;
755
+ const px = this.#prev_x, py = this.#prev_y, pz = this.#prev_z;
756
+ for (let i = 0; i < n_u; i++) px[i] = 2 * fx[i] - ax[i];
757
+ for (let i = 0; i < n_v; i++) py[i] = 2 * fy[i] - ay[i];
758
+ for (let i = 0; i < n_w; i++) pz[i] = 2 * fz[i] - az[i];
759
+
760
+ // u′ = advect(û, u½, dt/2). The advection kernels sample the
761
+ // carrier's OTHER lattices spatially, so the carrier must not
762
+ // alias the outputs — copy u½ into the aux trio (ũ there is dead,
763
+ // already folded into û).
764
+ this.#aux_x.set(fx);
765
+ this.#aux_y.set(fy);
766
+ this.#aux_z.set(fz);
767
+ this.#advect_velocity(field, res, half_dt, prev, [ax, ay, az]);
768
+
769
+ // u₁ = project(u′)
770
+ this.#project_with_current_mask(field);
771
+ } else {
772
+ // Stam reference sequence: project₁ (optional) → advect → project₂.
773
+ if (this.project_before_advection) {
774
+ this.#project_with_current_mask(field);
775
+ }
417
776
 
418
- v3_grid_apply_advection_forward(
419
- [field.velocity_x, field.velocity_y, field.velocity_z],
420
- [this.#prev_x, this.#prev_y, this.#prev_z],
421
- res[0], res[1], res[2],
422
- time_delta,
423
- solid
424
- );
777
+ this.#prev_x.set(field.velocity_x);
778
+ this.#prev_y.set(field.velocity_y);
779
+ this.#prev_z.set(field.velocity_z);
780
+ this.#advect_velocity(field, res, time_delta, prev, prev);
425
781
 
426
- // 5. Re-project after advection.
427
- this.project(field);
782
+ // Re-project after advection. Solids cannot have changed since the
783
+ // top-of-step mask refresh (only the simulator has touched the
784
+ // field), so the masks are still fresh.
785
+ this.#project_with_current_mask(field);
786
+ }
428
787
 
429
788
  // 6. Transport each passive scalar by the now-finalized velocity field.
430
789
  const scalars = field.getScalarAttributes();
@@ -433,8 +792,13 @@ export class FluidSimulator {
433
792
 
434
793
  if (this.scalar_diffusion_rate > 0 && this.scalar_diffusion_iterations > 0) {
435
794
  this.#scalar_scratch.set(attr.data);
795
+ // The diffusion scratch is face-lattice sized; the kernel's
796
+ // internal whole-buffer copies need an exact cell-count view.
797
+ const ping_pong = this.#diffusion_scratch.length === cell_count
798
+ ? this.#diffusion_scratch
799
+ : this.#diffusion_scratch.subarray(0, cell_count);
436
800
  v3_grid_apply_diffusion(
437
- attr.data, this.#scalar_scratch, this.#diffusion_scratch,
801
+ attr.data, this.#scalar_scratch, ping_pong,
438
802
  res[0], res[1], res[2],
439
803
  this.scalar_diffusion_rate,
440
804
  this.scalar_diffusion_iterations,
@@ -443,7 +807,10 @@ export class FluidSimulator {
443
807
  }
444
808
 
445
809
  this.#scalar_scratch.set(attr.data);
446
- v3_grid_apply_scalar_advection(
810
+ // Scalars are ALWAYS semi-Lagrangian, independent of
811
+ // advection_scheme — gather-MacCormack is non-conservative (see
812
+ // the AdvectionScheme docstring).
813
+ v3_mac_advect_sl_scalar(
447
814
  attr.data, this.#scalar_scratch,
448
815
  field.velocity_x, field.velocity_y, field.velocity_z,
449
816
  res[0], res[1], res[2],