@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
@@ -46,13 +46,6 @@ export class ClothInstance {
46
46
  * @type {Transform64|null}
47
47
  */
48
48
  transform: Transform64 | null;
49
- /**
50
- * How deep the anchor sits in the transform hierarchy. Instances step in
51
- * ascending depth so that a `Cloth` nested inside another one reads an
52
- * anchor the outer solve has already written this step.
53
- * @type {number}
54
- */
55
- depth: number;
56
49
  /**
57
50
  * `false` until the subtree has been walked. Seeding is deferred to the
58
51
  * first step rather than done at link, because a rope's links arrive as
@@ -343,32 +336,27 @@ export class ClothInstance {
343
336
  */
344
337
  blend_seen: number;
345
338
  /**
346
- * The colliders overlapping this cloth this step, packed in **its own
347
- * frame** rather than the world's — the same layout `ClothColliderIndex`
348
- * uses, in `Float32` rather than `Float64` because a cloth-local coordinate
349
- * is garment-sized (§12).
339
+ * Whether {@link state}'s buffer must be a `SharedArrayBuffer`.
350
340
  *
351
- * Grown, never shrunk, and rewritten every step by
352
- * `cloth_gather_colliders`. It lives on the instance rather than inside
353
- * {@link state}'s buffer because its size is a property of the *world* — how
354
- * many colliders happen to be near this cloth right now — and `ClothState`'s
355
- * one allocation is sized from the cloth. §12 puts it in the shared buffer
356
- * when M5 needs it there.
357
- * @type {Float32Array|null}
358
- */
359
- collider_table: Float32Array | null;
360
- /**
361
- * The index handle behind each record in {@link collider_table}. A record
362
- * index is this step's; a handle is the collider's, and it is what a
363
- * transient contact's multiplier is warm-started on.
364
- * @type {Int32Array|null}
341
+ * Set by {@link WorkerClothSystem} when the instance is linked, and read by
342
+ * `cloth_build_rows` every time the state is built — which is at seed and
343
+ * again at every re-seed, so a cloth that gains a link or changes a
344
+ * `ClothDynamics` field the rows depend on comes back shared without
345
+ * anything having to remember to ask.
346
+ * @type {boolean}
365
347
  */
366
- collider_key: Int32Array | null;
348
+ shared_state: boolean;
367
349
  /**
368
- * Live records in {@link collider_table}.
369
- * @type {number}
350
+ * `true` once this cloth has said its collider table overflowed.
351
+ *
352
+ * M5 moved that table into {@link state}'s buffer — §12's own layout, and
353
+ * what lets a worker step the cloth without being told about a new array
354
+ * every time the broadphase returns more. A fixed region has a capacity, and
355
+ * a cloth that overlaps more colliders than `CLOTH_COLLIDER_SLOTS` drops the
356
+ * remainder; this is how it says so once rather than once a frame.
357
+ * @type {boolean}
370
358
  */
371
- collider_count: number;
359
+ collider_overflow_reported: boolean;
372
360
  /**
373
361
  * Which particle pairs a self-collision row must never be built on, because
374
362
  * a persistent row already governs them (§9). CSR, sorted, built at seed and
@@ -414,6 +402,90 @@ export class ClothInstance {
414
402
  * @type {boolean}
415
403
  */
416
404
  refused: boolean;
405
+ /**
406
+ * The air at the cloth's centre the last time a step applied it, world-space
407
+ * metres per second (§10).
408
+ *
409
+ * What §7 P5's "wake on a wind change" compares against. It is the last
410
+ * **applied** air rather than the last sampled one, so a gust that builds
411
+ * slowly still wakes a sleeping banner instead of being reset by every step
412
+ * that declined to act on it.
413
+ * @type {Float64Array}
414
+ */
415
+ air_seen: Float64Array;
416
+ /**
417
+ * Whether the last step sampled the air per particle rather than once for
418
+ * the whole cloth — that is, whether a fluid field actually reached it.
419
+ * Diagnostic, and the one the playground shows: it is the difference
420
+ * between §10's simulated wake and its ambient fallback.
421
+ * @type {boolean}
422
+ */
423
+ air_varies: boolean;
424
+ /**
425
+ * Seconds of fixed step **this instance** has taken, which is the clock
426
+ * §10's gust is a function of.
427
+ *
428
+ * Per cloth rather than per world, and the difference only shows with more
429
+ * than one of them. A cloth registered with the worker while another is
430
+ * already running waits for its memory, and the world's clock moves during
431
+ * that wait because the other cloth is still being advanced — so the two
432
+ * systems reach *this* cloth's first step at different world times and hand
433
+ * it different weather. An age counted in its own steps is the same number
434
+ * on both sides by construction. `MEASUREMENTS.md` §57.
435
+ *
436
+ * Advanced on every step the instance is *offered*, including ones it
437
+ * sleeps through, because a sleeping cloth still has to be able to ask
438
+ * whether the air has changed enough to wake it.
439
+ * @type {number}
440
+ */
441
+ age: number;
442
+ /**
443
+ * The index handles this cloth last **stepped against**, in the order the
444
+ * broadphase returned them, and how many of them are meaningful.
445
+ *
446
+ * §7 P5's wake test compares each overlapping collider's previous pose with
447
+ * its current one, and `ClothColliderSystem#link` *places* a new collider —
448
+ * previous equals current — so a collider spawned around a sleeping cloth
449
+ * is one that has not moved and never woke it. The set is the other half of
450
+ * that question: a handle appearing or leaving is a change to the world the
451
+ * cloth went to sleep in, whatever the poses say.
452
+ * @type {Int32Array}
453
+ */
454
+ collider_keys: Int32Array;
455
+ /**
456
+ * @type {number}
457
+ */
458
+ collider_key_count: number;
459
+ /**
460
+ * The broadphase margin the last gather used, metres. The wake test has to
461
+ * query with the same one, or it compares a set built under one reach with
462
+ * a set built under another and wakes on the difference between the two
463
+ * questions rather than on a change in the world.
464
+ * @type {number}
465
+ */
466
+ gather_reach: number;
467
+ /**
468
+ * The joint entities this cloth's rig seeding took `TransformAttachment`
469
+ * authority from, so that removing the cloth can give it back. `null` on
470
+ * the entity path and before the first rig seeding.
471
+ *
472
+ * Only the ones the revoke actually changed: a joint that was already the
473
+ * CPU's is not one cloth has anything to hand back.
474
+ * @type {number[]|null}
475
+ */
476
+ revoked_joints: number[] | null;
477
+ /**
478
+ * Where every particle was when the current sleep window opened, or `null`
479
+ * before the first step — §7 P5's sleep test measures displacement from
480
+ * this rather than an instantaneous speed, because a cloth resting on a
481
+ * collider sits in a bounded limit cycle whose speed is not small.
482
+ *
483
+ * Re-anchored to the live positions whenever a particle leaves the
484
+ * threshold, so the window is "how far has anything moved since the cloth
485
+ * last moved" rather than a fixed grid of epochs.
486
+ * @type {Float32Array|null}
487
+ */
488
+ sleep_reference: Float32Array | null;
417
489
  /**
418
490
  * How many times this cloth has been re-seeded by a teleport. Diagnostic:
419
491
  * a cloth resetting every few seconds is being driven by something that
@@ -1 +1 @@
1
- {"version":3,"file":"ClothInstance.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/ClothInstance.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ClothInstance.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/ClothInstance.js"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { Transform64 } from "../../../ecs/transform/Transform64.js";
2
+ import { CLOTH_COLLIDER_SLOTS } from "../solver/cloth_solver_constants.js";
2
3
  import { ClothDynamics } from "./ClothDynamics.js";
3
4
 
4
5
  /**
@@ -53,14 +54,6 @@ export class ClothInstance {
53
54
  */
54
55
  transform = null;
55
56
 
56
- /**
57
- * How deep the anchor sits in the transform hierarchy. Instances step in
58
- * ascending depth so that a `Cloth` nested inside another one reads an
59
- * anchor the outer solve has already written this step.
60
- * @type {number}
61
- */
62
- depth = 0;
63
-
64
57
  /**
65
58
  * `false` until the subtree has been walked. Seeding is deferred to the
66
59
  * first step rather than done at link, because a rope's links arrive as
@@ -391,34 +384,28 @@ export class ClothInstance {
391
384
  blend_seen = 1;
392
385
 
393
386
  /**
394
- * The colliders overlapping this cloth this step, packed in **its own
395
- * frame** rather than the world's — the same layout `ClothColliderIndex`
396
- * uses, in `Float32` rather than `Float64` because a cloth-local coordinate
397
- * is garment-sized (§12).
387
+ * Whether {@link state}'s buffer must be a `SharedArrayBuffer`.
398
388
  *
399
- * Grown, never shrunk, and rewritten every step by
400
- * `cloth_gather_colliders`. It lives on the instance rather than inside
401
- * {@link state}'s buffer because its size is a property of the *world* — how
402
- * many colliders happen to be near this cloth right now — and `ClothState`'s
403
- * one allocation is sized from the cloth. §12 puts it in the shared buffer
404
- * when M5 needs it there.
405
- * @type {Float32Array|null}
406
- */
407
- collider_table = null;
408
-
409
- /**
410
- * The index handle behind each record in {@link collider_table}. A record
411
- * index is this step's; a handle is the collider's, and it is what a
412
- * transient contact's multiplier is warm-started on.
413
- * @type {Int32Array|null}
389
+ * Set by {@link WorkerClothSystem} when the instance is linked, and read by
390
+ * `cloth_build_rows` every time the state is built — which is at seed and
391
+ * again at every re-seed, so a cloth that gains a link or changes a
392
+ * `ClothDynamics` field the rows depend on comes back shared without
393
+ * anything having to remember to ask.
394
+ * @type {boolean}
414
395
  */
415
- collider_key = null;
396
+ shared_state = false;
416
397
 
417
398
  /**
418
- * Live records in {@link collider_table}.
419
- * @type {number}
399
+ * `true` once this cloth has said its collider table overflowed.
400
+ *
401
+ * M5 moved that table into {@link state}'s buffer — §12's own layout, and
402
+ * what lets a worker step the cloth without being told about a new array
403
+ * every time the broadphase returns more. A fixed region has a capacity, and
404
+ * a cloth that overlaps more colliders than `CLOTH_COLLIDER_SLOTS` drops the
405
+ * remainder; this is how it says so once rather than once a frame.
406
+ * @type {boolean}
420
407
  */
421
- collider_count = 0;
408
+ collider_overflow_reported = false;
422
409
 
423
410
  /**
424
411
  * Which particle pairs a self-collision row must never be built on, because
@@ -467,6 +454,98 @@ export class ClothInstance {
467
454
  */
468
455
  refused = false;
469
456
 
457
+ /**
458
+ * The air at the cloth's centre the last time a step applied it, world-space
459
+ * metres per second (§10).
460
+ *
461
+ * What §7 P5's "wake on a wind change" compares against. It is the last
462
+ * **applied** air rather than the last sampled one, so a gust that builds
463
+ * slowly still wakes a sleeping banner instead of being reset by every step
464
+ * that declined to act on it.
465
+ * @type {Float64Array}
466
+ */
467
+ air_seen = new Float64Array(3);
468
+
469
+ /**
470
+ * Whether the last step sampled the air per particle rather than once for
471
+ * the whole cloth — that is, whether a fluid field actually reached it.
472
+ * Diagnostic, and the one the playground shows: it is the difference
473
+ * between §10's simulated wake and its ambient fallback.
474
+ * @type {boolean}
475
+ */
476
+ air_varies = false;
477
+
478
+ /**
479
+ * Seconds of fixed step **this instance** has taken, which is the clock
480
+ * §10's gust is a function of.
481
+ *
482
+ * Per cloth rather than per world, and the difference only shows with more
483
+ * than one of them. A cloth registered with the worker while another is
484
+ * already running waits for its memory, and the world's clock moves during
485
+ * that wait because the other cloth is still being advanced — so the two
486
+ * systems reach *this* cloth's first step at different world times and hand
487
+ * it different weather. An age counted in its own steps is the same number
488
+ * on both sides by construction. `MEASUREMENTS.md` §57.
489
+ *
490
+ * Advanced on every step the instance is *offered*, including ones it
491
+ * sleeps through, because a sleeping cloth still has to be able to ask
492
+ * whether the air has changed enough to wake it.
493
+ * @type {number}
494
+ */
495
+ age = 0;
496
+
497
+ /**
498
+ * The index handles this cloth last **stepped against**, in the order the
499
+ * broadphase returned them, and how many of them are meaningful.
500
+ *
501
+ * §7 P5's wake test compares each overlapping collider's previous pose with
502
+ * its current one, and `ClothColliderSystem#link` *places* a new collider —
503
+ * previous equals current — so a collider spawned around a sleeping cloth
504
+ * is one that has not moved and never woke it. The set is the other half of
505
+ * that question: a handle appearing or leaving is a change to the world the
506
+ * cloth went to sleep in, whatever the poses say.
507
+ * @type {Int32Array}
508
+ */
509
+ collider_keys = new Int32Array(CLOTH_COLLIDER_SLOTS);
510
+
511
+ /**
512
+ * @type {number}
513
+ */
514
+ collider_key_count = 0;
515
+
516
+ /**
517
+ * The broadphase margin the last gather used, metres. The wake test has to
518
+ * query with the same one, or it compares a set built under one reach with
519
+ * a set built under another and wakes on the difference between the two
520
+ * questions rather than on a change in the world.
521
+ * @type {number}
522
+ */
523
+ gather_reach = 0;
524
+
525
+ /**
526
+ * The joint entities this cloth's rig seeding took `TransformAttachment`
527
+ * authority from, so that removing the cloth can give it back. `null` on
528
+ * the entity path and before the first rig seeding.
529
+ *
530
+ * Only the ones the revoke actually changed: a joint that was already the
531
+ * CPU's is not one cloth has anything to hand back.
532
+ * @type {number[]|null}
533
+ */
534
+ revoked_joints = null;
535
+
536
+ /**
537
+ * Where every particle was when the current sleep window opened, or `null`
538
+ * before the first step — §7 P5's sleep test measures displacement from
539
+ * this rather than an instantaneous speed, because a cloth resting on a
540
+ * collider sits in a bounded limit cycle whose speed is not small.
541
+ *
542
+ * Re-anchored to the live positions whenever a particle leaves the
543
+ * threshold, so the window is "how far has anything moved since the cloth
544
+ * last moved" rather than a fixed grid of epochs.
545
+ * @type {Float32Array|null}
546
+ */
547
+ sleep_reference = null;
548
+
470
549
  /**
471
550
  * How many times this cloth has been re-seeded by a teleport. Diagnostic:
472
551
  * a cloth resetting every few seconds is being driven by something that
@@ -0,0 +1,84 @@
1
+ /**
2
+ * # Binary serialization for {@link Cloth}
3
+ *
4
+ * The component is authoring data and nothing else, so the whole of it is
5
+ * written: the {@link ClothDynamics} value object inline, then `blend`, `layer`,
6
+ * `mask` and `flags`. There is no transient field to exclude — the live binding
7
+ * between a component and a simulation is a {@link ClothInstance} owned by
8
+ * `ClothWorld`, and everything world-tied lives over there: the seeded topology,
9
+ * the `ClothState` buffer, and `blend_seen`, which is what the write-back last
10
+ * saw rather than what the author asked for. All of it is rebuilt on link, the
11
+ * same division `RigidBodySerializationAdapter` makes against `_bodyId`.
12
+ *
13
+ * ## The dynamics are written **by value**, and that is not the `Collider#shape`
14
+ * case
15
+ *
16
+ * §3.2 sets out the convention for a component pointing at a built, shared,
17
+ * immutable asset — `Collider#shape`, `ParticleEffect`'s layout and program,
18
+ * `ClothRig#proxy` — which is that the reference is *not* in the stream and the
19
+ * asset pipeline wires it up, because what has to be restored is the asset's
20
+ * **identity**. A `ClothDynamics` is not that. §3.3's library is "a set of
21
+ * points rather than a mechanism": an entry is frozen and shared as an
22
+ * allocation optimisation, not because anything downstream refers to it by
23
+ * name, and a cloth built from `CLOTH_SILK.clone()` with one field moved has no
24
+ * identity to restore at all. Ten scalars are 68 bytes; an identity story for
25
+ * them would cost more than the bytes and would have to invent a name for every
26
+ * `clone()`. So the values go in the stream and a loaded cloth is equal to the
27
+ * saved one under {@link Cloth#equals}, which compares dynamics field-wise.
28
+ *
29
+ * ## Deserialize replaces the dynamics rather than writing into them
30
+ *
31
+ * Library entries are frozen and the engine is modules, so writing a field on
32
+ * one **throws** (`ClothDynamics.spec.js` pins that). Deserializing in place
33
+ * into a `Cloth` that holds `CLOTH_ROPE` — a reset-to-snapshot restore over a
34
+ * live scene, not a hypothetical — would be exactly that write. So the adapter
35
+ * builds a fresh instance and hands it over, which is also what
36
+ * {@link Cloth#fromJSON} does and for the same reason. The two codecs agreeing
37
+ * on it matters beyond the throw: a scene that round-trips as JSON and a scene
38
+ * that round-trips as binary must not disagree about whether the loaded cloth
39
+ * shares its dynamics with anything.
40
+ *
41
+ * ## `layer` and `mask` are read back unsigned, unlike the `RigidBody` pair
42
+ *
43
+ * `RigidBodySerializationAdapter` normalises those two fields with `| 0`,
44
+ * because a `RigidBody`'s default mask is the signed `0xFFFFFFFF | 0 === -1`
45
+ * and reading the raw unsigned value would make a round-tripped body compare
46
+ * unequal to a fresh one. `Cloth`'s default is the **unsigned** `0xFFFFFFFF`,
47
+ * and `Cloth.from` asserts `isNonNegativeInteger` on it, so here the same `| 0`
48
+ * would be the bug rather than the fix: it would hand back a `-1` that fails
49
+ * the component's own stated contract and compares unequal under
50
+ * {@link Cloth#equals}. `readUint32` already returns the unsigned value, so the
51
+ * correct code is the code with nothing in it — which is precisely why this
52
+ * paragraph exists, since the surrounding adapters all carry the opposite
53
+ * normalisation and it reads like an omission.
54
+ *
55
+ * ## Version 0, and no upgrader
56
+ *
57
+ * `RigidBodySerializationUpgrader_0_1` exists because a v0 stream had already
58
+ * shipped when the sleep fields were added; a first version has no predecessor
59
+ * stream to upgrade from. Adding a field here is a bump to 1 plus an upgrader
60
+ * that writes that field's pre-upgrade default, and the exact-size assertion in
61
+ * the spec is what makes forgetting the bump fail rather than corrupt.
62
+ *
63
+ * @author Alex Goldring
64
+ * @copyright Company Named Limited (c) 2026
65
+ */
66
+ export class ClothSerializationAdapter extends BinaryClassSerializationAdapter<any> {
67
+ constructor();
68
+ klass: typeof Cloth;
69
+ /**
70
+ *
71
+ * @param {BinaryBuffer} buffer
72
+ * @param {Cloth} value
73
+ */
74
+ serialize(buffer: BinaryBuffer, value: Cloth): void;
75
+ /**
76
+ *
77
+ * @param {BinaryBuffer} buffer
78
+ * @param {Cloth} value
79
+ */
80
+ deserialize(buffer: BinaryBuffer, value: Cloth): void;
81
+ }
82
+ import { BinaryClassSerializationAdapter } from "../../../ecs/storage/binary/BinaryClassSerializationAdapter.js";
83
+ import { Cloth } from "./Cloth.js";
84
+ //# sourceMappingURL=ClothSerializationAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClothSerializationAdapter.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/ClothSerializationAdapter.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AACH;;IAEI,oBAAc;IAGd;;;;OAIG;IACH,uCAFW,KAAK,QA2Bf;IAED;;;;OAIG;IACH,yCAFW,KAAK,QA8Bf;CACJ;gDA5I+C,gEAAgE;sBAC1F,YAAY"}
@@ -0,0 +1,141 @@
1
+ import { BinaryClassSerializationAdapter } from "../../../ecs/storage/binary/BinaryClassSerializationAdapter.js";
2
+ import { Cloth } from "./Cloth.js";
3
+ import { ClothDynamics } from "./ClothDynamics.js";
4
+
5
+ /**
6
+ * # Binary serialization for {@link Cloth}
7
+ *
8
+ * The component is authoring data and nothing else, so the whole of it is
9
+ * written: the {@link ClothDynamics} value object inline, then `blend`, `layer`,
10
+ * `mask` and `flags`. There is no transient field to exclude — the live binding
11
+ * between a component and a simulation is a {@link ClothInstance} owned by
12
+ * `ClothWorld`, and everything world-tied lives over there: the seeded topology,
13
+ * the `ClothState` buffer, and `blend_seen`, which is what the write-back last
14
+ * saw rather than what the author asked for. All of it is rebuilt on link, the
15
+ * same division `RigidBodySerializationAdapter` makes against `_bodyId`.
16
+ *
17
+ * ## The dynamics are written **by value**, and that is not the `Collider#shape`
18
+ * case
19
+ *
20
+ * §3.2 sets out the convention for a component pointing at a built, shared,
21
+ * immutable asset — `Collider#shape`, `ParticleEffect`'s layout and program,
22
+ * `ClothRig#proxy` — which is that the reference is *not* in the stream and the
23
+ * asset pipeline wires it up, because what has to be restored is the asset's
24
+ * **identity**. A `ClothDynamics` is not that. §3.3's library is "a set of
25
+ * points rather than a mechanism": an entry is frozen and shared as an
26
+ * allocation optimisation, not because anything downstream refers to it by
27
+ * name, and a cloth built from `CLOTH_SILK.clone()` with one field moved has no
28
+ * identity to restore at all. Ten scalars are 68 bytes; an identity story for
29
+ * them would cost more than the bytes and would have to invent a name for every
30
+ * `clone()`. So the values go in the stream and a loaded cloth is equal to the
31
+ * saved one under {@link Cloth#equals}, which compares dynamics field-wise.
32
+ *
33
+ * ## Deserialize replaces the dynamics rather than writing into them
34
+ *
35
+ * Library entries are frozen and the engine is modules, so writing a field on
36
+ * one **throws** (`ClothDynamics.spec.js` pins that). Deserializing in place
37
+ * into a `Cloth` that holds `CLOTH_ROPE` — a reset-to-snapshot restore over a
38
+ * live scene, not a hypothetical — would be exactly that write. So the adapter
39
+ * builds a fresh instance and hands it over, which is also what
40
+ * {@link Cloth#fromJSON} does and for the same reason. The two codecs agreeing
41
+ * on it matters beyond the throw: a scene that round-trips as JSON and a scene
42
+ * that round-trips as binary must not disagree about whether the loaded cloth
43
+ * shares its dynamics with anything.
44
+ *
45
+ * ## `layer` and `mask` are read back unsigned, unlike the `RigidBody` pair
46
+ *
47
+ * `RigidBodySerializationAdapter` normalises those two fields with `| 0`,
48
+ * because a `RigidBody`'s default mask is the signed `0xFFFFFFFF | 0 === -1`
49
+ * and reading the raw unsigned value would make a round-tripped body compare
50
+ * unequal to a fresh one. `Cloth`'s default is the **unsigned** `0xFFFFFFFF`,
51
+ * and `Cloth.from` asserts `isNonNegativeInteger` on it, so here the same `| 0`
52
+ * would be the bug rather than the fix: it would hand back a `-1` that fails
53
+ * the component's own stated contract and compares unequal under
54
+ * {@link Cloth#equals}. `readUint32` already returns the unsigned value, so the
55
+ * correct code is the code with nothing in it — which is precisely why this
56
+ * paragraph exists, since the surrounding adapters all carry the opposite
57
+ * normalisation and it reads like an omission.
58
+ *
59
+ * ## Version 0, and no upgrader
60
+ *
61
+ * `RigidBodySerializationUpgrader_0_1` exists because a v0 stream had already
62
+ * shipped when the sleep fields were added; a first version has no predecessor
63
+ * stream to upgrade from. Adding a field here is a bump to 1 plus an upgrader
64
+ * that writes that field's pre-upgrade default, and the exact-size assertion in
65
+ * the spec is what makes forgetting the bump fail rather than corrupt.
66
+ *
67
+ * @author Alex Goldring
68
+ * @copyright Company Named Limited (c) 2026
69
+ */
70
+ export class ClothSerializationAdapter extends BinaryClassSerializationAdapter {
71
+
72
+ klass = Cloth;
73
+ version = 0;
74
+
75
+ /**
76
+ *
77
+ * @param {BinaryBuffer} buffer
78
+ * @param {Cloth} value
79
+ */
80
+ serialize(buffer, value) {
81
+ const dynamics = value.dynamics;
82
+
83
+ buffer.writeFloat64(dynamics.stretch);
84
+ buffer.writeFloat64(dynamics.bend);
85
+ buffer.writeFloat64(dynamics.damping);
86
+ buffer.writeFloat64(dynamics.slack);
87
+ buffer.writeFloat64(dynamics.thickness);
88
+ buffer.writeFloat64(dynamics.inertia);
89
+ buffer.writeFloat64(dynamics.drag);
90
+
91
+ // A budget, not an enum: `assert.isPositiveInteger` is the whole of the
92
+ // component's contract on these two, so a u8 would be a silent clamp on
93
+ // a value the component considers legal. Four bytes each buys the
94
+ // absence of that.
95
+ buffer.writeUint32(dynamics.substeps);
96
+ buffer.writeUint32(dynamics.iterations);
97
+
98
+ buffer.writeUint32(dynamics.flags >>> 0);
99
+
100
+ buffer.writeFloat64(value.blend);
101
+
102
+ buffer.writeUint32(value.layer >>> 0);
103
+ buffer.writeUint32(value.mask >>> 0);
104
+ buffer.writeUint32(value.flags >>> 0);
105
+ }
106
+
107
+ /**
108
+ *
109
+ * @param {BinaryBuffer} buffer
110
+ * @param {Cloth} value
111
+ */
112
+ deserialize(buffer, value) {
113
+ // Fresh rather than in place: the target may hold a frozen library
114
+ // entry, and a loaded cloth always owns its dynamics — see the class
115
+ // docblock and Cloth#fromJSON.
116
+ const dynamics = new ClothDynamics();
117
+
118
+ dynamics.stretch = buffer.readFloat64();
119
+ dynamics.bend = buffer.readFloat64();
120
+ dynamics.damping = buffer.readFloat64();
121
+ dynamics.slack = buffer.readFloat64();
122
+ dynamics.thickness = buffer.readFloat64();
123
+ dynamics.inertia = buffer.readFloat64();
124
+ dynamics.drag = buffer.readFloat64();
125
+
126
+ dynamics.substeps = buffer.readUint32();
127
+ dynamics.iterations = buffer.readUint32();
128
+
129
+ dynamics.flags = buffer.readUint32();
130
+
131
+ value.dynamics = dynamics;
132
+
133
+ value.blend = buffer.readFloat64();
134
+
135
+ // Unsigned, deliberately — the `| 0` the RigidBody adapter applies
136
+ // would break this component's non-negative contract. Class docblock.
137
+ value.layer = buffer.readUint32();
138
+ value.mask = buffer.readUint32();
139
+ value.flags = buffer.readUint32();
140
+ }
141
+ }