@woosh/meep-engine 2.139.0 → 2.141.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 (199) hide show
  1. package/package.json +1 -1
  2. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.d.ts +3 -3
  3. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.d.ts.map +1 -1
  4. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.js +4 -4
  5. package/src/{engine/physics/broadphase/aabb_transform_oriented.d.ts → core/geom/3d/aabb/aabb3_transform_oriented.d.ts} +2 -2
  6. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -0
  7. package/src/{engine/physics/broadphase/aabb_transform_oriented.js → core/geom/3d/aabb/aabb3_transform_oriented.js} +1 -1
  8. package/src/core/geom/3d/quaternion/quat3_multiply.d.ts +21 -0
  9. package/src/core/geom/3d/quaternion/quat3_multiply.d.ts.map +1 -0
  10. package/src/core/geom/3d/quaternion/quat3_multiply.js +25 -0
  11. package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts +54 -0
  12. package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts.map +1 -0
  13. package/src/core/geom/3d/quaternion/quat3_to_matrix3.js +69 -0
  14. package/src/core/geom/3d/shape/AbstractShape3D.d.ts +24 -2
  15. package/src/core/geom/3d/shape/AbstractShape3D.d.ts.map +1 -1
  16. package/src/core/geom/3d/shape/AbstractShape3D.js +24 -1
  17. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +148 -0
  18. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -0
  19. package/src/core/geom/3d/shape/HeightMapShape3D.js +451 -0
  20. package/src/core/geom/3d/shape/MeshShape3D.d.ts +210 -0
  21. package/src/core/geom/3d/shape/MeshShape3D.d.ts.map +1 -0
  22. package/src/core/geom/3d/shape/MeshShape3D.js +593 -0
  23. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  24. package/src/core/geom/3d/shape/TransformedShape3D.js +46 -2
  25. package/src/core/geom/3d/shape/Triangle3D.d.ts +95 -0
  26. package/src/core/geom/3d/shape/Triangle3D.d.ts.map +1 -0
  27. package/src/core/geom/3d/shape/Triangle3D.js +318 -0
  28. package/src/core/geom/3d/shape/UnionShape3D.js +13 -0
  29. package/src/core/geom/3d/shape/shape_mesh_from_geometry.d.ts +30 -0
  30. package/src/core/geom/3d/shape/shape_mesh_from_geometry.d.ts.map +1 -0
  31. package/src/core/geom/3d/shape/shape_mesh_from_geometry.js +64 -0
  32. package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.js +9 -11
  33. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.d.ts +28 -0
  34. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.d.ts.map +1 -0
  35. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.js +48 -0
  36. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts.map +1 -1
  37. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +40 -18
  38. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts +9 -5
  39. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts.map +1 -1
  40. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +38 -10
  41. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts +14 -5
  42. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts.map +1 -1
  43. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +47 -5
  44. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts +19 -0
  45. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts.map +1 -1
  46. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +75 -13
  47. package/src/core/geom/3d/triangle/v3_compute_triangle_normal.d.ts +2 -2
  48. package/src/core/geom/3d/triangle/v3_compute_triangle_normal.d.ts.map +1 -1
  49. package/src/core/geom/3d/triangle/v3_compute_triangle_normal.js +1 -1
  50. package/src/core/geom/vec3/v3_dot_array_array.d.ts +3 -3
  51. package/src/core/geom/vec3/v3_dot_array_array.d.ts.map +1 -1
  52. package/src/core/geom/vec3/v3_dot_array_array.js +2 -2
  53. package/src/core/geom/vec3/v3_negate_array.d.ts +3 -3
  54. package/src/core/geom/vec3/v3_negate_array.d.ts.map +1 -1
  55. package/src/core/geom/vec3/v3_negate_array.js +2 -2
  56. package/src/core/geom/vec3/v3_quat3_apply.d.ts +29 -0
  57. package/src/core/geom/vec3/v3_quat3_apply.d.ts.map +1 -0
  58. package/src/core/geom/vec3/v3_quat3_apply.js +39 -0
  59. package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts +30 -0
  60. package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts.map +1 -0
  61. package/src/core/geom/vec3/v3_quat3_apply_inverse.js +41 -0
  62. package/src/core/geom/vec3/v3_triple_cross_product.d.ts +32 -0
  63. package/src/core/geom/vec3/v3_triple_cross_product.d.ts.map +1 -0
  64. package/src/core/geom/vec3/v3_triple_cross_product.js +45 -0
  65. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +16 -3
  66. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  67. package/src/engine/control/first-person/FirstPersonPlayerController.js +211 -211
  68. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +72 -8
  69. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  70. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +37 -5
  71. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +101 -3
  72. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
  73. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +1789 -1416
  74. package/src/engine/control/first-person/TODO.md +173 -127
  75. package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -1
  76. package/src/engine/control/first-person/abilities/Slide.js +9 -1
  77. package/src/engine/control/first-person/prototype_first_person_controller.js +88 -2
  78. package/src/engine/control/first-person/test/buildTestPlayer.d.ts.map +1 -1
  79. package/src/engine/control/first-person/test/buildTestPlayer.js +9 -1
  80. package/src/engine/graphics/geometry/CapsuleGeometry.d.ts +42 -0
  81. package/src/engine/graphics/geometry/CapsuleGeometry.d.ts.map +1 -0
  82. package/src/engine/graphics/geometry/CapsuleGeometry.js +171 -0
  83. package/src/engine/physics/BULLET_REVIEW.md +945 -0
  84. package/src/engine/physics/CANNON_REVIEW.md +1300 -0
  85. package/src/engine/physics/JOLT_REVIEW.md +913 -0
  86. package/src/engine/physics/PLAN.md +578 -236
  87. package/src/engine/physics/RAPIER_REVIEW.md +934 -0
  88. package/src/engine/physics/REVIEW_001_ACTION_PLAN.md +642 -0
  89. package/src/engine/physics/REVIEW_002.md +151 -0
  90. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +2 -2
  91. package/src/engine/physics/constraint/DofMode.d.ts +28 -0
  92. package/src/engine/physics/constraint/DofMode.d.ts.map +1 -0
  93. package/src/engine/physics/constraint/DofMode.js +35 -0
  94. package/src/engine/physics/constraint/solve_constraints.d.ts +16 -0
  95. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -0
  96. package/src/engine/physics/constraint/solve_constraints.js +436 -0
  97. package/src/engine/physics/contact/ManifoldStore.d.ts +83 -10
  98. package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
  99. package/src/engine/physics/contact/ManifoldStore.js +608 -499
  100. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +2 -2
  101. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -1
  102. package/src/engine/physics/ecs/Joint.d.ts +179 -0
  103. package/src/engine/physics/ecs/Joint.d.ts.map +1 -0
  104. package/src/engine/physics/ecs/Joint.js +234 -0
  105. package/src/engine/physics/ecs/PhysicsSystem.d.ts +180 -20
  106. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  107. package/src/engine/physics/ecs/PhysicsSystem.js +1423 -1159
  108. package/src/engine/physics/fluid/FluidField.d.ts +14 -10
  109. package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
  110. package/src/engine/physics/fluid/FluidField.js +14 -10
  111. package/src/engine/physics/fluid/FluidSimulator.js +1 -1
  112. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts +17 -10
  113. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts.map +1 -1
  114. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +18 -11
  115. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts +13 -10
  116. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts.map +1 -1
  117. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +18 -13
  118. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts +4 -3
  119. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts.map +1 -1
  120. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +15 -11
  121. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +30 -6
  122. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -1
  123. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +44 -18
  124. package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts +6 -6
  125. package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts.map +1 -1
  126. package/src/engine/physics/gjk/expanding_polytope_algorithm.js +68 -22
  127. package/src/engine/physics/gjk/gjk.d.ts +28 -2
  128. package/src/engine/physics/gjk/gjk.d.ts.map +1 -1
  129. package/src/engine/physics/gjk/gjk.js +421 -378
  130. package/src/engine/physics/gjk/minkowski_support.d.ts +37 -0
  131. package/src/engine/physics/gjk/minkowski_support.d.ts.map +1 -0
  132. package/src/engine/physics/gjk/minkowski_support.js +75 -0
  133. package/src/engine/physics/gjk/mpr.d.ts +56 -0
  134. package/src/engine/physics/gjk/mpr.d.ts.map +1 -0
  135. package/src/engine/physics/gjk/mpr.js +344 -0
  136. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +20 -5
  137. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
  138. package/src/engine/physics/inertia/world_inverse_inertia.js +36 -38
  139. package/src/engine/physics/integration/integrate_position.d.ts +25 -7
  140. package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
  141. package/src/engine/physics/integration/integrate_position.js +43 -12
  142. package/src/engine/physics/integration/integrate_velocity.d.ts +30 -0
  143. package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
  144. package/src/engine/physics/integration/integrate_velocity.js +82 -1
  145. package/src/engine/physics/island/IslandBuilder.d.ts +4 -1
  146. package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -1
  147. package/src/engine/physics/island/IslandBuilder.js +33 -16
  148. package/src/engine/physics/narrowphase/PosedShape.d.ts +0 -8
  149. package/src/engine/physics/narrowphase/PosedShape.d.ts.map +1 -1
  150. package/src/engine/physics/narrowphase/PosedShape.js +28 -30
  151. package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
  152. package/src/engine/physics/narrowphase/box_box_manifold.js +140 -18
  153. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts +30 -0
  154. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -0
  155. package/src/engine/physics/narrowphase/box_triangle_contact.js +811 -0
  156. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
  157. package/src/engine/physics/narrowphase/capsule_contacts.js +10 -56
  158. package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts +71 -0
  159. package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts.map +1 -0
  160. package/src/engine/physics/narrowphase/capsule_triangle_contact.js +375 -0
  161. package/src/engine/physics/narrowphase/compute_penetration.d.ts +91 -0
  162. package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -0
  163. package/src/engine/physics/narrowphase/compute_penetration.js +396 -0
  164. package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts +35 -0
  165. package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts.map +1 -0
  166. package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.js +80 -0
  167. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts +31 -0
  168. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts.map +1 -0
  169. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.js +55 -0
  170. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts +42 -0
  171. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts.map +1 -0
  172. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.js +204 -0
  173. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts +42 -0
  174. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -0
  175. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +94 -0
  176. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts +37 -0
  177. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts.map +1 -0
  178. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.js +37 -0
  179. package/src/engine/physics/narrowphase/narrowphase_step.d.ts +41 -2
  180. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  181. package/src/engine/physics/narrowphase/narrowphase_step.js +1497 -382
  182. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
  183. package/src/engine/physics/narrowphase/sphere_box_contact.js +16 -23
  184. package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts +48 -0
  185. package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts.map +1 -0
  186. package/src/engine/physics/narrowphase/sphere_triangle_contact.js +143 -0
  187. package/src/engine/physics/queries/overlap_shape.d.ts +51 -0
  188. package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -0
  189. package/src/engine/physics/queries/overlap_shape.js +183 -0
  190. package/src/engine/physics/queries/shape_cast.d.ts +56 -0
  191. package/src/engine/physics/queries/shape_cast.d.ts.map +1 -0
  192. package/src/engine/physics/queries/shape_cast.js +387 -0
  193. package/src/engine/physics/solver/solve_contacts.d.ts +146 -32
  194. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
  195. package/src/engine/physics/solver/solve_contacts.js +809 -223
  196. package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts.map +0 -1
  197. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts +0 -20
  198. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts.map +0 -1
  199. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.js +0 -83
