@woosh/meep-engine 3.24.0 → 3.26.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 (349) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +59 -0
  3. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  4. package/src/core/geom/3d/shape/HeightMapShape3D.js +285 -0
  5. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
  6. package/src/core/geom/3d/shape/PosedShape3D.js +57 -0
  7. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  8. package/src/core/geom/3d/shape/TransformedShape3D.js +102 -0
  9. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  10. package/src/core/geom/3d/shape/UnionShape3D.js +64 -0
  11. package/src/engine/graphics3/PickingSystem.d.ts +3 -3
  12. package/src/engine/graphics3/PickingSystem.d.ts.map +1 -1
  13. package/src/engine/graphics3/PickingSystem.js +52 -55
  14. package/src/engine/graphics3/shader_picking_gather.d.ts +40 -0
  15. package/src/engine/graphics3/shader_picking_gather.d.ts.map +1 -0
  16. package/src/engine/graphics3/shader_picking_gather.js +120 -0
  17. package/src/engine/physics/cloth/MEASUREMENTS.md +1632 -0
  18. package/src/engine/physics/cloth/PLAN.md +738 -95
  19. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +84 -17
  20. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
  21. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +451 -42
  22. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts +52 -0
  23. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts.map +1 -0
  24. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.js +70 -0
  25. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts +12 -3
  26. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts.map +1 -1
  27. package/src/engine/physics/cloth/ecs/ClothDynamics.js +340 -331
  28. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +101 -29
  29. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  30. package/src/engine/physics/cloth/ecs/ClothInstance.js +110 -31
  31. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts +84 -0
  32. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts.map +1 -0
  33. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.js +141 -0
  34. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +71 -81
  35. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  36. package/src/engine/physics/cloth/ecs/ClothSystem.js +135 -856
  37. package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts +48 -0
  38. package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts.map +1 -0
  39. package/src/engine/physics/cloth/ecs/ClothWorkerCore.js +107 -0
  40. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +323 -0
  41. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -0
  42. package/src/engine/physics/cloth/ecs/ClothWorld.js +1248 -0
  43. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +192 -0
  44. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -0
  45. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +578 -0
  46. package/src/engine/physics/cloth/ecs/cloth.worker.d.ts +2 -0
  47. package/src/engine/physics/cloth/ecs/cloth.worker.d.ts.map +1 -0
  48. package/src/engine/physics/cloth/ecs/cloth.worker.js +12 -0
  49. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  50. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +2 -1
  51. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +85 -3
  52. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  53. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +366 -271
  54. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +95 -12
  55. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
  56. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +170 -27
  57. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +19 -0
  58. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  59. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +249 -201
  60. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -0
  61. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  62. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +62 -1
  63. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts +29 -0
  64. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts.map +1 -0
  65. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.js +78 -0
  66. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  67. package/src/engine/physics/cloth/ecs/cloth_write_back.js +18 -10
  68. package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts +17 -0
  69. package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts.map +1 -0
  70. package/src/engine/physics/cloth/ecs/makeClothWorker.js +18 -0
  71. package/src/engine/physics/cloth/playground/README.md +73 -2
  72. package/src/engine/physics/cloth/playground/collide_main.js +1 -1
  73. package/src/engine/physics/cloth/playground/wind.html +166 -0
  74. package/src/engine/physics/cloth/playground/wind_build.d.ts +81 -0
  75. package/src/engine/physics/cloth/playground/wind_build.d.ts.map +1 -0
  76. package/src/engine/physics/cloth/playground/wind_build.js +141 -0
  77. package/src/engine/physics/cloth/playground/wind_main.d.ts +2 -0
  78. package/src/engine/physics/cloth/playground/wind_main.d.ts.map +1 -0
  79. package/src/engine/physics/cloth/playground/wind_main.js +681 -0
  80. package/src/engine/physics/cloth/solver/ClothState.d.ts +134 -79
  81. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  82. package/src/engine/physics/cloth/solver/ClothState.js +273 -12
  83. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +29 -8
  84. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  85. package/src/engine/physics/cloth/solver/cloth_contact_find.js +37 -9
  86. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +45 -2
  87. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  88. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +46 -2
  89. package/src/engine/physics/cloth/solver/cloth_step.d.ts +21 -2
  90. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  91. package/src/engine/physics/cloth/solver/cloth_step.js +173 -4
  92. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +40 -0
  93. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -0
  94. package/src/engine/physics/cloth/solver/cloth_step_instance.js +284 -0
  95. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts +107 -0
  96. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts.map +1 -0
  97. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.js +263 -0
  98. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +9 -2
  99. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -1
  100. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +9 -2
  101. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +102 -0
  102. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts.map +1 -0
  103. package/src/engine/physics/cloth/wind/AbstractClothWind.js +114 -0
  104. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts +87 -0
  105. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts.map +1 -0
  106. package/src/engine/physics/cloth/wind/ClothAmbientWind.js +185 -0
  107. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +79 -0
  108. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -0
  109. package/src/engine/physics/cloth/wind/ClothFluidWind.js +213 -0
  110. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +106 -0
  111. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -0
  112. package/src/engine/physics/cloth/wind/cloth_sample_air.js +297 -0
  113. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  114. package/src/shade/device/mock/texture_copy.d.ts.map +1 -1
  115. package/src/shade/device/mock/texture_copy.js +28 -0
  116. package/src/shade/playground/vgeo_runtime/README.md +94 -0
  117. package/src/shade/playground/vgeo_runtime/index.html +62 -0
  118. package/src/shade/playground/vgeo_runtime/main.d.ts +2 -0
  119. package/src/shade/playground/vgeo_runtime/main.d.ts.map +1 -0
  120. package/src/shade/playground/vgeo_runtime/main.js +399 -0
  121. package/src/shade/playground/vgeo_viewer/sample_asset.js +1 -1
  122. package/src/shade/renderer/camera/Camera.d.ts +14 -0
  123. package/src/shade/renderer/camera/Camera.d.ts.map +1 -1
  124. package/src/shade/renderer/camera/Camera.js +7 -1
  125. package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.d.ts.map +1 -1
  126. package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.js +16 -1
  127. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  128. package/src/shade/renderer/geometry/GPUGeometryManager.js +29 -9
  129. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts +10 -0
  130. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts.map +1 -1
  131. package/src/shade/renderer/geometry/GPUGeometryMetadata.js +13 -0
  132. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +46 -18
  133. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +70 -22
  134. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +97 -19
  135. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +12 -2
  136. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  137. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +14 -3
  138. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +2 -2
  139. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +124 -6
  141. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +22 -0
  142. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +1 -0
  143. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.js +53 -0
  144. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +8 -1
  145. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  146. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +8 -1
  147. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts +16 -0
  148. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts.map +1 -0
  149. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.js +15 -0
  150. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts +54 -0
  151. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts.map +1 -0
  152. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.js +53 -0
  153. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +13 -2
  154. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
  155. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +14 -2
  156. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +100 -0
  157. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  158. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +113 -0
  159. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  160. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +5 -0
  161. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  162. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +108 -0
  163. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  164. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +23 -0
  165. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  166. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +40 -0
  167. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +228 -0
  168. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -0
  169. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +932 -0
  170. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +176 -0
  171. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -0
  172. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +425 -0
  173. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +241 -0
  174. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +574 -0
  175. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +120 -0
  176. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -0
  177. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +674 -0
  178. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +287 -0
  179. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -0
  180. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +976 -0
  181. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +42 -0
  182. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -0
  183. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +96 -0
  184. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts +16 -0
  185. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts.map +1 -0
  186. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.js +15 -0
  187. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts +19 -0
  188. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -0
  189. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +83 -0
  190. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts +9 -0
  191. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts.map +1 -0
  192. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.js +8 -0
  193. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +19 -0
  194. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -0
  195. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +160 -0
  196. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts +3 -0
  197. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -0
  198. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +255 -0
  199. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts +3 -0
  200. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -0
  201. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +80 -0
  202. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts +3 -0
  203. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -0
  204. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +144 -0
  205. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts +3 -0
  206. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -0
  207. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +530 -0
  208. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +39 -0
  209. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -0
  210. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +54 -0
  211. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts +41 -0
  212. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts.map +1 -0
  213. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.js +56 -0
  214. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts +49 -0
  215. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -0
  216. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +328 -0
  217. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +10 -0
  218. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts.map +1 -0
  219. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +51 -0
  220. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +13 -0
  221. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -0
  222. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +12 -0
  223. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +17 -0
  224. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts.map +1 -0
  225. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +99 -0
  226. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts +9 -0
  227. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts.map +1 -0
  228. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +8 -0
  229. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +7 -0
  230. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts.map +1 -0
  231. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +27 -0
  232. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts +14 -0
  233. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts.map +1 -0
  234. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.js +13 -0
  235. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts +7 -0
  236. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts.map +1 -0
  237. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.js +35 -0
  238. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts +9 -0
  239. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts.map +1 -0
  240. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.js +8 -0
  241. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts +15 -0
  242. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts.map +1 -0
  243. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.js +14 -0
  244. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +7 -0
  245. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts.map +1 -0
  246. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +36 -0
  247. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +10 -0
  248. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -0
  249. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +9 -0
  250. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts +11 -0
  251. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts.map +1 -0
  252. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.js +54 -0
  253. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts +9 -0
  254. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts.map +1 -0
  255. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.js +8 -0
  256. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts +11 -0
  257. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts.map +1 -0
  258. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.js +10 -0
  259. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts +7 -0
  260. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts.map +1 -0
  261. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.js +30 -0
  262. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts +9 -0
  263. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts.map +1 -0
  264. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.js +8 -0
  265. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts +13 -0
  266. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts.map +1 -0
  267. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.js +12 -0
  268. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts +14 -0
  269. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts.map +1 -0
  270. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.js +13 -0
  271. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +11 -0
  272. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts.map +1 -0
  273. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +61 -0
  274. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts +9 -0
  275. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -0
  276. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +8 -0
  277. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts +13 -0
  278. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts.map +1 -0
  279. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.js +12 -0
  280. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts +9 -0
  281. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts.map +1 -0
  282. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.js +8 -0
  283. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts +20 -0
  284. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts.map +1 -0
  285. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.js +19 -0
  286. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts +23 -0
  287. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -0
  288. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +70 -0
  289. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +18 -0
  290. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -0
  291. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +25 -0
  292. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +35 -0
  293. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -0
  294. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +41 -0
  295. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +32 -0
  296. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -0
  297. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +138 -0
  298. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  299. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  300. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  301. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +9 -0
  302. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  303. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +12 -1
  304. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  305. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +12 -1
  306. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  307. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +10 -0
  308. package/src/shade/renderer/scene/GPUSceneContext.d.ts +18 -0
  309. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  310. package/src/shade/renderer/scene/GPUSceneContext.js +647 -594
  311. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  312. package/src/shade/renderer/scene/rows/GPUSceneRows.js +22 -0
  313. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts +35 -0
  314. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts.map +1 -0
  315. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.js +91 -0
  316. package/src/engine/graphics3/instantiate_scene_bundle.d.ts +0 -54
  317. package/src/engine/graphics3/instantiate_scene_bundle.d.ts.map +0 -1
  318. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts +0 -39
  319. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts.map +0 -1
  320. package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts +0 -35
  321. package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts.map +0 -1
  322. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts +0 -96
  323. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts.map +0 -1
  324. package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts +0 -20
  325. package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts.map +0 -1
  326. package/src/shade/renderer/animation/skin_bind_transform.d.ts +0 -25
  327. package/src/shade/renderer/animation/skin_bind_transform.d.ts.map +0 -1
  328. package/src/shade/renderer/animation/skin_frame_defect.d.ts +0 -34
  329. package/src/shade/renderer/animation/skin_frame_defect.d.ts.map +0 -1
  330. package/src/shade/renderer/animation/skin_joint_matrix.d.ts +0 -24
  331. package/src/shade/renderer/animation/skin_joint_matrix.d.ts.map +0 -1
  332. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts +0 -70
  333. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts.map +0 -1
  334. package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts +0 -96
  335. package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts.map +0 -1
  336. package/src/shade/renderer/scene/InstanceBatch.d.ts +0 -92
  337. package/src/shade/renderer/scene/InstanceBatch.d.ts.map +0 -1
  338. package/src/shade/renderer/scene/Mesh.d.ts +0 -55
  339. package/src/shade/renderer/scene/Mesh.d.ts.map +0 -1
  340. package/src/shade/renderer/scene/Node3D.d.ts +0 -159
  341. package/src/shade/renderer/scene/Node3D.d.ts.map +0 -1
  342. package/src/shade/renderer/scene/Node3DDirtyList.d.ts +0 -59
  343. package/src/shade/renderer/scene/Node3DDirtyList.d.ts.map +0 -1
  344. package/src/shade/renderer/scene/SceneNodeBinding.d.ts +0 -52
  345. package/src/shade/renderer/scene/SceneNodeBinding.d.ts.map +0 -1
  346. package/src/shade/renderer/scene/SkinnedMesh.d.ts +0 -27
  347. package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +0 -1
  348. package/src/shade/renderer/scene/TransformAuthority.d.ts +0 -19
  349. package/src/shade/renderer/scene/TransformAuthority.d.ts.map +0 -1
