@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
@@ -0,0 +1,578 @@
1
+ import { ResourceAccessKind } from "../../../../core/model/ResourceAccessKind.js";
2
+ import { ResourceAccessSpecification } from "../../../../core/model/ResourceAccessSpecification.js";
3
+ import { WorkerSystem } from "../../../ecs/async/WorkerSystem.js";
4
+ import {
5
+ TransformAttachment
6
+ } from "../../../ecs/transform-attachment/TransformAttachment.js";
7
+ import { Transform64 } from "../../../ecs/transform/Transform64.js";
8
+ import { ClothStepParam } from "../solver/cloth_step_instance.js";
9
+ import { Cloth } from "./Cloth.js";
10
+ import { ClothCollider } from "./ClothCollider.js";
11
+ import { ClothExclude } from "./ClothExclude.js";
12
+ import { ClothRig } from "./ClothRig.js";
13
+ import { ClothWorld } from "./ClothWorld.js";
14
+ import {
15
+ ClothCommand,
16
+ cloth_command_offset,
17
+ cloth_command_word_count
18
+ } from "./cloth_worker_protocol.js";
19
+
20
+ /**
21
+ * Default ceiling on simultaneously stepped cloths. Sizes the command region,
22
+ * which is allocated once at startup and cannot grow.
23
+ * @type {number}
24
+ */
25
+ const DEFAULT_MAX_CLOTH_COUNT = 64;
26
+
27
+ /**
28
+ * Drop-in alternative to {@link ClothSystem} that runs the solve on a worker
29
+ * thread.
30
+ *
31
+ * ## What moves, and what does not
32
+ *
33
+ * A cloth's fixed step is "work that needs the world" followed by "arithmetic
34
+ * over typed arrays", and `MEASUREMENTS.md` §7 puts 69% of the frame in the
35
+ * stretch rows alone — so the split is where §12 drew it:
36
+ *
37
+ * - **main thread**: seeding, the anchor's pose, the local-frame carry, the
38
+ * leash centres, the collider broadphase, the sleep test and the write-back.
39
+ * All of it reads components, walks hierarchies or queries an index, and
40
+ * none of it is where the time goes.
41
+ * - **worker**: `cloth_step_instance(state, exclusions, params, offset)` — the
42
+ * damping, the contact search, the self-collision pair search, the solve and
43
+ * the velocity clamp.
44
+ *
45
+ * Both sides call {@link ClothWorld}, and both hand `cloth_step_instance` the
46
+ * *same* `Float64` parameter block — {@link ClothSystem} in a private scratch
47
+ * array, this one in a slice of the shared command region. Identical code over
48
+ * identical data in an identical order, so results are bit-for-bit equal to
49
+ * {@link ClothSystem}'s (`WorkerClothSystem.spec.js` holds that as a standing
50
+ * gate).
51
+ *
52
+ * Nothing is copied. A cloth's `ClothState` lives in a {@link SharedArrayBuffer}
53
+ * and the worker steps it in place; a completed step is published by advancing a
54
+ * single atomic.
55
+ *
56
+ * ## Using it
57
+ *
58
+ * ```js
59
+ * entityManager.addSystem(new WorkerClothSystem({ worker_factory: makeClothWorker }));
60
+ * ```
61
+ *
62
+ * There is no per-component opt-in, unlike {@link WorkerFluidSystem}'s
63
+ * `field.shared_memory`: a cloth's state does not exist until the cloth seeds,
64
+ * and seeding is this system's own work, so it simply builds them shared.
65
+ *
66
+ * Requires a cross-origin isolated page (`Cross-Origin-Opener-Policy:
67
+ * same-origin` + `Cross-Origin-Embedder-Policy: require-corp`) — without it
68
+ * `SharedArrayBuffer` does not exist and startup throws.
69
+ *
70
+ * ## Ownership — the one behavioural difference
71
+ *
72
+ * {@link ClothSystem} leaves every cloth consistent at all times. Here a cloth's
73
+ * `ClothState` is **owned by the worker** from the moment this system's
74
+ * `fixedUpdate` dispatches until the next tick joins the result. Concretely:
75
+ *
76
+ * - The `Transform64`/`Node3D` poses this system writes are *not* affected:
77
+ * the write-back happens at join, on this thread, inside the fixed pass. A
78
+ * renderer reading a cloth's transforms reads them exactly as it always did.
79
+ * - What must not be read outside the fixed pass is `ClothInstance#state` —
80
+ * particle positions, velocities, the contact slots. Nothing in the engine
81
+ * does; the playgrounds' diagnostics run inside the fixed pass.
82
+ * - {@link ClothColliderSystem} is refreshed from inside this system's own
83
+ * `collect`, as it is under {@link ClothSystem}, so the index is never read
84
+ * while a step is in flight.
85
+ *
86
+ * Two further differences from {@link ClothSystem}:
87
+ *
88
+ * - Results lag by one tick: the pose written at tick `T` is step `T - 1`'s.
89
+ * The *sequence* of states is unchanged — it is observed one tick later.
90
+ * - A newly seeded cloth is not stepped until the worker acknowledges its
91
+ * registration (a cold-plane round trip, so at least one tick and in
92
+ * practice a few). Until then it is not advanced either — not stepped, not
93
+ * carried across anchor motion, not written back — which is what keeps the
94
+ * step *sequence* identical to {@link ClothSystem}'s rather than merely
95
+ * similar. A garment therefore holds its bind pose for a few ticks after it
96
+ * spawns, and a re-seed does the same, because a re-seed builds a new buffer
97
+ * and the worker has to be told about it.
98
+ *
99
+ * @author Alex Goldring
100
+ * @copyright Company Named Limited (c) 2026
101
+ */
102
+ export class WorkerClothSystem extends WorkerSystem {
103
+
104
+ dependencies = [Cloth, Transform64];
105
+
106
+ components_used = [
107
+ ResourceAccessSpecification.from(Cloth, ResourceAccessKind.Read),
108
+ ResourceAccessSpecification.from(Transform64, ResourceAccessKind.Read | ResourceAccessKind.Write),
109
+ ResourceAccessSpecification.from(TransformAttachment, ResourceAccessKind.Read | ResourceAccessKind.Write),
110
+ ResourceAccessSpecification.from(ClothExclude, ResourceAccessKind.Read),
111
+ ResourceAccessSpecification.from(ClothCollider, ResourceAccessKind.Read),
112
+ ResourceAccessSpecification.from(ClothRig, ResourceAccessKind.Read)
113
+ ];
114
+
115
+ /**
116
+ * The cloths, and everything about stepping one that is not arithmetic.
117
+ * Shared with {@link ClothSystem}, which is what makes the two systems one
118
+ * implementation.
119
+ * @type {ClothWorld}
120
+ */
121
+ world = new ClothWorld();
122
+
123
+ /**
124
+ * @type {(() => Worker)|null}
125
+ */
126
+ #worker_factory = null;
127
+
128
+ /**
129
+ * @type {number}
130
+ */
131
+ #max_cloth_count = DEFAULT_MAX_CLOTH_COUNT;
132
+
133
+ /**
134
+ * The cold-plane message that announced each registered cloth, the state it
135
+ * announced, and whether the worker has acknowledged it.
136
+ *
137
+ * Keyed by instance, and carrying the `ClothState` rather than trusting the
138
+ * instance still to hold it: a re-seed replaces the state with a new buffer,
139
+ * and the registration the worker holds then names memory nobody writes to
140
+ * any more. Comparing identity is how that is noticed without a dirty flag.
141
+ * @type {Map<ClothInstance, {id: number, sequence: number, state: ClothState, acknowledged: boolean}>}
142
+ */
143
+ #registrations = new Map();
144
+
145
+ /**
146
+ * Cloths announced but not yet acknowledged.
147
+ * @type {ClothInstance[]}
148
+ */
149
+ #pending = [];
150
+
151
+ /**
152
+ * Cloths dispatched at the tick now in flight, in nomination order — the
153
+ * ones {@link apply} will finish.
154
+ * @type {ClothInstance[]}
155
+ */
156
+ #dispatched = [];
157
+
158
+ /**
159
+ * @type {number}
160
+ */
161
+ #next_cloth_id = 1;
162
+
163
+ /**
164
+ * Latches the max_cloth_count overflow report so a persistent
165
+ * misconfiguration warns once instead of once per tick.
166
+ * @type {boolean}
167
+ */
168
+ #cloth_overflow_reported = false;
169
+
170
+ /**
171
+ * @param {object} options
172
+ * @param {() => Worker} options.worker_factory spawns the worker. Supplied
173
+ * rather than hard-coded because the spawn expression needs
174
+ * `import.meta.url`, which cannot be parsed by the CommonJS transform
175
+ * the test runner uses — see `makeClothWorker.js`.
176
+ * @param {number} [options.max_cloth_count] ceiling on simultaneously
177
+ * stepped cloths; sizes the fixed command region.
178
+ */
179
+ constructor({ worker_factory, max_cloth_count = DEFAULT_MAX_CLOTH_COUNT } = {}) {
180
+ super();
181
+
182
+ this.#worker_factory = worker_factory;
183
+ this.#max_cloth_count = max_cloth_count;
184
+
185
+ this.world.shared_state = true;
186
+
187
+ this.command_word_count = cloth_command_word_count(max_cloth_count);
188
+ }
189
+
190
+ /**
191
+ * World gravity, m/s². Rotated into each cloth's local frame per step.
192
+ * @returns {Float64Array}
193
+ */
194
+ get gravity() {
195
+ return this.world.gravity;
196
+ }
197
+
198
+ /**
199
+ * @param {Float64Array} value
200
+ */
201
+ set gravity(value) {
202
+ this.world.gravity = value;
203
+ }
204
+
205
+ /**
206
+ * Where the air comes from — see {@link ClothWorld#wind}. Sampled on **this**
207
+ * thread even under the worker, because a fluid field cannot cross and its
208
+ * answer can: `cloth_sample_air.js` is the argument, and it lands in a region
209
+ * of the cloth's own shared buffer.
210
+ * @returns {AbstractClothWind|null}
211
+ */
212
+ get wind() {
213
+ return this.world.wind;
214
+ }
215
+
216
+ /**
217
+ * @param {AbstractClothWind|null} value
218
+ */
219
+ set wind(value) {
220
+ this.world.wind = value;
221
+ }
222
+
223
+ /**
224
+ * @returns {ClothInstance[]}
225
+ */
226
+ get instances() {
227
+ return this.world.instances;
228
+ }
229
+
230
+ /**
231
+ * @returns {{instance_of: function(number): (PrefabInstance|null)}|null}
232
+ */
233
+ get models() {
234
+ return this.world.models;
235
+ }
236
+
237
+ /**
238
+ * @param {{instance_of: function(number): (PrefabInstance|null)}|null} value
239
+ */
240
+ set models(value) {
241
+ this.world.models = value;
242
+ }
243
+
244
+ /**
245
+ * @returns {Worker}
246
+ */
247
+ createWorker() {
248
+ if (typeof this.#worker_factory !== "function") {
249
+ throw new Error(
250
+ "WorkerClothSystem requires a worker factory:"
251
+ + " new WorkerClothSystem({ worker_factory: makeClothWorker })"
252
+ );
253
+ }
254
+
255
+ return this.#worker_factory();
256
+ }
257
+
258
+ /**
259
+ * @param {EntityManager} entityManager
260
+ * @returns {Promise<void>}
261
+ */
262
+ async startup(entityManager) {
263
+ this.world.attach(entityManager);
264
+
265
+ await super.startup(entityManager);
266
+ }
267
+
268
+ /**
269
+ * @param {EntityComponentDataset} dataset
270
+ * @returns {void}
271
+ */
272
+ handleDatasetAttached(dataset) {
273
+ this.world.attach_dataset(dataset);
274
+ }
275
+
276
+ /**
277
+ * @param {EntityComponentDataset} dataset
278
+ * @returns {void}
279
+ */
280
+ handleDatasetDetached(dataset) {
281
+ this.world.detach_dataset(dataset);
282
+ }
283
+
284
+ /**
285
+ * @param {EntityManager} entityManager
286
+ * @returns {Promise<void>}
287
+ */
288
+ async shutdown(entityManager) {
289
+ await super.shutdown(entityManager);
290
+
291
+ this.#registrations.clear();
292
+ this.#pending.length = 0;
293
+ this.#dispatched.length = 0;
294
+ }
295
+
296
+ /**
297
+ * @param {Cloth} cloth
298
+ * @param {Transform64} transform
299
+ * @param {number} entity
300
+ */
301
+ link(cloth, transform, entity) {
302
+ this.world.link(cloth, transform, entity);
303
+ }
304
+
305
+ /**
306
+ * @param {Cloth} cloth
307
+ * @param {Transform64} transform
308
+ * @param {number} entity
309
+ */
310
+ unlink(cloth, transform, entity) {
311
+ const instance = this.world.unlink(entity);
312
+
313
+ if (instance !== undefined) {
314
+ this.#retire(instance);
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Throw away a cloth's binding so the next step walks its subtree again.
320
+ * @param {number} entity
321
+ * @returns {void}
322
+ */
323
+ reseed(entity) {
324
+ this.world.reseed(entity);
325
+ }
326
+
327
+ /**
328
+ * Wake a sleeping cloth.
329
+ * @param {number} entity
330
+ * @returns {void}
331
+ */
332
+ wake(entity) {
333
+ this.world.wake(entity);
334
+ }
335
+
336
+ /**
337
+ * @param {number} entity
338
+ * @returns {ClothInstance|undefined}
339
+ */
340
+ instanceOf(entity) {
341
+ return this.world.instanceOf(entity);
342
+ }
343
+
344
+ /**
345
+ * @returns {boolean} whether cloth *particle state* may currently be read
346
+ * from the main thread. False while a step is in flight. The poses
347
+ * on the scene are always readable — they are written at join.
348
+ */
349
+ get is_state_readable() {
350
+ return !this.is_step_in_flight;
351
+ }
352
+
353
+ /**
354
+ * @param {Float64Array} command
355
+ * @param {number} tick
356
+ * @param {number} time_delta_seconds
357
+ * @returns {boolean}
358
+ */
359
+ collect(command, tick, time_delta_seconds) {
360
+ const em = this.entityManager;
361
+
362
+ if (em === null) {
363
+ return false;
364
+ }
365
+
366
+ const ecd = em.dataset;
367
+
368
+ if (ecd === null || ecd === undefined) {
369
+ return false;
370
+ }
371
+
372
+ this.#promote_acknowledged_cloths();
373
+
374
+ const world = this.world;
375
+
376
+ world.begin(ecd, time_delta_seconds);
377
+
378
+ const instances = world.instances;
379
+
380
+ const max_cloth_count = this.#max_cloth_count;
381
+
382
+ const dispatched = this.#dispatched;
383
+
384
+ dispatched.length = 0;
385
+
386
+ let cloth_count = 0;
387
+
388
+ for (let i = 0; i < instances.length; i++) {
389
+ const instance = instances[i];
390
+
391
+ if (!world.ensure_seeded(instance, ecd, time_delta_seconds)) {
392
+ continue;
393
+ }
394
+
395
+ const registration = this.#registrations.get(instance);
396
+
397
+ if (registration === undefined || registration.state !== instance.state) {
398
+ // Either the cloth has just seeded, or a re-seed built it a new
399
+ // buffer. Announce the current one and wait — nominating memory
400
+ // the worker has not attached to is a protocol error, and
401
+ // advancing the cloth without stepping it would put its step
402
+ // sequence out of step with ClothSystem's for the rest of the
403
+ // run.
404
+ this.#register(instance);
405
+
406
+ continue;
407
+ }
408
+
409
+ if (!registration.acknowledged) {
410
+ continue;
411
+ }
412
+
413
+ if (cloth_count === max_cloth_count) {
414
+ if (!this.#cloth_overflow_reported) {
415
+ this.#cloth_overflow_reported = true;
416
+
417
+ console.error(
418
+ `WorkerClothSystem: more live cloths than max_cloth_count (${max_cloth_count});`
419
+ + ` the remainder will not be simulated. Raise max_cloth_count in the constructor.`
420
+ );
421
+ }
422
+
423
+ break;
424
+ }
425
+
426
+ const offset = cloth_command_offset(cloth_count);
427
+
428
+ if (!world.advance(instance, time_delta_seconds, command, offset)) {
429
+ // Asleep. §7 P5: not stepped, not written back, and costing
430
+ // nothing but its absence from this list.
431
+ continue;
432
+ }
433
+
434
+ command[offset + ClothStepParam.ID] = registration.id;
435
+
436
+ dispatched.push(instance);
437
+
438
+ cloth_count++;
439
+ }
440
+
441
+ if (cloth_count === 0) {
442
+ // Nothing to do. Skipping the dispatch also keeps the fixed-step
443
+ // gate open, since there is no result to wait for.
444
+ return false;
445
+ }
446
+
447
+ command[ClothCommand.CLOTH_COUNT] = cloth_count;
448
+
449
+ return true;
450
+ }
451
+
452
+ /**
453
+ * The worker stepped each nominated cloth in place, so joining is the sleep
454
+ * test and the write-back — the half of `ClothSystem`'s loop that needs the
455
+ * scene rather than the arithmetic.
456
+ *
457
+ * @param {number} tick
458
+ */
459
+ apply(tick) {
460
+ const ecd = this.entityManager.dataset;
461
+
462
+ if (ecd === null || ecd === undefined) {
463
+ return;
464
+ }
465
+
466
+ const dispatched = this.#dispatched;
467
+
468
+ const world = this.world;
469
+
470
+ for (let i = 0; i < dispatched.length; i++) {
471
+ const instance = dispatched[i];
472
+
473
+ if (!this.#registrations.has(instance)) {
474
+ // Unlinked between dispatch and join. Its entity is gone, so
475
+ // there is nothing to write the pose onto.
476
+ continue;
477
+ }
478
+
479
+ world.finish(instance, ecd);
480
+ }
481
+
482
+ dispatched.length = 0;
483
+ }
484
+
485
+ /**
486
+ * Announce a cloth's current `ClothState` to the worker, retiring whatever
487
+ * it was registered with before.
488
+ *
489
+ * @param {ClothInstance} instance
490
+ * @private
491
+ */
492
+ #register(instance) {
493
+ const state = instance.state;
494
+
495
+ if (!state.isSharedMemory()) {
496
+ // Not an assert: asserts are stripped from a production build, and a
497
+ // non-shared buffer does not fail loudly on its own — `postMessage`
498
+ // structured-clones it, both threads get a private copy of a cloth,
499
+ // and each simulates a garment the other cannot see. A cloth built
500
+ // through this system is always shared (`ClothWorld#shared_state`),
501
+ // so reaching here means someone handed it a world that is not.
502
+ throw new Error(
503
+ `WorkerClothSystem: the ClothState of entity ${instance.entity} is not shared-memory backed,`
504
+ + ` so the worker would step a copy of it. Build the world with shared_state set, or use`
505
+ + ` ClothSystem, which is the same solver on this thread.`
506
+ );
507
+ }
508
+
509
+ this.#retire(instance);
510
+
511
+ const id = this.#next_cloth_id++;
512
+
513
+ const sequence = this.postToWorker({
514
+ type: "add_cloth",
515
+ id,
516
+ state: state.getSharedDescriptor(),
517
+ self_exclusions: instance.self_exclusions
518
+ });
519
+
520
+ this.#registrations.set(instance, { id, sequence, state, acknowledged: false });
521
+ this.#pending.push(instance);
522
+ }
523
+
524
+ /**
525
+ * Drop a cloth's registration, telling the worker to forget it.
526
+ *
527
+ * @param {ClothInstance} instance
528
+ * @private
529
+ */
530
+ #retire(instance) {
531
+ const registration = this.#registrations.get(instance);
532
+
533
+ if (registration === undefined) {
534
+ return;
535
+ }
536
+
537
+ this.#registrations.delete(instance);
538
+
539
+ const pending_index = this.#pending.indexOf(instance);
540
+
541
+ if (pending_index !== -1) {
542
+ this.#pending.splice(pending_index, 1);
543
+ }
544
+
545
+ // Safe even mid-step: the worker may still be stepping this cloth, and
546
+ // will simply finish. It is dropped from the next dispatch regardless of
547
+ // when the message lands, and the shared buffer outlives both sides'
548
+ // references.
549
+ this.postToWorker({ type: "remove_cloth", id: registration.id });
550
+ }
551
+
552
+ /**
553
+ * Move cloths whose registration message the worker has consumed into the
554
+ * dispatchable set. Until then the worker has no view of their memory and
555
+ * nominating them would be a protocol error.
556
+ *
557
+ * @private
558
+ */
559
+ #promote_acknowledged_cloths() {
560
+ let write = 0;
561
+
562
+ for (let i = 0; i < this.#pending.length; i++) {
563
+ const instance = this.#pending[i];
564
+
565
+ const registration = this.#registrations.get(instance);
566
+
567
+ if (registration !== undefined && this.isMessageHandled(registration.sequence)) {
568
+ registration.acknowledged = true;
569
+
570
+ continue;
571
+ }
572
+
573
+ this.#pending[write++] = instance;
574
+ }
575
+
576
+ this.#pending.length = write;
577
+ }
578
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cloth.worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloth.worker.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth.worker.js"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { SystemWorkerHost } from "../../../ecs/async/SystemWorkerHost.js";
2
+ import { ClothWorkerCore } from "./ClothWorkerCore.js";
3
+
4
+ /**
5
+ * Worker entry point for {@link WorkerClothSystem}.
6
+ *
7
+ * A real module worker rather than a generated blob, so the solver it pulls in
8
+ * is the ordinary `cloth_step_instance` — same source, same bundler treatment,
9
+ * same source maps — which is what makes bit-parity with the main-thread
10
+ * {@link ClothSystem} a property of the build rather than a coincidence.
11
+ */
12
+ SystemWorkerHost.serve(new ClothWorkerCore());
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_build_rows.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_build_rows.js"],"names":[],"mappings":"AAuDA;;;;GAIG;AACH,+DAFa,IAAI,CAyBhB;AAID;;;;;;;GAOG;AACH,8DAHW,MAAM,GACJ,IAAI,CA4LhB;AAWD;;;;;;;;;;;;;;;;GAgBG;AACH,kEAHW,MAAM,GACJ,IAAI,CAoChB;AAED;;;;;;;;;;;GAWG;AACH,iGAFa,OAAO,CAkBnB;AAhXD;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;GAIG;AACH,kCAFU,MAAM,CAEwB;AAIxC;;;;;;;;;;;;;;;;GAgBG;AACH,gCAFU,MAAM,CAEmB"}
1
+ {"version":3,"file":"cloth_build_rows.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_build_rows.js"],"names":[],"mappings":"AAuDA;;;;GAIG;AACH,+DAFa,IAAI,CAyBhB;AAID;;;;;;;GAOG;AACH,8DAHW,MAAM,GACJ,IAAI,CA6LhB;AAWD;;;;;;;;;;;;;;;;GAgBG;AACH,kEAHW,MAAM,GACJ,IAAI,CAoChB;AAED;;;;;;;;;;;GAWG;AACH,iGAFa,OAAO,CAkBnB;AAjXD;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;GAIG;AACH,kCAFU,MAAM,CAEwB;AAIxC;;;;;;;;;;;;;;;;GAgBG;AACH,gCAFU,MAAM,CAEmB"}
@@ -249,7 +249,8 @@ export function cloth_build_rows(instance, dt) {
249
249
  stretch_force_min: Float32Array.from(stretch_force_min),
250
250
  stretch_force_max: Float32Array.from(stretch_force_max),
251
251
  leash_particle: Int32Array.from(leash_particle),
252
- leash_radius: Float32Array.from(leash_radius)
252
+ leash_radius: Float32Array.from(leash_radius),
253
+ shared: instance.shared_state
253
254
  });
254
255
 
255
256
  const particle_of_node = new Int32Array(node_count);