@@ -45,17 +45,21 @@ export class FluidField {
45
45
  * Per-cell pre-baked neighbourhood mask consumed by the pressure SOR loop.
46
46
  * One byte per cell encoding which of the 6 cardinal neighbours are fluid:
47
47
  *
48
- * bit 0 (= 1) : -x neighbour is fluid (in-bounds AND non-solid)
49
- * bit 1 (= 2) : +x neighbour is fluid
50
- * bit 2 (= 4) : -y neighbour is fluid
51
- * bit 3 (= 8) : +y neighbour is fluid
52
- * bit 4 (= 16) : -z neighbour is fluid
53
- * bit 5 (= 32) : +z neighbour is fluid
48
+ * bit 0 (= 1) : -x neighbour is fluid (in-bounds AND non-solid)
49
+ * bit 1 (= 2) : +x neighbour is fluid
50
+ * bit 2 (= 4) : -y neighbour is fluid
51
+ * bit 3 (= 8) : +y neighbour is fluid
52
+ * bit 4 (= 16) : -z neighbour is fluid
53
+ * bit 5 (= 32) : +z neighbour is fluid
54
+ * bit 7 (= 128) : this cell is itself solid
54
55
  *
55
- * Solid cells themselves are encoded as `mask = 0` so the SOR loop's
56
- * `if (mask === 0) continue` skip handles both "this cell is solid" and
57
- * "this fluid cell is isolated" with a single comparison instead of one
58
- * solid-self-check plus six solid-neighbour-checks plus six boundary checks.
56
+ * A solid cell encodes as `128` (bit 7 set, neighbour bits clear) and an
57
+ * isolated fluid cell as `0`, so the SOR / PCG loops' `if ((mask & 63) === 0)
58
+ * continue` skip handles both "this cell is solid" and "this fluid cell is
59
+ * isolated" with a single comparison instead of one solid-self-check plus six
60
+ * solid-neighbour-checks plus six boundary checks. Bit 7 additionally lets
61
+ * {@link v3_grid_subtract_pressure_gradient} zero solid-cell velocity without
62
+ * consulting the {@link solid} array.
59
63
  *
60
64
  * Computed once by {@link recomputeSolidNeighbourMask} after every solid-mask
61
65
  * mutation. The simulator runs that recompute at the top of every project()
@@ -1 +1 @@
1
- {"version":3,"file":"FluidField.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/fluid/FluidField.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAQI;;;;OAIG;IACH,YAFU,YAAY,GAAC,IAAI,CAET;IAElB;;OAEG;IACH,YAFU,YAAY,GAAC,IAAI,CAET;IAElB;;OAEG;IACH,YAFU,YAAY,GAAC,IAAI,CAET;IAElB;;;;;;OAMG;IACH,OAFU,UAAU,GAAC,IAAI,CAEZ;IAEb;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,sBAFU,UAAU,GAAC,IAAI,CAEG;IAE5B;;;;;;;;;;;;;OAaG;IACH,UAFU,YAAY,kBAAc,IAAI,CAExB;IAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,yBAFU,OAAO,CAEe;IAShC;;;;;;OAMG;IACH,qBAJW,MAAM,SACN,MAAM,SACN,MAAM,QAWhB;IAED;;;OAGG;IACH,iBAHY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAKnC;IAED;;;OAGG;IACH,aAHY,MAAM,CAKjB;IAED;;;;;;;;;OASG;IACH,gBAHW,MAAM,GACL,MAAM,CAejB;IAED;;;OAGG;IACH,kBAHW,MAAM,GACL,MAAM,CAIjB;IAED;;;;OAIG;IACH,oBAJW,MAAM,GACL,YAAY,GAAC,IAAI,CAM5B;IAED;;OAEG;IACH,uBAFY;QAAE,MAAM,MAAM,CAAC;QAAC,IAAI,EAAE,YAAY,CAAA;KAAE,EAAE,CAIjD;IAED;;;OAGG;IACH,cAmBC;IAED;;;;;;OAMG;IACH,aALW,MAAM,KACN,MAAM,KACN,MAAM,GACL,MAAM,CAajB;IAED;;;;;;;;OAQG;IACH,iBAPW,MAAM,KACN,MAAM,KACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAOhB;IAED;;;;;;;;OAQG;IACH,iBAPW,MAAM,KACN,MAAM,KACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,QAOhB;IAED;;;;;;OAMG;IACH,kCANW,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,SACN,MAAM,QAOhB;IAED;;;;;;OAMG;IACH,cALW,MAAM,KACN,MAAM,KACN,MAAM,YACN,OAAO,QAIjB;IAED;;;;;OAKG;IACH,aALW,MAAM,KACN,MAAM,KACN,MAAM,GACL,OAAO,CAIlB;IAED;;;;;;;;OAQG;IACH,oBANW,YAAY,GAAC,MAAM,EAAE,KACrB,MAAM,KACN,MAAM,KACN,MAAM,GACL,YAAY,GAAC,MAAM,EAAE,CAUhC;IAED;;;;;;;OAOG;IACH,mBANW,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,GACL,MAAM,CAMjB;IAED;;;;;;;;;;OAUG;IACH,cAHW,UAAU,GACT,OAAO,CAqDlB;IAED;;;;;;;;;;;OAWG;IACH,QAFY,MAAM,CAajB;IAED;;;;;;;;;OASG;IACH,oCASC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,eAJW,MAAM,WACN,MAAM,WACN,MAAM,QAyChB;IAED;;;;OAIG;IACH,cASC;;CACJ"}
1
+ {"version":3,"file":"FluidField.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/fluid/FluidField.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAQI;;;;OAIG;IACH,YAFU,YAAY,GAAC,IAAI,CAET;IAElB;;OAEG;IACH,YAFU,YAAY,GAAC,IAAI,CAET;IAElB;;OAEG;IACH,YAFU,YAAY,GAAC,IAAI,CAET;IAElB;;;;;;OAMG;IACH,OAFU,UAAU,GAAC,IAAI,CAEZ;IAEb;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,sBAFU,UAAU,GAAC,IAAI,CAEG;IAE5B;;;;;;;;;;;;;OAaG;IACH,UAFU,YAAY,kBAAc,IAAI,CAExB;IAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,yBAFU,OAAO,CAEe;IAShC;;;;;;OAMG;IACH,qBAJW,MAAM,SACN,MAAM,SACN,MAAM,QAWhB;IAED;;;OAGG;IACH,iBAHY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAKnC;IAED;;;OAGG;IACH,aAHY,MAAM,CAKjB;IAED;;;;;;;;;OASG;IACH,gBAHW,MAAM,GACL,MAAM,CAejB;IAED;;;OAGG;IACH,kBAHW,MAAM,GACL,MAAM,CAIjB;IAED;;;;OAIG;IACH,oBAJW,MAAM,GACL,YAAY,GAAC,IAAI,CAM5B;IAED;;OAEG;IACH,uBAFY;QAAE,MAAM,MAAM,CAAC;QAAC,IAAI,EAAE,YAAY,CAAA;KAAE,EAAE,CAIjD;IAED;;;OAGG;IACH,cAmBC;IAED;;;;;;OAMG;IACH,aALW,MAAM,KACN,MAAM,KACN,MAAM,GACL,MAAM,CAajB;IAED;;;;;;;;OAQG;IACH,iBAPW,MAAM,KACN,MAAM,KACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAOhB;IAED;;;;;;;;OAQG;IACH,iBAPW,MAAM,KACN,MAAM,KACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,QAOhB;IAED;;;;;;OAMG;IACH,kCANW,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,SACN,MAAM,QAOhB;IAED;;;;;;OAMG;IACH,cALW,MAAM,KACN,MAAM,KACN,MAAM,YACN,OAAO,QAIjB;IAED;;;;;OAKG;IACH,aALW,MAAM,KACN,MAAM,KACN,MAAM,GACL,OAAO,CAIlB;IAED;;;;;;;;OAQG;IACH,oBANW,YAAY,GAAC,MAAM,EAAE,KACrB,MAAM,KACN,MAAM,KACN,MAAM,GACL,YAAY,GAAC,MAAM,EAAE,CAUhC;IAED;;;;;;;OAOG;IACH,mBANW,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,GACL,MAAM,CAMjB;IAED;;;;;;;;;;OAUG;IACH,cAHW,UAAU,GACT,OAAO,CAqDlB;IAED;;;;;;;;;;;OAWG;IACH,QAFY,MAAM,CAajB;IAED;;;;;;;;;OASG;IACH,oCASC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,eAJW,MAAM,WACN,MAAM,WACN,MAAM,QAyChB;IAED;;;;OAIG;IACH,cASC;;CACJ"}
@@ -65,17 +65,21 @@ export class FluidField {
65
65
  * Per-cell pre-baked neighbourhood mask consumed by the pressure SOR loop.
66
66
  * One byte per cell encoding which of the 6 cardinal neighbours are fluid:
67
67
  *
68
- * bit 0 (= 1) : -x neighbour is fluid (in-bounds AND non-solid)
69
- * bit 1 (= 2) : +x neighbour is fluid
70
- * bit 2 (= 4) : -y neighbour is fluid
71
- * bit 3 (= 8) : +y neighbour is fluid
72
- * bit 4 (= 16) : -z neighbour is fluid
73
- * bit 5 (= 32) : +z neighbour is fluid
68
+ * bit 0 (= 1) : -x neighbour is fluid (in-bounds AND non-solid)
69
+ * bit 1 (= 2) : +x neighbour is fluid
70
+ * bit 2 (= 4) : -y neighbour is fluid
71
+ * bit 3 (= 8) : +y neighbour is fluid
72
+ * bit 4 (= 16) : -z neighbour is fluid
73
+ * bit 5 (= 32) : +z neighbour is fluid
74
+ * bit 7 (= 128) : this cell is itself solid
74
75
  *
75
- * Solid cells themselves are encoded as `mask = 0` so the SOR loop's
76
- * `if (mask === 0) continue` skip handles both "this cell is solid" and
77
- * "this fluid cell is isolated" with a single comparison instead of one
78
- * solid-self-check plus six solid-neighbour-checks plus six boundary checks.
76
+ * A solid cell encodes as `128` (bit 7 set, neighbour bits clear) and an
77
+ * isolated fluid cell as `0`, so the SOR / PCG loops' `if ((mask & 63) === 0)
78
+ * continue` skip handles both "this cell is solid" and "this fluid cell is
79
+ * isolated" with a single comparison instead of one solid-self-check plus six
80
+ * solid-neighbour-checks plus six boundary checks. Bit 7 additionally lets
81
+ * {@link v3_grid_subtract_pressure_gradient} zero solid-cell velocity without
82
+ * consulting the {@link solid} array.
79
83
  *
80
84
  * Computed once by {@link recomputeSolidNeighbourMask} after every solid-mask
81
85
  * mutation. The simulator runs that recompute at the top of every project()
@@ -332,7 +332,7 @@ export class FluidSimulator {
332
332
  field.velocity_x, field.velocity_y, field.velocity_z,
333
333
  field.pressure,
334
334
  res[0], res[1], res[2],
335
- solid
335
+ field.solid_neighbour_mask
336
336
  );
337
337
  }
338
338
 
@@ -4,18 +4,25 @@
4
4
  * {@link v3_grid_solve_pressure}, which uses the mask to skip boundary checks
5
5
  * and solid-neighbour checks entirely.
6
6
  *
7
- * Encoding (one byte per cell, low 6 bits):
7
+ * Encoding (one byte per cell):
8
8
  *
9
- * bit 0 (= 1) : -x neighbour is fluid
10
- * bit 1 (= 2) : +x neighbour is fluid
11
- * bit 2 (= 4) : -y neighbour is fluid
12
- * bit 3 (= 8) : +y neighbour is fluid
13
- * bit 4 (= 16) : -z neighbour is fluid
14
- * bit 5 (= 32) : +z neighbour is fluid
9
+ * bit 0 (= 1) : -x neighbour is fluid
10
+ * bit 1 (= 2) : +x neighbour is fluid
11
+ * bit 2 (= 4) : -y neighbour is fluid
12
+ * bit 3 (= 8) : +y neighbour is fluid
13
+ * bit 4 (= 16) : -z neighbour is fluid
14
+ * bit 5 (= 32) : +z neighbour is fluid
15
+ * bit 7 (= 128) : this cell is itself solid
15
16
  *
16
- * Solid cells themselves are encoded as `mask = 0` (not "their own neighbours
17
- * are fluid") so the SOR loop's `mask === 0 skip` branch covers both
18
- * "self-solid" and "fluid but no fluid neighbours" with one comparison.
17
+ * The low 6 bits are the fluid-neighbour set; bit 7 flags the cell as solid.
18
+ * A solid cell encodes as exactly `128` bit 7 set, every neighbour bit clear
19
+ * and an isolated fluid cell (no fluid neighbours) as `0`. Both therefore
20
+ * satisfy `(mask & 63) === 0`, so the SOR / PCG loops' "no fluid neighbours →
21
+ * skip" branch is a single `(mask & 63) === 0` comparison that covers
22
+ * "self-solid" and "fluid but no fluid neighbours" alike. The dedicated bit 7
23
+ * additionally lets {@link v3_grid_subtract_pressure_gradient} tell solid cells
24
+ * (zero the velocity) apart from isolated fluid (leave it) without the original
25
+ * `solid` array.
19
26
  *
20
27
  * O(N) — one byte-write per cell, up to six byte-reads per cell. The output
21
28
  * fully replaces whatever was in `mask` before; no need to zero-init.
@@ -1 +1 @@
1
- {"version":3,"file":"v3_grid_compute_solid_neighbour_mask.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,2DANW,UAAU,SACV,UAAU,SACV,MAAM,SACN,MAAM,SACN,MAAM,QAqChB"}
1
+ {"version":3,"file":"v3_grid_compute_solid_neighbour_mask.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,2DANW,UAAU,SACV,UAAU,SACV,MAAM,SACN,MAAM,SACN,MAAM,QAqChB"}
@@ -6,18 +6,25 @@ import { assert } from "../../../../core/assert.js";
6
6
  * {@link v3_grid_solve_pressure}, which uses the mask to skip boundary checks
7
7
  * and solid-neighbour checks entirely.
8
8
  *
9
- * Encoding (one byte per cell, low 6 bits):
9
+ * Encoding (one byte per cell):
10
10
  *
11
- * bit 0 (= 1) : -x neighbour is fluid
12
- * bit 1 (= 2) : +x neighbour is fluid
13
- * bit 2 (= 4) : -y neighbour is fluid
14
- * bit 3 (= 8) : +y neighbour is fluid
15
- * bit 4 (= 16) : -z neighbour is fluid
16
- * bit 5 (= 32) : +z neighbour is fluid
11
+ * bit 0 (= 1) : -x neighbour is fluid
12
+ * bit 1 (= 2) : +x neighbour is fluid
13
+ * bit 2 (= 4) : -y neighbour is fluid
14
+ * bit 3 (= 8) : +y neighbour is fluid
15
+ * bit 4 (= 16) : -z neighbour is fluid
16
+ * bit 5 (= 32) : +z neighbour is fluid
17
+ * bit 7 (= 128) : this cell is itself solid
17
18
  *
18
- * Solid cells themselves are encoded as `mask = 0` (not "their own neighbours
19
- * are fluid") so the SOR loop's `mask === 0 skip` branch covers both
20
- * "self-solid" and "fluid but no fluid neighbours" with one comparison.
19
+ * The low 6 bits are the fluid-neighbour set; bit 7 flags the cell as solid.
20
+ * A solid cell encodes as exactly `128` bit 7 set, every neighbour bit clear
21
+ * and an isolated fluid cell (no fluid neighbours) as `0`. Both therefore
22
+ * satisfy `(mask & 63) === 0`, so the SOR / PCG loops' "no fluid neighbours →
23
+ * skip" branch is a single `(mask & 63) === 0` comparison that covers
24
+ * "self-solid" and "fluid but no fluid neighbours" alike. The dedicated bit 7
25
+ * additionally lets {@link v3_grid_subtract_pressure_gradient} tell solid cells
26
+ * (zero the velocity) apart from isolated fluid (leave it) without the original
27
+ * `solid` array.
21
28
  *
22
29
  * O(N) — one byte-write per cell, up to six byte-reads per cell. The output
23
30
  * fully replaces whatever was in `mask` before; no need to zero-init.
@@ -49,7 +56,7 @@ export function v3_grid_compute_solid_neighbour_mask(mask, solid, res_x, res_y,
49
56
  for (let x = 0; x < res_x; x++) {
50
57
  const c = y_off + x;
51
58
  if (solid[c] !== 0) {
52
- mask[c] = 0;
59
+ mask[c] = 128; // bit 7 = this cell is solid; neighbour bits stay clear
53
60
  continue;
54
61
  }
55
62
  let m = 0;
@@ -11,17 +11,20 @@
11
11
  * a Uint8Array allocated and populated by {@link FluidField} via
12
12
  * {@link FluidField.recomputeSolidNeighbourMask}. The encoding is:
13
13
  *
14
- * bit 0 (= 1) : -x neighbour is fluid
15
- * bit 1 (= 2) : +x neighbour is fluid
16
- * bit 2 (= 4) : -y neighbour is fluid
17
- * bit 3 (= 8) : +y neighbour is fluid
18
- * bit 4 (= 16) : -z neighbour is fluid
19
- * bit 5 (= 32) : +z neighbour is fluid
14
+ * bit 0 (= 1) : -x neighbour is fluid
15
+ * bit 1 (= 2) : +x neighbour is fluid
16
+ * bit 2 (= 4) : -y neighbour is fluid
17
+ * bit 3 (= 8) : +y neighbour is fluid
18
+ * bit 4 (= 16) : -z neighbour is fluid
19
+ * bit 5 (= 32) : +z neighbour is fluid
20
+ * bit 7 (= 128) : this cell is itself solid (consumed by
21
+ * {@link v3_grid_subtract_pressure_gradient}, ignored here)
20
22
  *
21
- * Solid cells encode as `mask = 0`, so the inner loop's `mask === 0 ? skip` covers
22
- * both self-solid AND fluid-with-no-fluid-neighbours in one comparison. This
23
- * eliminates six boundary checks plus six solid-neighbour checks per cell per
24
- * iteration, replacing them with a single mask read and six bit-tests on a
23
+ * The low 6 bits are the fluid-neighbour set. A solid cell encodes as `128` and
24
+ * an isolated fluid cell as `0`, so the inner loop's `(mask & 63) === 0 ? skip`
25
+ * covers both self-solid AND fluid-with-no-fluid-neighbours in one comparison.
26
+ * This eliminates six boundary checks plus six solid-neighbour checks per cell
27
+ * per iteration, replacing them with a single mask read and six bit-tests on a
25
28
  * register-resident value. Boundary handling (cells at x=0, x=last, etc.) is
26
29
  * implicit — the recompute step writes 0 into the boundary-facing bit, so the
27
30
  * SOR loop never reads out-of-range memory.
@@ -1 +1 @@
1
- {"version":3,"file":"v3_grid_solve_pressure.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_solve_pressure.js"],"names":[],"mappings":"AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,iDAdW,YAAY,eAAa,cAEzB,YAAY,eAAa,SAEzB,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,MAAM,kBAEN,UAAU,QA+DpB"}
1
+ {"version":3,"file":"v3_grid_solve_pressure.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_solve_pressure.js"],"names":[],"mappings":"AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,iDAdW,YAAY,eAAa,cAEzB,YAAY,eAAa,SAEzB,MAAM,SACN,MAAM,SACN,MAAM,cACN,MAAM,SACN,MAAM,kBAEN,UAAU,QAiEpB"}
@@ -30,17 +30,20 @@ const POPCOUNT_6 = (function () {
30
30
  * a Uint8Array allocated and populated by {@link FluidField} via
31
31
  * {@link FluidField.recomputeSolidNeighbourMask}. The encoding is:
32
32
  *
33
- * bit 0 (= 1) : -x neighbour is fluid
34
- * bit 1 (= 2) : +x neighbour is fluid
35
- * bit 2 (= 4) : -y neighbour is fluid
36
- * bit 3 (= 8) : +y neighbour is fluid
37
- * bit 4 (= 16) : -z neighbour is fluid
38
- * bit 5 (= 32) : +z neighbour is fluid
33
+ * bit 0 (= 1) : -x neighbour is fluid
34
+ * bit 1 (= 2) : +x neighbour is fluid
35
+ * bit 2 (= 4) : -y neighbour is fluid
36
+ * bit 3 (= 8) : +y neighbour is fluid
37
+ * bit 4 (= 16) : -z neighbour is fluid
38
+ * bit 5 (= 32) : +z neighbour is fluid
39
+ * bit 7 (= 128) : this cell is itself solid (consumed by
40
+ * {@link v3_grid_subtract_pressure_gradient}, ignored here)
39
41
  *
40
- * Solid cells encode as `mask = 0`, so the inner loop's `mask === 0 ? skip` covers
41
- * both self-solid AND fluid-with-no-fluid-neighbours in one comparison. This
42
- * eliminates six boundary checks plus six solid-neighbour checks per cell per
43
- * iteration, replacing them with a single mask read and six bit-tests on a
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
44
47
  * register-resident value. Boundary handling (cells at x=0, x=last, etc.) is
45
48
  * implicit — the recompute step writes 0 into the boundary-facing bit, so the
46
49
  * SOR loop never reads out-of-range memory.
@@ -101,9 +104,11 @@ export function v3_grid_solve_pressure(pressure, divergence, res_x, res_y, res_z
101
104
  const c = z_off + y_off + x;
102
105
 
103
106
  const mask = neighbour_mask[c];
104
- if (mask === 0) {
105
- // Solid cell OR isolated fluid with no fluid neighbours.
106
- // Either way, no degrees of freedom — skip.
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.
107
112
  continue;
108
113
  }
109
114
 
@@ -69,9 +69,10 @@
69
69
  * the hot path that prevents MIC-PCG from parallelizing onto a GPU without
70
70
  * substantial reformulation. On single-thread JS that's not a concern.
71
71
  *
72
- * Solid cells (mask = 0) are excluded from the system: their pressure stays at
73
- * whatever it was (typically 0), their entries in r, z, s, As stay 0, and they
74
- * contribute nothing to dot products.
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.
75
76
  *
76
77
  * @param {Float32Array|Float16Array} pressure Mutated in place. Pre-fill with 0
77
78
  * or with the previous step's solution to warm-start.
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;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,QAuNtB"}
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"}
@@ -108,9 +108,10 @@ const MIC_SIGMA = 0.25;
108
108
  * the hot path that prevents MIC-PCG from parallelizing onto a GPU without
109
109
  * substantial reformulation. On single-thread JS that's not a concern.
110
110
  *
111
- * Solid cells (mask = 0) are excluded from the system: their pressure stays at
112
- * whatever it was (typically 0), their entries in r, z, s, As stay 0, and they
113
- * contribute nothing to dot products.
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.
114
115
  *
115
116
  * @param {Float32Array|Float16Array} pressure Mutated in place. Pre-fill with 0
116
117
  * or with the previous step's solution to warm-start.
@@ -173,9 +174,12 @@ export function v3_grid_solve_pressure_pcg(
173
174
  // (Standard fluids practice — see Bridson §5.5. The alternative is to pin
174
175
  // one cell to a Dirichlet value and exclude it from the system, but mean
175
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.
176
180
  let fluid_count = 0;
177
181
  for (let c = 0; c < cells; c++) {
178
- if (neighbour_mask[c] !== 0) fluid_count++;
182
+ if ((neighbour_mask[c] & 63) !== 0) fluid_count++;
179
183
  }
180
184
  if (fluid_count === 0) {
181
185
  return;
@@ -193,7 +197,7 @@ export function v3_grid_solve_pressure_pcg(
193
197
  precon.fill(0);
194
198
  for (let c = 0; c < cells; c++) {
195
199
  const mask = neighbour_mask[c];
196
- if (mask === 0) {
200
+ if ((mask & 63) === 0) {
197
201
  continue;
198
202
  }
199
203
  const a_diag = POPCOUNT_6[mask];
@@ -246,7 +250,7 @@ export function v3_grid_solve_pressure_pcg(
246
250
 
247
251
  for (let c = 0; c < cells; c++) {
248
252
  const mask = neighbour_mask[c];
249
- if (mask === 0) {
253
+ if ((mask & 63) === 0) {
250
254
  r[c] = 0;
251
255
  continue;
252
256
  }
@@ -285,7 +289,7 @@ export function v3_grid_solve_pressure_pcg(
285
289
  let s_dot_As = 0;
286
290
  for (let c = 0; c < cells; c++) {
287
291
  const mask = neighbour_mask[c];
288
- if (mask === 0) {
292
+ if ((mask & 63) === 0) {
289
293
  As[c] = 0;
290
294
  continue;
291
295
  }
@@ -379,11 +383,11 @@ export function v3_grid_solve_pressure_pcg(
379
383
  function subtract_mean_fluid(v, mask_array, cells, fluid_count) {
380
384
  let sum = 0;
381
385
  for (let c = 0; c < cells; c++) {
382
- if (mask_array[c] !== 0) sum += v[c];
386
+ if ((mask_array[c] & 63) !== 0) sum += v[c];
383
387
  }
384
388
  const mean = sum / fluid_count;
385
389
  for (let c = 0; c < cells; c++) {
386
- if (mask_array[c] !== 0) v[c] -= mean;
390
+ if ((mask_array[c] & 63) !== 0) v[c] -= mean;
387
391
  }
388
392
  }
389
393
 
@@ -391,7 +395,7 @@ function apply_preconditioner(r, z, precon, mask_array, cells, rx, slice) {
391
395
  // Forward solve L · y = r. Store y in z (we won't read z[c'] for c' > c).
392
396
  for (let c = 0; c < cells; c++) {
393
397
  const mask = mask_array[c];
394
- if (mask === 0) {
398
+ if ((mask & 63) === 0) {
395
399
  z[c] = 0;
396
400
  continue;
397
401
  }
@@ -410,7 +414,7 @@ function apply_preconditioner(r, z, precon, mask_array, cells, rx, slice) {
410
414
  // indices, processed first in reverse).
411
415
  for (let c = cells - 1; c >= 0; c--) {
412
416
  const mask = mask_array[c];
413
- if (mask === 0) {
417
+ if ((mask & 63) === 0) {
414
418
  continue;
415
419
  }
416
420
  let t = z[c]; // = y[c] from forward pass
@@ -13,14 +13,38 @@
13
13
  * pressure (consistent with the Neumann condition used in the solve), which keeps the
14
14
  * flow tangent to the boundary.
15
15
  *
16
- * @param {Float32Array} vel_x Mutated in place.
17
- * @param {Float32Array} vel_y Mutated in place.
18
- * @param {Float32Array} vel_z Mutated in place.
19
- * @param {Float32Array} pressure From {@link v3_grid_solve_pressure}.
16
+ * Everything this needs is read straight from `neighbour_mask`, the same pre-baked
17
+ * per-cell bitmask {@link v3_grid_solve_pressure} consumes (populated by
18
+ * {@link FluidField.recomputeSolidNeighbourMask}). Encoding:
19
+ *
20
+ * bit 0 (= 1) : -x neighbour is fluid
21
+ * bit 1 (= 2) : +x neighbour is fluid
22
+ * bit 2 (= 4) : -y neighbour is fluid
23
+ * bit 3 (= 8) : +y neighbour is fluid
24
+ * bit 4 (= 16) : -z neighbour is fluid
25
+ * bit 5 (= 32) : +z neighbour is fluid
26
+ * bit 7 (= 128) : this cell is itself solid
27
+ *
28
+ * A set neighbour bit means "that neighbour is fluid (in-bounds AND non-solid)", so a
29
+ * clear bit reflects the cell's own pressure — folding the boundary check and the
30
+ * solid-neighbour check into one register-resident bit-test per face.
31
+ *
32
+ * Bit 7 carries the self-solid flag that used to require the separate `solid` array.
33
+ * The solve can't use the low 6 bits for this (a solid cell and an isolated fluid cell
34
+ * both have zero fluid-neighbour bits) but needs opposite handling here — the solid
35
+ * must be zeroed for no-slip, while the isolated fluid's gradient already nets to zero
36
+ * (every face reflects its own pressure) and must be left alone. Bit 7 distinguishes
37
+ * them, so a single mask read drives both the zeroing and the gradient.
38
+ *
39
+ * @param {Float32Array} vel_x Mutated in place.
40
+ * @param {Float32Array} vel_y Mutated in place.
41
+ * @param {Float32Array} vel_z Mutated in place.
42
+ * @param {Float32Array} pressure From {@link v3_grid_solve_pressure}.
20
43
  * @param {number} res_x
21
44
  * @param {number} res_y
22
45
  * @param {number} res_z
23
- * @param {Uint8Array} solid Required (zero-filled for a wall-free domain).
46
+ * @param {Uint8Array} neighbour_mask Length res_x*res_y*res_z. Same buffer the
47
+ * pressure solve uses; MUST be recomputed whenever the solid mask changes.
24
48
  */
25
- export function v3_grid_subtract_pressure_gradient(vel_x: Float32Array, vel_y: Float32Array, vel_z: Float32Array, pressure: Float32Array, res_x: number, res_y: number, res_z: number, solid: Uint8Array): void;
49
+ export function v3_grid_subtract_pressure_gradient(vel_x: Float32Array, vel_y: Float32Array, vel_z: Float32Array, pressure: Float32Array, res_x: number, res_y: number, res_z: number, neighbour_mask: Uint8Array): void;
26
50
  //# sourceMappingURL=v3_grid_subtract_pressure_gradient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"v3_grid_subtract_pressure_gradient.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,0DATW,YAAY,SACZ,YAAY,SACZ,YAAY,YACZ,YAAY,SACZ,MAAM,SACN,MAAM,SACN,MAAM,SACN,UAAU,QA6CpB"}
1
+ {"version":3,"file":"v3_grid_subtract_pressure_gradient.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,0DAVW,YAAY,SACZ,YAAY,SACZ,YAAY,YACZ,YAAY,SACZ,MAAM,SACN,MAAM,SACN,MAAM,kBACN,UAAU,QAgDpB"}
@@ -15,26 +15,48 @@ import { assert } from "../../../../core/assert.js";
15
15
  * pressure (consistent with the Neumann condition used in the solve), which keeps the
16
16
  * flow tangent to the boundary.
17
17
  *
18
- * @param {Float32Array} vel_x Mutated in place.
19
- * @param {Float32Array} vel_y Mutated in place.
20
- * @param {Float32Array} vel_z Mutated in place.
21
- * @param {Float32Array} pressure From {@link v3_grid_solve_pressure}.
18
+ * Everything this needs is read straight from `neighbour_mask`, the same pre-baked
19
+ * per-cell bitmask {@link v3_grid_solve_pressure} consumes (populated by
20
+ * {@link FluidField.recomputeSolidNeighbourMask}). Encoding:
21
+ *
22
+ * bit 0 (= 1) : -x neighbour is fluid
23
+ * bit 1 (= 2) : +x neighbour is fluid
24
+ * bit 2 (= 4) : -y neighbour is fluid
25
+ * bit 3 (= 8) : +y neighbour is fluid
26
+ * bit 4 (= 16) : -z neighbour is fluid
27
+ * bit 5 (= 32) : +z neighbour is fluid
28
+ * bit 7 (= 128) : this cell is itself solid
29
+ *
30
+ * A set neighbour bit means "that neighbour is fluid (in-bounds AND non-solid)", so a
31
+ * clear bit reflects the cell's own pressure — folding the boundary check and the
32
+ * solid-neighbour check into one register-resident bit-test per face.
33
+ *
34
+ * Bit 7 carries the self-solid flag that used to require the separate `solid` array.
35
+ * The solve can't use the low 6 bits for this (a solid cell and an isolated fluid cell
36
+ * both have zero fluid-neighbour bits) but needs opposite handling here — the solid
37
+ * must be zeroed for no-slip, while the isolated fluid's gradient already nets to zero
38
+ * (every face reflects its own pressure) and must be left alone. Bit 7 distinguishes
39
+ * them, so a single mask read drives both the zeroing and the gradient.
40
+ *
41
+ * @param {Float32Array} vel_x Mutated in place.
42
+ * @param {Float32Array} vel_y Mutated in place.
43
+ * @param {Float32Array} vel_z Mutated in place.
44
+ * @param {Float32Array} pressure From {@link v3_grid_solve_pressure}.
22
45
  * @param {number} res_x
23
46
  * @param {number} res_y
24
47
  * @param {number} res_z
25
- * @param {Uint8Array} solid Required (zero-filled for a wall-free domain).
48
+ * @param {Uint8Array} neighbour_mask Length res_x*res_y*res_z. Same buffer the
49
+ * pressure solve uses; MUST be recomputed whenever the solid mask changes.
26
50
  */
27
- export function v3_grid_subtract_pressure_gradient(vel_x, vel_y, vel_z, pressure, res_x, res_y, res_z, solid) {
51
+ export function v3_grid_subtract_pressure_gradient(vel_x, vel_y, vel_z, pressure, res_x, res_y, res_z, neighbour_mask) {
28
52
  const cell_count = res_x * res_y * res_z;
29
53
  assert.greaterThanOrEqual(vel_x.length, cell_count, "vel_x covers grid");
30
54
  assert.greaterThanOrEqual(vel_y.length, cell_count, "vel_y covers grid");
31
55
  assert.greaterThanOrEqual(vel_z.length, cell_count, "vel_z covers grid");
32
56
  assert.greaterThanOrEqual(pressure.length, cell_count, "pressure covers grid");
57
+ assert.greaterThanOrEqual(neighbour_mask.length, cell_count, "neighbour_mask covers grid");
33
58
 
34
59
  const slice_size = res_x * res_y;
35
- const last_x = res_x - 1;
36
- const last_y = res_y - 1;
37
- const last_z = res_z - 1;
38
60
 
39
61
  for (let z = 0; z < res_z; z++) {
40
62
  const z_off = z * slice_size;
@@ -45,21 +67,25 @@ export function v3_grid_subtract_pressure_gradient(vel_x, vel_y, vel_z, pressure
45
67
  for (let x = 0; x < res_x; x++) {
46
68
  const c = z_off + y_off + x;
47
69
 
48
- if (solid[c] !== 0) {
70
+ const mask = neighbour_mask[c];
71
+
72
+ if (mask & 128) {
73
+ // Solid cell (bit 7): enforce no-slip.
49
74
  vel_x[c] = 0;
50
75
  vel_y[c] = 0;
51
76
  vel_z[c] = 0;
52
77
  continue;
53
78
  }
54
79
 
55
- // Reflect pressure across a solid neighbour: that face contributes 0
56
- // to the gradient, consistent with ∂p/∂n = 0 at the wall.
57
- const p_xm = (x > 0 && solid[c - 1] === 0) ? pressure[c - 1] : pressure[c];
58
- const p_xp = (x < last_x && solid[c + 1] === 0) ? pressure[c + 1] : pressure[c];
59
- const p_ym = (y > 0 && solid[c - res_x] === 0) ? pressure[c - res_x] : pressure[c];
60
- const p_yp = (y < last_y && solid[c + res_x] === 0) ? pressure[c + res_x] : pressure[c];
61
- const p_zm = (z > 0 && solid[c - slice_size] === 0) ? pressure[c - slice_size] : pressure[c];
62
- const p_zp = (z < last_z && solid[c + slice_size] === 0) ? pressure[c + slice_size] : pressure[c];
80
+ // A clear bit means the neighbour is out-of-bounds or solid; reflect
81
+ // the cell's own pressure so that face contributes 0 to the gradient,
82
+ // consistent with ∂p/∂n = 0 at the wall.
83
+ const p_xm = (mask & 1) ? pressure[c - 1] : pressure[c];
84
+ const p_xp = (mask & 2) ? pressure[c + 1] : pressure[c];
85
+ const p_ym = (mask & 4) ? pressure[c - res_x] : pressure[c];
86
+ const p_yp = (mask & 8) ? pressure[c + res_x] : pressure[c];
87
+ const p_zm = (mask & 16) ? pressure[c - slice_size] : pressure[c];
88
+ const p_zp = (mask & 32) ? pressure[c + slice_size] : pressure[c];
63
89
 
64
90
  vel_x[c] -= 0.5 * (p_xp - p_xm);
65
91
  vel_y[c] -= 0.5 * (p_yp - p_ym);
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * TODO: needs to be tested thoroughly, intended to be working with GJK
3
- * @param {number[]} result
3
+ * @param {number[]|Float64Array} result
4
4
  * @param {number} result_offset
5
- * @param {number[]} a
6
- * @param {number[]} b
7
- * @param {number[]} c
8
- * @param {number[]} d
5
+ * @param {number[]|Float64Array} a
6
+ * @param {number[]|Float64Array} b
7
+ * @param {number[]|Float64Array} c
8
+ * @param {number[]|Float64Array} d
9
9
  * @param {AbstractShape3D} coll1
10
10
  * @param {AbstractShape3D} coll2
11
11
  */
12
- export function expanding_polytope_algorithm(result: number[], result_offset: number, a: number[], b: number[], c: number[], d: number[], coll1: AbstractShape3D, coll2: AbstractShape3D): void;
12
+ export function expanding_polytope_algorithm(result: number[] | Float64Array, result_offset: number, a: number[] | Float64Array, b: number[] | Float64Array, c: number[] | Float64Array, d: number[] | Float64Array, coll1: AbstractShape3D, coll2: AbstractShape3D): void;
13
13
  //# sourceMappingURL=expanding_polytope_algorithm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"expanding_polytope_algorithm.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/gjk/expanding_polytope_algorithm.js"],"names":[],"mappings":"AAgEA;;;;;;;;;;GAUG;AACH,qDATW,MAAM,EAAE,iBACR,MAAM,KACN,MAAM,EAAE,KACR,MAAM,EAAE,KACR,MAAM,EAAE,KACR,MAAM,EAAE,wDA8PlB"}
1
+ {"version":3,"file":"expanding_polytope_algorithm.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/gjk/expanding_polytope_algorithm.js"],"names":[],"mappings":"AAqGA;;;;;;;;;;GAUG;AACH,qDATW,MAAM,EAAE,GAAC,YAAY,iBACrB,MAAM,KACN,MAAM,EAAE,GAAC,YAAY,KACrB,MAAM,EAAE,GAAC,YAAY,KACrB,MAAM,EAAE,GAAC,YAAY,KACrB,MAAM,EAAE,GAAC,YAAY,wDAuQ/B"}