@@ -12,9 +12,12 @@
12
12
  * @param {Float32Array|Float64Array} table packed colliders, cloth-local
13
13
  * @param {Int32Array} keys index handle per record in `table`
14
14
  * @param {number} count records in `table`
15
+ * @param {number} dt seconds, the fixed step the discovered rows will be used
16
+ * across — how far a particle carries its current velocity before anything
17
+ * gets a chance to stop it
15
18
  * @returns {number} how many contact rows were created
16
19
  */
17
- export function cloth_contact_find(state: ClothState, table: Float32Array | Float64Array, keys: Int32Array, count: number): number;
20
+ export function cloth_contact_find(state: ClothState, table: Float32Array | Float64Array, keys: Int32Array, count: number, dt: number): number;
18
21
  /**
19
22
  * # Finding the contacts, once per step
20
23
  *
@@ -54,11 +57,30 @@ export function cloth_contact_find(state: ClothState, table: Float32Array | Floa
54
57
  * to the reach costs one subtraction per record per step and makes the whole
55
58
  * range from 2 to 40 m/s behave the same way. `MEASUREMENTS.md` §20.
56
59
  *
60
+ * **And it has to include how far the *particle* moves**, which M2 left out and
61
+ * argued its way past. The paragraph that used to stand here said a cloth
62
+ * approaching faster than half a metre a second is one "the velocity clamp of
63
+ * §7 P1 is already the bound on". It is not: that clamp is
64
+ * `shortest_row · substeps · iterations / dt` times four, which for a garment is
65
+ * about **154 m/s** — three orders of magnitude above the speed at which this
66
+ * margin stops covering the approach. A collider that does not move is not a
67
+ * collider a cloth cannot hit. Measured, one particle at 8 mm against a static
68
+ * 3 cm capsule with no gravity at 2 × 4: at 1 and 2 m/s the rows appear and hold
69
+ * it; at 3 m/s and above there is **no row on the step it crosses the axis**,
70
+ * and the row the next step finally makes is on the far side and pushes it the
71
+ * rest of the way out. So the reach carries `|v_i|·dt` per particle as well —
72
+ * one square root per particle per step, hoisted out of the record loop.
73
+ * `MEASUREMENTS.md` §54.
74
+ *
57
75
  * That is also the honest boundary of P3's "swept collision": the *set* is
58
- * swept by this margin, and the *poses* are swept by `cloth_collider_pose_at`.
59
- * Both are translation-first — a collider spinning fast enough that a point on
60
- * its surface travels more than its own radius within one substep is still
61
- * missed, and more substeps is the answer to that.
76
+ * swept by both margins, and the *poses* are swept by `cloth_collider_pose_at`.
77
+ * All of it is translation-first — a collider spinning fast enough that a point
78
+ * on its surface travels more than its own radius within one substep is still
79
+ * missed, and more substeps is the answer to that. And the *set* being right is
80
+ * necessary rather than sufficient: a row that exists is still evaluated at
81
+ * substep positions, so a particle crossing a whole collider inside one substep
82
+ * has a row that never sees it touching. That bound is `substeps` and nothing
83
+ * else, and §54 measures where it lands.
62
84
  *
63
85
  * ## Warm-starting across the rebuild
64
86
  *
@@ -78,9 +100,8 @@ export function cloth_contact_find(state: ClothState, table: Float32Array | Floa
78
100
  *
79
101
  * One, so a row exists from twice the offset inwards. At a garment's 8 mm that
80
102
  * is 8 mm of warning, which at 60 Hz covers half a metre a second of approach
81
- * before a substep can carry a particle past the discovery — and a cloth moving
82
- * faster than that relative to a collider is one the velocity clamp of §7 P1 is
83
- * already the bound on.
103
+ * on its own — and the rest of the approach, from either side, is what the two
104
+ * travel terms in {@link cloth_contact_find} add to it.
84
105
  * @type {number}
85
106
  */
