@woosh/meep-engine 3.22.0 → 3.23.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 (267) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts +118 -0
  3. package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts.map +1 -0
  4. package/src/core/geom/3d/hash-grid/PointHashGrid3.js +283 -0
  5. package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -1
  6. package/src/core/geom/3d/shape/BoxShape3D.js +6 -17
  7. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
  8. package/src/core/geom/3d/shape/CapsuleShape3D.js +3 -14
  9. package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
  10. package/src/core/geom/3d/shape/CylinderShape3D.js +3 -21
  11. package/src/core/geom/3d/shape/PlaneShape3D.d.ts +105 -0
  12. package/src/core/geom/3d/shape/PlaneShape3D.d.ts.map +1 -0
  13. package/src/core/geom/3d/shape/PlaneShape3D.js +251 -0
  14. package/src/core/geom/3d/shape/SphereShape3D.js +3 -3
  15. package/src/core/geom/3d/shape/json/shape_to_type.d.ts.map +1 -1
  16. package/src/core/geom/3d/shape/json/shape_to_type.js +3 -0
  17. package/src/core/geom/3d/shape/json/type_adapters.d.ts +14 -0
  18. package/src/core/geom/3d/shape/json/type_adapters.d.ts.map +1 -1
  19. package/src/core/geom/3d/shape/json/type_adapters.js +15 -0
  20. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts +51 -0
  21. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts.map +1 -0
  22. package/src/core/geom/3d/shape/sdf/sdf3_box.js +113 -0
  23. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts +46 -0
  24. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts.map +1 -0
  25. package/src/core/geom/3d/shape/sdf/sdf3_capsule.js +82 -0
  26. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts +60 -0
  27. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts.map +1 -0
  28. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.js +126 -0
  29. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts +50 -0
  30. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts.map +1 -0
  31. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.js +53 -0
  32. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts +52 -0
  33. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts.map +1 -0
  34. package/src/core/geom/3d/shape/sdf/sdf3_plane.js +61 -0
  35. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts +41 -0
  36. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts.map +1 -0
  37. package/src/core/geom/3d/shape/sdf/sdf3_sphere.js +71 -0
  38. package/src/core/process/ConcurrencyGate.d.ts +103 -0
  39. package/src/core/process/ConcurrencyGate.d.ts.map +1 -0
  40. package/src/core/process/ConcurrencyGate.js +207 -0
  41. package/src/engine/asset/AssetManager.d.ts +10 -0
  42. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  43. package/src/engine/asset/AssetManager.js +10 -0
  44. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +30 -13
  45. package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts +26 -0
  46. package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts.map +1 -0
  47. package/src/engine/graphics3/pose/collect_entity_playbacks.js +40 -0
  48. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  49. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +74 -101
  50. package/src/engine/physics/cloth/MEASUREMENTS.md +1287 -4
  51. package/src/engine/physics/cloth/PLAN.md +1967 -1581
  52. package/src/engine/physics/cloth/build/ClothProxy.d.ts +147 -0
  53. package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -0
  54. package/src/engine/physics/cloth/build/ClothProxy.js +207 -0
  55. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +70 -0
  56. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -0
  57. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +256 -0
  58. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +176 -0
  59. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -0
  60. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +435 -0
  61. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts +12 -0
  62. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts.map +1 -0
  63. package/src/engine/physics/cloth/collider/ClothColliderKind.js +38 -0
  64. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts +120 -0
  65. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts.map +1 -0
  66. package/src/engine/physics/cloth/collider/ClothColliderRecord.js +137 -0
  67. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts +25 -0
  68. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -0
  69. package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +190 -0
  70. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +44 -0
  71. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -0
  72. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +173 -0
  73. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +94 -0
  74. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -0
  75. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +275 -0
  76. package/src/engine/physics/cloth/ecs/ClothCollider.d.ts +126 -0
  77. package/src/engine/physics/cloth/ecs/ClothCollider.d.ts.map +1 -0
  78. package/src/engine/physics/cloth/ecs/ClothCollider.js +199 -0
  79. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +9 -0
  80. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts.map +1 -0
  81. package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +32 -0
  82. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +114 -0
  83. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -0
  84. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +243 -0
  85. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +66 -57
  86. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +109 -1
  87. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  88. package/src/engine/physics/cloth/ecs/ClothInstance.js +479 -363
  89. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +95 -0
  90. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -0
  91. package/src/engine/physics/cloth/ecs/ClothRig.js +140 -0
  92. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +30 -1
  93. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  94. package/src/engine/physics/cloth/ecs/ClothSystem.js +1021 -773
  95. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +90 -0
  96. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -0
  97. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +374 -0
  98. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts +32 -3
  99. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts.map +1 -1
  100. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.js +283 -254
  101. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +59 -0
  102. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -0
  103. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +328 -0
  104. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +13 -0
  105. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -0
  106. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +288 -0
  107. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +58 -0
  108. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -0
  109. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +199 -0
  110. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +8 -63
  111. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  112. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +317 -645
  113. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +61 -0
  114. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  115. package/src/engine/physics/cloth/ecs/cloth_write_back.js +212 -449
  116. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +49 -0
  117. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -0
  118. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +115 -0
  119. package/src/engine/physics/cloth/playground/README.md +155 -1
  120. package/src/engine/physics/cloth/playground/collide.html +178 -0
  121. package/src/engine/physics/cloth/playground/collide_build.d.ts +95 -0
  122. package/src/engine/physics/cloth/playground/collide_build.d.ts.map +1 -0
  123. package/src/engine/physics/cloth/playground/collide_build.js +315 -0
  124. package/src/engine/physics/cloth/playground/collide_main.d.ts +2 -0
  125. package/src/engine/physics/cloth/playground/collide_main.d.ts.map +1 -0
  126. package/src/engine/physics/cloth/playground/collide_main.js +720 -0
  127. package/src/engine/physics/cloth/playground/garment.html +182 -0
  128. package/src/engine/physics/cloth/playground/garment_build.d.ts +78 -0
  129. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -0
  130. package/src/engine/physics/cloth/playground/garment_build.js +359 -0
  131. package/src/engine/physics/cloth/playground/garment_main.d.ts +2 -0
  132. package/src/engine/physics/cloth/playground/garment_main.d.ts.map +1 -0
  133. package/src/engine/physics/cloth/playground/garment_main.js +633 -0
  134. package/src/engine/physics/cloth/solver/ClothState.d.ts +208 -5
  135. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  136. package/src/engine/physics/cloth/solver/ClothState.js +302 -8
  137. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +87 -0
  138. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -0
  139. package/src/engine/physics/cloth/solver/cloth_contact_find.js +343 -0
  140. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +112 -0
  141. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -0
  142. package/src/engine/physics/cloth/solver/cloth_self_find.js +448 -0
  143. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts +4 -1
  144. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
  145. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +16 -1
  146. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +112 -5
  147. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  148. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +117 -6
  149. package/src/engine/physics/cloth/solver/cloth_step.d.ts +40 -9
  150. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  151. package/src/engine/physics/cloth/solver/cloth_step.js +122 -10
  152. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +95 -0
  153. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -0
  154. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +285 -0
  155. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +129 -0
  156. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -0
  157. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +501 -0
  158. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +75 -0
  159. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -0
  160. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +202 -0
  161. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  162. package/src/shade/playground/vgeo_viewer/README.md +18 -0
  163. package/src/shade/playground/vgeo_viewer/main.js +87 -50
  164. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  165. package/src/shade/renderer/buffer/table/GPUDatabase.js +191 -62
  166. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +94 -2
  167. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  168. package/src/shade/renderer/buffer/table/GPUTypedTable.js +414 -2
  169. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts +14 -0
  170. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts.map +1 -0
  171. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.js +13 -0
  172. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts +17 -0
  173. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts.map +1 -0
  174. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.js +116 -0
  175. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +9 -4
  176. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  177. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +843 -734
  178. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts +12 -0
  179. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts.map +1 -1
  180. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js +13 -0
  181. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +17 -0
  182. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  183. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +185 -30
  184. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +17 -0
  185. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +141 -24
  186. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +204 -64
  187. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +110 -10
  188. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +19 -0
  189. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +19 -6
  190. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
  191. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +26 -7
  192. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +173 -14
  193. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  194. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +458 -51
  195. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +49 -13
  196. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
  197. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +52 -14
  198. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts +20 -0
  199. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts.map +1 -0
  200. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.js +19 -0
  201. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts +27 -0
  202. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts.map +1 -0
  203. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.js +48 -0
  204. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts +29 -0
  205. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts.map +1 -0
  206. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.js +60 -0
  207. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +8 -1
  208. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
  209. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +32 -2
  210. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +258 -0
  211. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +1 -0
  212. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +723 -0
  213. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +49 -0
  214. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +1 -0
  215. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +50 -0
  216. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  217. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  218. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts +3 -0
  219. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts.map +1 -1
  220. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +121 -21
  221. package/src/shade/renderer/texture/virtual/README.md +6 -4
  222. package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
  223. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +7 -0
  224. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.d.ts +3 -3
  225. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +3 -3
  226. package/src/engine/ecs/system/SystemExecutionPhase.d.ts +0 -9
  227. package/src/engine/ecs/system/SystemExecutionPhase.d.ts.map +0 -1
  228. package/src/engine/graphics/texture/virtual/NOTES.md +0 -128
  229. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts +0 -6
  230. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts.map +0 -1
  231. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.js +0 -5
  232. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts +0 -49
  233. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts.map +0 -1
  234. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.js +0 -264
  235. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts +0 -44
  236. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts.map +0 -1
  237. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.js +0 -228
  238. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts +0 -3
  239. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts.map +0 -1
  240. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.js +0 -73
  241. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts +0 -14
  242. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts.map +0 -1
  243. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.js +0 -85
  244. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts +0 -12
  245. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts.map +0 -1
  246. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.js +0 -63
  247. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts +0 -12
  248. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts.map +0 -1
  249. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.js +0 -243
  250. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts +0 -30
  251. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts.map +0 -1
  252. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.js +0 -39
  253. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts +0 -9
  254. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts.map +0 -1
  255. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.js +0 -24
  256. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts +0 -9
  257. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts.map +0 -1
  258. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.js +0 -26
  259. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts +0 -11
  260. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts.map +0 -1
  261. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.js +0 -12
  262. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts +0 -7
  263. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts.map +0 -1
  264. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.js +0 -16
  265. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts +0 -7
  266. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts.map +0 -1
  267. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.js +0 -35
