@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,36 +1,19 @@
1
1
  import { assert } from "../../../../core/assert.js";
2
2
 
3
- /**
4
- * Popcount lookup for the 6-bit neighbour mask. Index = mask value (0–63 used in
5
- * practice; the table is sized 64 so the read is a single bounded indexed access).
6
- * Values are the SOR denominator (number of fluid neighbours) for each mask.
7
- *
8
- * @type {Uint8Array}
9
- */
10
- const POPCOUNT_6 = (function () {
11
- const t = new Uint8Array(64);
12
- for (let i = 0; i < 64; i++) {
13
- let c = 0;
14
- for (let b = 0; b < 6; b++) if (i & (1 << b)) c++;
15
- t[i] = c;
16
- }
17
- return t;
18
- })();
19
-
20
3
  /**
21
4
  * Solve the pressure Poisson equation `∇²p = div(v)` by red-black Successive
22
- * Over-Relaxation (SOR), gated by a pre-baked per-cell neighbour mask.
5
+ * Over-Relaxation (SOR), gated by pre-baked per-cell neighbour data.
23
6
  *
24
7
  * Per cell, the update is:
25
8
  *
26
- * p_jacobi(c) = ( sum_of_fluid_neighbour_pressures - div(c) ) / count
9
+ * p_jacobi(c) = ( sum_of_fluid_neighbour_pressures - div(c) ) / diag(c)
27
10
  * p(c) = (1 - ω) * p(c) + ω * p_jacobi(c)
28
11
  *
29
- * "Which neighbours count as fluid" is determined entirely by `neighbour_mask`,
30
- * a Uint8Array allocated and populated by {@link FluidField} via
31
- * {@link FluidField.recomputeSolidNeighbourMask}. The encoding is:
12
+ * Which faces participate is determined entirely by `neighbour_mask` and
13
+ * `diag`, both produced by {@link v3_grid_compute_solid_neighbour_mask}
14
+ * (via {@link FluidField.recomputeSolidNeighbourMask}):
32
15
  *
33
- * bit 0 (= 1) : -x neighbour is fluid
16
+ * bit 0 (= 1) : -x neighbour is fluid — read its pressure
34
17
  * bit 1 (= 2) : +x neighbour is fluid
35
18
  * bit 2 (= 4) : -y neighbour is fluid
36
19
  * bit 3 (= 8) : +y neighbour is fluid
@@ -39,14 +22,19 @@ const POPCOUNT_6 = (function () {
39
22
  * bit 7 (= 128) : this cell is itself solid (consumed by
40
23
  * {@link v3_grid_subtract_pressure_gradient}, ignored here)
41
24
  *
42
- * The low 6 bits are the fluid-neighbour set. A solid cell encodes as `128` and
43
- * an isolated fluid cell as `0`, so the inner loop's `(mask & 63) === 0 ? skip`
44
- * covers both self-solid AND fluid-with-no-fluid-neighbours in one comparison.
45
- * This eliminates six boundary checks plus six solid-neighbour checks per cell
46
- * per iteration, replacing them with a single mask read and six bit-tests on a
47
- * register-resident value. Boundary handling (cells at x=0, x=last, etc.) is
48
- * implicit — the recompute step writes 0 into the boundary-facing bit, so the
49
- * SOR loop never reads out-of-range memory.
25
+ * diag(c) = (# fluid neighbours) + (# open faces)
26
+ *
27
+ * Boundary semantics fall out of the encoding:
28
+ * - SOLID face (in-bounds neighbour with the bit clear): Neumann/reflecting
29
+ * absent from both the sum and `diag`.
30
+ * - OPEN face (out-of-bounds neighbour): Dirichlet ghost `p = 0` absent
31
+ * from the sum (a zero contribution) but counted in `diag`. The domain
32
+ * edge therefore behaves as an open boundary; sealed domains are built by
33
+ * lining the edge with solid cells.
34
+ *
35
+ * `diag === 0` covers "this cell is solid" AND "this fluid cell is sealed on
36
+ * all six faces" with a single comparison, so the inner loop pays one byte
37
+ * read and one test per skipped cell and never reads out-of-range memory.
50
38
  *
51
39
  * Cells are visited in two passes per iteration: first "red" (`(x+y+z) % 2 === 0`)
52
40
  * then "black". Adjacent cells have opposite colour, so each pass reads only
@@ -62,18 +50,21 @@ const POPCOUNT_6 = (function () {
62
50
  * @param {number} res_z
63
51
  * @param {number} iterations Number of red-black sweeps.
64
52
  * @param {number} omega SOR relaxation factor in (0, 2). Near-optimal values
65
- * come from {@link optimal_sor_omega}.
66
- * @param {Uint8Array} neighbour_mask Length ≥ res_x*res_y*res_z. Each byte
67
- * encodes the fluid-neighbour bitmask (see above). MUST be recomputed
68
- * whenever the underlying solid mask changes.
53
+ * come from {@link sor_optimal_omega}.
54
+ * @param {Uint8Array} neighbour_mask Length ≥ res_x*res_y*res_z. Fluid-neighbour
55
+ * bitmask (see above). MUST be recomputed whenever the underlying solid
56
+ * mask changes.
57
+ * @param {Uint8Array} diag Length ≥ res_x*res_y*res_z. Laplacian diagonal per
58
+ * cell, baked by the same kernel as `neighbour_mask`.
69
59
  */