86
107
  export const CLOTH_CONTACT_MARGIN: number;
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_contact_find.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_contact_find.js"],"names":[],"mappings":"AA8FA;;;;;;;;;;;;;;;GAeG;AACH,6DALW,YAAY,GAAC,YAAY,QACzB,UAAU,SACV,MAAM,GACJ,MAAM,CA4KlB;AAjQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH;;;;;;;;;;GAUG;AACH,mCAFU,MAAM,CAEsB"}
1
+ {"version":3,"file":"cloth_contact_find.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_contact_find.js"],"names":[],"mappings":"AAgHA;;;;;;;;;;;;;;;;;;GAkBG;AACH,6DARW,YAAY,GAAC,YAAY,QACzB,UAAU,SACV,MAAM,MACN,MAAM,GAGJ,MAAM,CAmLlB;AA7RD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AAEH;;;;;;;;;GASG;AACH,mCAFU,MAAM,CAEsB"}
@@ -60,11 +60,30 @@ import { CLOTH_CONTACT_SLOTS } from "./constraint/cloth_contact_row.js";
60
60
  * to the reach costs one subtraction per record per step and makes the whole
61
61
  * range from 2 to 40 m/s behave the same way. `MEASUREMENTS.md` §20.
62
62
  *
63
+ * **And it has to include how far the *particle* moves**, which M2 left out and
64
+ * argued its way past. The paragraph that used to stand here said a cloth
65
+ * approaching faster than half a metre a second is one "the velocity clamp of
66
+ * §7 P1 is already the bound on". It is not: that clamp is
67
+ * `shortest_row · substeps · iterations / dt` times four, which for a garment is
68
+ * about **154 m/s** — three orders of magnitude above the speed at which this
69
+ * margin stops covering the approach. A collider that does not move is not a
70
+ * collider a cloth cannot hit. Measured, one particle at 8 mm against a static
71
+ * 3 cm capsule with no gravity at 2 × 4: at 1 and 2 m/s the rows appear and hold
72
+ * it; at 3 m/s and above there is **no row on the step it crosses the axis**,
73
+ * and the row the next step finally makes is on the far side and pushes it the
74
+ * rest of the way out. So the reach carries `|v_i|·dt` per particle as well —
75
+ * one square root per particle per step, hoisted out of the record loop.
76
+ * `MEASUREMENTS.md` §54.
77
+ *
63
78
  * That is also the honest boundary of P3's "swept collision": the *set* is