@@ -0,0 +1,501 @@
1
+ import {
2
+ CCR_FEATURE,
3
+ CCR_FRICTION,
4
+ CCR_INFLATION,
5
+ CCR_STRIDE
6
+ } from "../../collider/ClothColliderRecord.js";
7
+ import {
8
+ cloth_collider_from_local,
9
+ cloth_collider_signed_distance,
10
+ cloth_collider_to_local
11
+ } from "../../collider/cloth_collider_sdf.js";
12
+ import {
13
+ CVA_F_X,
14
+ CVA_F_Y,
15
+ CVA_F_Z,
16
+ CVA_H_XX,
17
+ CVA_H_XY,
18
+ CVA_H_XZ,
19
+ CVA_H_YY,
20
+ CVA_H_YZ,
21
+ CVA_H_ZZ,
22
+ CVA_TRUST
23
+ } from "../cloth_vertex_accumulator.js";
24
+
25
+ /**
26
+ * # Contact — the collision row and its friction row, which are one contact
27
+ *
28
+ * §6's table has them as two rows and they are, but they are two rows of the
29
+ * *same thing*: friction's clamp is the collision row's own force, so a module
30
+ * that carried only one of them would have to reach into the other, and a
31
+ * contact that carried its normal multiplier in one table and its tangential
32
+ * one in another would have to keep two lifetimes in step. One module, one pair
33
+ * of slots, one lifetime.
34
+ *
35
+ * collision C = (r + inflation) − sdf_c(x) [0, +∞) hard
36
+ * g = −∇sdf_c(x)
37
+ *
38
+ * friction C = ‖P_t(x − a)‖ [0, μ·f_n) hard
39
+ * g = P_t(x − a)/‖P_t(x − a)‖
40
+ *
41
+ * where `a` is where the particle stuck to the collider, carried in the
42
+ * collider's own frame, and `P_t = I − n nᵀ` projects onto the contact's
43
+ * tangent plane.
44
+ *
45
+ * ## The collision row is hard, which §6's table does not say
46
+ *
47
+ * §6 gives it a stiffness `k_contact` and friction a `k_friction`, and M0's own
48
+ * rule — "a row is **hard** exactly when its stiffness is `Infinity`" — makes
49
+ * that a statement that both are soft penalties. They cannot be. A soft row
50
+ * above about `8·(m/h²)` makes the step *add* energy (`MEASUREMENTS.md` §6),
51
+ * and a contact soft enough to stay under that boundary is a contact cloth
52
+ * sinks through: measured at 2.3 cm of penetration into a 25 cm sphere for a
53
+ * cape that is 4 mm thick. Both rows are therefore hard, with the multiplier
54
+ * carrying the load and the penalty living in the measured band — and that is
55
+ * also what finally gives `β` something to do, because these are the first rows
56
+ * in the system that arrive and leave. `MEASUREMENTS.md` §17.
57
+ *
58
+ * ## The friction clamp is one-sided because `C` is a magnitude
59
+ *
60
+ * §6 writes friction's clamps as `±μ·f_n`, which is the *signed-slip*
61
+ * formulation — a row whose `C` is a displacement along a chosen tangent. This
62
+ * one measures the magnitude of the slip in the tangent plane and points its
63
+ * gradient along it, so `C ≥ 0` always and the negative half of that clamp
64
+ * names a force that pulls the particle further from where it stuck. The row is
65
+ * `[0, μ·f_n]`, which is the same physics: static friction while the force it
66
+ * needs is under the cap, sliding at exactly the cap once it is not.
67
+ *
68
+ * Writing it as a magnitude is what removes the tangent basis. A signed row
69
+ * needs two of them, chosen per contact, and any choice that is continuous
70
+ * frame to frame is a choice with state in it — which is exactly what §7 P4(a)
71
+ * exists to keep out of this system.
72
+ *
73
+ * ## Which force the friction cap reads
74
+ *
75
+ * The *current iteration's* normal force, not the previous iteration's
76
+ * multiplier. VBD uses the multiplier, which is one iteration stale and
77
+ * therefore exactly zero on a contact's first iteration — so at the one
78
+ * iteration per substep §5.1 says the solver must be usable at, friction would
79
+ * never act at all. The current force is already computed, already
80
+ * non-negative, and makes a cloth land on a slope and stay there at 1×1.
81
+ *
82
+ * @author Alex Goldring
83
+ * @copyright Company Named Limited (c) 2026
84
+ */
85
+
86
+ /**
87
+ * Contact rows per particle.
88
+ *
89
+ * Four, because a particle in a garment's worst corner — an armpit, between two
90
+ * fingers — is inside three or four collider bounds at once and inside more
91
+ * than that only when a rig has redundant colliders, where the fifth is a
92
+ * duplicate of one of the first four. Slots are filled nearest-first, so the
93
+ * ones dropped are the ones furthest from binding.
94
+ *
95
+ * It is a compile-time constant rather than a field because it is a stride: the
96
+ * accumulation is a counted loop over `CLOTH_CONTACT_SLOTS` adjacent entries,
97
+ * and a per-cloth capacity would put a load and a multiply in the inner loop to
98
+ * buy a garment nothing.
99
+ * @type {number}
100
+ */
101
+ export const CLOTH_CONTACT_SLOTS = 4;
102
+
103
+ /**
104
+ * Below this a tangential slip is treated as zero and the friction row is
105
+ * skipped: `‖·‖` is not differentiable there, and a particle that has not moved
106
+ * relative to the surface has nothing for friction to resist.
107
+ * @type {number}
108
+ */
109
+ export const CLOTH_FRICTION_EPSILON = 1e-7;
110
+
111
+ /**
112
+ * Add every contact touching `particle` into the vertex accumulator.
113
+ *
114
+ * @param {Float64Array} accumulator
115
+ * @param {ClothState} state
116
+ * @param {number} particle
117
+ * @param {Float32Array|Float64Array} table packed colliders, cloth-local, posed
118
+ * at the substep in progress
119
+ */
120
+ export function cloth_contact_accumulate(accumulator, state, particle, table) {
121
+ const collider = state.contact_collider;
122
+
123
+ const base = particle * CLOTH_CONTACT_SLOTS;
124
+
125
+ const position = state.position;
126
+
127
+ const self = particle * 3;
128
+
129
+ const x = position[self];
130
+ const y = position[self + 1];
131
+ const z = position[self + 2];
132
+
133
+ const radius = state.contact_radius;
134
+
135
+ const lambda = state.contact_lambda;
136
+ const penalty = state.contact_penalty;
137
+ const friction_lambda = state.contact_friction_lambda;
138
+ const friction_penalty = state.contact_friction_penalty;
139
+ const anchor = state.contact_anchor;
140
+
141
+ let f_x = accumulator[CVA_F_X];
142
+ let f_y = accumulator[CVA_F_Y];
143
+ let f_z = accumulator[CVA_F_Z];
144
+
145
+ let h_xx = accumulator[CVA_H_XX];
146
+ let h_yy = accumulator[CVA_H_YY];
147
+ let h_zz = accumulator[CVA_H_ZZ];
148
+ let h_xy = accumulator[CVA_H_XY];
149
+ let h_xz = accumulator[CVA_H_XZ];
150
+ let h_yz = accumulator[CVA_H_YZ];
151
+
152
+ let trust = accumulator[CVA_TRUST];
153
+
154
+ for (let s = 0; s < CLOTH_CONTACT_SLOTS; s++) {
155
+ const slot = base + s;
156
+
157
+ const record = collider[slot];
158
+
159
+ if (record < 0) {
160
+ continue;
161
+ }
162
+
163
+ const r = record * CCR_STRIDE;
164
+
165
+ const distance = cloth_collider_signed_distance(NORMAL, 0, table, record, x, y, z);
166
+
167
+ const offset = radius + table[r + CCR_INFLATION];
168
+
169
+ const k = penalty[slot];
170
+
171
+ const force = k * (offset - distance) + lambda[slot];
172
+
173
+ if (force <= 0) {
174
+ // Not touching, and carrying no accumulated force. The row is
175
+ // clamped out — and while it is, the friction anchor follows the
176
+ // particle, so that when it *does* touch it sticks where it landed
177
+ // rather than being dragged back to wherever it last was.
178
+ cloth_collider_to_local(anchor, slot * 3, table, record, x, y, z);
179
+
180
+ friction_lambda[slot] = 0;
181
+
182
+ continue;
183
+ }
184
+
185
+ const nx = NORMAL[0];
186
+ const ny = NORMAL[1];
187
+ const nz = NORMAL[2];
188
+
189
+ // `g = −n`, so `f -= fc·g` is `f += fc·n` — out of the collider.
190
+ f_x += force * nx;
191
+ f_y += force * ny;
192
+ f_z += force * nz;
193
+
194
+ // The row is active whenever it is not clamped out, and the clamp is
195
+ // one-sided at zero, so reaching here *is* `fc == fu` and the penalty
196
+ // curvature always goes in.
197
+ h_xx += k * nx * nx;
198
+ h_yy += k * ny * ny;
199
+ h_zz += k * nz * nz;
200
+ h_xy += k * nx * ny;
201
+ h_xz += k * nx * nz;
202
+ h_yz += k * ny * nz;
203
+
204
+ // Geometric stiffness, and there is none to keep. For a convex
205
+ // primitive `∇²sdf` is positive semidefinite outside the shape, so
206
+ // `fc·∂²C/∂x² = −fc·∇²sdf` is *negative* semidefinite — the half §5.3
207
+ // drops. A distance row's geometric term is the opposite sign because
208
+ // its `C` is written the opposite way round, which is the same trap §6's
209
+ // clamp gloss set for M1.
210
+
211
+ // The trust region, from the collider rather than from a constant: a
212
+ // surface normal describes a surface over the surface's own curvature
213
+ // radius and no further.
214
+ const feature = table[r + CCR_FEATURE];
215
+
216
+ if (feature < trust) {
217
+ trust = feature;
218
+ }
219
+
220
+ const friction = table[r + CCR_FRICTION];
221
+
222
+ if (friction <= 0) {
223
+ continue;
224
+ }
225
+
226
+ cloth_collider_from_local(
227
+ ANCHOR_WORLD, 0, table, record,
228
+ anchor[slot * 3], anchor[slot * 3 + 1], anchor[slot * 3 + 2]
229
+ );
230
+
231
+ const dx = x - ANCHOR_WORLD[0];
232
+ const dy = y - ANCHOR_WORLD[1];
233
+ const dz = z - ANCHOR_WORLD[2];
234
+
235
+ const along = dx * nx + dy * ny + dz * nz;
236
+
237
+ const tx = dx - along * nx;
238
+ const ty = dy - along * ny;
239
+ const tz = dz - along * nz;
240
+
241
+ const slip = Math.sqrt(tx * tx + ty * ty + tz * tz);
242
+
243
+ if (slip < CLOTH_FRICTION_EPSILON) {
244
+ continue;
245
+ }
246
+
247
+ const kf = friction_penalty[slot];
248
+
249
+ const unclamped = kf * slip + friction_lambda[slot];
250
+
251
+ const cap = friction * force;
252
+
253
+ const tangential = unclamped < cap ? unclamped : cap;
254
+
255
+ const inverse = 1 / slip;
256
+
257
+ const gx = tx * inverse;
258
+ const gy = ty * inverse;
259
+ const gz = tz * inverse;
260
+
261
+ f_x -= tangential * gx;
262
+ f_y -= tangential * gy;
263
+ f_z -= tangential * gz;
264
+
265
+ if (unclamped <= cap) {
266
+ h_xx += kf * gx * gx;
267
+ h_yy += kf * gy * gy;
268
+ h_zz += kf * gz * gz;
269
+ h_xy += kf * gx * gy;
270
+ h_xz += kf * gx * gz;
271
+ h_yz += kf * gy * gz;
272
+ }
273
+
274
+ // Geometric stiffness, `(fc/L)·(P − g gᵀ)` with `P = I − n nᵀ`. `g` lies
275
+ // in the tangent plane, so `P − g gᵀ` is the rank-one projector onto the
276
+ // other tangent direction — positive semidefinite, and kept whether or
277
+ // not the row is clamped, because a saturated row still swings as the
278
+ // slip direction rotates.
279
+ const scale = tangential * inverse;
280
+
281
+ h_xx += scale * (1 - nx * nx - gx * gx);
282
+ h_yy += scale * (1 - ny * ny - gy * gy);
283
+ h_zz += scale * (1 - nz * nz - gz * gz);
284
+ h_xy -= scale * (nx * ny + gx * gy);
285
+ h_xz -= scale * (nx * nz + gx * gz);
286
+ h_yz -= scale * (ny * nz + gy * gz);
287
+ }
288
+
289
+ accumulator[CVA_F_X] = f_x;
290
+ accumulator[CVA_F_Y] = f_y;
291
+ accumulator[CVA_F_Z] = f_z;
292
+
293
+ accumulator[CVA_H_XX] = h_xx;
294
+ accumulator[CVA_H_YY] = h_yy;
295
+ accumulator[CVA_H_ZZ] = h_zz;
296
+ accumulator[CVA_H_XY] = h_xy;
297
+ accumulator[CVA_H_XZ] = h_xz;
298
+ accumulator[CVA_H_YZ] = h_yz;
299
+
300
+ accumulator[CVA_TRUST] = trust;
301
+ }
302
+
303
+ /**
304
+ * Warm start every occupied contact slot for a substep.
305
+ *
306
+ * A contact is where `β` finally means something. M0 chose `k_min = k_max`,
307
+ * which disables the ramp, and measured that it was as good as any ramped
308
+ * alternative — for *persistent* rows, which is all M0 and M1 had. A contact
309
+ * arrives: on the first substep it exists, its penalty starts at `k_min` and
310
+ * climbs by `β·|C|` per iteration, so a cape meeting a shoulder is pushed out
311
+ * over a few iterations instead of being shot off it in one.
312
+ *
313
+ * @param {ClothState} state
314
+ * @param {number} alpha
315
+ * @param {number} gamma
316
+ * @param {number} k_min_ratio
317
+ * @param {number} k_max_ratio
318
+ * @param {number} inverse_h_squared
319
+ */
320
+ export function cloth_contact_warm_start(state, alpha, gamma, k_min_ratio, k_max_ratio, inverse_h_squared) {
321
+ const particle_count = state.particle_count;
322
+
323
+ const collider = state.contact_collider;
324
+ const mass_inverse = state.mass_inverse;
325
+ const lambda = state.contact_lambda;
326
+ const penalty = state.contact_penalty;
327
+ const friction_lambda = state.contact_friction_lambda;
328
+ const friction_penalty = state.contact_friction_penalty;
329
+
330
+ const decay = alpha * gamma;
331
+
332
+ for (let particle = 0; particle < particle_count; particle++) {
333
+ const compliance = mass_inverse[particle];
334
+
335
+ if (compliance === 0) {
336
+ continue;
337
+ }
338
+
339
+ const scale = inverse_h_squared / compliance;
340
+
341
+ const lo = k_min_ratio * scale;
342
+ const hi = k_max_ratio * scale;
343
+
344
+ const base = particle * CLOTH_CONTACT_SLOTS;
345
+
346
+ for (let s = 0; s < CLOTH_CONTACT_SLOTS; s++) {
347
+ const slot = base + s;
348
+
349
+ if (collider[slot] < 0) {
350
+ continue;
351
+ }
352
+
353
+ lambda[slot] *= decay;
354
+ friction_lambda[slot] *= decay;
355
+
356
+ penalty[slot] = clamp_band(penalty[slot] * gamma, lo, hi);
357
+ friction_penalty[slot] = clamp_band(friction_penalty[slot] * gamma, lo, hi);
358
+ }
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Dual update for every occupied contact slot.
364
+ *
365
+ * The constraint is re-evaluated here rather than cached from the accumulation,
366
+ * for the same reason every other row kind re-evaluates: the accumulation's `C`
367
+ * is measured *before* the vertex update it feeds, and a multiplier absorbing a
368
+ * violation that has already been corrected is a multiplier that overshoots on
369
+ * the next iteration. It costs a second field evaluation per contact per
370
+ * iteration and it is what makes the multiplier converge within the step.
371
+ *
372
+ * @param {ClothState} state
373
+ * @param {Float32Array|Float64Array} table
374
+ * @param {number} beta
375
+ * @param {number} k_max_ratio
376
+ * @param {number} inverse_h_squared
377
+ */
378
+ export function cloth_contact_dual_update(state, table, beta, k_max_ratio, inverse_h_squared) {
379
+ const particle_count = state.particle_count;
380
+
381
+ const collider = state.contact_collider;
382
+ const mass_inverse = state.mass_inverse;
383
+ const position = state.position;
384
+ const lambda = state.contact_lambda;
385
+ const penalty = state.contact_penalty;
386
+ const friction_lambda = state.contact_friction_lambda;
387
+ const friction_penalty = state.contact_friction_penalty;
388
+ const anchor = state.contact_anchor;
389
+
390
+ const radius = state.contact_radius;
391
+
392
+ for (let particle = 0; particle < particle_count; particle++) {
393
+ const compliance = mass_inverse[particle];
394
+
395
+ if (compliance === 0) {
396
+ continue;
397
+ }
398
+
399
+ const base = particle * CLOTH_CONTACT_SLOTS;
400
+
401
+ const self = particle * 3;
402
+
403
+ const x = position[self];
404
+ const y = position[self + 1];
405
+ const z = position[self + 2];
406
+
407
+ const k_max = k_max_ratio * inverse_h_squared / compliance;
408
+
409
+ for (let s = 0; s < CLOTH_CONTACT_SLOTS; s++) {
410
+ const slot = base + s;
411
+
412
+ const record = collider[slot];
413
+
414
+ if (record < 0) {
415
+ continue;
416
+ }
417
+
418
+ const r = record * CCR_STRIDE;
419
+
420
+ const distance = cloth_collider_signed_distance(NORMAL, 0, table, record, x, y, z);
421
+
422
+ const c = radius + table[r + CCR_INFLATION] - distance;
423
+
424
+ const k = penalty[slot];
425
+
426
+ const next = k * c + lambda[slot];
427
+
428
+ const normal_force = next > 0 ? next : 0;
429
+
430
+ lambda[slot] = normal_force;
431
+
432
+ const ramped = k + beta * Math.abs(c);
433
+
434
+ penalty[slot] = ramped < k_max ? ramped : k_max;
435
+
436
+ const friction = table[r + CCR_FRICTION];
437
+
438
+ if (friction <= 0 || normal_force <= 0) {
439
+ friction_lambda[slot] = 0;
440
+
441
+ continue;
442
+ }
443
+
444
+ cloth_collider_from_local(
445
+ ANCHOR_WORLD, 0, table, record,
446
+ anchor[slot * 3], anchor[slot * 3 + 1], anchor[slot * 3 + 2]
447
+ );
448
+
449
+ const dx = x - ANCHOR_WORLD[0];
450
+ const dy = y - ANCHOR_WORLD[1];
451
+ const dz = z - ANCHOR_WORLD[2];
452
+
453
+ const along = dx * NORMAL[0] + dy * NORMAL[1] + dz * NORMAL[2];
454
+
455
+ const tx = dx - along * NORMAL[0];
456
+ const ty = dy - along * NORMAL[1];
457
+ const tz = dz - along * NORMAL[2];
458
+
459
+ const slip = Math.sqrt(tx * tx + ty * ty + tz * tz);
460
+
461
+ const kf = friction_penalty[slot];
462
+
463
+ const cap = friction * normal_force;
464
+
465
+ const unclamped = kf * slip + friction_lambda[slot];
466
+
467
+ friction_lambda[slot] = unclamped < cap ? (unclamped > 0 ? unclamped : 0) : cap;
468
+
469
+ const ramped_friction = kf + beta * slip;
470
+
471
+ friction_penalty[slot] = ramped_friction < k_max ? ramped_friction : k_max;
472
+ }
473
+ }
474
+ }
475
+
476
+ /**
477
+ * @param {number} value
478
+ * @param {number} lo
479
+ * @param {number} hi
480
+ * @returns {number}
481
+ * @private
482
+ */
483
+ function clamp_band(value, lo, hi) {
484
+ if (value < lo) {
485
+ return lo;
486
+ }
487
+
488
+ return value > hi ? hi : value;
489
+ }
490
+
491
+ /**
492
+ * @type {Float64Array}
493
+ * @private
494
+ */
495
+ const NORMAL = new Float64Array(3);
496
+
497
+ /**
498
+ * @type {Float64Array}
499
+ * @private
500
+ */
501
+ const ANCHOR_WORLD = new Float64Array(3);
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Rebuild the per-particle Jacobi scratch from the pair list.
3
+ *
4
+ * Called once per iteration, before the colour sweep, from the positions the
5
+ * previous iteration left. Every pair contributes to both of its particles.
6
+ *
7
+ * @param {ClothState} state
8
+ * @param {number} stiffness penalty, N/m — the same for every pair, because
9
+ * every pair has the same two free ends and therefore the same inertial scale
10
+ * @returns {number} how many pairs were in contact
11
+ */
12
+ export function cloth_self_accumulate_scratch(state: ClothState, stiffness: number): number;
13
+ /**
14
+ * Add one particle's share of the Jacobi scratch into its vertex accumulator.
15
+ *
16
+ * @param {Float64Array} accumulator
17
+ * @param {ClothState} state
18
+ * @param {number} particle
19
+ */
20
+ export function cloth_self_accumulate(accumulator: Float64Array, state: ClothState, particle: number): void;
21
+ /**
22
+ * # Self-collision — the row that keeps cloth off itself
23
+ *
24
+ * C(x) = ‖x_i − x_j‖ − (r_i + r_j)
25
+ * ∂C/∂x_i = (x_i − x_j)/‖x_i − x_j‖ = n
26
+ * ∂C/∂x_j = −n
27
+ * clamp (−∞, 0]
28
+ *
29
+ * **That clamp is right and it is the one place in §6's table where the negative
30
+ * half is the live one.** The rule is that `[0, +∞)` admits only forces that
31
+ * *reduce* `C` and `(−∞, 0]` only forces that *increase* it; this row is violated
32
+ * when the two particles are closer than their radii, which is `C < 0`, so what
33
+ * it needs is `C` increased. Under the solver's `f -= fc·g`, a negative `fc`
34
+ * pushes `i` along `+n` and `j` along `−n` — apart. Every distance row above it
35
+ * in the table bounds a distance from *above* and therefore takes the other
36
+ * half; this one bounds from below.
37
+ *
38
+ * ## It is applied Jacobi-style, and this is where §5.4 was right
39
+ *
40
+ * A collider contact is unary and needs none of §5.4's machinery (`MEASUREMENTS.md`
41
+ * §18). A self-collision row is a **pair**, and pairs are exactly what the
42
+ * colouring cannot pre-partition: two particles of the same colour can be
43
+ * neighbours in space and would then both move against each other inside one
44
+ * sweep, in an order that depends on how the sweep was split. So the pairs are
45
+ * accumulated once per iteration into a per-particle `(f, H)` scratch, from the
46
+ * positions at the start of that iteration, and every vertex update adds its own
47
+ * entry. The result is a step that is the same whatever order the colours were
48
+ * swept in, which is what §12's bit-parity gate is going to be held to.
49
+ *
50
+ * ## The row is soft, which the collision row could not be
51
+ *
52
+ * `MEASUREMENTS.md` §18 measured that a collider contact cannot be a soft
53
+ * penalty: the force it has to produce is an *arrested impact*, 376 N for a
54
+ * sheet arriving at 8 m/s, against the 4.6 N a soft row inside M0's dissipative
55
+ * band can deliver at one thickness of penetration.
56
+ *
57
+ * A self-collision row carries nothing of the kind. What it holds apart is cloth
58
+ * against cloth — grams, moving at the speed cloth moves relative to itself — and
59
+ * a penalty at the top of the band produces newtons per millimetre against a
60
+ * load of fractions of a newton. So it is a plain penalty with no multiplier, no
61
+ * warm start and no identity across steps, which is also what makes a pair list
62
+ * that is rebuilt from scratch every step affordable: there is nothing on a pair
63
+ * worth carrying. `MEASUREMENTS.md` §33.
64
+ *
65
+ * @author Alex Goldring
66
+ * @copyright Company Named Limited (c) 2026
67
+ */
68
+ /**
69
+ * Below this a separation is treated as zero and the row is skipped: `‖·‖` is
70
+ * not differentiable there, and two particles at exactly the same place have no
71
+ * direction to be pushed apart along.
72
+ * @type {number}
73
+ */
74
+ export const CLOTH_SELF_EPSILON: number;
75
+ //# sourceMappingURL=cloth_self_row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloth_self_row.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/physics/cloth/solver/constraint/cloth_self_row.js"],"names":[],"mappings":"AAoEA;;;;;;;;;;GAUG;AACH,4EAJW,MAAM,GAEJ,MAAM,CA4FlB;AAED;;;;;;GAMG;AACH,mDAJW,YAAY,+BAEZ,MAAM,QAyBhB;AA7LD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH;;;;;GAKG;AACH,iCAFU,MAAM,CAEuB"}