70
- export function v3_grid_solve_pressure(pressure, divergence, res_x, res_y, res_z, iterations, omega, neighbour_mask) {
60
+ export function v3_grid_solve_pressure(pressure, divergence, res_x, res_y, res_z, iterations, omega, neighbour_mask, diag) {
71
61
  const cell_count = res_x * res_y * res_z;
72
62
 
73
63
  assert.notEqual(pressure, divergence, "pressure must not alias divergence");
74
64
  assert.greaterThanOrEqual(pressure.length, cell_count, "pressure covers grid");
75
65
  assert.greaterThanOrEqual(divergence.length, cell_count, "divergence covers grid");
76
66
  assert.greaterThanOrEqual(neighbour_mask.length, cell_count, "neighbour_mask covers grid");
67
+ assert.greaterThanOrEqual(diag.length, cell_count, "diag covers grid");
77
68
  assert.isNonNegativeInteger(iterations, "iterations");
78
69
  assert.greaterThan(omega, 0, "omega");
79
70
  assert.lessThan(omega, 2, "omega");
@@ -84,6 +75,7 @@ export function v3_grid_solve_pressure(pressure, divergence, res_x, res_y, res_z
84
75
 
85
76
  const slice_size = res_x * res_y;
86
77
  const one_minus_omega = 1 - omega;
78
+ const omega_sixth = omega / 6;
87
79
 
88
80
  for (let iter = 0; iter < iterations; iter++) {
89
81
 
@@ -104,11 +96,24 @@ export function v3_grid_solve_pressure(pressure, divergence, res_x, res_y, res_z
104
96
  const c = z_off + y_off + x;
105
97
 
106
98
  const mask = neighbour_mask[c];
107
- if ((mask & 63) === 0) {
108
- // No fluid neighbours: solid cell (bit 7 set) OR isolated
109
- // fluid. Either way, no degrees of freedom skip. Cells
110
- // that reach past here have bit 7 clear, so `mask` indexes
111
- // POPCOUNT_6 (sized 64) in range.
99
+ if (mask === 63) {
100
+ // Full-interior fluid cell (all six neighbours fluid,
101
+ // which implies diag === 6): branch-free body with a
102
+ // constant diagonal and no diag-array read. The
103
+ // overwhelmingly common case on open fields — ~91% of
104
+ // cells at 64³ — measured 37% faster per sweep there
105
+ // and within noise at small shallow grids.
106
+ const sum = pressure[c - 1] + pressure[c + 1]
107
+ + pressure[c - res_x] + pressure[c + res_x]
108
+ + pressure[c - slice_size] + pressure[c + slice_size];
109
+ pressure[c] = one_minus_omega * pressure[c] + omega_sixth * (sum - divergence[c]);
110
+ continue;
111
+ }
112
+
113
+ const count = diag[c];
114
+ if (count === 0) {
115
+ // No degrees of freedom: solid cell or fluid sealed on
116
+ // all six faces. Skip.
112
117
  continue;
113
118
  }
114
119
 
@@ -120,7 +125,6 @@ export function v3_grid_solve_pressure(pressure, divergence, res_x, res_y, res_z
120
125
  if (mask & 16) sum += pressure[c - slice_size];
121
126
  if (mask & 32) sum += pressure[c + slice_size];
122
127
 
123
- const count = POPCOUNT_6[mask];
124
128
  const p_target = (sum - divergence[c]) / count;
125
129
  pressure[c] = one_minus_omega * pressure[c] + omega * p_target;
126
130
  }
@@ -3,12 +3,18 @@
3
3
  * Gradient — MIC(0)-PCG.
4
4
  *
5
5
  * Solves `A * p = -div(v)` where A is the 7-point discrete Laplacian over fluid
6
- * cells (same sign convention as {@link v3_grid_solve_pressure} — that
7
- * function's SOR update is exactly the splitting `A * p = -div`). Per cell:
6
+ * cells (same matrix as {@link v3_grid_solve_pressure} — that function's SOR
7
+ * update is exactly the splitting `A * p = -div`). Per cell:
8
8
  *
9
- * A[c, c] = number of fluid neighbours (= popcount(neighbour_mask[c]))
9
+ * A[c, c] = diag[c] = (# fluid neighbours) + (# open faces)
10
10
  * A[c, c'] = -1 if c' is a fluid neighbour of c, else 0
11
11
  *
12
+ * Open faces (out-of-bounds neighbours — the domain edge) carry a Dirichlet
13
+ * ghost pressure of 0: they enlarge the diagonal without adding an
14
+ * off-diagonal entry, exactly like a fluid neighbour whose pressure is pinned
15
+ * at zero. Solid faces are Neumann: absent from both. See
16
+ * {@link v3_grid_compute_solid_neighbour_mask} for the boundary model.
17
+ *
12
18
  * PCG converges in roughly `O(√κ)` iterations where κ is the spectral condition
13
19
  * number of `M⁻¹A`. The MIC(0) preconditioner reduces κ from `O(N²)` (raw
14
20
  * Laplacian) to `O(N)`, so a single PCG iter does a lot more useful work than
@@ -69,10 +75,22 @@
69
75
  * the hot path that prevents MIC-PCG from parallelizing onto a GPU without
70
76
  * substantial reformulation. On single-thread JS that's not a concern.
71
77
  *
72
- * Cells with no fluid neighbours solid cells (mask bit 7 set) and isolated
73
- * fluid (mask = 0), both identified by `(mask & 63) === 0` — are excluded from
74
- * the system: their pressure stays at whatever it was (typically 0), their
75
- * entries in r, z, s, As stay 0, and they contribute nothing to dot products.
78
+ * Null space: when NO fluid cell touches the domain edge (a fully sealed
79
+ * domain every boundary cell solid), A is the pure-Neumann Laplacian and has
80
+ * the constant vector in its null space. The residual is then projected onto
81
+ * the mean-zero subspace after every update, the standard fluids practice
82
+ * (Bridson §5.5) — without it alpha explodes once the search direction aligns
83
+ * with the null space. With ANY open face the system is non-singular and the
84
+ * projection is skipped (subtracting the mean there would solve a different
85
+ * right-hand side). Caveat: a sealed sub-region inside an otherwise open
86
+ * domain is still locally singular; its constant mode is harmless to the open
87
+ * region but convergence inside that pocket is not guaranteed — split fields
88
+ * rather than simulating disconnected sealed rooms in one volume.
89
+ *
90
+ * Cells with `diag[c] === 0` — solid cells and fluid sealed on all six faces —
91
+ * are excluded from the system: their pressure stays at whatever it was
92
+ * (typically 0), their entries in r, z, s, As stay 0, and they contribute
93
+ * nothing to dot products.
76
94
  *
77
95
  * @param {Float32Array|Float16Array} pressure Mutated in place. Pre-fill with 0
78
96
  * or with the previous step's solution to warm-start.
@@ -80,9 +98,19 @@
80
98
  * @param {number} res_x
81
99
  * @param {number} res_y
82
100
  * @param {number} res_z
83
- * @param {number} max_iterations Cap. Converged early-exits via implicit-zero
84
- * dot product (sigma reaches 0 or numerical noise).
101
+ * @param {number} max_iterations Cap. The solve also exits as soon as the
102
+ * tolerance is met (below), or via the implicit-zero dot product guards.
103
+ * @param {number} relative_tolerance Convergence exit: stop when
104
+ * `max|r| <= relative_tolerance * max|−div|` over fluid cells (residual
105
+ * measured after the null-space mean subtraction, where that applies).
106
+ * `0` disables the tolerance exit — the solve then runs to
107
+ * `max_iterations` exactly as the pre-tolerance implementation did.
108
+ * Production use: the cap is sized for the cold-start worst case, and the
109
+ * warm-started steady state exits in a fraction of it; without this exit
110
+ * every warm frame pays the cold-start budget for no quality gain.
85
111
  * @param {Uint8Array} neighbour_mask From `v3_grid_compute_solid_neighbour_mask`.
112
+ * @param {Uint8Array} diag Laplacian diagonal per cell, baked by the same
113
+ * kernel as `neighbour_mask`.
86
114
  * @param {Float32Array} scratch_r Length ≥ rx*ry*rz. Residual.
87
115
  * @param {Float32Array} scratch_z Length ≥ rx*ry*rz. Preconditioned residual.
88
116
  * @param {Float32Array} scratch_s Length ≥ rx*ry*rz. Search direction.
@@ -90,5 +118,5 @@
90
118
  * @param {Float32Array} scratch_precon Length ≥ rx*ry*rz. Preconditioner
91
119
  * diagonal (1/sqrt(e_c) per fluid cell, 0 for solid).
92
120
  */
93
- export function v3_grid_solve_pressure_pcg(pressure: Float32Array | Float16Array, divergence: Float32Array | Float16Array, res_x: number, res_y: number, res_z: number, max_iterations: number, neighbour_mask: Uint8Array, scratch_r: Float32Array, scratch_z: Float32Array, scratch_s: Float32Array, scratch_As: Float32Array, scratch_precon: Float32Array): void;
121
+ export function v3_grid_solve_pressure_pcg(pressure: Float32Array | Float16Array, divergence: Float32Array | Float16Array, res_x: number, res_y: number, res_z: number, max_iterations: number, relative_tolerance: number, neighbour_mask: Uint8Array, diag: Uint8Array, scratch_r: Float32Array, scratch_z: Float32Array, scratch_s: Float32Array, scratch_As: Float32Array, scratch_precon: Float32Array): void;
94
122
  //# sourceMappingURL=v3_grid_solve_pressure_pcg.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"v3_grid_solve_pressure_pcg.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js"],"names":[],"mappings":"AAuCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2FG;AACH,qDAhBW,YAAY,eAAa,cAEzB,YAAY,eAAa,SACzB,MAAM,SACN,MAAM,SACN,MAAM,kBACN,MAAM,kBAEN,UAAU,aACV,YAAY,aACZ,YAAY,aACZ,YAAY,cACZ,YAAY,kBACZ,YAAY,QA0NtB"}
1
+ {"version":3,"file":"v3_grid_solve_pressure_pcg.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js"],"names":[],"mappings":"AAuCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuHG;AACH,qDA1BW,YAAY,eAAa,cAEzB,YAAY,eAAa,SACzB,MAAM,SACN,MAAM,SACN,MAAM,kBACN,MAAM,sBAEN,MAAM,kBAQN,UAAU,QACV,UAAU,aAEV,YAAY,aACZ,YAAY,aACZ,YAAY,cACZ,YAAY,kBACZ,YAAY,QAgPtB"}
@@ -1,9 +1,9 @@
1
1
  import { assert } from "../../../../core/assert.js";
2
2
 
3
3
  /**
4
- * Popcount table for the 6-bit neighbour mask same encoding used by
5
- * {@link v3_grid_solve_pressure}. Indexed by the mask byte (0-63), value is the
6
- * SOR / Laplacian denominator = number of fluid neighbours.
4
+ * Popcount table for the 6-bit neighbour mask. Used to detect open faces:
5
+ * a cell whose Laplacian diagonal exceeds its fluid-neighbour count touches
6
+ * the domain edge (open boundary), which decides the null-space handling.
7
7
  *
8
8
  * @type {Uint8Array}
9
9
  */
@@ -42,12 +42,18 @@ const MIC_SIGMA = 0.25;
42
42
  * Gradient — MIC(0)-PCG.
43
43
  *
44
44
  * Solves `A * p = -div(v)` where A is the 7-point discrete Laplacian over fluid
45
- * cells (same sign convention as {@link v3_grid_solve_pressure} — that
46
- * function's SOR update is exactly the splitting `A * p = -div`). Per cell:
45
+ * cells (same matrix as {@link v3_grid_solve_pressure} — that function's SOR
46
+ * update is exactly the splitting `A * p = -div`). Per cell:
47
47
  *
48
- * A[c, c] = number of fluid neighbours (= popcount(neighbour_mask[c]))
48
+ * A[c, c] = diag[c] = (# fluid neighbours) + (# open faces)
49
49
  * A[c, c'] = -1 if c' is a fluid neighbour of c, else 0
50
50
  *
51
+ * Open faces (out-of-bounds neighbours — the domain edge) carry a Dirichlet
52
+ * ghost pressure of 0: they enlarge the diagonal without adding an
53
+ * off-diagonal entry, exactly like a fluid neighbour whose pressure is pinned
54
+ * at zero. Solid faces are Neumann: absent from both. See
55
+ * {@link v3_grid_compute_solid_neighbour_mask} for the boundary model.
56
+ *
51
57
  * PCG converges in roughly `O(√κ)` iterations where κ is the spectral condition
52
58
  * number of `M⁻¹A`. The MIC(0) preconditioner reduces κ from `O(N²)` (raw
53
59
  * Laplacian) to `O(N)`, so a single PCG iter does a lot more useful work than
@@ -108,10 +114,22 @@ const MIC_SIGMA = 0.25;
108
114
  * the hot path that prevents MIC-PCG from parallelizing onto a GPU without
109
115
  * substantial reformulation. On single-thread JS that's not a concern.
110
116
  *
111
- * Cells with no fluid neighbours solid cells (mask bit 7 set) and isolated
112
- * fluid (mask = 0), both identified by `(mask & 63) === 0` — are excluded from
113
- * the system: their pressure stays at whatever it was (typically 0), their
114
- * entries in r, z, s, As stay 0, and they contribute nothing to dot products.
117
+ * Null space: when NO fluid cell touches the domain edge (a fully sealed
118
+ * domain every boundary cell solid), A is the pure-Neumann Laplacian and has
119
+ * the constant vector in its null space. The residual is then projected onto
120
+ * the mean-zero subspace after every update, the standard fluids practice
121
+ * (Bridson §5.5) — without it alpha explodes once the search direction aligns
122
+ * with the null space. With ANY open face the system is non-singular and the
123
+ * projection is skipped (subtracting the mean there would solve a different
124
+ * right-hand side). Caveat: a sealed sub-region inside an otherwise open
125
+ * domain is still locally singular; its constant mode is harmless to the open
126
+ * region but convergence inside that pocket is not guaranteed — split fields
127
+ * rather than simulating disconnected sealed rooms in one volume.
128
+ *
129
+ * Cells with `diag[c] === 0` — solid cells and fluid sealed on all six faces —
130
+ * are excluded from the system: their pressure stays at whatever it was
131
+ * (typically 0), their entries in r, z, s, As stay 0, and they contribute
132
+ * nothing to dot products.
115
133
  *
116
134
  * @param {Float32Array|Float16Array} pressure Mutated in place. Pre-fill with 0
117
135
  * or with the previous step's solution to warm-start.
@@ -119,9 +137,19 @@ const MIC_SIGMA = 0.25;
119
137
  * @param {number} res_x
120
138
  * @param {number} res_y
121
139
  * @param {number} res_z
122
- * @param {number} max_iterations Cap. Converged early-exits via implicit-zero
123
- * dot product (sigma reaches 0 or numerical noise).
140
+ * @param {number} max_iterations Cap. The solve also exits as soon as the
141
+ * tolerance is met (below), or via the implicit-zero dot product guards.
142
+ * @param {number} relative_tolerance Convergence exit: stop when
143
+ * `max|r| <= relative_tolerance * max|−div|` over fluid cells (residual
144
+ * measured after the null-space mean subtraction, where that applies).
145
+ * `0` disables the tolerance exit — the solve then runs to
146
+ * `max_iterations` exactly as the pre-tolerance implementation did.
147
+ * Production use: the cap is sized for the cold-start worst case, and the
148
+ * warm-started steady state exits in a fraction of it; without this exit
149
+ * every warm frame pays the cold-start budget for no quality gain.
124
150
  * @param {Uint8Array} neighbour_mask From `v3_grid_compute_solid_neighbour_mask`.
151
+ * @param {Uint8Array} diag Laplacian diagonal per cell, baked by the same
152
+ * kernel as `neighbour_mask`.
125
153
  * @param {Float32Array} scratch_r Length ≥ rx*ry*rz. Residual.
126
154
  * @param {Float32Array} scratch_z Length ≥ rx*ry*rz. Preconditioned residual.
127
155
  * @param {Float32Array} scratch_s Length ≥ rx*ry*rz. Search direction.
@@ -132,8 +160,8 @@ const MIC_SIGMA = 0.25;
132
160
  export function v3_grid_solve_pressure_pcg(
133
161
  pressure, divergence,
134
162
  res_x, res_y, res_z,
135
- max_iterations,
136
- neighbour_mask,
163
+ max_iterations, relative_tolerance,
164
+ neighbour_mask, diag,
137
165
  scratch_r, scratch_z, scratch_s, scratch_As, scratch_precon
138
166
  ) {
139
167
  const cells = res_x * res_y * res_z;
@@ -142,12 +170,15 @@ export function v3_grid_solve_pressure_pcg(
142
170
  assert.greaterThanOrEqual(pressure.length, cells, "pressure covers grid");
143
171
  assert.greaterThanOrEqual(divergence.length, cells, "divergence covers grid");
144
172
  assert.greaterThanOrEqual(neighbour_mask.length, cells, "neighbour_mask covers grid");
173
+ assert.greaterThanOrEqual(diag.length, cells, "diag covers grid");
145
174
  assert.greaterThanOrEqual(scratch_r.length, cells, "scratch_r covers grid");
146
175
  assert.greaterThanOrEqual(scratch_z.length, cells, "scratch_z covers grid");
147
176
  assert.greaterThanOrEqual(scratch_s.length, cells, "scratch_s covers grid");
148
177
  assert.greaterThanOrEqual(scratch_As.length, cells, "scratch_As covers grid");
149
178
  assert.greaterThanOrEqual(scratch_precon.length, cells, "scratch_precon covers grid");
150
179
  assert.isNonNegativeInteger(max_iterations, "max_iterations");
180
+ assert.isNumber(relative_tolerance, "relative_tolerance");
181
+ assert.greaterThanOrEqual(relative_tolerance, 0, "relative_tolerance");
151
182
 
152
183
  if (max_iterations === 0) {
153
184
  return;
@@ -162,24 +193,18 @@ export function v3_grid_solve_pressure_pcg(
162
193
  const s = scratch_s;
163
194
  const As = scratch_As;
164
195
 
165
- // Count fluid cells for the null-space projection (mean subtraction). With
166
- // all-Neumann boundary conditions and no Dirichlet anchor, the discrete
167
- // Laplacian has a 1-D null space (constant pressure). Plain (P)CG drifts
168
- // along that direction — iterates can explode within ~10 sweeps even
169
- // though the residual stays small in the orthogonal complement. Projecting
170
- // r back onto the mean-zero subspace after every update keeps the search
171
- // direction perpendicular to the null space and lets PCG converge as
172
- // theory predicts.
173
- //
174
- // (Standard fluids practice — see Bridson §5.5. The alternative is to pin
175
- // one cell to a Dirichlet value and exclude it from the system, but mean
176
- // subtraction has the same effect with simpler bookkeeping.)
177
- // A cell is a degree of freedom iff it has ≥1 fluid neighbour, i.e. any of
178
- // the low 6 bits set. Solid cells (bit 7) and isolated fluid (all-zero) are
179
- // both excluded by masking off bit 7 with & 63.
196
+ // Count degrees of freedom and detect open faces. A DOF is any cell with
197
+ // diag > 0. `has_open` (any cell whose diagonal exceeds its fluid-neighbour
198
+ // count) decides the null-space treatment see the class of comment above.
180
199
  let fluid_count = 0;
200
+ let has_open = false;
181
201
  for (let c = 0; c < cells; c++) {
182
- if ((neighbour_mask[c] & 63) !== 0) fluid_count++;
202
+ const d = diag[c];
203
+ if (d === 0) continue;
204
+ fluid_count++;
205
+ if (d > POPCOUNT_6[neighbour_mask[c] & 63]) {
206
+ has_open = true;
207
+ }
183
208
  }
184
209
  if (fluid_count === 0) {
185
210
  return;
@@ -189,18 +214,18 @@ export function v3_grid_solve_pressure_pcg(
189
214
  //
190
215
  // Walk fluid cells in lex order; for each, compute the modified Cholesky
191
216
  // diagonal e[c] from the backward (-x, -y, -z) fluid neighbours and store
192
- // precon[c] = 1 / sqrt(e[c]). Solid / isolated cells keep precon = 0.
217
+ // precon[c] = 1 / sqrt(e[c]). Solid / sealed cells keep precon = 0.
193
218
  //
194
219
  // The "modified" piece adds tau * (off-direction terms) back onto the
195
220
  // diagonal — it compensates for fill-in that plain IC(0) drops, and makes
196
221
  // PCG converge in O(√N) instead of O(N²/³).
197
222
  precon.fill(0);
198
223
  for (let c = 0; c < cells; c++) {
199
- const mask = neighbour_mask[c];
200
- if ((mask & 63) === 0) {
224
+ const a_diag = diag[c];
225
+ if (a_diag === 0) {
201
226
  continue;
202
227
  }
203
- const a_diag = POPCOUNT_6[mask];
228
+ const mask = neighbour_mask[c];
204
229
  let e = a_diag;
205
230
 
206
231
  if (mask & 1) { // -x backward neighbour is fluid
@@ -248,13 +273,18 @@ export function v3_grid_solve_pressure_pcg(
248
273
 
249
274
  // ─── 2. r = -div - A * pressure (initial residual) ─────────────────────
250
275
 
276
+ // max|b| over fluid cells anchors the relative tolerance exit.
277
+ let max_b = 0;
251
278
  for (let c = 0; c < cells; c++) {
252
- const mask = neighbour_mask[c];
253
- if ((mask & 63) === 0) {
279
+ const a_diag = diag[c];
280
+ if (a_diag === 0) {
254
281
  r[c] = 0;
255
282
  continue;
256
283
  }
257
- let Ap = POPCOUNT_6[mask] * pressure[c];
284
+ const b_abs = Math.abs(divergence[c]);
285
+ if (b_abs > max_b) max_b = b_abs;
286
+ const mask = neighbour_mask[c];
287
+ let Ap = a_diag * pressure[c];
258
288
  if (mask & 1) Ap -= pressure[c - 1];
259
289
  if (mask & 2) Ap -= pressure[c + 1];
260
290
  if (mask & 4) Ap -= pressure[c - rx];
@@ -263,11 +293,21 @@ export function v3_grid_solve_pressure_pcg(
263
293
  if (mask & 32) Ap -= pressure[c + slice];
264
294
  r[c] = -divergence[c] - Ap;
265
295
  }
266
- subtract_mean_fluid(r, neighbour_mask, cells, fluid_count);
296
+ const tolerance = relative_tolerance * max_b;
297
+
298
+ const r0_worst = has_open
299
+ ? max_abs_dof(r, diag, cells)
300
+ : subtract_mean_fluid(r, diag, cells, fluid_count);
301
+ if (r0_worst <= tolerance) {
302
+ // Warm start already within tolerance — nothing to refine. (With
303
+ // relative_tolerance = 0 this only triggers on an exactly-zero
304
+ // residual, matching the historical behaviour.)
305
+ return;
306
+ }
267
307
 
268
308
  // ─── 3. z = M⁻¹ * r, s = z, sigma = r · z ───────────────────────────────
269
309
 
270
- apply_preconditioner(r, z, precon, neighbour_mask, cells, rx, slice);
310
+ apply_preconditioner(r, z, precon, neighbour_mask, diag, cells, rx, slice);
271
311
 
272
312
  let sigma = 0;
273
313
  for (let c = 0; c < cells; c++) {
@@ -288,12 +328,13 @@ export function v3_grid_solve_pressure_pcg(
288
328
  // As = A * s, accumulating s · As in the same pass.
289
329
  let s_dot_As = 0;
290
330
  for (let c = 0; c < cells; c++) {
291
- const mask = neighbour_mask[c];
292
- if ((mask & 63) === 0) {
331
+ const a_diag = diag[c];
332
+ if (a_diag === 0) {
293
333
  As[c] = 0;
294
334
  continue;
295
335
  }
296
- let val = POPCOUNT_6[mask] * s[c];
336
+ const mask = neighbour_mask[c];
337
+ let val = a_diag * s[c];
297
338
  if (mask & 1) val -= s[c - 1];
298
339
  if (mask & 2) val -= s[c + 1];
299
340
  if (mask & 4) val -= s[c - rx];
@@ -317,13 +358,22 @@ export function v3_grid_solve_pressure_pcg(
317
358
  pressure[c] += alpha * s[c];
318
359
  r[c] -= alpha * As[c];
319
360
  }
320
- // Project r back onto the mean-zero (range(A)) subspace. Round-off
321
- // accumulates a constant component each iter; without this, alpha
322
- // explodes within ~8 iters once s aligns with the null space.
323
- subtract_mean_fluid(r, neighbour_mask, cells, fluid_count);
361
+ // Sealed domain: project r back onto the mean-zero (range(A)) subspace
362
+ // — round-off accumulates a constant component each iter; without this,
363
+ // alpha explodes within ~8 iters once s aligns with the null space.
364
+ // Open domain: A is non-singular, no projection — just measure max|r|.
365
+ const r_worst = has_open
366
+ ? max_abs_dof(r, diag, cells)
367
+ : subtract_mean_fluid(r, diag, cells, fluid_count);
368
+
369
+ if (r_worst <= tolerance) {
370
+ // Converged to the requested tolerance — pressure is already
371
+ // updated for this iteration, stop paying for more sweeps.
372
+ break;
373
+ }
324
374
 
325
375
  // z = M⁻¹ * r
326
- apply_preconditioner(r, z, precon, neighbour_mask, cells, rx, slice);
376
+ apply_preconditioner(r, z, precon, neighbour_mask, diag, cells, rx, slice);
327
377
 
328
378
  // sigma_new = r · z
329
379
  let sigma_new = 0;
@@ -346,6 +396,59 @@ export function v3_grid_solve_pressure_pcg(
346
396
  }
347
397
  }
348
398
 
399
+ /**
400
+ * Subtract the mean (over fluid cells) from a buffer in place. Used to project
401
+ * a vector onto range(A) = mean-zero subspace; required for CG to converge on
402
+ * a system with a non-trivial null space (pure Neumann pressure Poisson —
403
+ * i.e. a fully sealed domain).
404
+ *
405
+ * @param {Float32Array} v
406
+ * @param {Uint8Array} diag
407
+ * @param {number} cells
408
+ * @param {number} fluid_count
409
+ * @return {number} max|v[c]| over fluid cells AFTER the subtraction — the
410
+ * residual max-norm the tolerance exit checks, measured for free in the
411
+ * subtraction pass.
412
+ */
413
+ function subtract_mean_fluid(v, diag, cells, fluid_count) {
414
+ let sum = 0;
415
+ for (let c = 0; c < cells; c++) {
416
+ if (diag[c] !== 0) sum += v[c];
417
+ }
418
+ const mean = sum / fluid_count;
419
+ let worst = 0;
420
+ for (let c = 0; c < cells; c++) {
421
+ if (diag[c] !== 0) {
422
+ const nv = v[c] - mean;
423
+ v[c] = nv;
424
+ const a = Math.abs(nv);
425
+ if (a > worst) worst = a;
426
+ }
427
+ }
428
+ return worst;
429
+ }
430
+
431
+ /**
432
+ * max|v[c]| over fluid cells. The open-domain counterpart of
433
+ * {@link subtract_mean_fluid}'s return value — no projection needed when the
434
+ * system is non-singular, only the residual norm for the tolerance exit.
435
+ *
436
+ * @param {Float32Array} v
437
+ * @param {Uint8Array} diag
438
+ * @param {number} cells
439
+ * @return {number}
440
+ */
441
+ function max_abs_dof(v, diag, cells) {
442
+ let worst = 0;
443
+ for (let c = 0; c < cells; c++) {
444
+ if (diag[c] !== 0) {
445
+ const a = Math.abs(v[c]);
446
+ if (a > worst) worst = a;
447
+ }
448
+ }
449
+ return worst;
450
+ }
451
+
349
452
  /**
350
453
  * Apply the MIC(0) preconditioner: solve M · z = r where M = L · Lᵀ.
351
454
  *
@@ -356,9 +459,9 @@ export function v3_grid_solve_pressure_pcg(
356
459
  * fluid neighbours' already-computed z values.
357
460
  *
358
461
  * Both write into `z` in place; the forward pass stores y in z, the backward
359
- * pass overwrites with the final z. Solid cells stay at 0 throughout.
462
+ * pass overwrites with the final z. Solid / sealed cells stay at 0 throughout.
360
463
  *
361
- * For our normalized Laplacian (A = -1 off-diagonal, popcount diagonal), the
464
+ * For our normalized Laplacian (A = -1 off-diagonal, `diag` diagonal), the
362
465
  * L factor has L[c, c-1] = -precon[c-1] etc., L[c, c] = 1/precon[c], so each
363
466
  * triangular solve degenerates to ~4 floating-point ops per cell.
364
467
  *
@@ -366,39 +469,19 @@ export function v3_grid_solve_pressure_pcg(
366
469
  * @param {Float32Array} z
367
470
  * @param {Float32Array} precon
368
471
  * @param {Uint8Array} mask_array
472
+ * @param {Uint8Array} diag
369
473
  * @param {number} cells
370
474
  * @param {number} rx
371
475
  * @param {number} slice
372
476
  */
373
- /**
374
- * Subtract the mean (over fluid cells) from a buffer in place. Used to project
375
- * a vector onto range(A) = mean-zero subspace; required for CG to converge on
376
- * a system with a non-trivial null space (pure Neumann pressure Poisson).
377
- *
378
- * @param {Float32Array} v
379
- * @param {Uint8Array} mask_array
380
- * @param {number} cells
381
- * @param {number} fluid_count
382
- */
383
- function subtract_mean_fluid(v, mask_array, cells, fluid_count) {
384
- let sum = 0;
385
- for (let c = 0; c < cells; c++) {
386
- if ((mask_array[c] & 63) !== 0) sum += v[c];
387
- }
388
- const mean = sum / fluid_count;
389
- for (let c = 0; c < cells; c++) {
390
- if ((mask_array[c] & 63) !== 0) v[c] -= mean;
391
- }
392
- }
393
-
394
- function apply_preconditioner(r, z, precon, mask_array, cells, rx, slice) {
477
+ function apply_preconditioner(r, z, precon, mask_array, diag, cells, rx, slice) {
395
478
  // Forward solve L · y = r. Store y in z (we won't read z[c'] for c' > c).
396
479
  for (let c = 0; c < cells; c++) {
397
- const mask = mask_array[c];
398
- if ((mask & 63) === 0) {
480
+ if (diag[c] === 0) {
399
481
  z[c] = 0;
400
482
  continue;
401
483
  }
484
+ const mask = mask_array[c];
402
485
  let t = r[c];
403
486
  // L[c, c-1] = -precon[c-1] when -x neighbour fluid → subtracting L·y is
404
487
  // adding precon[c-1] * y[c-1].
@@ -413,10 +496,10 @@ function apply_preconditioner(r, z, precon, mask_array, cells, rx, slice) {
413
496
  // z[c+slice], those were written in this same backward pass (higher
414
497
  // indices, processed first in reverse).
415
498
  for (let c = cells - 1; c >= 0; c--) {
416
- const mask = mask_array[c];
417
- if ((mask & 63) === 0) {
499
+ if (diag[c] === 0) {
418
500
  continue;
419
501
  }
502
+ const mask = mask_array[c];
420
503
  let t = z[c]; // = y[c] from forward pass
421
504
  // L[c+1, c] = -precon[c] when c+1's -x neighbour (= c) is fluid, which
422
505
  // is equivalent to "c's +x neighbour (= c+1) is fluid", i.e. mask & 2.