64
- * swept by this margin, and the *poses* are swept by `cloth_collider_pose_at`.
65
- * Both are translation-first — a collider spinning fast enough that a point on
66
- * its surface travels more than its own radius within one substep is still
67
- * missed, and more substeps is the answer to that.
79
+ * swept by both margins, and the *poses* are swept by `cloth_collider_pose_at`.
80
+ * All of it is translation-first — a collider spinning fast enough that a point
81
+ * on its surface travels more than its own radius within one substep is still
82
+ * missed, and more substeps is the answer to that. And the *set* being right is
83
+ * necessary rather than sufficient: a row that exists is still evaluated at
84
+ * substep positions, so a particle crossing a whole collider inside one substep
85
+ * has a row that never sees it touching. That bound is `substeps` and nothing
86
+ * else, and §54 measures where it lands.
68
87
  *
69
88
  * ## Warm-starting across the rebuild
70
89
  *
@@ -85,9 +104,8 @@ import { CLOTH_CONTACT_SLOTS } from "./constraint/cloth_contact_row.js";
85
104
  *
86
105
  * One, so a row exists from twice the offset inwards. At a garment's 8 mm that
87
106
  * is 8 mm of warning, which at 60 Hz covers half a metre a second of approach
88
- * before a substep can carry a particle past the discovery — and a cloth moving
89
- * faster than that relative to a collider is one the velocity clamp of §7 P1 is
90
- * already the bound on.
107
+ * on its own — and the rest of the approach, from either side, is what the two
108
+ * travel terms in {@link cloth_contact_find} add to it.
91
109
  * @type {number}
92
110
  */
93
111
  export const CLOTH_CONTACT_MARGIN = 1;
@@ -106,9 +124,12 @@ export const CLOTH_CONTACT_MARGIN = 1;
106
124
  * @param {Float32Array|Float64Array} table packed colliders, cloth-local
107
125
  * @param {Int32Array} keys index handle per record in `table`
108
126
  * @param {number} count records in `table`
127
+ * @param {number} dt seconds, the fixed step the discovered rows will be used
128
+ * across — how far a particle carries its current velocity before anything
129
+ * gets a chance to stop it
109
130
  * @returns {number} how many contact rows were created
110
131
  */
