@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
@@ -48,8 +48,15 @@ import {
48
48
  * garment's own skinned surface — `b` a short way inside along the vertex
49
49
  * normal, `r_b` that distance again — and a skinned garment is M3. M2's entity
50
50
  * path has a chain rather than a surface, so it has no normal to offer: a rope
51
- * has no inside. So the row ships with storage, a spec and a playground demo
52
- * driving it directly, and `cloth_proxy_build` is what will fill it.
51
+ * has no inside. So the row ships with storage and a spec, and
52
+ * `cloth_proxy_build` is what will fill it.
53
+ *
54
+ * **Nothing drives it in a scene.** This docblock used to say "and a playground
55
+ * demo driving it directly", and no page under `playground/` writes
56
+ * {@link ClothState#backstop_plane} — M3 arrived and filled nothing in either.
57
+ * What holds the row up is `cloth_backstop_row.spec.js` alone, which is the
58
+ * honest status of a row with no author: the arithmetic is gated, the
59
+ * integration is not.
53
60
  *
54
61
  * ## No trust region, and no geometric stiffness
55
62
  *
@@ -0,0 +1,102 @@
1
+ /**
2
+ * # Where the air comes from — one interface, two answers
3
+ *
4
+ * §10's design in one sentence: this engine has something better than a wind
5
+ * zone, so cloth should **sample** the air rather than invent it. Two things can
6
+ * answer "how fast is the air at this point": a running fluid simulation
7
+ * ({@link ClothFluidWind}), and an ambient model for everywhere a simulation is
8
+ * not ({@link ClothAmbientWind}). §10 asks for both to be read "through *the
9
+ * same interface*, so the cloth code has one path and does not branch on whether
10
+ * a simulation is present", and this is that interface.
11
+ *
12
+ * It is two questions rather than one, and the second is what makes the feature
13
+ * affordable:
14
+ *
15
+ * - {@link sample} answers the air's **world** velocity at a world point, in
16
+ * metres per second.
17
+ * - {@link varies} answers whether it is worth asking {@link sample} more than
18
+ * once for a given box. An ambient source answers `false` for every box and a
19
+ * whole garment costs one sample; a fluid source answers `true` only where one
20
+ * of its fields actually reaches, which is §10's "a cloth outside every fluid
21
+ * field's bounds skips it entirely" expressed as a question the cloth can ask.
22
+ *
23
+ * ## Determinism, because two systems share one of these
24
+ *
25
+ * `ClothSystem` and `WorkerClothSystem` share a {@link ClothWorld} and therefore
26
+ * share its wind source, and §12's bit-parity gate is over the whole
27
+ * `ClothState` buffer at every step. The air is sampled **once**, by the world,
28
+ * into that buffer — so the two systems do not agree about the wind, they read
29
+ * the same bytes of it. What this interface has to promise is only that
30
+ * {@link sample} is a pure function of (its `time` argument, the point), with no
31
+ * wall clock and no random source: a gust that consulted `Date.now()` would make
32
+ * two runs of the same scene differ and would take the parity spec's guarantee
33
+ * with it.
34
+ *
35
+ * **And the clock is the cloth's own age, not the world's.** M6 made the world
36
+ * clock count steps rather than ticks so that a cloth's *first* step got the
37
+ * same weather under both systems, and that is right for the first cloth in a
38
+ * scene and wrong for every one after it: while cloth B's registration is in
39
+ * flight, cloth A is still being advanced, so the world clock moves and B's
40
+ * first step lands at a different time under the worker than under the inline
41
+ * system. Measured at a two-tick delivery: 0.1000 s against 0.1333 s, a
42
+ * divergence at B's step 1, byte 0. So `time` is **seconds this instance has
43
+ * stepped**, which is the same number on both sides by construction.
44
+ * `MEASUREMENTS.md` §57.
45
+ *
46
+ * @author Alex Goldring
47
+ * @copyright Company Named Limited (c) 2026
48
+ */
49
+ export class AbstractClothWind {
50
+ /**
51
+ * Called once per fixed step, before any cloth is advanced, so a source that
52
+ * reads the **scene** — every live fluid field and its world box — can walk
53
+ * it once rather than once a cloth.
54
+ *
55
+ * `time` is the cloth world's own accumulated fixed-step clock rather than a
56
+ * wall clock. It is *not* what a gust is a function of: see the note above,
57
+ * and {@link sample}'s own `time`.
58
+ *
59
+ * @param {number} time seconds of fixed step this world has stepped
60
+ * @param {EntityComponentDataset} ecd for a source that reads components
61
+ * @returns {void}
62
+ */
63
+ begin(time: number, ecd: EntityComponentDataset): void;
64
+ /**
65
+ * Whether the air could differ from point to point inside this box — and so
66
+ * whether a caller has to sample per particle instead of once.
67
+ *
68
+ * Answering `false` is a promise rather than a hint: the caller will sample
69
+ * one point and apply the answer to every particle of the cloth.
70
+ *
71
+ * @param {number} min_x world-space, metres
72
+ * @param {number} min_y
73
+ * @param {number} min_z
74
+ * @param {number} max_x
75
+ * @param {number} max_y
76
+ * @param {number} max_z
77
+ * @returns {boolean}
78
+ */
79
+ varies(min_x: number, min_y: number, min_z: number, max_x: number, max_y: number, max_z: number): boolean;
80
+ /**
81
+ * The air's velocity at a world point, **metres per second**.
82
+ *
83
+ * The units are worth stating because the field this is most often reading
84
+ * does not use them: `FluidField#sampleVelocity` answers in *grid cells* per
85
+ * second and documents that it deliberately does not rescale, on the
86
+ * assumption that its callers want a direction times a magnitude. Cloth is
87
+ * not such a caller — its drag row is an acceleration toward a velocity, and
88
+ * a velocity in cells is a garment that blows differently depending on how
89
+ * finely someone voxelised the room. {@link ClothFluidWind} multiplies by
90
+ * `cell_size`. `MEASUREMENTS.md` §45.
91
+ *
92
+ * @param {Float64Array|number[]} out length 3
93
+ * @param {number} x world-space, metres
94
+ * @param {number} y
95
+ * @param {number} z
96
+ * @param {number} time seconds the asking cloth has stepped — see the note
97
+ * above for why this is the cloth's own age and not the world's clock
98
+ * @returns {Float64Array|number[]} `out`, for chaining
99
+ */
100
+ sample(out: Float64Array | number[], x: number, y: number, z: number, time: number): Float64Array | number[];
101
+ }
102
+ //# sourceMappingURL=AbstractClothWind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractClothWind.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/wind/AbstractClothWind.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH;IAEI;;;;;;;;;;;;OAYG;IACH,YAJW,MAAM,gCAEJ,IAAI,CAIhB;IAED;;;;;;;;;;;;;;OAcG;IACH,cARW,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,YARW,YAAY,GAAC,MAAM,EAAE,KACrB,MAAM,KACN,MAAM,KACN,MAAM,QACN,MAAM,GAEJ,YAAY,GAAC,MAAM,EAAE,CAQjC;CACJ"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * # Where the air comes from — one interface, two answers
3
+ *
4
+ * §10's design in one sentence: this engine has something better than a wind
5
+ * zone, so cloth should **sample** the air rather than invent it. Two things can
6
+ * answer "how fast is the air at this point": a running fluid simulation
7
+ * ({@link ClothFluidWind}), and an ambient model for everywhere a simulation is
8
+ * not ({@link ClothAmbientWind}). §10 asks for both to be read "through *the
9
+ * same interface*, so the cloth code has one path and does not branch on whether
10
+ * a simulation is present", and this is that interface.
11
+ *
12
+ * It is two questions rather than one, and the second is what makes the feature
13
+ * affordable:
14
+ *
15
+ * - {@link sample} answers the air's **world** velocity at a world point, in
16
+ * metres per second.
17
+ * - {@link varies} answers whether it is worth asking {@link sample} more than
18
+ * once for a given box. An ambient source answers `false` for every box and a
19
+ * whole garment costs one sample; a fluid source answers `true` only where one
20
+ * of its fields actually reaches, which is §10's "a cloth outside every fluid
21
+ * field's bounds skips it entirely" expressed as a question the cloth can ask.
22
+ *
23
+ * ## Determinism, because two systems share one of these
24
+ *
25
+ * `ClothSystem` and `WorkerClothSystem` share a {@link ClothWorld} and therefore
26
+ * share its wind source, and §12's bit-parity gate is over the whole
27
+ * `ClothState` buffer at every step. The air is sampled **once**, by the world,
28
+ * into that buffer — so the two systems do not agree about the wind, they read
29
+ * the same bytes of it. What this interface has to promise is only that
30
+ * {@link sample} is a pure function of (its `time` argument, the point), with no
31
+ * wall clock and no random source: a gust that consulted `Date.now()` would make
32
+ * two runs of the same scene differ and would take the parity spec's guarantee
33
+ * with it.
34
+ *
35
+ * **And the clock is the cloth's own age, not the world's.** M6 made the world
36
+ * clock count steps rather than ticks so that a cloth's *first* step got the
37
+ * same weather under both systems, and that is right for the first cloth in a
38
+ * scene and wrong for every one after it: while cloth B's registration is in
39
+ * flight, cloth A is still being advanced, so the world clock moves and B's
40
+ * first step lands at a different time under the worker than under the inline
41
+ * system. Measured at a two-tick delivery: 0.1000 s against 0.1333 s, a
42
+ * divergence at B's step 1, byte 0. So `time` is **seconds this instance has
43
+ * stepped**, which is the same number on both sides by construction.
44
+ * `MEASUREMENTS.md` §57.
45
+ *
46
+ * @author Alex Goldring
47
+ * @copyright Company Named Limited (c) 2026
48
+ */
49
+ export class AbstractClothWind {
50
+
51
+ /**
52
+ * Called once per fixed step, before any cloth is advanced, so a source that
53
+ * reads the **scene** — every live fluid field and its world box — can walk
54
+ * it once rather than once a cloth.
55
+ *
56
+ * `time` is the cloth world's own accumulated fixed-step clock rather than a
57
+ * wall clock. It is *not* what a gust is a function of: see the note above,
58
+ * and {@link sample}'s own `time`.
59
+ *
60
+ * @param {number} time seconds of fixed step this world has stepped
61
+ * @param {EntityComponentDataset} ecd for a source that reads components
62
+ * @returns {void}
63
+ */
64
+ begin(time, ecd) {
65
+ // A constant atmosphere has nothing to refresh.
66
+ }
67
+
68
+ /**
69
+ * Whether the air could differ from point to point inside this box — and so
70
+ * whether a caller has to sample per particle instead of once.
71
+ *
72
+ * Answering `false` is a promise rather than a hint: the caller will sample
73
+ * one point and apply the answer to every particle of the cloth.
74
+ *
75
+ * @param {number} min_x world-space, metres
76
+ * @param {number} min_y
77
+ * @param {number} min_z
78
+ * @param {number} max_x
79
+ * @param {number} max_y
80
+ * @param {number} max_z
81
+ * @returns {boolean}
82
+ */
83
+ varies(min_x, min_y, min_z, max_x, max_y, max_z) {
84
+ return false;
85
+ }
86
+
87
+ /**
88
+ * The air's velocity at a world point, **metres per second**.
89
+ *
90
+ * The units are worth stating because the field this is most often reading
91
+ * does not use them: `FluidField#sampleVelocity` answers in *grid cells* per
92
+ * second and documents that it deliberately does not rescale, on the
93
+ * assumption that its callers want a direction times a magnitude. Cloth is
94
+ * not such a caller — its drag row is an acceleration toward a velocity, and
95
+ * a velocity in cells is a garment that blows differently depending on how
96
+ * finely someone voxelised the room. {@link ClothFluidWind} multiplies by
97
+ * `cell_size`. `MEASUREMENTS.md` §45.
98
+ *
99
+ * @param {Float64Array|number[]} out length 3
100
+ * @param {number} x world-space, metres
101
+ * @param {number} y
102
+ * @param {number} z
103
+ * @param {number} time seconds the asking cloth has stepped — see the note
104
+ * above for why this is the cloth's own age and not the world's clock
105
+ * @returns {Float64Array|number[]} `out`, for chaining
106
+ */
107
+ sample(out, x, y, z, time) {
108
+ out[0] = 0;
109
+ out[1] = 0;
110
+ out[2] = 0;
111
+
112
+ return out;
113
+ }
114
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * # The air everywhere a fluid simulation is not
3
+ *
4
+ * §10's fallback: "a `GlobalFluidEffector`-shaped ambient term — a constant
5
+ * `wind` vector plus a small band-limited noise for gusting". The shape is
6
+ * deliberate. `GlobalFluidEffector` with a `wind` and a `drag` makes every fluid
7
+ * field relax *toward* `wind`, so a field with one in the scene already reads
8
+ * `wind` away from whatever is disturbing it — which means this is not an
9
+ * approximation of the simulation, it is **the same far field the simulation
10
+ * has**, evaluated where no simulation exists. A cloth walking out of a fluid
11
+ * volume walks into the volume's own ambient rather than into still air.
12
+ *
13
+ * ## The gust is three sinusoids, not a noise function
14
+ *
15
+ * "Band-limited" is exactly what a sum of sinusoids is, and the three properties
16
+ * that matters for here are all free: it is bounded (so `gust` is a real
17
+ * amplitude rather than a scale factor over an unbounded tail), it is smooth
18
+ * (so a settled banner is lifted rather than kicked), and it carries **no
19
+ * state** — `g(t)` is a pure function of the cloth world's own fixed-step clock,
20
+ * which is what lets two systems sharing this source produce bit-identical
21
+ * cloth. A value-noise lattice would need a seed and an interpolation rule to
22
+ * buy the same three.
23
+ *
24
+ * The three components sit at 1, 2.41 and 5.83 times the base frequency, which
25
+ * are mutually irrational enough that the pattern does not visibly repeat, and
26
+ * the three axes are offset in phase so the gust turns as well as pulses. It is
27
+ * the cheapest thing that reads as weather; it is not turbulence, and a scene
28
+ * that wants turbulence has a fluid simulator.
29
+ *
30
+ * The clock `g(t)` reads is the **asking cloth's own age**, handed in per
31
+ * sample, not a clock this object holds — see {@link AbstractClothWind} for the
32
+ * parity argument. The visible consequence is that two garments spawned a second
33
+ * apart are a second apart in the gust rather than in phase with it, which for a
34
+ * bounded sum of sinusoids is indistinguishable from weather and is the reason
35
+ * this costs nothing to make true.
36
+ *
37
+ * ## Uniform in space, and that is the interesting limit
38
+ *
39
+ * {@link varies} is always `false`, so a whole garment costs **one** sample —
40
+ * which is what makes the no-simulation case essentially free on the main thread
41
+ * regardless of particle count (`MEASUREMENTS.md` §47). The cost is that the
42
+ * whole cloth is lifted together and a long banner does not see a gust arrive at
43
+ * one end before the other. Spatial structure is the thing a fluid field has and
44
+ * this does not, and §10's argument is that building a second, worse one here
45
+ * would be the duplication the design exists to avoid.
46
+ *
47
+ * @author Alex Goldring
48
+ * @copyright Company Named Limited (c) 2026
49
+ */
50
+ export class ClothAmbientWind extends AbstractClothWind {
51
+ /**
52
+ * Prevailing wind, world-space metres per second. The same quantity and the
53
+ * same units as `GlobalFluidEffector#wind`.
54
+ * @type {Float64Array}
55
+ */
56
+ wind: Float64Array;
57
+ /**
58
+ * Peak gust speed on top of {@link wind}, metres per second. The gust is
59
+ * bounded by exactly this — the component amplitudes below sum to one — so
60
+ * the air's speed never leaves `|wind| ± gust`.
61
+ * @type {number}
62
+ */
63
+ gust: number;
64
+ /**
65
+ * Period of the gust's slowest component, seconds. Four is a breeze that
66
+ * arrives and leaves a few times a minute; a fraction of a second is a
67
+ * flutter.
68
+ * @type {number}
69
+ */
70
+ period: number;
71
+ /**
72
+ * @param {number} time
73
+ * @param {EntityComponentDataset} [ecd]
74
+ * @returns {void}
75
+ */
76
+ begin(time: number, ecd?: EntityComponentDataset): void;
77
+ /**
78
+ * Always `false`: the ambient is one vector for the whole world at any
79
+ * instant, so one sample describes a garment exactly rather than
80
+ * approximately.
81
+ *
82
+ * @returns {boolean}
83
+ */
84
+ varies(): boolean;
85
+ }
86
+ import { AbstractClothWind } from "./AbstractClothWind.js";
87
+ //# sourceMappingURL=ClothAmbientWind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClothAmbientWind.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/wind/ClothAmbientWind.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH;IAEI;;;;OAIG;IACH,MAFU,YAAY,CAEK;IAE3B;;;;;OAKG;IACH,MAFU,MAAM,CAEP;IAET;;;;;OAKG;IACH,QAFU,MAAM,CAEL;IAEX;;;;OAIG;IACH,YAJW,MAAM,iCAEJ,IAAI,CAKhB;IAED;;;;;;OAMG;IACH,UAFa,OAAO,CAInB;CAuCJ;kCAtIiC,wBAAwB"}
@@ -0,0 +1,185 @@
1
+ import { AbstractClothWind } from "./AbstractClothWind.js";
2
+
3
+ /**
4
+ * # The air everywhere a fluid simulation is not
5
+ *
6
+ * §10's fallback: "a `GlobalFluidEffector`-shaped ambient term — a constant
7
+ * `wind` vector plus a small band-limited noise for gusting". The shape is
8
+ * deliberate. `GlobalFluidEffector` with a `wind` and a `drag` makes every fluid
9
+ * field relax *toward* `wind`, so a field with one in the scene already reads
10
+ * `wind` away from whatever is disturbing it — which means this is not an
11
+ * approximation of the simulation, it is **the same far field the simulation
12
+ * has**, evaluated where no simulation exists. A cloth walking out of a fluid
13
+ * volume walks into the volume's own ambient rather than into still air.
14
+ *
15
+ * ## The gust is three sinusoids, not a noise function
16
+ *
17
+ * "Band-limited" is exactly what a sum of sinusoids is, and the three properties
18
+ * that matters for here are all free: it is bounded (so `gust` is a real
19
+ * amplitude rather than a scale factor over an unbounded tail), it is smooth
20
+ * (so a settled banner is lifted rather than kicked), and it carries **no
21
+ * state** — `g(t)` is a pure function of the cloth world's own fixed-step clock,
22
+ * which is what lets two systems sharing this source produce bit-identical
23
+ * cloth. A value-noise lattice would need a seed and an interpolation rule to
24
+ * buy the same three.
25
+ *
26
+ * The three components sit at 1, 2.41 and 5.83 times the base frequency, which
27
+ * are mutually irrational enough that the pattern does not visibly repeat, and
28
+ * the three axes are offset in phase so the gust turns as well as pulses. It is
29
+ * the cheapest thing that reads as weather; it is not turbulence, and a scene
30
+ * that wants turbulence has a fluid simulator.
31
+ *
32
+ * The clock `g(t)` reads is the **asking cloth's own age**, handed in per
33
+ * sample, not a clock this object holds — see {@link AbstractClothWind} for the
34
+ * parity argument. The visible consequence is that two garments spawned a second
35
+ * apart are a second apart in the gust rather than in phase with it, which for a
36
+ * bounded sum of sinusoids is indistinguishable from weather and is the reason
37
+ * this costs nothing to make true.
38
+ *
39
+ * ## Uniform in space, and that is the interesting limit
40
+ *
41
+ * {@link varies} is always `false`, so a whole garment costs **one** sample —
42
+ * which is what makes the no-simulation case essentially free on the main thread
43
+ * regardless of particle count (`MEASUREMENTS.md` §47). The cost is that the
44
+ * whole cloth is lifted together and a long banner does not see a gust arrive at
45
+ * one end before the other. Spatial structure is the thing a fluid field has and
46
+ * this does not, and §10's argument is that building a second, worse one here
47
+ * would be the duplication the design exists to avoid.
48
+ *
49
+ * @author Alex Goldring
50
+ * @copyright Company Named Limited (c) 2026
51
+ */
52
+ export class ClothAmbientWind extends AbstractClothWind {
53
+
54
+ /**
55
+ * Prevailing wind, world-space metres per second. The same quantity and the
56
+ * same units as `GlobalFluidEffector#wind`.
57
+ * @type {Float64Array}
58
+ */
59
+ wind = new Float64Array(3);
60
+
61
+ /**
62
+ * Peak gust speed on top of {@link wind}, metres per second. The gust is
63
+ * bounded by exactly this — the component amplitudes below sum to one — so
64
+ * the air's speed never leaves `|wind| ± gust`.
65
+ * @type {number}
66
+ */
67
+ gust = 0;
68
+
69
+ /**
70
+ * Period of the gust's slowest component, seconds. Four is a breeze that
71
+ * arrives and leaves a few times a minute; a fraction of a second is a
72
+ * flutter.
73
+ * @type {number}
74
+ */
75
+ period = 4;
76
+
77
+ /**
78
+ * @param {number} time
79
+ * @param {EntityComponentDataset} [ecd]
80
+ * @returns {void}
81
+ */
82
+ begin(time, ecd) {
83
+ // Nothing to refresh: the gust is a pure function of the time each
84
+ // sample is taken at, and there is no scene to walk.
85
+ }
86
+
87
+ /**
88
+ * Always `false`: the ambient is one vector for the whole world at any
89
+ * instant, so one sample describes a garment exactly rather than
90
+ * approximately.
91
+ *
92
+ * @returns {boolean}
93
+ */
94
+ varies() {
95
+ return false;
96
+ }
97
+
98
+ /**
99
+ * @param {Float64Array|number[]} out
100
+ * @param {number} x unused — the ambient has no spatial structure
101
+ * @param {number} y
102
+ * @param {number} z
103
+ * @param {number} time seconds the asking cloth has stepped
104
+ * @returns {Float64Array|number[]}
105
+ */
106
+ sample(out, x, y, z, time) {
107
+ const wind = this.wind;
108
+
109
+ out[0] = wind[0];
110
+ out[1] = wind[1];
111
+ out[2] = wind[2];
112
+
113
+ const gust = this.gust;
114
+
115
+ if (gust === 0) {
116
+ return out;
117
+ }
118
+
119
+ const period = this.period > 0 ? this.period : 1;
120
+
121
+ const w = 2 * Math.PI * time / period;
122
+
123
+ for (let axis = 0; axis < 3; axis++) {
124
+ const phase = PHASE[axis];
125
+
126
+ out[axis] += gust * (
127
+ AMPLITUDE_0 * Math.sin(w * RATE_0 + phase)
128
+ + AMPLITUDE_1 * Math.sin(w * RATE_1 + phase * 2)
129
+ + AMPLITUDE_2 * Math.sin(w * RATE_2 + phase * 3)
130
+ );
131
+ }
132
+
133
+ return out;
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Component rates, as multiples of the base frequency. Mutually irrational
139
+ * enough that the sum's own period is far longer than anyone watches.
140
+ * @type {number}
141
+ * @private
142
+ */
143
+ const RATE_0 = 1;
144
+
145
+ /**
146
+ * @type {number}
147
+ * @private
148
+ */
149
+ const RATE_1 = 2.41;
150
+
151
+ /**
152
+ * @type {number}
153
+ * @private
154
+ */
155
+ const RATE_2 = 5.83;
156
+
157
+ /**
158
+ * Component amplitudes. They sum to exactly one, which is what makes
159
+ * {@link ClothAmbientWind#gust} a bound rather than a scale — a pink-ish
160
+ * `1 : 1/2 : 1/4` normalised by its own total.
161
+ * @type {number}
162
+ * @private
163
+ */
164
+ const AMPLITUDE_0 = 4 / 7;
165
+
166
+ /**
167
+ * @type {number}
168
+ * @private
169
+ */
170
+ const AMPLITUDE_1 = 2 / 7;
171
+
172
+ /**
173
+ * @type {number}
174
+ * @private
175
+ */
176
+ const AMPLITUDE_2 = 1 / 7;
177
+
178
+ /**
179
+ * Per-axis phase offsets, so the three axes are not a single pulse along the
180
+ * diagonal. Thirds of a turn, scaled per component so the axes stay apart at
181
+ * every rate rather than only at the slowest.
182
+ * @type {number[]}
183
+ * @private
184
+ */
185
+ const PHASE = [0, 2 * Math.PI / 3, 4 * Math.PI / 3];
@@ -0,0 +1,79 @@
1
+ /**
2
+ * # The air, read out of the fluid simulation that is already running
3
+ *
4
+ * §10's whole argument: this engine has a fluid simulator, `FluidObstacle`
5
+ * already voxelises physics colliders into it, so a character running past a
6
+ * cape gets a **wake** without anything cloth-specific being authored. This is
7
+ * the source that reads it — every enabled {@link FluidComponent} in the scene,
8
+ * sampled trilinearly where a particle actually is.
9
+ *
10
+ * Where no field reaches, {@link ambient} answers instead, so this is the one
11
+ * source a scene needs rather than a thing to switch between: a banner inside a
12
+ * wind tunnel volume reads the tunnel, the same banner carried outside reads the
13
+ * prevailing weather, and the cloth never learns which happened.
14
+ *
15
+ * ## Two units problems, and they are the reason this class exists at all
16
+ *
17
+ * A caller cannot simply forward `FluidComponent#sampleVelocityAtWorld`:
18
+ *
19
+ * - **Cells, not metres.** `FluidField#sampleVelocity` answers in *grid cells*
20
+ * per second and says so — it "does NOT rescale them, on the assumption that
21
+ * callers (vegetation sway, dust drift) interpret the field as a direction ×
22
+ * magnitude wind". Cloth's drag row is a relaxation toward a **velocity**, so
23
+ * the same wind voxelised at 0.25 m instead of 1 m would blow a garment four
24
+ * times as hard. The multiply by `cell_size` is here. `MEASUREMENTS.md` §45.
25
+ * - **Unbuilt fields read as null.** A `FluidComponent` exists from the moment
26
+ * the entity is spawned and its field's buffers arrive at `build()`. Sampling
27
+ * before that is a null dereference rather than a zero, so an unbuilt field is
28
+ * skipped exactly like a disabled one.
29
+ *
30
+ * ## The field list is rebuilt once a step, not once a cloth
31
+ *
32
+ * {@link begin} walks the dataset and caches each live field with its world
33
+ * box. Every cloth's {@link varies} and every particle's {@link sample} then
34
+ * read that cache, so a scene with twenty garments and one wind volume walks the
35
+ * dataset once. `FluidSystem` does the equivalent per field for its effectors
36
+ * and notes the same trade.
37
+ *
38
+ * ## What it does not do
39
+ *
40
+ * **It does not blend at a field's edge.** A point inside a field's box reads
41
+ * the field and a point outside reads the ambient, so a garment straddling the
42
+ * boundary sees a step in the air rather than a ramp. In a scene where the
43
+ * ambient is the far field the volume relaxes toward — `GlobalFluidEffector`'s
44
+ * `wind` — the step is small and mostly the disturbance the volume exists to
45
+ * carry; where it is not, it is visible, and the answer is a volume large enough
46
+ * to hold what moves through it. **Overlapping fields are resolved by order**,
47
+ * first match wins, which is the same arbitrary-but-deterministic rule
48
+ * `FluidSystem` applies when it steps them independently.
49
+ *
50
+ * @author Alex Goldring
51
+ * @copyright Company Named Limited (c) 2026
52
+ */
53
+ export class ClothFluidWind extends AbstractClothWind {
54
+ /**
55
+ * What the air is where no field reaches. Present rather than optional
56
+ * because "outside every fluid volume" is most of the world.
57
+ * @type {ClothAmbientWind}
58
+ */
59
+ ambient: ClothAmbientWind;
60
+ /**
61
+ * Live fields this step: the component and its world box, six words each.
62
+ * @type {FluidComponent[]}
63
+ * @private
64
+ */
65
+ private __components;
66
+ /**
67
+ * @type {number[]}
68
+ * @private
69
+ */
70
+ private __bounds;
71
+ /**
72
+ * @type {number}
73
+ * @private
74
+ */
75
+ private __count;
76
+ }
77
+ import { AbstractClothWind } from "./AbstractClothWind.js";
78
+ import { ClothAmbientWind } from "./ClothAmbientWind.js";
79
+ //# sourceMappingURL=ClothFluidWind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClothFluidWind.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/wind/ClothFluidWind.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH;IAEI;;;;OAIG;IACH,SAFU,gBAAgB,CAEO;IAEjC;;;;OAIG;IACH,qBAAkB;IAElB;;;OAGG;IACH,iBAAc;IAEd;;;OAGG;IACH,gBAAY;CAkIf;kCAnNiC,wBAAwB;iCACzB,uBAAuB"}