111
- export function cloth_contact_find(state, table, keys, count) {
132
+ export function cloth_contact_find(state, table, keys, count, dt) {
112
133
  const particle_count = state.particle_count;
113
134
 
114
135
  const collider = state.contact_collider;
@@ -120,6 +141,7 @@ export function cloth_contact_find(state, table, keys, count) {
120
141
  const anchor = state.contact_anchor;
121
142
 
122
143
  const position = state.position;
144
+ const velocity = state.velocity;
123
145
  const mass_inverse = state.mass_inverse;
124
146
 
125
147
  const radius = state.contact_radius;
@@ -188,12 +210,18 @@ export function cloth_contact_find(state, table, keys, count) {
188
210
  const y = position[p + 1];
189
211
  const z = position[p + 2];
190
212
 
213
+ // How far this particle carries its current velocity across the step.
214
+ // Hoisted out of the record loop: it is a property of the particle, and
215
+ // the loop below is the hot one.
216
+ const travel = dt * Math.hypot(velocity[p], velocity[p + 1], velocity[p + 2]);
217
+
191
218
  let found = 0;
192
219
 
193
220
  for (let record = 0; record < count; record++) {
194
221
  const r = record * CCR_STRIDE;
195
222
 
196
- const reach = (radius + table[r + CCR_INFLATION]) * (1 + CLOTH_CONTACT_MARGIN) + TRAVEL[record];
223
+ const reach = (radius + table[r + CCR_INFLATION]) * (1 + CLOTH_CONTACT_MARGIN)
224
+ + TRAVEL[record] + travel;
197
225
 
198
226
  if (x + reach < table[r + CCR_AABB_MIN_X] || x - reach > table[r + CCR_AABB_MAX_X]) {
199
227
  continue;
@@ -37,8 +37,18 @@
37
37
  * two clear of divergence.** γ is left at 1 because its second job — decaying
38
38
  * the penalty — has nothing to do while the band is a single point, so putting
39
39
  * the whole decay in α, whose only job is the multiplier, is the truthful
40
- * placement. When M2's contacts make the band real again, γ becomes live and
41
- * has to be re-measured.
40
+ * placement.
41
+ *
42
+ * **γ is the one unmeasured constant in this file, and that is now a decision.**
43
+ * The sentence above used to end "when M2's contacts make the band real again, γ
44
+ * becomes live and has to be re-measured". M2 made the band real — a contact's
45
+ * floor is {@link CLOTH_CONTACT_K_MIN_RATIO} and its ceiling is
46
+ * {@link CLOTH_K_MAX_RATIO} — and the sweep was never run. Nothing measured
47
+ * since has asked for a decaying penalty; what a `γ < 1` *would* reach is the
48
+ * one thing PLAN §18 records as a coupling rather than a bug, which is that a
49
+ * contact's penalty ramps to the ceiling and never comes back down. Sweeping it
50
+ * means re-measuring every hard row in the system against `α·γ`, because the two
51
+ * act only through their product and `α` is the one that was measured.
42
52
  *
43
53
  * **`k_min` and `k_max` are equal, which disables the ramp.** Pinning the
44
54
  * penalty at the top of the band measured as good as or better than every
@@ -189,6 +199,39 @@ export const CLOTH_SELF_RADIUS_MIN_RATIO: number;
189
199
  * @type {number}
190
200
  */
191
201
  export const CLOTH_SELF_RADIUS_MAX_RATIO: number;
202
+ /**
203
+ * How many collider records one cloth's per-step table holds.
204
+ *
205
+ * The table is the broadphase's answer for this step, written by
206
+ * `cloth_gather_colliders` and read by the contact search and the vertex
207
+ * update. M4 kept it on the instance and grew it on demand; M5 moved it into
208
+ * {@link ClothState}'s single buffer, which is where §12's table always put it
209
+ * — and a region inside one allocation has to be sized rather than grown.
210
+ *
211
+ * **A capacity rather than a growth policy is the point.** The worker steps a
212
+ * cloth out of shared memory, and memory whose size can change mid-run is
213
+ * memory the worker has to be told about again before it can be named — a
214
+ * cold-plane round trip in the middle of a step. Fixing the size makes
215
+ * `ClothSystem` and `WorkerClothSystem` read the same bytes by construction
216
+ * instead of by agreement, which is what the §12 parity gate is.
217
+ *
218
+ * **The number is a scene bound rather than a garment bound**, which is what the
219
+ * measurement changed about it. A garment's query box is its own bounds fattened
220
+ * by a step's travel, so what lands in the table is *every collider on every
221
+ * character standing inside it* — one ten-part body fills ten slots, two fill
222
+ * twenty, three fill twenty-eight (`MEASUREMENTS.md` §41). Sizing this to a
223
+ * garment would have been sizing it to the wrong thing.
224
+ *
225
+ * Sixty-four, so a cloth can be inside six characters' collider sets before it
226
+ * drops anything, against M2's twenty-collider scene and §41's measured
227
+ * twenty-eight for three. A cloth past that keeps what the index returned first,
228
+ * which is **arbitrary among the overflow** — the index answers in its own
229
+ * order, not in order of how much a collider matters — so the capacity is set
230
+ * well clear of a plausible scene rather than tightly against it, and the drop
231
+ * warns once. Nine kilobytes a cloth, 1.4% of the §17 workload's state.
232
+ * @type {number}
233
+ */
234
+ export const CLOTH_COLLIDER_SLOTS: number;
192
235
  /**
193
236
  * The five constants as one frozen object, which is what {@link cloth_step}
194
237
  * takes. A sweep passes its own; nothing else should.
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_solver_constants.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_solver_constants.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AAEH;;;GAGG;AACH,0BAFU,MAAM,CAEgB;AAEhC;;;;GAIG;AACH,yBAFU,MAAM,CAEc;AAE9B;;;GAGG;AACH,0BAFU,MAAM,CAEa;AAE7B;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wCAFU,MAAM,CAE8B;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,+BAFU,MAAM,CAEkB;AAElC;;;;;;;;;GASG;AACH,0CAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,0CAFU,MAAM,CAE+B;AAE/C;;;;GAIG;AACH,kCAFU,SAAS;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,CAAC,CAQvG"}
1
+ {"version":3,"file":"cloth_solver_constants.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_solver_constants.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AAEH;;;GAGG;AACH,0BAFU,MAAM,CAEgB;AAEhC;;;;GAIG;AACH,yBAFU,MAAM,CAEc;AAE9B;;;GAGG;AACH,0BAFU,MAAM,CAEa;AAE7B;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wCAFU,MAAM,CAE8B;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,+BAFU,MAAM,CAEkB;AAElC;;;;;;;;;GASG;AACH,0CAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,0CAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,mCAFU,MAAM,CAEuB;AAEvC;;;;GAIG;AACH,kCAFU,SAAS;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,CAAC,CAQvG"}
@@ -37,8 +37,18 @@
37
37
  * two clear of divergence.** γ is left at 1 because its second job — decaying
38
38
  * the penalty — has nothing to do while the band is a single point, so putting
39
39
  * the whole decay in α, whose only job is the multiplier, is the truthful
40
- * placement. When M2's contacts make the band real again, γ becomes live and
41
- * has to be re-measured.
40
+ * placement.
41
+ *
42
+ * **γ is the one unmeasured constant in this file, and that is now a decision.**
43
+ * The sentence above used to end "when M2's contacts make the band real again, γ
44
+ * becomes live and has to be re-measured". M2 made the band real — a contact's
45
+ * floor is {@link CLOTH_CONTACT_K_MIN_RATIO} and its ceiling is
46
+ * {@link CLOTH_K_MAX_RATIO} — and the sweep was never run. Nothing measured
47
+ * since has asked for a decaying penalty; what a `γ < 1` *would* reach is the
48
+ * one thing PLAN §18 records as a coupling rather than a bug, which is that a
49
+ * contact's penalty ramps to the ceiling and never comes back down. Sweeping it
50
+ * means re-measuring every hard row in the system against `α·γ`, because the two
51
+ * act only through their product and `α` is the one that was measured.
42
52
  *
43
53
  * **`k_min` and `k_max` are equal, which disables the ramp.** Pinning the
44
54
  * penalty at the top of the band measured as good as or better than every
@@ -199,6 +209,40 @@ export const CLOTH_SELF_RADIUS_MIN_RATIO = 0.5;
199
209
  */
200
210
  export const CLOTH_SELF_RADIUS_MAX_RATIO = 0.4;
201
211
 
212
+ /**
213
+ * How many collider records one cloth's per-step table holds.
214
+ *
215
+ * The table is the broadphase's answer for this step, written by
216
+ * `cloth_gather_colliders` and read by the contact search and the vertex
217
+ * update. M4 kept it on the instance and grew it on demand; M5 moved it into
218
+ * {@link ClothState}'s single buffer, which is where §12's table always put it
219
+ * — and a region inside one allocation has to be sized rather than grown.
220
+ *
221
+ * **A capacity rather than a growth policy is the point.** The worker steps a
222
+ * cloth out of shared memory, and memory whose size can change mid-run is
223
+ * memory the worker has to be told about again before it can be named — a
224
+ * cold-plane round trip in the middle of a step. Fixing the size makes
225
+ * `ClothSystem` and `WorkerClothSystem` read the same bytes by construction
226
+ * instead of by agreement, which is what the §12 parity gate is.
227
+ *
228
+ * **The number is a scene bound rather than a garment bound**, which is what the
229
+ * measurement changed about it. A garment's query box is its own bounds fattened
230
+ * by a step's travel, so what lands in the table is *every collider on every
231
+ * character standing inside it* — one ten-part body fills ten slots, two fill
232
+ * twenty, three fill twenty-eight (`MEASUREMENTS.md` §41). Sizing this to a
233
+ * garment would have been sizing it to the wrong thing.
234
+ *
235
+ * Sixty-four, so a cloth can be inside six characters' collider sets before it
236
+ * drops anything, against M2's twenty-collider scene and §41's measured
237
+ * twenty-eight for three. A cloth past that keeps what the index returned first,
238
+ * which is **arbitrary among the overflow** — the index answers in its own
239
+ * order, not in order of how much a collider matters — so the capacity is set
240
+ * well clear of a plausible scene rather than tightly against it, and the drop
241
+ * warns once. Nine kilobytes a cloth, 1.4% of the §17 workload's state.
242
+ * @type {number}
243
+ */
244
+ export const CLOTH_COLLIDER_SLOTS = 64;
245
+
202
246
  /**
203
247
  * The five constants as one frozen object, which is what {@link cloth_step}
204
248
  * takes. A sweep passes its own; nothing else should.
@@ -39,6 +39,21 @@
39
39
  * substep that is the collider's final pose, which is the one a particle must
40
40
  * not be inside when the step is over.
41
41
  *
42
+ * ## The external acceleration is per particle when there is wind
43
+ *
44
+ * Gravity is one vector for the whole cloth; §10's aerodynamic drag is not —
45
+ * it depends on the air each particle sits in and on which way that particle's
46
+ * own surface faces. So the predict and the integrate come in two forms, chosen
47
+ * once per substep rather than once per particle: the uniform pair, which is
48
+ * what a cloth with no air runs and what M0 through M5 measured, and a varying
49
+ * pair that reads `ClothState#external_acceleration` instead.
50
+ *
51
+ * Two loops rather than a branch inside one, because the branch would sit in the
52
+ * innermost per-particle loop of a step that has no wind in it. And the uniform
53
+ * pair is untouched rather than expressed as a special case of the varying one,
54
+ * which is what makes "no wind produces the bytes M5 measured" a fact about the
55
+ * code rather than a claim about floating point.
56
+ *
42
57
  * ## What each piece is for
43
58
  *
44
59
  * **Warm start** carries the multipliers into the next substep so a hard row
@@ -101,7 +116,8 @@
101
116
  *
102
117
  * @param {ClothState} state
103
118
  * @param {number} dt fixed step length, seconds — divided into `substeps`
104
- * @param {number} acceleration_x external acceleration, cloth-local, m/s²
119
+ * @param {number} acceleration_x external acceleration, cloth-local, m/s²; ignored
120
+ * when `external` is given
105
121
  * @param {number} acceleration_y
106
122
  * @param {number} acceleration_z
107
123
  * @param {number} substeps
@@ -110,6 +126,9 @@
110
126
  * cloth's own frame, with their contact rows already found
111
127
  * @param {number} [collider_count]
112
128
  * @param {{alpha: number, beta: number, gamma: number, k_min_ratio: number, k_max_ratio: number, self_ratio?: number}} [tuning]
129
+ * @param {Float32Array|null} [external] per-particle external acceleration,
130
+ * cloth-local, 3 each — §10's wind, already carrying gravity. `null` takes the
131
+ * uniform path above, which is what a scene with no air in it runs.
113
132
  */
114
133
  export function cloth_step(state: ClothState, dt: number, acceleration_x: number, acceleration_y: number, acceleration_z: number, substeps: number, iterations: number, collider_table?: Float32Array | Float64Array | null, collider_count?: number, tuning?: {
115
134
  alpha: number;
@@ -118,5 +137,5 @@ export function cloth_step(state: ClothState, dt: number, acceleration_x: number
118
137
  k_min_ratio: number;
119
138
  k_max_ratio: number;
120
139
  self_ratio?: number;
121
- }): void;
140
+ }, external?: Float32Array | null): void;
122
141
  //# sourceMappingURL=cloth_step.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_step.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_step.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiGG;AAEH;;;;;;;;;;;;;;GAcG;AACH,kDAXW,MAAM,kBACN,MAAM,kBACN,MAAM,kBACN,MAAM,YACN,MAAM,cACN,MAAM,mBACN,YAAY,GAAC,YAAY,GAAC,IAAI,mBAE9B,MAAM,WACN;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAC,QA2FrH"}
1
+ {"version":3,"file":"cloth_step.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_step.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgHG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,kDAfW,MAAM,kBACN,MAAM,kBAEN,MAAM,kBACN,MAAM,YACN,MAAM,cACN,MAAM,mBACN,YAAY,GAAC,YAAY,GAAC,IAAI,mBAE9B,MAAM,WACN;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAC,aAC3G,YAAY,GAAC,IAAI,QAsG3B"}
@@ -70,6 +70,21 @@ import { find_non_finite_cloth_state } from "./find_non_finite_cloth_state.js";
70
70
  * substep that is the collider's final pose, which is the one a particle must
71
71
  * not be inside when the step is over.
72
72
  *
73
+ * ## The external acceleration is per particle when there is wind
74
+ *
75
+ * Gravity is one vector for the whole cloth; §10's aerodynamic drag is not —
76
+ * it depends on the air each particle sits in and on which way that particle's
77
+ * own surface faces. So the predict and the integrate come in two forms, chosen
78
+ * once per substep rather than once per particle: the uniform pair, which is
79
+ * what a cloth with no air runs and what M0 through M5 measured, and a varying
80
+ * pair that reads `ClothState#external_acceleration` instead.
81
+ *
82
+ * Two loops rather than a branch inside one, because the branch would sit in the
83
+ * innermost per-particle loop of a step that has no wind in it. And the uniform
84
+ * pair is untouched rather than expressed as a special case of the varying one,
85
+ * which is what makes "no wind produces the bytes M5 measured" a fact about the
86
+ * code rather than a claim about floating point.
87
+ *
73
88
  * ## What each piece is for
74
89
  *
75
90
  * **Warm start** carries the multipliers into the next substep so a hard row
@@ -133,7 +148,8 @@ import { find_non_finite_cloth_state } from "./find_non_finite_cloth_state.js";
133
148
  *
134
149
  * @param {ClothState} state
135
150
  * @param {number} dt fixed step length, seconds — divided into `substeps`
136
- * @param {number} acceleration_x external acceleration, cloth-local, m/s²
151
+ * @param {number} acceleration_x external acceleration, cloth-local, m/s²; ignored
152
+ * when `external` is given
137
153
  * @param {number} acceleration_y
138
154
  * @param {number} acceleration_z
139
155
  * @param {number} substeps
@@ -142,6 +158,9 @@ import { find_non_finite_cloth_state } from "./find_non_finite_cloth_state.js";
142
158
  * cloth's own frame, with their contact rows already found
143
159
  * @param {number} [collider_count]
144
160
  * @param {{alpha: number, beta: number, gamma: number, k_min_ratio: number, k_max_ratio: number, self_ratio?: number}} [tuning]
161
+ * @param {Float32Array|null} [external] per-particle external acceleration,
162
+ * cloth-local, 3 each — §10's wind, already carrying gravity. `null` takes the
163
+ * uniform path above, which is what a scene with no air in it runs.
145
164
  */
146
165
  export function cloth_step(
147
166
  state,
@@ -151,7 +170,8 @@ export function cloth_step(
151
170
  iterations,
152
171
  collider_table = null,
153
172
  collider_count = 0,
154
- tuning = CLOTH_SOLVER_TUNING
173
+ tuning = CLOTH_SOLVER_TUNING,
174
+ external = null
155
175
  ) {
156
176
  assert.isPositiveInteger(substeps, 'substeps');
157
177
  assert.isPositiveInteger(iterations, 'iterations');
@@ -184,7 +204,11 @@ export function cloth_step(
184
204
  const contacts = collider_table !== null && collider_count > 0 ? collider_table : null;
185
205
 
186
206
  for (let substep = 0; substep < substeps; substep++) {
187
- cloth_predict(state, h, acceleration_x, acceleration_y, acceleration_z);
207
+ if (external === null) {
208
+ cloth_predict(state, h, acceleration_x, acceleration_y, acceleration_z);
209
+ } else {
210
+ cloth_predict_varying(state, h, external);
211
+ }
188
212
 
189
213
  if (contacts !== null) {
190
214
  cloth_collider_pose_at(contacts, collider_count, (substep + 1) / substeps);
@@ -225,7 +249,11 @@ export function cloth_step(
225
249
  }
226
250
  }
227
251
 
228
- cloth_integrate(state, inverse_h, acceleration_x, acceleration_y, acceleration_z);
252
+ if (external === null) {
253
+ cloth_integrate(state, inverse_h, acceleration_x, acceleration_y, acceleration_z);
254
+ } else {
255
+ cloth_integrate_varying(state, inverse_h, external);
256
+ }
229
257
  }
230
258
 
231
259
  assert.equal(
@@ -331,6 +359,70 @@ function cloth_predict(state, h, acceleration_x, acceleration_y, acceleration_z)
331
359
  }
332
360
  }
333
361
 
362
+ /**
363
+ * {@link cloth_predict} with a per-particle external acceleration — §10's wind,
364
+ * with gravity already folded in by `cloth_wind_accelerate`.
365
+ *
366
+ * Identical in every other respect, including the pinned-particle rule: a pin is
367
+ * held exactly, so the air does not move it and its inertial target is its own
368
+ * position.
369
+ *
370
+ * @param {ClothState} state
371
+ * @param {number} h
372
+ * @param {Float32Array} external 3 per particle, cloth-local, m/s²
373
+ * @private
374
+ */
375
+ function cloth_predict_varying(state, h, external) {
376
+ const particle_count = state.particle_count;
377
+
378
+ const position = state.position;
379
+ const position_previous = state.position_previous;
380
+ const velocity = state.velocity;
381
+ const inertial = state.inertial;
382
+ const mass_inverse = state.mass_inverse;
383
+ const inertia_blend = state.inertia_blend;
384
+
385
+ const h_squared = h * h;
386
+
387
+ for (let i = 0; i < particle_count; i++) {
388
+ const p = i * 3;
389
+
390
+ const x = position[p];
391
+ const y = position[p + 1];
392
+ const z = position[p + 2];
393
+
394
+ position_previous[p] = x;
395
+ position_previous[p + 1] = y;
396
+ position_previous[p + 2] = z;
397
+
398
+ if (mass_inverse[i] === 0) {
399
+ inertial[p] = x;
400
+ inertial[p + 1] = y;
401
+ inertial[p + 2] = z;
402
+
403
+ continue;
404
+ }
405
+
406
+ const drift_x = h * velocity[p];
407
+ const drift_y = h * velocity[p + 1];
408
+ const drift_z = h * velocity[p + 2];
409
+
410
+ const push_x = h_squared * external[p];
411
+ const push_y = h_squared * external[p + 1];
412
+ const push_z = h_squared * external[p + 2];
413
+
414
+ inertial[p] = x + drift_x + push_x;
415
+ inertial[p + 1] = y + drift_y + push_y;
416
+ inertial[p + 2] = z + drift_z + push_z;
417
+
418
+ const blend = inertia_blend[i];
419
+
420
+ position[p] = x + drift_x + blend * push_x;
421
+ position[p + 1] = y + drift_y + blend * push_y;
422
+ position[p + 2] = z + drift_z + blend * push_z;
423
+ }
424
+ }
425
+
334
426
  /**
335
427
  * Integrate: read velocity back out of the positions the descent produced, and
336
428
  * record how much of the resulting acceleration was the external one so the
@@ -399,3 +491,80 @@ function cloth_integrate(state, inverse_h, acceleration_x, acceleration_y, accel
399
491
  velocity[p + 2] = next_z;
400
492
  }
401
493
  }
494
+
495
+ /**
496
+ * {@link cloth_integrate} with a per-particle external acceleration.
497
+ *
498
+ * The adaptive-initialisation blend is a projection of the realised acceleration
499
+ * onto the external one, so with wind it is projected onto **that particle's**
500
+ * external acceleration rather than onto gravity — which is the answer that
501
+ * keeps its meaning: a particle being carried sideways by a gust is in free fall
502
+ * along the direction it is actually being accelerated in, and seeding it along
503
+ * gravity instead would be seeding it against most of what is happening to it.
504
+ *
505
+ * @param {ClothState} state
506
+ * @param {number} inverse_h
507
+ * @param {Float32Array} external 3 per particle, cloth-local, m/s²
508
+ * @private
509
+ */
510
+ function cloth_integrate_varying(state, inverse_h, external) {
511
+ const particle_count = state.particle_count;
512
+
513
+ const position = state.position;
514
+ const position_previous = state.position_previous;
515
+ const velocity = state.velocity;
516
+ const mass_inverse = state.mass_inverse;
517
+ const inertia_blend = state.inertia_blend;
518
+
519
+ for (let i = 0; i < particle_count; i++) {
520
+ if (mass_inverse[i] === 0) {
521
+ continue;
522
+ }
523
+
524
+ const p = i * 3;
525
+
526
+ const acceleration_x = external[p];
527
+ const acceleration_y = external[p + 1];
528
+ const acceleration_z = external[p + 2];
529
+
530
+ const acceleration_squared =
531
+ acceleration_x * acceleration_x +
532
+ acceleration_y * acceleration_y +
533
+ acceleration_z * acceleration_z;
534
+
535
+ const next_x = (position[p] - position_previous[p]) * inverse_h;
536
+ const next_y = (position[p + 1] - position_previous[p + 1]) * inverse_h;
537
+ const next_z = (position[p + 2] - position_previous[p + 2]) * inverse_h;
538
+
539
+ if (acceleration_squared > 0) {
540
+ const realised =
541
+ (next_x - velocity[p]) * acceleration_x +
542
+ (next_y - velocity[p + 1]) * acceleration_y +
543
+ (next_z - velocity[p + 2]) * acceleration_z;
544
+
545
+ // The reciprocal rather than the division, which is the form
546
+ // {@link cloth_integrate} uses — the two differ in the last bit, and
547
+ // a cloth whose external acceleration happens to be exactly gravity
548
+ // should follow the same trajectory whichever loop stepped it.
549
+ let blend = realised * inverse_h * (1 / acceleration_squared);
550
+
551
+ if (blend < 0) {
552
+ blend = 0;
553
+ } else if (blend > 1) {
554
+ blend = 1;
555
+ }
556
+
557
+ inertia_blend[i] = blend;
558
+ } else {
559
+ // No direction to project onto, so nothing to seed. The uniform
560
+ // path reaches this for the whole cloth at once; here it is a
561
+ // particle whose air exactly cancels its gravity, which is a real
562
+ // configuration rather than a degenerate one.
563
+ inertia_blend[i] = 0;
564
+ }
565
+
566
+ velocity[p] = next_x;
567
+ velocity[p + 1] = next_y;
568
+ velocity[p + 2] = next_z;
569
+ }
570
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Step one cloth.
3
+ *
4
+ * @param {ClothState} state the cloth, with its collider table already gathered
5
+ * @param {{offset: Int32Array, partner: Int32Array}|null} self_exclusions pairs
6
+ * a persistent row already governs; `null` when the cloth never self-collides
7
+ * @param {Float64Array} params
8
+ * @param {number} offset first word of this cloth's block in `params`
9
+ * @returns {void}
10
+ */
11
+ export function cloth_step_instance(state: ClothState, self_exclusions: {
12
+ offset: Int32Array;
13
+ partner: Int32Array;
14
+ } | null, params: Float64Array, offset: number): void;
15
+ /**
16
+ * Words of one cloth's parameter block.
17
+ */
18
+ export type ClothStepParam = number;
19
+ export namespace ClothStepParam {
20
+ let ID: number;
21
+ let DT: number;
22
+ let GRAVITY_X: number;
23
+ let GRAVITY_Y: number;
24
+ let GRAVITY_Z: number;
25
+ let SUBSTEPS: number;
26
+ let ITERATIONS: number;
27
+ let RETENTION: number;
28
+ let VELOCITY_LIMIT: number;
29
+ let CONTACT_RADIUS: number;
30
+ let SELF_RADIUS: number;
31
+ let COLLIDER_COUNT: number;
32
+ let SELF_COLLISION: number;
33
+ let DRAG_RESPONSE: number;
34
+ }
35
+ /**
36
+ * `Float64` words one cloth's parameter block occupies.
37
+ * @type {number}
38
+ */
39
+ export const CLOTH_STEP_PARAM_STRIDE: number;
40
+ //# sourceMappingURL=cloth_step_instance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloth_step_instance.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_step_instance.js"],"names":[],"mappings":"AAsIA;;;;;;;;;GASG;AACH,wEANW;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAC,GAAC,IAAI,UAE9C,YAAY,UACZ,MAAM,GACJ,IAAI,CA4DhB;;;;6BA/IS,MAAM;;;;;;;;;;;;;;;;;AAqEhB;;;GAGG;AACH,sCAFU,MAAM,CAE0B"}