@woosh/meep-engine 3.21.0 → 3.22.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 (1596) hide show
  1. package/README.md +96 -213
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  3. package/editor/particles/effect/ParticleEffectDocument.js +0 -3
  4. package/editor/particles/effect/ParticleReferenceSimulation.js +1 -1
  5. package/editor/persistence/SceneMetadata.d.ts +9 -4
  6. package/editor/persistence/SceneMetadata.d.ts.map +1 -1
  7. package/editor/persistence/SceneMetadata.js +4 -3
  8. package/editor/tools/TransformToolV2.d.ts +2 -1
  9. package/editor/tools/TransformToolV2.d.ts.map +1 -1
  10. package/editor/tools/engine/Tool.d.ts +1 -1
  11. package/editor/tools/engine/Tool.d.ts.map +1 -1
  12. package/editor/tools/engine/ToolEngine.d.ts +1 -1
  13. package/editor/tools/engine/ToolEngine.d.ts.map +1 -1
  14. package/editor/view/ecs/EntityEditor.d.ts +3 -2
  15. package/editor/view/ecs/EntityEditor.d.ts.map +1 -1
  16. package/editor/view/ecs/EntityList.d.ts +7 -3
  17. package/editor/view/ecs/EntityList.d.ts.map +1 -1
  18. package/editor/view/ecs/EntityList.js +3 -2
  19. package/editor/view/ecs/components/common/NumericIntervalController.d.ts +8 -3
  20. package/editor/view/ecs/components/common/NumericIntervalController.d.ts.map +1 -1
  21. package/editor/view/ecs/components/common/NumericIntervalController.js +3 -2
  22. package/editor/view/ecs/components/common/TextController.d.ts +7 -3
  23. package/editor/view/ecs/components/common/TextController.d.ts.map +1 -1
  24. package/editor/view/ecs/components/common/TextController.js +3 -2
  25. package/editor/view/library/MeshLibraryView.d.ts.map +1 -1
  26. package/editor/view/library/MeshLibraryView.js +3 -2
  27. package/editor/view/node-graph/NodeIconView.d.ts +5 -2
  28. package/editor/view/node-graph/NodeIconView.d.ts.map +1 -1
  29. package/editor/view/node-graph/NodeIconView.js +2 -1
  30. package/editor/view/node-graph/PortView.d.ts +9 -4
  31. package/editor/view/node-graph/PortView.d.ts.map +1 -1
  32. package/editor/view/node-graph/PortView.js +4 -3
  33. package/editor/view/particles/ColorLutGradientView.d.ts +7 -3
  34. package/editor/view/particles/ColorLutGradientView.d.ts.map +1 -1
  35. package/editor/view/particles/ColorLutGradientView.js +3 -2
  36. package/editor/view/particles/ScalarLutCurveView.d.ts +9 -4
  37. package/editor/view/particles/ScalarLutCurveView.d.ts.map +1 -1
  38. package/editor/view/particles/ScalarLutCurveView.js +4 -3
  39. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  40. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +0 -1
  41. package/editor/view/tools/ToolView.d.ts +7 -3
  42. package/editor/view/tools/ToolView.d.ts.map +1 -1
  43. package/editor/view/tools/ToolView.js +3 -2
  44. package/package.json +2 -1
  45. package/src/core/binary/allocator/OffsetAllocator.d.ts +24 -1
  46. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  47. package/src/core/binary/allocator/OffsetAllocator.js +101 -1
  48. package/src/core/binary/type/Field.d.ts +5 -1
  49. package/src/core/binary/type/Field.d.ts.map +1 -1
  50. package/src/core/binary/type/Field.js +4 -0
  51. package/src/core/binary/type/Type.d.ts +4 -0
  52. package/src/core/binary/type/Type.d.ts.map +1 -1
  53. package/src/core/binary/type/Type.js +4 -0
  54. package/src/core/cache/Cache.d.ts +15 -7
  55. package/src/core/cache/Cache.d.ts.map +1 -1
  56. package/src/core/cache/Cache.js +7 -6
  57. package/src/core/cache/wtinylfu/CacheRegionWTinylfu.d.ts +5 -2
  58. package/src/core/cache/wtinylfu/CacheRegionWTinylfu.d.ts.map +1 -1
  59. package/src/core/cache/wtinylfu/CacheRegionWTinylfu.js +2 -1
  60. package/src/core/cache/wtinylfu/CacheWTinylfu.d.ts +20 -10
  61. package/src/core/cache/wtinylfu/CacheWTinylfu.d.ts.map +1 -1
  62. package/src/core/cache/wtinylfu/CacheWTinylfu.js +9 -8
  63. package/src/core/collection/CuckooFilter.d.ts +8 -4
  64. package/src/core/collection/CuckooFilter.d.ts.map +1 -1
  65. package/src/core/collection/CuckooFilter.js +3 -2
  66. package/src/core/collection/list/List.d.ts +0 -1
  67. package/src/core/collection/list/List.d.ts.map +1 -1
  68. package/src/core/collection/list/List.js +0 -1
  69. package/src/core/collection/map/HashMap.d.ts +12 -7
  70. package/src/core/collection/map/HashMap.d.ts.map +1 -1
  71. package/src/core/collection/map/HashMap.js +5 -5
  72. package/src/core/collection/map/ObservedMap.d.ts +1 -2
  73. package/src/core/collection/map/ObservedMap.d.ts.map +1 -1
  74. package/src/core/collection/map/ObservedMap.js +0 -1
  75. package/src/core/collection/table/RowFirstTable.d.ts +1 -0
  76. package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
  77. package/src/core/collection/table/RowFirstTable.js +4 -0
  78. package/src/core/color/Color.d.ts +1 -2
  79. package/src/core/color/Color.d.ts.map +1 -1
  80. package/src/core/color/Color.js +5 -4
  81. package/src/core/color/hsv/hsv2rgb_float.d.ts +23 -1
  82. package/src/core/color/hsv/hsv2rgb_float.d.ts.map +1 -1
  83. package/src/core/color/hsv/hsv2rgb_float.js +31 -3
  84. package/src/core/color/hsv/hsv_to_rgb.d.ts +20 -9
  85. package/src/core/color/hsv/hsv_to_rgb.d.ts.map +1 -1
  86. package/src/core/color/hsv/hsv_to_rgb.js +30 -10
  87. package/src/core/color/hsv/hsv_to_rgb_uint8.d.ts.map +1 -1
  88. package/src/core/color/hsv/hsv_to_rgb_uint8.js +10 -5
  89. package/src/core/function/FunctionCompiler.d.ts +9 -4
  90. package/src/core/function/FunctionCompiler.d.ts.map +1 -1
  91. package/src/core/function/FunctionCompiler.js +8 -6
  92. package/src/core/geom/3d/quaternion/quat3_shortest_arc.d.ts +41 -0
  93. package/src/core/geom/3d/quaternion/quat3_shortest_arc.d.ts.map +1 -0
  94. package/src/core/geom/3d/quaternion/quat3_shortest_arc.js +94 -0
  95. package/src/core/geom/3d/ray/Ray3.d.ts +5 -5
  96. package/src/core/geom/3d/ray/Ray3.d.ts.map +1 -1
  97. package/src/core/geom/3d/ray/Ray3.js +3 -3
  98. package/src/core/geom/3d/shape/AbstractShape3D.d.ts +1 -0
  99. package/src/core/geom/3d/shape/AbstractShape3D.d.ts.map +1 -1
  100. package/src/core/geom/3d/shape/AbstractShape3D.js +4 -0
  101. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts +2 -4
  102. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
  103. package/src/core/geom/3d/shape/ConvexHullShape3D.js +0 -2
  104. package/src/core/geom/3d/shape/TransformedShape3D.d.ts +1 -2
  105. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  106. package/src/core/geom/3d/shape/TransformedShape3D.js +0 -1
  107. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +6 -0
  108. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
  109. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +5 -0
  110. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts +2 -0
  111. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts.map +1 -1
  112. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +5 -0
  113. package/src/core/geom/Quaternion.d.ts +1 -0
  114. package/src/core/geom/Quaternion.d.ts.map +1 -1
  115. package/src/core/geom/Quaternion.js +4 -0
  116. package/src/core/geom/Vector1.d.ts +8 -0
  117. package/src/core/geom/Vector1.d.ts.map +1 -1
  118. package/src/core/geom/Vector1.js +6 -0
  119. package/src/core/geom/Vector3.d.ts +6 -0
  120. package/src/core/geom/Vector3.d.ts.map +1 -1
  121. package/src/core/geom/Vector3.js +5 -0
  122. package/src/core/geom/Vector4.d.ts +10 -2
  123. package/src/core/geom/Vector4.d.ts.map +1 -1
  124. package/src/core/geom/Vector4.js +6 -1
  125. package/src/core/geom/packing/max-rect/MaxRectanglesPacker.d.ts +4 -4
  126. package/src/core/geom/packing/max-rect/MaxRectanglesPacker.d.ts.map +1 -1
  127. package/src/core/geom/packing/max-rect/MaxRectanglesPacker.js +1 -1
  128. package/src/core/graph/convert_graph_to_dot_string.d.ts +7 -3
  129. package/src/core/graph/convert_graph_to_dot_string.d.ts.map +1 -1
  130. package/src/core/graph/convert_graph_to_dot_string.js +3 -2
  131. package/src/core/localization/Localization.d.ts +3 -2
  132. package/src/core/localization/Localization.d.ts.map +1 -1
  133. package/src/core/localization/Localization.js +4 -0
  134. package/src/core/math/noise/create_simplex_noise_2d.js +6 -6
  135. package/src/core/model/ObservedValue.d.ts +8 -6
  136. package/src/core/model/ObservedValue.d.ts.map +1 -1
  137. package/src/core/model/ObservedValue.js +3 -1
  138. package/src/core/model/node-graph/Connection.d.ts +1 -0
  139. package/src/core/model/node-graph/Connection.d.ts.map +1 -1
  140. package/src/core/model/node-graph/Connection.js +4 -0
  141. package/src/core/model/node-graph/NodeGraph.d.ts +8 -5
  142. package/src/core/model/node-graph/NodeGraph.d.ts.map +1 -1
  143. package/src/core/model/node-graph/NodeGraph.js +3 -3
  144. package/src/core/model/node-graph/json/serializeNodeGraphToJSON.d.ts +9 -4
  145. package/src/core/model/node-graph/json/serializeNodeGraphToJSON.d.ts.map +1 -1
  146. package/src/core/model/node-graph/json/serializeNodeGraphToJSON.js +4 -3
  147. package/src/core/model/node-graph/node/NodeDescription.d.ts +12 -4
  148. package/src/core/model/node-graph/node/NodeDescription.d.ts.map +1 -1
  149. package/src/core/model/node-graph/node/NodeDescription.js +10 -3
  150. package/src/core/model/node-graph/node/NodeInstance.d.ts +5 -2
  151. package/src/core/model/node-graph/node/NodeInstance.d.ts.map +1 -1
  152. package/src/core/model/node-graph/node/NodeInstance.js +6 -0
  153. package/src/core/model/node-graph/node/NodeInstancePortReference.d.ts +5 -2
  154. package/src/core/model/node-graph/node/NodeInstancePortReference.d.ts.map +1 -1
  155. package/src/core/model/node-graph/node/NodeInstancePortReference.js +6 -0
  156. package/src/core/model/node-graph/node/NodeRegistry.d.ts +2 -1
  157. package/src/core/model/node-graph/node/NodeRegistry.d.ts.map +1 -1
  158. package/src/core/model/node-graph/node/NodeRegistry.js +4 -0
  159. package/src/core/model/node-graph/node/Port.d.ts +12 -5
  160. package/src/core/model/node-graph/node/Port.d.ts.map +1 -1
  161. package/src/core/model/node-graph/node/Port.js +9 -4
  162. package/src/core/model/node-graph/util/convert_node_graph_to_dot_string.d.ts +5 -2
  163. package/src/core/model/node-graph/util/convert_node_graph_to_dot_string.d.ts.map +1 -1
  164. package/src/core/model/node-graph/util/convert_node_graph_to_dot_string.js +2 -1
  165. package/src/core/model/node-graph/util/graph_clone_by_node_subset.d.ts +5 -2
  166. package/src/core/model/node-graph/util/graph_clone_by_node_subset.d.ts.map +1 -1
  167. package/src/core/model/node-graph/util/graph_clone_by_node_subset.js +2 -1
  168. package/src/core/model/node-graph/util/graph_collect_connections_amongst_nodes.d.ts +5 -2
  169. package/src/core/model/node-graph/util/graph_collect_connections_amongst_nodes.d.ts.map +1 -1
  170. package/src/core/model/node-graph/util/graph_collect_connections_amongst_nodes.js +2 -1
  171. package/src/core/primitives/Class.d.ts +15 -0
  172. package/src/core/primitives/Class.d.ts.map +1 -0
  173. package/src/core/primitives/Class.js +18 -0
  174. package/src/core/primitives/TypedArray.d.ts +15 -0
  175. package/src/core/primitives/TypedArray.d.ts.map +1 -0
  176. package/src/core/primitives/TypedArray.js +27 -0
  177. package/src/core/process/buildPromiseChain.d.ts +9 -4
  178. package/src/core/process/buildPromiseChain.d.ts.map +1 -1
  179. package/src/core/process/buildPromiseChain.js +4 -3
  180. package/src/core/process/executor/ConcurrentExecutor.d.ts +2 -0
  181. package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
  182. package/src/core/process/executor/ConcurrentExecutor.js +5 -0
  183. package/src/core/process/task/Task.d.ts +17 -7
  184. package/src/core/process/task/Task.d.ts.map +1 -1
  185. package/src/core/process/task/Task.js +12 -6
  186. package/src/engine/Engine.d.ts +17 -7
  187. package/src/engine/Engine.d.ts.map +1 -1
  188. package/src/engine/Engine.js +9 -4
  189. package/src/engine/EngineConfiguration.d.ts +33 -9
  190. package/src/engine/EngineConfiguration.d.ts.map +1 -1
  191. package/src/engine/EngineConfiguration.js +22 -4
  192. package/src/engine/EngineHarness.d.ts +22 -10
  193. package/src/engine/EngineHarness.d.ts.map +1 -1
  194. package/src/engine/EngineHarness.js +13 -8
  195. package/src/engine/EntityCreator.d.ts +26 -11
  196. package/src/engine/EntityCreator.d.ts.map +1 -1
  197. package/src/engine/EntityCreator.js +16 -13
  198. package/src/engine/animation/EntityAnimation.d.ts +1 -1
  199. package/src/engine/animation/EntityAnimation.d.ts.map +1 -1
  200. package/src/engine/animation/curve/actionProcessorOperations/curveActions.d.ts +28 -18
  201. package/src/engine/animation/curve/actionProcessorOperations/curveActions.d.ts.map +1 -1
  202. package/src/engine/animation/curve/actionProcessorOperations/curveActions.js +9 -8
  203. package/src/engine/animation/curve/draw/build_plot_entity_from_array.d.ts +18 -8
  204. package/src/engine/animation/curve/draw/build_plot_entity_from_array.d.ts.map +1 -1
  205. package/src/engine/animation/curve/draw/build_plot_entity_from_array.js +8 -7
  206. package/src/engine/animation/curve/editor/CurveEditorView.d.ts +22 -11
  207. package/src/engine/animation/curve/editor/CurveEditorView.d.ts.map +1 -1
  208. package/src/engine/animation/curve/editor/CurveEditorView.js +7 -6
  209. package/src/engine/animation/curve/editor/DragHandler.d.ts +12 -7
  210. package/src/engine/animation/curve/editor/DragHandler.d.ts.map +1 -1
  211. package/src/engine/animation/curve/editor/DragHandler.js +4 -3
  212. package/src/engine/animation/curve/editor/KeyframeStateManager.d.ts +3 -2
  213. package/src/engine/animation/curve/editor/KeyframeStateManager.d.ts.map +1 -1
  214. package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.d.ts +21 -10
  215. package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.d.ts.map +1 -1
  216. package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.js +10 -9
  217. package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.d.ts +20 -9
  218. package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.d.ts.map +1 -1
  219. package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.js +9 -8
  220. package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.d.ts +15 -7
  221. package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.d.ts.map +1 -1
  222. package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.js +7 -6
  223. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts +39 -18
  224. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts.map +1 -1
  225. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.js +18 -17
  226. package/src/engine/animation/curve/editor/createPanTool.d.ts +13 -5
  227. package/src/engine/animation/curve/editor/createPanTool.d.ts.map +1 -1
  228. package/src/engine/animation/curve/editor/createPanTool.js +5 -4
  229. package/src/engine/animation/curve/editor/createSelectionBoxTool.d.ts +19 -8
  230. package/src/engine/animation/curve/editor/createSelectionBoxTool.d.ts.map +1 -1
  231. package/src/engine/animation/curve/editor/createSelectionBoxTool.js +8 -7
  232. package/src/engine/animation/keyed2/AnimationTrackPlayback.d.ts +6 -2
  233. package/src/engine/animation/keyed2/AnimationTrackPlayback.d.ts.map +1 -1
  234. package/src/engine/animation/keyed2/AnimationTrackPlayback.js +4 -0
  235. package/src/engine/animation/removeEntityGenericEffect.d.ts +13 -6
  236. package/src/engine/animation/removeEntityGenericEffect.d.ts.map +1 -1
  237. package/src/engine/animation/removeEntityGenericEffect.js +6 -5
  238. package/src/engine/animation/removeEntityWithMeshParticlesEffect.d.ts +11 -5
  239. package/src/engine/animation/removeEntityWithMeshParticlesEffect.d.ts.map +1 -1
  240. package/src/engine/animation/removeEntityWithMeshParticlesEffect.js +5 -4
  241. package/src/engine/asset/Asset.d.ts +6 -3
  242. package/src/engine/asset/Asset.d.ts.map +1 -1
  243. package/src/engine/asset/Asset.js +4 -1
  244. package/src/engine/asset/AssetManager.d.ts +42 -21
  245. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  246. package/src/engine/asset/AssetManager.js +20 -12
  247. package/src/engine/asset/AssetRequest.d.ts +4 -2
  248. package/src/engine/asset/AssetRequest.d.ts.map +1 -1
  249. package/src/engine/asset/AssetRequest.js +5 -0
  250. package/src/engine/asset/AssetRequestScope.d.ts +1 -0
  251. package/src/engine/asset/AssetRequestScope.d.ts.map +1 -1
  252. package/src/engine/asset/AssetRequestScope.js +4 -0
  253. package/src/engine/asset/AssetTransformer.d.ts +7 -1
  254. package/src/engine/asset/AssetTransformer.d.ts.map +1 -1
  255. package/src/engine/asset/AssetTransformer.js +5 -0
  256. package/src/engine/asset/PendingAsset.d.ts +8 -0
  257. package/src/engine/asset/PendingAsset.d.ts.map +1 -1
  258. package/src/engine/asset/PendingAsset.js +6 -0
  259. package/src/engine/asset/loaders/ArrayBufferLoader.d.ts +6 -3
  260. package/src/engine/asset/loaders/ArrayBufferLoader.d.ts.map +1 -1
  261. package/src/engine/asset/loaders/ArrayBufferLoader.js +2 -1
  262. package/src/engine/asset/loaders/AssetLoader.d.ts +8 -2
  263. package/src/engine/asset/loaders/AssetLoader.d.ts.map +1 -1
  264. package/src/engine/asset/loaders/AssetLoader.js +5 -0
  265. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts +10 -0
  266. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts.map +1 -1
  267. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +5 -2
  268. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
  269. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +2 -1
  270. package/src/engine/asset/preloader/AssetPreloader.d.ts +2 -1
  271. package/src/engine/asset/preloader/AssetPreloader.d.ts.map +1 -1
  272. package/src/engine/asset/preloader/AssetPreloader.js +4 -0
  273. package/src/engine/development/performance/MetricCollection.d.ts +11 -3
  274. package/src/engine/development/performance/MetricCollection.d.ts.map +1 -1
  275. package/src/engine/development/performance/MetricCollection.js +7 -2
  276. package/src/engine/ecs/Entity.d.ts +3 -2
  277. package/src/engine/ecs/Entity.d.ts.map +1 -1
  278. package/src/engine/ecs/Entity.js +9 -1
  279. package/src/engine/ecs/EntityComponentDataset.d.ts +8 -6
  280. package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
  281. package/src/engine/ecs/EntityComponentDataset.js +9 -0
  282. package/src/engine/ecs/EntityManager.d.ts +2 -1
  283. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  284. package/src/engine/ecs/EntityManager.js +5 -0
  285. package/src/engine/ecs/EntityObserver.d.ts +4 -0
  286. package/src/engine/ecs/EntityObserver.d.ts.map +1 -1
  287. package/src/engine/ecs/EntityObserver.js +4 -0
  288. package/src/engine/ecs/EntityReference.d.ts +4 -0
  289. package/src/engine/ecs/EntityReference.d.ts.map +1 -1
  290. package/src/engine/ecs/EntityReference.js +4 -0
  291. package/src/engine/ecs/System.d.ts +11 -2
  292. package/src/engine/ecs/System.d.ts.map +1 -1
  293. package/src/engine/ecs/System.js +6 -0
  294. package/src/engine/ecs/async/WorkerSystem.d.ts +10 -0
  295. package/src/engine/ecs/async/WorkerSystem.d.ts.map +1 -1
  296. package/src/engine/ecs/dynamic_actions/actions/definition/SpeakLineActionDescription.d.ts +7 -3
  297. package/src/engine/ecs/dynamic_actions/actions/definition/SpeakLineActionDescription.d.ts.map +1 -1
  298. package/src/engine/ecs/dynamic_actions/actions/definition/SpeakLineActionDescription.js +3 -2
  299. package/src/engine/ecs/dynamic_actions/actions/definition/WriteToBlackboardActionDescription.d.ts +7 -3
  300. package/src/engine/ecs/dynamic_actions/actions/definition/WriteToBlackboardActionDescription.d.ts.map +1 -1
  301. package/src/engine/ecs/dynamic_actions/actions/definition/WriteToBlackboardActionDescription.js +3 -2
  302. package/src/engine/ecs/gui/menu/radial/RadialContextMenu.d.ts +36 -17
  303. package/src/engine/ecs/gui/menu/radial/RadialContextMenu.d.ts.map +1 -1
  304. package/src/engine/ecs/gui/menu/radial/RadialContextMenu.js +17 -16
  305. package/src/engine/ecs/gui/parallax/GuiElementParallaxSystem.d.ts +7 -3
  306. package/src/engine/ecs/gui/parallax/GuiElementParallaxSystem.d.ts.map +1 -1
  307. package/src/engine/ecs/gui/parallax/GuiElementParallaxSystem.js +3 -2
  308. package/src/engine/ecs/ik/InverseKinematics.d.ts +17 -8
  309. package/src/engine/ecs/ik/InverseKinematics.d.ts.map +1 -1
  310. package/src/engine/ecs/ik/InverseKinematics.js +8 -7
  311. package/src/engine/ecs/storage/binary/BinaryClassSerializationAdapter.d.ts +9 -0
  312. package/src/engine/ecs/storage/binary/BinaryClassSerializationAdapter.d.ts.map +1 -1
  313. package/src/engine/ecs/storage/binary/BinaryClassSerializationAdapter.js +9 -0
  314. package/src/engine/ecs/storage/binary/BinaryClassUpgrader.d.ts +4 -0
  315. package/src/engine/ecs/storage/binary/BinaryClassUpgrader.d.ts.map +1 -1
  316. package/src/engine/ecs/storage/binary/BinaryClassUpgrader.js +4 -0
  317. package/src/engine/ecs/storage/binary/BinarySerializationRegistry.d.ts +10 -4
  318. package/src/engine/ecs/storage/binary/BinarySerializationRegistry.d.ts.map +1 -1
  319. package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +5 -0
  320. package/src/engine/ecs/storage/binary/collection/BinaryCollectionDeSerializer.d.ts +5 -2
  321. package/src/engine/ecs/storage/binary/collection/BinaryCollectionDeSerializer.d.ts.map +1 -1
  322. package/src/engine/ecs/storage/binary/collection/BinaryCollectionDeSerializer.js +2 -1
  323. package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.d.ts +7 -3
  324. package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.d.ts.map +1 -1
  325. package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +3 -2
  326. package/src/engine/ecs/system/SystemExecutionPhase.d.ts +9 -0
  327. package/src/engine/ecs/system/SystemExecutionPhase.d.ts.map +1 -0
  328. package/src/engine/ecs/systems/ScriptSystem.d.ts +1 -0
  329. package/src/engine/ecs/systems/ScriptSystem.d.ts.map +1 -1
  330. package/src/engine/ecs/terrain/ecs/Terrain.d.ts +7 -2
  331. package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
  332. package/src/engine/ecs/terrain/ecs/Terrain.js +8 -0
  333. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSerializationUpgrader_0_1.d.ts +6 -0
  334. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSerializationUpgrader_0_1.d.ts.map +1 -1
  335. package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.d.ts +3 -1
  336. package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.d.ts.map +1 -1
  337. package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.js +5 -0
  338. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.d.ts +3 -1
  339. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.d.ts.map +1 -1
  340. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +5 -0
  341. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts +4 -0
  342. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts.map +1 -1
  343. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +4 -0
  344. package/src/engine/ecs/terrain/tiles/TerrainTile.d.ts +7 -2
  345. package/src/engine/ecs/terrain/tiles/TerrainTile.d.ts.map +1 -1
  346. package/src/engine/ecs/terrain/tiles/TerrainTile.js +1 -1
  347. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts +6 -2
  348. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
  349. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +6 -1
  350. package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.d.ts +9 -4
  351. package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.d.ts.map +1 -1
  352. package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +4 -3
  353. package/src/engine/ecs/transform/Transform64.d.ts +4 -0
  354. package/src/engine/ecs/transform/Transform64.d.ts.map +1 -1
  355. package/src/engine/ecs/transform/Transform64.js +4 -0
  356. package/src/engine/graphics/camera/CameraShakeBehavior.d.ts +20 -10
  357. package/src/engine/graphics/camera/CameraShakeBehavior.d.ts.map +1 -1
  358. package/src/engine/graphics/camera/CameraShakeBehavior.js +9 -8
  359. package/src/engine/graphics/camera/CameraShakeTraumaBehavior.d.ts +8 -4
  360. package/src/engine/graphics/camera/CameraShakeTraumaBehavior.d.ts.map +1 -1
  361. package/src/engine/graphics/camera/CameraShakeTraumaBehavior.js +3 -2
  362. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +11 -5
  363. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  364. package/src/engine/graphics/camera/makeOrbitalCameraController.js +5 -4
  365. package/src/engine/graphics/canvas/canvas2d_draw_grid.d.ts +19 -9
  366. package/src/engine/graphics/canvas/canvas2d_draw_grid.d.ts.map +1 -1
  367. package/src/engine/graphics/canvas/canvas2d_draw_grid.js +9 -8
  368. package/src/engine/graphics/canvas/canvas2d_draw_label.d.ts +17 -8
  369. package/src/engine/graphics/canvas/canvas2d_draw_label.d.ts.map +1 -1
  370. package/src/engine/graphics/canvas/canvas2d_draw_label.js +8 -7
  371. package/src/engine/graphics/canvas/canvas2d_draw_linear_scale.d.ts +21 -10
  372. package/src/engine/graphics/canvas/canvas2d_draw_linear_scale.d.ts.map +1 -1
  373. package/src/engine/graphics/canvas/canvas2d_draw_linear_scale.js +10 -9
  374. package/src/engine/graphics/canvas/canvas2d_plot_data_line.d.ts +18 -8
  375. package/src/engine/graphics/canvas/canvas2d_plot_data_line.d.ts.map +1 -1
  376. package/src/engine/graphics/canvas/canvas2d_plot_data_line.js +8 -7
  377. package/src/engine/graphics/ecs/camera/Camera.d.ts +4 -0
  378. package/src/engine/graphics/ecs/camera/Camera.d.ts.map +1 -1
  379. package/src/engine/graphics/ecs/camera/Camera.js +4 -0
  380. package/src/engine/graphics/ecs/camera/filter/setup_filtered_camera_controller.d.ts +11 -5
  381. package/src/engine/graphics/ecs/camera/filter/setup_filtered_camera_controller.d.ts.map +1 -1
  382. package/src/engine/graphics/ecs/camera/filter/setup_filtered_camera_controller.js +5 -4
  383. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -1
  384. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  385. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +5 -5
  386. package/src/engine/graphics/ecs/particles/ParticleEffect.js +5 -5
  387. package/src/engine/graphics/ecs/trail3d/make_gradient_stroke.d.ts +19 -9
  388. package/src/engine/graphics/ecs/trail3d/make_gradient_stroke.d.ts.map +1 -1
  389. package/src/engine/graphics/ecs/trail3d/make_gradient_stroke.js +9 -8
  390. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +3 -0
  391. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts.map +1 -1
  392. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +3 -0
  393. package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.d.ts +9 -4
  394. package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.d.ts.map +1 -1
  395. package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +4 -3
  396. package/src/engine/graphics/render/frame_graph/FrameGraph.d.ts +7 -1
  397. package/src/engine/graphics/render/frame_graph/FrameGraph.d.ts.map +1 -1
  398. package/src/engine/graphics/render/frame_graph/FrameGraph.js +5 -0
  399. package/src/engine/graphics/render/frame_graph/FrameGraphNode.d.ts +4 -0
  400. package/src/engine/graphics/render/frame_graph/FrameGraphNode.d.ts.map +1 -1
  401. package/src/engine/graphics/render/frame_graph/FrameGraphNode.js +4 -0
  402. package/src/engine/graphics/render/frame_graph/FramePassBuilder.d.ts +9 -1
  403. package/src/engine/graphics/render/frame_graph/FramePassBuilder.d.ts.map +1 -1
  404. package/src/engine/graphics/render/frame_graph/FramePassBuilder.js +6 -0
  405. package/src/engine/graphics/render/frame_graph/FramePassNode.d.ts +6 -0
  406. package/src/engine/graphics/render/frame_graph/FramePassNode.d.ts.map +1 -1
  407. package/src/engine/graphics/render/frame_graph/FramePassNode.js +5 -0
  408. package/src/engine/graphics/render/frame_graph/FramePassResources.d.ts +7 -1
  409. package/src/engine/graphics/render/frame_graph/FramePassResources.d.ts.map +1 -1
  410. package/src/engine/graphics/render/frame_graph/FramePassResources.js +5 -0
  411. package/src/engine/graphics/render/frame_graph/IFrameGraphContext.d.ts +6 -2
  412. package/src/engine/graphics/render/frame_graph/IFrameGraphContext.d.ts.map +1 -1
  413. package/src/engine/graphics/render/frame_graph/IFrameGraphContext.js +4 -0
  414. package/src/engine/graphics/render/frame_graph/ResourceEntry.d.ts +13 -5
  415. package/src/engine/graphics/render/frame_graph/ResourceEntry.d.ts.map +1 -1
  416. package/src/engine/graphics/render/frame_graph/ResourceEntry.js +7 -1
  417. package/src/engine/graphics/render/frame_graph/ResourceNode.d.ts +9 -3
  418. package/src/engine/graphics/render/frame_graph/ResourceNode.d.ts.map +1 -1
  419. package/src/engine/graphics/render/frame_graph/ResourceNode.js +6 -1
  420. package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.d.ts +5 -1
  421. package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.d.ts.map +1 -1
  422. package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.js +4 -0
  423. package/src/engine/graphics/render/frame_graph/resource/ResourceDescriptor.d.ts +7 -3
  424. package/src/engine/graphics/render/frame_graph/resource/ResourceDescriptor.d.ts.map +1 -1
  425. package/src/engine/graphics/render/frame_graph/resource/ResourceDescriptor.js +6 -2
  426. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.d.ts +5 -2
  427. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.d.ts.map +1 -1
  428. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.js +2 -1
  429. package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.d.ts +9 -4
  430. package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.d.ts.map +1 -1
  431. package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.js +4 -3
  432. package/src/engine/graphics/texture/sampler/Sampler2D.d.ts +4 -0
  433. package/src/engine/graphics/texture/sampler/Sampler2D.d.ts.map +1 -1
  434. package/src/engine/graphics/texture/sampler/Sampler2D.js +4 -0
  435. package/src/engine/graphics/texture/sampler/debug/prototypeSamplerFiltering.js +3 -2
  436. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +0 -5
  437. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  438. package/src/engine/graphics3/GraphicsEngine.d.ts +6 -0
  439. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  440. package/src/engine/graphics3/GraphicsEngine.js +9 -0
  441. package/src/engine/graphics3/ParticipatingMedia.d.ts +9 -4
  442. package/src/engine/graphics3/ParticipatingMedia.d.ts.map +1 -1
  443. package/src/engine/graphics3/ParticipatingMedia.js +4 -3
  444. package/src/engine/graphics3/ShadeCameraAdapter.d.ts +5 -1
  445. package/src/engine/graphics3/ShadeCameraAdapter.d.ts.map +1 -1
  446. package/src/engine/graphics3/ShadeCameraAdapter.js +4 -0
  447. package/src/engine/graphics3/TooltipComponentSystem.d.ts +13 -6
  448. package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -1
  449. package/src/engine/graphics3/TooltipComponentSystem.js +6 -5
  450. package/src/engine/graphics3/VolumetricLightMap.d.ts +5 -2
  451. package/src/engine/graphics3/VolumetricLightMap.d.ts.map +1 -1
  452. package/src/engine/graphics3/VolumetricLightMap.js +2 -1
  453. package/src/engine/input/devices/PointerDevice.d.ts.map +1 -1
  454. package/src/engine/input/devices/PointerDevice.js +7 -6
  455. package/src/engine/input/devices/gamepad/GamepadHandle.d.ts +4 -0
  456. package/src/engine/input/devices/gamepad/GamepadHandle.d.ts.map +1 -1
  457. package/src/engine/input/devices/gamepad/GamepadHandle.js +4 -0
  458. package/src/engine/input/devices/touch/observePinch.d.ts +17 -8
  459. package/src/engine/input/devices/touch/observePinch.d.ts.map +1 -1
  460. package/src/engine/input/devices/touch/observePinch.js +8 -7
  461. package/src/engine/input/ecs/components/InputBinding.d.ts +11 -5
  462. package/src/engine/input/ecs/components/InputBinding.d.ts.map +1 -1
  463. package/src/engine/input/ecs/components/InputBinding.js +5 -4
  464. package/src/engine/input/ecs/ism/InputMapSystem.d.ts +4 -0
  465. package/src/engine/input/ecs/ism/InputMapSystem.d.ts.map +1 -1
  466. package/src/engine/input/ecs/systems/InputControllerSystem.d.ts +1 -1
  467. package/src/engine/input/ecs/systems/InputControllerSystem.d.ts.map +1 -1
  468. package/src/engine/input/ecs/util/TerrainCameraTargetSampler.d.ts +5 -2
  469. package/src/engine/input/ecs/util/TerrainCameraTargetSampler.d.ts.map +1 -1
  470. package/src/engine/input/ecs/util/TerrainCameraTargetSampler.js +2 -1
  471. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.d.ts +9 -4
  472. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.d.ts.map +1 -1
  473. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +4 -3
  474. package/src/engine/intelligence/behavior/ecs/SendEventBehavior.d.ts +9 -4
  475. package/src/engine/intelligence/behavior/ecs/SendEventBehavior.d.ts.map +1 -1
  476. package/src/engine/intelligence/behavior/ecs/SendEventBehavior.js +4 -3
  477. package/src/engine/intelligence/behavior/util/syncExecuteBehaviorToCompletion.d.ts +9 -4
  478. package/src/engine/intelligence/behavior/util/syncExecuteBehaviorToCompletion.d.ts.map +1 -1
  479. package/src/engine/intelligence/behavior/util/syncExecuteBehaviorToCompletion.js +4 -3
  480. package/src/engine/intelligence/mcts/MonteCarlo.d.ts +19 -9
  481. package/src/engine/intelligence/mcts/MonteCarlo.d.ts.map +1 -1
  482. package/src/engine/intelligence/mcts/MonteCarlo.js +9 -8
  483. package/src/engine/intelligence/optimization/RandomOptimizer.d.ts +13 -6
  484. package/src/engine/intelligence/optimization/RandomOptimizer.d.ts.map +1 -1
  485. package/src/engine/intelligence/optimization/RandomOptimizer.js +6 -5
  486. package/src/engine/interpolation/InterpolationSystem.d.ts +4 -0
  487. package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
  488. package/src/engine/knowledge/database/StaticKnowledgeDataTable.d.ts +5 -2
  489. package/src/engine/knowledge/database/StaticKnowledgeDataTable.d.ts.map +1 -1
  490. package/src/engine/knowledge/database/StaticKnowledgeDataTable.js +6 -0
  491. package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.d.ts +6 -2
  492. package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.d.ts.map +1 -1
  493. package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.js +4 -0
  494. package/src/engine/knowledge/database/StaticKnowledgeDatabase.d.ts +7 -4
  495. package/src/engine/knowledge/database/StaticKnowledgeDatabase.d.ts.map +1 -1
  496. package/src/engine/knowledge/database/StaticKnowledgeDatabase.js +6 -0
  497. package/src/engine/makeSimpleTaskProgressView.d.ts +10 -4
  498. package/src/engine/makeSimpleTaskProgressView.d.ts.map +1 -1
  499. package/src/engine/makeSimpleTaskProgressView.js +4 -3
  500. package/src/engine/navigation/mesh/build/navmesh_build_topology.d.ts +20 -9
  501. package/src/engine/navigation/mesh/build/navmesh_build_topology.d.ts.map +1 -1
  502. package/src/engine/navigation/mesh/build/navmesh_build_topology.js +9 -8
  503. package/src/engine/network/sim/ActionLog.d.ts +1 -2
  504. package/src/engine/network/sim/ActionLog.d.ts.map +1 -1
  505. package/src/engine/network/sim/ActionLog.js +0 -1
  506. package/src/engine/network/state/InputRing.d.ts +1 -2
  507. package/src/engine/network/state/InputRing.d.ts.map +1 -1
  508. package/src/engine/network/state/InputRing.js +0 -1
  509. package/src/engine/notify/Notification.d.ts +15 -9
  510. package/src/engine/notify/Notification.d.ts.map +1 -1
  511. package/src/engine/notify/Notification.js +5 -4
  512. package/src/engine/options/OptionAbstract.d.ts +4 -0
  513. package/src/engine/options/OptionAbstract.d.ts.map +1 -1
  514. package/src/engine/options/OptionAbstract.js +4 -0
  515. package/src/engine/options/OptionsView.d.ts +10 -4
  516. package/src/engine/options/OptionsView.d.ts.map +1 -1
  517. package/src/engine/options/OptionsView.js +4 -3
  518. package/src/engine/physics/ccd/linear_sweep.d.ts +4 -7
  519. package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
  520. package/src/engine/physics/ccd/linear_sweep.js +3 -1
  521. package/src/engine/physics/cloth/MEASUREMENTS.md +956 -0
  522. package/src/engine/physics/cloth/PLAN.md +1581 -0
  523. package/src/engine/physics/cloth/ecs/Cloth.d.ts +145 -0
  524. package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -0
  525. package/src/engine/physics/cloth/ecs/Cloth.js +212 -0
  526. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts +208 -0
  527. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts.map +1 -0
  528. package/src/engine/physics/cloth/ecs/ClothDynamics.js +331 -0
  529. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.d.ts +10 -0
  530. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.d.ts.map +1 -0
  531. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +57 -0
  532. package/src/engine/physics/cloth/ecs/ClothExclude.d.ts +45 -0
  533. package/src/engine/physics/cloth/ecs/ClothExclude.d.ts.map +1 -0
  534. package/src/engine/physics/cloth/ecs/ClothExclude.js +59 -0
  535. package/src/engine/physics/cloth/ecs/ClothFlags.d.ts +10 -0
  536. package/src/engine/physics/cloth/ecs/ClothFlags.d.ts.map +1 -0
  537. package/src/engine/physics/cloth/ecs/ClothFlags.js +47 -0
  538. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +321 -0
  539. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -0
  540. package/src/engine/physics/cloth/ecs/ClothInstance.js +363 -0
  541. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +149 -0
  542. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -0
  543. package/src/engine/physics/cloth/ecs/ClothSystem.js +773 -0
  544. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts +157 -0
  545. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts.map +1 -0
  546. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.js +254 -0
  547. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +235 -0
  548. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -0
  549. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +271 -0
  550. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +114 -0
  551. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -0
  552. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +645 -0
  553. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +9 -0
  554. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -0
  555. package/src/engine/physics/cloth/ecs/cloth_write_back.js +449 -0
  556. package/src/engine/physics/cloth/playground/README.md +185 -0
  557. package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts +58 -0
  558. package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts.map +1 -0
  559. package/src/engine/physics/cloth/playground/cloth_playground_build.js +333 -0
  560. package/src/engine/physics/cloth/playground/cloth_playground_draw.d.ts +79 -0
  561. package/src/engine/physics/cloth/playground/cloth_playground_draw.d.ts.map +1 -0
  562. package/src/engine/physics/cloth/playground/cloth_playground_draw.js +519 -0
  563. package/src/engine/physics/cloth/playground/index.html +200 -0
  564. package/src/engine/physics/cloth/playground/main.d.ts +2 -0
  565. package/src/engine/physics/cloth/playground/main.d.ts.map +1 -0
  566. package/src/engine/physics/cloth/playground/main.js +876 -0
  567. package/src/engine/physics/cloth/playground/rig.html +187 -0
  568. package/src/engine/physics/cloth/playground/rig_build.d.ts +81 -0
  569. package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -0
  570. package/src/engine/physics/cloth/playground/rig_build.js +296 -0
  571. package/src/engine/physics/cloth/playground/rig_main.d.ts +2 -0
  572. package/src/engine/physics/cloth/playground/rig_main.d.ts.map +1 -0
  573. package/src/engine/physics/cloth/playground/rig_main.js +955 -0
  574. package/src/engine/physics/cloth/solver/ClothState.d.ts +323 -0
  575. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -0
  576. package/src/engine/physics/cloth/solver/ClothState.js +673 -0
  577. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts +67 -0
  578. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts.map +1 -0
  579. package/src/engine/physics/cloth/solver/cloth_color_particles.js +220 -0
  580. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts +13 -0
  581. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -0
  582. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +201 -0
  583. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +97 -0
  584. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -0
  585. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +102 -0
  586. package/src/engine/physics/cloth/solver/cloth_step.d.ts +91 -0
  587. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -0
  588. package/src/engine/physics/cloth/solver/cloth_step.js +289 -0
  589. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts +54 -0
  590. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts.map +1 -0
  591. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.js +56 -0
  592. package/src/engine/physics/cloth/solver/constraint/cloth_bend_row.d.ts +125 -0
  593. package/src/engine/physics/cloth/solver/constraint/cloth_bend_row.d.ts.map +1 -0
  594. package/src/engine/physics/cloth/solver/constraint/cloth_bend_row.js +383 -0
  595. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +112 -0
  596. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -0
  597. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +346 -0
  598. package/src/engine/physics/cloth/solver/constraint/cloth_stretch_row.d.ts +94 -0
  599. package/src/engine/physics/cloth/solver/constraint/cloth_stretch_row.d.ts.map +1 -0
  600. package/src/engine/physics/cloth/solver/constraint/cloth_stretch_row.js +383 -0
  601. package/src/engine/physics/cloth/solver/find_non_finite_cloth_state.d.ts +27 -0
  602. package/src/engine/physics/cloth/solver/find_non_finite_cloth_state.d.ts.map +1 -0
  603. package/src/engine/physics/cloth/solver/find_non_finite_cloth_state.js +104 -0
  604. package/src/engine/physics/ecs/PhysicsSystem.d.ts +5 -7
  605. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  606. package/src/engine/physics/ecs/PhysicsSystem.js +4 -1
  607. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.d.ts +6 -0
  608. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.d.ts.map +1 -1
  609. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  610. package/src/engine/physics/narrowphase/compute_penetration.d.ts +26 -23
  611. package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -1
  612. package/src/engine/physics/narrowphase/compute_penetration.js +25 -4
  613. package/src/engine/physics/narrowphase/narrowphase_step.d.ts +16 -23
  614. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  615. package/src/engine/physics/narrowphase/narrowphase_step.js +15 -4
  616. package/src/engine/physics/narrowphase/refine_ray_concave.d.ts +4 -6
  617. package/src/engine/physics/narrowphase/refine_ray_concave.d.ts.map +1 -1
  618. package/src/engine/physics/narrowphase/refine_ray_concave.js +3 -1
  619. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts +6 -6
  620. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
  621. package/src/engine/physics/narrowphase/refine_ray_hit.js +5 -1
  622. package/src/engine/physics/queries/shape_cast.d.ts +9 -7
  623. package/src/engine/physics/queries/shape_cast.d.ts.map +1 -1
  624. package/src/engine/physics/queries/shape_cast.js +8 -1
  625. package/src/engine/platform/EnginePlatform.d.ts +4 -0
  626. package/src/engine/platform/EnginePlatform.d.ts.map +1 -1
  627. package/src/engine/platform/EnginePlatform.js +4 -0
  628. package/src/engine/plugin/EnginePlugin.d.ts +9 -0
  629. package/src/engine/plugin/EnginePlugin.d.ts.map +1 -1
  630. package/src/engine/plugin/EnginePlugin.js +9 -0
  631. package/src/engine/plugin/EnginePluginManager.d.ts +13 -2
  632. package/src/engine/plugin/EnginePluginManager.d.ts.map +1 -1
  633. package/src/engine/plugin/EnginePluginManager.js +10 -0
  634. package/src/engine/save/StorageBackedList.d.ts +8 -4
  635. package/src/engine/save/StorageBackedList.d.ts.map +1 -1
  636. package/src/engine/save/StorageBackedList.js +3 -2
  637. package/src/engine/scene/Scene.d.ts +10 -0
  638. package/src/engine/scene/Scene.d.ts.map +1 -1
  639. package/src/engine/scene/Scene.js +7 -0
  640. package/src/engine/scene/SceneManager.d.ts +4 -0
  641. package/src/engine/scene/SceneManager.d.ts.map +1 -1
  642. package/src/engine/scene/SceneManager.js +4 -0
  643. package/src/engine/scene/SerializedScene.d.ts +8 -4
  644. package/src/engine/scene/SerializedScene.d.ts.map +1 -1
  645. package/src/engine/scene/SerializedScene.js +3 -2
  646. package/src/engine/scene/transitionToScene.d.ts +11 -5
  647. package/src/engine/scene/transitionToScene.d.ts.map +1 -1
  648. package/src/engine/scene/transitionToScene.js +5 -4
  649. package/src/engine/simulation/Ticker.d.ts +5 -2
  650. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  651. package/src/engine/simulation/Ticker.js +2 -1
  652. package/src/engine/sound/SoundEngine.d.ts +4 -0
  653. package/src/engine/sound/SoundEngine.d.ts.map +1 -1
  654. package/src/engine/sound/SoundEngine.js +4 -0
  655. package/src/engine/sound/material/concrete/json/deserializeSoundMaterialFromJSON.d.ts +7 -3
  656. package/src/engine/sound/material/concrete/json/deserializeSoundMaterialFromJSON.d.ts.map +1 -1
  657. package/src/engine/sound/material/concrete/json/deserializeSoundMaterialFromJSON.js +3 -2
  658. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +10 -0
  659. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  660. package/src/engine/sound/sopra/SopraEngine.d.ts +5 -0
  661. package/src/engine/sound/sopra/SopraEngine.d.ts.map +1 -1
  662. package/src/engine/sound/sopra/SopraEngine.js +8 -0
  663. package/src/engine/sound/sopra/definition/BusDefinition.d.ts +4 -0
  664. package/src/engine/sound/sopra/definition/BusDefinition.d.ts.map +1 -1
  665. package/src/engine/sound/sopra/definition/BusDefinition.js +4 -0
  666. package/src/engine/sound/sopra/definition/EventDescription.d.ts +1 -0
  667. package/src/engine/sound/sopra/definition/EventDescription.d.ts.map +1 -1
  668. package/src/engine/sound/sopra/definition/EventDescription.js +4 -0
  669. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +6 -0
  670. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -1
  671. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +5 -0
  672. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +1 -1
  673. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts +1 -0
  674. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts.map +1 -1
  675. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +1 -1
  676. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +10 -2
  677. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -1
  678. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +7 -0
  679. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +1 -1
  680. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +1 -1
  681. package/src/engine/sound/sopra/runtime/BusGraph.d.ts +4 -0
  682. package/src/engine/sound/sopra/runtime/BusGraph.d.ts.map +1 -1
  683. package/src/engine/sound/sopra/runtime/BusGraph.js +4 -0
  684. package/src/engine/sound/sopra/runtime/EventInstance.d.ts +9 -1
  685. package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
  686. package/src/engine/sound/sopra/runtime/EventInstance.js +11 -0
  687. package/src/engine/sound/sopra/runtime/VoiceManager.d.ts +2 -0
  688. package/src/engine/sound/sopra/runtime/VoiceManager.d.ts.map +1 -1
  689. package/src/engine/sound/sopra/runtime/VoiceManager.js +5 -0
  690. package/src/engine/ui/DraggableAspect.d.ts +14 -6
  691. package/src/engine/ui/DraggableAspect.d.ts.map +1 -1
  692. package/src/engine/ui/DraggableAspect.js +6 -5
  693. package/src/engine/ui/GUIEngine.d.ts +73 -26
  694. package/src/engine/ui/GUIEngine.d.ts.map +1 -1
  695. package/src/engine/ui/GUIEngine.js +37 -19
  696. package/src/engine/ui/bindings/DomElementBindingDescription.d.ts +7 -3
  697. package/src/engine/ui/bindings/DomElementBindingDescription.d.ts.map +1 -1
  698. package/src/engine/ui/bindings/DomElementBindingDescription.js +3 -2
  699. package/src/engine/ui/modal/ModalStack.d.ts +4 -0
  700. package/src/engine/ui/modal/ModalStack.d.ts.map +1 -1
  701. package/src/engine/ui/modal/ModalStack.js +4 -0
  702. package/src/engine/ui/notification/AnimatedObjectEmitter.d.ts +4 -0
  703. package/src/engine/ui/notification/AnimatedObjectEmitter.d.ts.map +1 -1
  704. package/src/engine/ui/notification/AnimatedObjectEmitter.js +4 -0
  705. package/src/engine/ui/notification/NotificationManager.d.ts +21 -8
  706. package/src/engine/ui/notification/NotificationManager.d.ts.map +1 -1
  707. package/src/engine/ui/notification/NotificationManager.js +10 -3
  708. package/src/engine/ui/notification/ViewEmitter.d.ts +8 -2
  709. package/src/engine/ui/notification/ViewEmitter.d.ts.map +1 -1
  710. package/src/engine/ui/notification/ViewEmitter.js +6 -1
  711. package/src/engine/ui/scene/SceneGUIContext.d.ts +4 -0
  712. package/src/engine/ui/scene/SceneGUIContext.d.ts.map +1 -1
  713. package/src/engine/ui/scene/SceneGUIContext.js +4 -0
  714. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.d.ts +9 -4
  715. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.d.ts.map +1 -1
  716. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.js +4 -3
  717. package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.d.ts +9 -4
  718. package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.d.ts.map +1 -1
  719. package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.js +4 -3
  720. package/src/generation/grid/generation/GridTaskApplyActionToCells.d.ts +9 -4
  721. package/src/generation/grid/generation/GridTaskApplyActionToCells.d.ts.map +1 -1
  722. package/src/generation/grid/generation/GridTaskApplyActionToCells.js +4 -3
  723. package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.d.ts +9 -4
  724. package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.d.ts.map +1 -1
  725. package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.js +4 -3
  726. package/src/generation/grid/generation/grid/select/CellSupplierBestN.d.ts +11 -5
  727. package/src/generation/grid/generation/grid/select/CellSupplierBestN.d.ts.map +1 -1
  728. package/src/generation/grid/generation/grid/select/CellSupplierBestN.js +5 -4
  729. package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts +9 -4
  730. package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts.map +1 -1
  731. package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +12 -10
  732. package/src/generation/grid/generation/util/buildDistanceMapToObjective.d.ts +19 -9
  733. package/src/generation/grid/generation/util/buildDistanceMapToObjective.d.ts.map +1 -1
  734. package/src/generation/grid/generation/util/buildDistanceMapToObjective.js +9 -8
  735. package/src/generation/grid/generation/util/buildPathFromDistanceMap.d.ts +17 -8
  736. package/src/generation/grid/generation/util/buildPathFromDistanceMap.d.ts.map +1 -1
  737. package/src/generation/grid/generation/util/buildPathFromDistanceMap.js +8 -7
  738. package/src/generation/markers/GridActionRuleSet.d.ts +11 -5
  739. package/src/generation/markers/GridActionRuleSet.d.ts.map +1 -1
  740. package/src/generation/markers/GridActionRuleSet.js +5 -4
  741. package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.d.ts +9 -4
  742. package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.d.ts.map +1 -1
  743. package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +4 -3
  744. package/src/generation/markers/actions/MarkerNodeActionImaginary.d.ts +9 -4
  745. package/src/generation/markers/actions/MarkerNodeActionImaginary.d.ts.map +1 -1
  746. package/src/generation/markers/actions/MarkerNodeActionImaginary.js +4 -3
  747. package/src/generation/markers/actions/MarkerProcessingRule.d.ts +11 -5
  748. package/src/generation/markers/actions/MarkerProcessingRule.d.ts.map +1 -1
  749. package/src/generation/markers/actions/MarkerProcessingRule.js +5 -4
  750. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.d.ts +5 -2
  751. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.d.ts.map +1 -1
  752. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.js +2 -1
  753. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.d.ts +13 -6
  754. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.d.ts.map +1 -1
  755. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +6 -5
  756. package/src/generation/markers/emitter/MarkerNodeEmitterPredicated.d.ts +7 -3
  757. package/src/generation/markers/emitter/MarkerNodeEmitterPredicated.d.ts.map +1 -1
  758. package/src/generation/markers/emitter/MarkerNodeEmitterPredicated.js +3 -2
  759. package/src/generation/placement/GridCellPlacementRule.d.ts +15 -7
  760. package/src/generation/placement/GridCellPlacementRule.d.ts.map +1 -1
  761. package/src/generation/placement/GridCellPlacementRule.js +7 -6
  762. package/src/shade/descriptor/ObjectDescriptorBase.d.ts +8 -3
  763. package/src/shade/descriptor/ObjectDescriptorBase.d.ts.map +1 -1
  764. package/src/shade/descriptor/ObjectDescriptorBase.js +7 -2
  765. package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.d.ts +12 -0
  766. package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.d.ts.map +1 -1
  767. package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.js +8 -0
  768. package/src/shade/descriptor/binding/BufferBindingLayout.d.ts +11 -6
  769. package/src/shade/descriptor/binding/BufferBindingLayout.d.ts.map +1 -1
  770. package/src/shade/descriptor/binding/BufferBindingLayout.js +5 -4
  771. package/src/shade/descriptor/binding/SamplerBindingLayout.d.ts +2 -2
  772. package/src/shade/descriptor/binding/SamplerBindingLayout.d.ts.map +1 -1
  773. package/src/shade/descriptor/binding/SamplerBindingLayout.js +1 -1
  774. package/src/shade/descriptor/binding/StorageTextureBindingLayout.d.ts +2 -2
  775. package/src/shade/descriptor/binding/StorageTextureBindingLayout.d.ts.map +1 -1
  776. package/src/shade/descriptor/binding/StorageTextureBindingLayout.js +1 -1
  777. package/src/shade/descriptor/binding/TextureBindingLayout.d.ts +4 -4
  778. package/src/shade/descriptor/binding/TextureBindingLayout.d.ts.map +1 -1
  779. package/src/shade/descriptor/binding/TextureBindingLayout.js +2 -2
  780. package/src/shade/descriptor/blend/BlendComponent.d.ts +6 -6
  781. package/src/shade/descriptor/blend/BlendComponent.d.ts.map +1 -1
  782. package/src/shade/descriptor/blend/BlendComponent.js +3 -3
  783. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts +12 -0
  784. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts.map +1 -1
  785. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +8 -0
  786. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +18 -5
  787. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
  788. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +14 -4
  789. package/src/shade/descriptor/pipeline/render/DepthStencilState.d.ts +4 -1
  790. package/src/shade/descriptor/pipeline/render/DepthStencilState.d.ts.map +1 -1
  791. package/src/shade/descriptor/pipeline/render/DepthStencilState.js +3 -0
  792. package/src/shade/descriptor/pipeline/render/FragmentState.d.ts +5 -2
  793. package/src/shade/descriptor/pipeline/render/FragmentState.d.ts.map +1 -1
  794. package/src/shade/descriptor/pipeline/render/FragmentState.js +4 -1
  795. package/src/shade/descriptor/pipeline/render/PrimitiveState.d.ts +8 -8
  796. package/src/shade/descriptor/pipeline/render/PrimitiveState.d.ts.map +1 -1
  797. package/src/shade/descriptor/pipeline/render/PrimitiveState.js +4 -4
  798. package/src/shade/descriptor/pipeline/render/StencilFaceState.d.ts +16 -4
  799. package/src/shade/descriptor/pipeline/render/StencilFaceState.d.ts.map +1 -1
  800. package/src/shade/descriptor/pipeline/render/StencilFaceState.js +12 -0
  801. package/src/shade/descriptor/pipeline/render/VertexState.d.ts +5 -2
  802. package/src/shade/descriptor/pipeline/render/VertexState.d.ts.map +1 -1
  803. package/src/shade/descriptor/pipeline/render/VertexState.js +4 -1
  804. package/src/shade/descriptor/texture/SamplerDescriptor.d.ts +24 -6
  805. package/src/shade/descriptor/texture/SamplerDescriptor.d.ts.map +1 -1
  806. package/src/shade/descriptor/texture/SamplerDescriptor.js +18 -0
  807. package/src/shade/descriptor/texture/TextureDescriptor.d.ts +2 -2
  808. package/src/shade/descriptor/texture/TextureDescriptor.d.ts.map +1 -1
  809. package/src/shade/descriptor/texture/TextureDescriptor.js +1 -1
  810. package/src/shade/device/ShadeGPUCommandContext.d.ts +46 -12
  811. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  812. package/src/shade/device/ShadeGPUCommandContext.js +28 -8
  813. package/src/shade/device/graph/GraphicsExecutionContext.d.ts +6 -0
  814. package/src/shade/device/graph/GraphicsExecutionContext.d.ts.map +1 -1
  815. package/src/shade/device/graph/GraphicsExecutionContext.js +5 -0
  816. package/src/shade/device/graph/TextureResourceDescriptor.d.ts +13 -6
  817. package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
  818. package/src/shade/device/graph/TextureResourceDescriptor.js +6 -5
  819. package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts +6 -0
  820. package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts.map +1 -1
  821. package/src/shade/device/pass/ShadeGPUComputePassEncoder.js +5 -0
  822. package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts +6 -0
  823. package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts.map +1 -1
  824. package/src/shade/device/pass/ShadeGPURenderPassEncoder.js +5 -0
  825. package/src/shade/device/pipeline/ComputePipelineManager.d.ts +9 -1
  826. package/src/shade/device/pipeline/ComputePipelineManager.d.ts.map +1 -1
  827. package/src/shade/device/pipeline/ComputePipelineManager.js +6 -0
  828. package/src/shade/device/pipeline/PipelineLayoutManager.d.ts +6 -0
  829. package/src/shade/device/pipeline/PipelineLayoutManager.d.ts.map +1 -1
  830. package/src/shade/device/pipeline/PipelineLayoutManager.js +5 -0
  831. package/src/shade/device/pipeline/RenderPipelineManager.d.ts +7 -1
  832. package/src/shade/device/pipeline/RenderPipelineManager.d.ts.map +1 -1
  833. package/src/shade/device/pipeline/RenderPipelineManager.js +5 -0
  834. package/src/shade/device/shader/ShaderModuleCompiler.d.ts +4 -0
  835. package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
  836. package/src/shade/device/shader/ShaderModuleCompiler.js +4 -0
  837. package/src/shade/device/timing/profile/GPUFrameRecorder.d.ts +6 -0
  838. package/src/shade/device/timing/profile/GPUFrameRecorder.d.ts.map +1 -1
  839. package/src/shade/device/timing/profile/GPUFrameRecorder.js +5 -0
  840. package/src/shade/device/timing/profile/GPUProfileFrame.d.ts +6 -0
  841. package/src/shade/device/timing/profile/GPUProfileFrame.d.ts.map +1 -1
  842. package/src/shade/device/timing/profile/GPUProfileFrame.js +5 -0
  843. package/src/shade/device/timing/profile/GPUProfileSession.d.ts +1 -0
  844. package/src/shade/device/timing/profile/GPUProfileSession.d.ts.map +1 -1
  845. package/src/shade/device/timing/profile/GPUProfileSession.js +4 -0
  846. package/src/shade/device/timing/profile/GPUProfileSpan.d.ts +4 -0
  847. package/src/shade/device/timing/profile/GPUProfileSpan.d.ts.map +1 -1
  848. package/src/shade/device/timing/profile/GPUProfileSpan.js +4 -0
  849. package/src/shade/playground/add_random_meshes.d.ts +19 -8
  850. package/src/shade/playground/add_random_meshes.d.ts.map +1 -1
  851. package/src/shade/playground/add_random_meshes.js +8 -7
  852. package/src/shade/playground/ground_seam/capture_scene_color.d.ts +4 -0
  853. package/src/shade/playground/ground_seam/capture_scene_color.d.ts.map +1 -1
  854. package/src/shade/playground/particle_ecs/index.html +0 -2
  855. package/src/shade/playground/particle_ecs/main.js +8 -29
  856. package/src/shade/playground/particle_system/main.js +8 -21
  857. package/src/shade/playground/particle_system/particle_prototype.js +8 -8
  858. package/src/shade/playground/particle_system/particle_scene.d.ts +0 -61
  859. package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
  860. package/src/shade/playground/particle_system/particle_scene.js +0 -57
  861. package/src/shade/playground/ssr_variance/reference.d.ts +1 -1
  862. package/src/shade/playground/ssr_variance/reference.d.ts.map +1 -1
  863. package/src/shade/playground/vgeo_viewer/README.md +11 -2
  864. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +1 -1
  865. package/src/shade/playground/vgeo_viewer/cut_geometry.js +3 -40
  866. package/src/shade/playground/vgeo_viewer/main.js +14 -0
  867. package/src/shade/playground/vgeo_viewer/select_cut.d.ts +19 -0
  868. package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +1 -1
  869. package/src/shade/playground/vgeo_viewer/select_cut.js +53 -9
  870. package/src/shade/renderer/GPUSamplerManager.d.ts +4 -0
  871. package/src/shade/renderer/GPUSamplerManager.d.ts.map +1 -1
  872. package/src/shade/renderer/GPUSamplerManager.js +4 -0
  873. package/src/shade/renderer/GraphicsContext.d.ts +2 -0
  874. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  875. package/src/shade/renderer/GraphicsContext.js +5 -0
  876. package/src/shade/renderer/Renderer.d.ts +14 -4
  877. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  878. package/src/shade/renderer/Renderer.js +70 -67
  879. package/src/shade/renderer/ResourceManager.d.ts +10 -0
  880. package/src/shade/renderer/ResourceManager.d.ts.map +1 -1
  881. package/src/shade/renderer/ResourceManager.js +7 -0
  882. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +18 -11
  883. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  884. package/src/shade/renderer/animation/GPUAnimationManager.js +2063 -1958
  885. package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts +2 -0
  886. package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts.map +1 -1
  887. package/src/shade/renderer/animation/ShadeAnimationChannel.js +5 -0
  888. package/src/shade/renderer/animation/ShadeAnimationClip.d.ts +4 -0
  889. package/src/shade/renderer/animation/ShadeAnimationClip.d.ts.map +1 -1
  890. package/src/shade/renderer/animation/ShadeAnimationClip.js +4 -0
  891. package/src/shade/renderer/animation/Skin.d.ts +6 -0
  892. package/src/shade/renderer/animation/Skin.d.ts.map +1 -1
  893. package/src/shade/renderer/animation/Skin.js +5 -0
  894. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +48 -0
  895. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  896. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +201 -14
  897. package/src/shade/renderer/binding/BindGroupDescriptor.d.ts +2 -1
  898. package/src/shade/renderer/binding/BindGroupDescriptor.d.ts.map +1 -1
  899. package/src/shade/renderer/binding/BindGroupDescriptor.js +4 -0
  900. package/src/shade/renderer/binding/BindGroupManager.d.ts +1 -0
  901. package/src/shade/renderer/binding/BindGroupManager.d.ts.map +1 -1
  902. package/src/shade/renderer/binding/BindGroupManager.js +4 -0
  903. package/src/shade/renderer/buffer/GPUBufferAllocatorNative.d.ts +4 -0
  904. package/src/shade/renderer/buffer/GPUBufferAllocatorNative.d.ts.map +1 -1
  905. package/src/shade/renderer/buffer/GPUBufferAllocatorNative.js +4 -0
  906. package/src/shade/renderer/buffer/GPUTypedBuffer.d.ts +20 -8
  907. package/src/shade/renderer/buffer/GPUTypedBuffer.d.ts.map +1 -1
  908. package/src/shade/renderer/buffer/GPUTypedBuffer.js +11 -6
  909. package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.d.ts +15 -7
  910. package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.d.ts.map +1 -1
  911. package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +7 -6
  912. package/src/shade/renderer/buffer/inspect_gpu_buffer.d.ts +26 -12
  913. package/src/shade/renderer/buffer/inspect_gpu_buffer.d.ts.map +1 -1
  914. package/src/shade/renderer/buffer/inspect_gpu_buffer.js +12 -10
  915. package/src/shade/renderer/buffer/inspect_gpu_buffer_typed.d.ts +13 -6
  916. package/src/shade/renderer/buffer/inspect_gpu_buffer_typed.d.ts.map +1 -1
  917. package/src/shade/renderer/buffer/inspect_gpu_buffer_typed.js +6 -5
  918. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +13 -5
  919. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  920. package/src/shade/renderer/buffer/table/GPUDatabase.js +10 -4
  921. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +3 -1
  922. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  923. package/src/shade/renderer/buffer/table/GPUTypedTable.js +5 -0
  924. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts +4 -0
  925. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts.map +1 -1
  926. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.js +4 -0
  927. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts +11 -4
  928. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  929. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +9 -3
  930. package/src/shade/renderer/camera/CameraManager.d.ts +4 -0
  931. package/src/shade/renderer/camera/CameraManager.d.ts.map +1 -1
  932. package/src/shade/renderer/camera/CameraManager.js +4 -0
  933. package/src/shade/renderer/camera/GPUCameraContext.d.ts +4 -2
  934. package/src/shade/renderer/camera/GPUCameraContext.d.ts.map +1 -1
  935. package/src/shade/renderer/camera/GPUCameraContext.js +5 -0
  936. package/src/shade/renderer/extension/FrameContext.d.ts +15 -5
  937. package/src/shade/renderer/extension/FrameContext.d.ts.map +1 -1
  938. package/src/shade/renderer/extension/FrameContext.js +7 -0
  939. package/src/shade/renderer/extension/FrameRecord.d.ts +7 -1
  940. package/src/shade/renderer/extension/FrameRecord.d.ts.map +1 -1
  941. package/src/shade/renderer/extension/FrameRecord.js +5 -0
  942. package/src/shade/renderer/extension/RenderExtension.d.ts +4 -0
  943. package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
  944. package/src/shade/renderer/extension/RenderExtension.js +4 -0
  945. package/src/shade/renderer/geometry/Attribute.d.ts +2 -2
  946. package/src/shade/renderer/geometry/Attribute.d.ts.map +1 -1
  947. package/src/shade/renderer/geometry/Attribute.js +1 -1
  948. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts +30 -2
  949. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  950. package/src/shade/renderer/geometry/GPUGeometryManager.js +642 -591
  951. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts +4 -0
  952. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts.map +1 -1
  953. package/src/shade/renderer/geometry/GPUGeometryMetadata.js +4 -0
  954. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts +7 -3
  955. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts.map +1 -1
  956. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.js +3 -2
  957. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +4 -0
  958. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  959. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +4 -0
  960. package/src/shade/renderer/geometry/bvh/bvh_to_gpu_buffer.d.ts +11 -5
  961. package/src/shade/renderer/geometry/bvh/bvh_to_gpu_buffer.d.ts.map +1 -1
  962. package/src/shade/renderer/geometry/bvh/bvh_to_gpu_buffer.js +5 -4
  963. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +12 -4
  964. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  965. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +10 -3
  966. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts +1 -0
  967. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  968. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +4 -0
  969. package/src/shade/renderer/geometry/meshlet_batch_to_bvh.d.ts +13 -6
  970. package/src/shade/renderer/geometry/meshlet_batch_to_bvh.d.ts.map +1 -1
  971. package/src/shade/renderer/geometry/meshlet_batch_to_bvh.js +6 -5
  972. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +2 -0
  973. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  974. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +5 -0
  975. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts +13 -6
  976. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts.map +1 -1
  977. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +6 -5
  978. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +31 -0
  979. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  980. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +345 -0
  981. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.d.ts +11 -5
  982. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.d.ts.map +1 -1
  983. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.js +5 -4
  984. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts +12 -5
  985. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts.map +1 -1
  986. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.js +5 -4
  987. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts +11 -5
  988. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts.map +1 -1
  989. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +5 -4
  990. package/src/shade/renderer/global_illumination/lpv/GPULightProbeVolume.d.ts +5 -1
  991. package/src/shade/renderer/global_illumination/lpv/GPULightProbeVolume.d.ts.map +1 -1
  992. package/src/shade/renderer/global_illumination/lpv/GPULightProbeVolume.js +4 -0
  993. package/src/shade/renderer/global_illumination/lpv/LightProbeVolume.d.ts +4 -0
  994. package/src/shade/renderer/global_illumination/lpv/LightProbeVolume.d.ts.map +1 -1
  995. package/src/shade/renderer/global_illumination/lpv/LightProbeVolume.js +4 -0
  996. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts +7 -1
  997. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  998. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +5 -0
  999. package/src/shade/renderer/global_illumination/lpv/graph_bake_irradiance_lookup_2d.d.ts +11 -5
  1000. package/src/shade/renderer/global_illumination/lpv/graph_bake_irradiance_lookup_2d.d.ts.map +1 -1
  1001. package/src/shade/renderer/global_illumination/lpv/graph_bake_irradiance_lookup_2d.js +5 -4
  1002. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts +9 -4
  1003. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts.map +1 -1
  1004. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.js +4 -3
  1005. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts +9 -4
  1006. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts.map +1 -1
  1007. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +4 -3
  1008. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts +7 -3
  1009. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts.map +1 -1
  1010. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.js +3 -2
  1011. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts +28 -8
  1012. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts.map +1 -1
  1013. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +17 -6
  1014. package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.d.ts +13 -6
  1015. package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.d.ts.map +1 -1
  1016. package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.js +6 -5
  1017. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.d.ts +15 -7
  1018. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.d.ts.map +1 -1
  1019. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.js +7 -6
  1020. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts +17 -8
  1021. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts.map +1 -1
  1022. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +8 -7
  1023. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.d.ts +17 -8
  1024. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.d.ts.map +1 -1
  1025. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.js +8 -7
  1026. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts +15 -7
  1027. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts.map +1 -1
  1028. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js +7 -6
  1029. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts +19 -9
  1030. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts.map +1 -1
  1031. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +9 -8
  1032. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +9 -4
  1033. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  1034. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +4 -3
  1035. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +11 -5
  1036. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  1037. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +5 -4
  1038. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +9 -1
  1039. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  1040. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +6 -0
  1041. package/src/shade/renderer/hiz/generate_downsampler_code.d.ts +11 -5
  1042. package/src/shade/renderer/hiz/generate_downsampler_code.d.ts.map +1 -1
  1043. package/src/shade/renderer/hiz/generate_downsampler_code.js +5 -4
  1044. package/src/shade/renderer/hiz/graph_build_hzb.d.ts +13 -6
  1045. package/src/shade/renderer/hiz/graph_build_hzb.d.ts.map +1 -1
  1046. package/src/shade/renderer/hiz/graph_build_hzb.js +6 -5
  1047. package/src/shade/renderer/light/GPULightCollection.d.ts +4 -1
  1048. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  1049. package/src/shade/renderer/light/GPULightCollection.js +6 -0
  1050. package/src/shade/renderer/light/LightCollection.d.ts +9 -3
  1051. package/src/shade/renderer/light/LightCollection.d.ts.map +1 -1
  1052. package/src/shade/renderer/light/LightCollection.js +5 -0
  1053. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts +11 -5
  1054. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
  1055. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +17 -14
  1056. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts +13 -6
  1057. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
  1058. package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +6 -5
  1059. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts +13 -6
  1060. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts.map +1 -1
  1061. package/src/shade/renderer/light/cluster/graph_build_light_clusters.js +6 -5
  1062. package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts +7 -3
  1063. package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts.map +1 -1
  1064. package/src/shade/renderer/light/environment/graph_filter_environment_map.js +3 -2
  1065. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts +11 -5
  1066. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
  1067. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +5 -4
  1068. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  1069. package/src/shade/renderer/material/GPUMaterialContext.d.ts +17 -1
  1070. package/src/shade/renderer/material/GPUMaterialContext.d.ts.map +1 -1
  1071. package/src/shade/renderer/material/GPUMaterialContext.js +10 -0
  1072. package/src/shade/renderer/material/GPUMaterialManager.d.ts +19 -5
  1073. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  1074. package/src/shade/renderer/material/GPUMaterialManager.js +19 -4
  1075. package/src/shade/renderer/material/ShadeMaterial.d.ts +2 -1
  1076. package/src/shade/renderer/material/ShadeMaterial.d.ts.map +1 -1
  1077. package/src/shade/renderer/material/ShadeMaterial.js +4 -0
  1078. package/src/shade/renderer/material/StandardShadeMaterial.d.ts +6 -0
  1079. package/src/shade/renderer/material/StandardShadeMaterial.d.ts.map +1 -1
  1080. package/src/shade/renderer/material/StandardShadeMaterial.js +5 -0
  1081. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -0
  1082. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  1083. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +8 -0
  1084. package/src/shade/renderer/particles/DESIGN.md +82 -69
  1085. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +93 -48
  1086. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  1087. package/src/shade/renderer/particles/GPUParticleSystem.js +117 -176
  1088. package/src/shade/renderer/particles/ParticleConstants.d.ts +6 -12
  1089. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  1090. package/src/shade/renderer/particles/ParticleConstants.js +6 -13
  1091. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -4
  1092. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +6 -6
  1093. package/src/shade/renderer/particles/coherence/particle_program_buckets.d.ts +2 -1
  1094. package/src/shade/renderer/particles/coherence/particle_program_buckets.d.ts.map +1 -1
  1095. package/src/shade/renderer/particles/coherence/particle_program_buckets.js +6 -8
  1096. package/src/shade/renderer/particles/coherence/shader_particle_bucket.d.ts.map +1 -1
  1097. package/src/shade/renderer/particles/coherence/shader_particle_bucket.js +4 -3
  1098. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts +10 -14
  1099. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts.map +1 -1
  1100. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.js +10 -14
  1101. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +6 -5
  1102. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  1103. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +6 -5
  1104. package/src/shade/renderer/particles/graph_particles.d.ts +19 -32
  1105. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  1106. package/src/shade/renderer/particles/graph_particles.js +18 -25
  1107. package/src/shade/renderer/particles/graph_particles_avboit.js +16 -16
  1108. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +3 -2
  1109. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  1110. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +31 -27
  1111. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +4 -4
  1112. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +4 -4
  1113. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js +4 -4
  1114. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts +7 -6
  1115. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts.map +1 -1
  1116. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +7 -6
  1117. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +4 -3
  1118. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts.map +1 -1
  1119. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +4 -3
  1120. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +2 -2
  1121. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +10 -10
  1122. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +3 -3
  1123. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts.map +1 -1
  1124. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.js +2 -1
  1125. package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
  1126. package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +13 -16
  1127. package/src/shade/renderer/particles/shaders/shader_particle_render.d.ts.map +1 -1
  1128. package/src/shade/renderer/particles/shaders/shader_particle_render.js +22 -19
  1129. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts +10 -3
  1130. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  1131. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +12 -2
  1132. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts +7 -3
  1133. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
  1134. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +3 -2
  1135. package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.d.ts +11 -5
  1136. package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.d.ts.map +1 -1
  1137. package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.js +5 -4
  1138. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts +13 -6
  1139. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts.map +1 -1
  1140. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.js +11 -9
  1141. package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.d.ts +31 -15
  1142. package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.d.ts.map +1 -1
  1143. package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.js +15 -14
  1144. package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.d.ts +21 -10
  1145. package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.d.ts.map +1 -1
  1146. package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.js +10 -9
  1147. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts +17 -8
  1148. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts.map +1 -1
  1149. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +8 -7
  1150. package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.d.ts +6 -0
  1151. package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.d.ts.map +1 -1
  1152. package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.js +5 -0
  1153. package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.d.ts +6 -0
  1154. package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.d.ts.map +1 -1
  1155. package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.js +5 -0
  1156. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +14 -6
  1157. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  1158. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +6 -4
  1159. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts +13 -6
  1160. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts.map +1 -1
  1161. package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.js +6 -5
  1162. package/src/shade/renderer/postprocess/gtao/render_copy_texture.d.ts +28 -13
  1163. package/src/shade/renderer/postprocess/gtao/render_copy_texture.d.ts.map +1 -1
  1164. package/src/shade/renderer/postprocess/gtao/render_copy_texture.js +13 -11
  1165. package/src/shade/renderer/postprocess/motion_blur/MotionBlur.d.ts +4 -0
  1166. package/src/shade/renderer/postprocess/motion_blur/MotionBlur.d.ts.map +1 -1
  1167. package/src/shade/renderer/postprocess/motion_blur/MotionBlur.js +4 -0
  1168. package/src/shade/renderer/postprocess/nss/NSS.d.ts +7 -1
  1169. package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
  1170. package/src/shade/renderer/postprocess/nss/NSS.js +5 -0
  1171. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts +9 -4
  1172. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts.map +1 -1
  1173. package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.js +4 -3
  1174. package/src/shade/renderer/postprocess/ssr/ssr_graph_prefilter_color.d.ts +13 -6
  1175. package/src/shade/renderer/postprocess/ssr/ssr_graph_prefilter_color.d.ts.map +1 -1
  1176. package/src/shade/renderer/postprocess/ssr/ssr_graph_prefilter_color.js +6 -5
  1177. package/src/shade/renderer/postprocess/taa/TAA.d.ts +15 -7
  1178. package/src/shade/renderer/postprocess/taa/TAA.d.ts.map +1 -1
  1179. package/src/shade/renderer/postprocess/taa/TAA.js +7 -6
  1180. package/src/shade/renderer/postprocess/velocity/graph_add_camera_velocity.d.ts +13 -6
  1181. package/src/shade/renderer/postprocess/velocity/graph_add_camera_velocity.d.ts.map +1 -1
  1182. package/src/shade/renderer/postprocess/velocity/graph_add_camera_velocity.js +6 -5
  1183. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts +11 -5
  1184. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts.map +1 -1
  1185. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.js +5 -4
  1186. package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.d.ts +11 -5
  1187. package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.d.ts.map +1 -1
  1188. package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.js +5 -4
  1189. package/src/shade/renderer/rasterize/execute_rasterization_jobs.d.ts +12 -5
  1190. package/src/shade/renderer/rasterize/execute_rasterization_jobs.d.ts.map +1 -1
  1191. package/src/shade/renderer/rasterize/execute_rasterization_jobs.js +5 -4
  1192. package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.d.ts +2 -0
  1193. package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.d.ts.map +1 -1
  1194. package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.js +5 -0
  1195. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts +11 -5
  1196. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts.map +1 -1
  1197. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.js +5 -4
  1198. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.d.ts +9 -4
  1199. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.d.ts.map +1 -1
  1200. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.js +4 -3
  1201. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts +11 -5
  1202. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  1203. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +5 -4
  1204. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts +15 -7
  1205. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts.map +1 -1
  1206. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.js +7 -6
  1207. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_two_way.d.ts +15 -7
  1208. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_two_way.d.ts.map +1 -1
  1209. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_two_way.js +7 -6
  1210. package/src/shade/renderer/rasterize/expand/graph_meshlets_expand.d.ts +13 -6
  1211. package/src/shade/renderer/rasterize/expand/graph_meshlets_expand.d.ts.map +1 -1
  1212. package/src/shade/renderer/rasterize/expand/graph_meshlets_expand.js +6 -5
  1213. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts +17 -8
  1214. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  1215. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +8 -7
  1216. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts +13 -6
  1217. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
  1218. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +6 -5
  1219. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts +21 -10
  1220. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  1221. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +10 -9
  1222. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +13 -6
  1223. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +1 -1
  1224. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +6 -5
  1225. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_one_way.d.ts +17 -8
  1226. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_one_way.d.ts.map +1 -1
  1227. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_one_way.js +8 -7
  1228. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_two_way.d.ts +13 -6
  1229. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_two_way.d.ts.map +1 -1
  1230. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_two_way.js +6 -5
  1231. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts +15 -7
  1232. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  1233. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +7 -6
  1234. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts +11 -5
  1235. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  1236. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +5 -4
  1237. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts +9 -4
  1238. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  1239. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +4 -3
  1240. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +80 -37
  1241. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  1242. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +37 -33
  1243. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.d.ts +28 -13
  1244. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.d.ts.map +1 -1
  1245. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +13 -12
  1246. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  1247. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +12 -11
  1248. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  1249. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +5 -4
  1250. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts +9 -4
  1251. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  1252. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +4 -3
  1253. package/src/shade/renderer/restir/di/ReSTIRDI.d.ts +10 -0
  1254. package/src/shade/renderer/restir/di/ReSTIRDI.d.ts.map +1 -1
  1255. package/src/shade/renderer/restir/di/ReSTIRDI.js +7 -0
  1256. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +2 -0
  1257. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  1258. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +5 -0
  1259. package/src/shade/renderer/scene/GPUSceneContext.d.ts +4 -0
  1260. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  1261. package/src/shade/renderer/scene/GPUSceneContext.js +15 -0
  1262. package/src/shade/renderer/scene/InstanceBatch.d.ts +11 -3
  1263. package/src/shade/renderer/scene/InstanceBatch.d.ts.map +1 -1
  1264. package/src/shade/renderer/scene/InstanceBatch.js +6 -0
  1265. package/src/shade/renderer/scene/Mesh.d.ts +8 -2
  1266. package/src/shade/renderer/scene/Mesh.d.ts.map +1 -1
  1267. package/src/shade/renderer/scene/Mesh.js +6 -1
  1268. package/src/shade/renderer/scene/SceneManager.d.ts +6 -0
  1269. package/src/shade/renderer/scene/SceneManager.d.ts.map +1 -1
  1270. package/src/shade/renderer/scene/SceneManager.js +5 -0
  1271. package/src/shade/renderer/scene/SkinnedMesh.d.ts +4 -0
  1272. package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +1 -1
  1273. package/src/shade/renderer/scene/SkinnedMesh.js +4 -0
  1274. package/src/shade/renderer/scene/serialization/serialize_scene.d.ts +7 -3
  1275. package/src/shade/renderer/scene/serialization/serialize_scene.d.ts.map +1 -1
  1276. package/src/shade/renderer/scene/serialization/serialize_scene.js +3 -2
  1277. package/src/shade/renderer/shader/ComputeShader.d.ts +64 -29
  1278. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  1279. package/src/shade/renderer/shader/ComputeShader.js +29 -23
  1280. package/src/shade/renderer/shader/ImageShader.d.ts +9 -4
  1281. package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
  1282. package/src/shade/renderer/shader/ImageShader.js +4 -3
  1283. package/src/shade/renderer/shader/ShaderDescriptor.d.ts +10 -4
  1284. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  1285. package/src/shade/renderer/shader/ShaderDescriptor.js +4 -3
  1286. package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.d.ts +7 -3
  1287. package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.d.ts.map +1 -1
  1288. package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.js +6 -4
  1289. package/src/shade/renderer/shader/fullscreen/create_full_quad_pipeline_descriptor.d.ts +13 -6
  1290. package/src/shade/renderer/shader/fullscreen/create_full_quad_pipeline_descriptor.d.ts.map +1 -1
  1291. package/src/shade/renderer/shader/fullscreen/create_full_quad_pipeline_descriptor.js +6 -5
  1292. package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.d.ts +13 -6
  1293. package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.d.ts.map +1 -1
  1294. package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.js +6 -5
  1295. package/src/shade/renderer/shader/graph/compute/graph_compute_pass.d.ts +13 -6
  1296. package/src/shade/renderer/shader/graph/compute/graph_compute_pass.d.ts.map +1 -1
  1297. package/src/shade/renderer/shader/graph/compute/graph_compute_pass.js +6 -5
  1298. package/src/shade/renderer/shader/graph/graph_image_pass.d.ts +27 -13
  1299. package/src/shade/renderer/shader/graph/graph_image_pass.d.ts.map +1 -1
  1300. package/src/shade/renderer/shader/graph/graph_image_pass.js +13 -12
  1301. package/src/shade/renderer/shader/graph/graph_import_raw_buffer.d.ts +15 -7
  1302. package/src/shade/renderer/shader/graph/graph_import_raw_buffer.d.ts.map +1 -1
  1303. package/src/shade/renderer/shader/graph/graph_import_raw_buffer.js +7 -6
  1304. package/src/shade/renderer/shader/graph/graph_import_typed_buffer.d.ts +13 -6
  1305. package/src/shade/renderer/shader/graph/graph_import_typed_buffer.d.ts.map +1 -1
  1306. package/src/shade/renderer/shader/graph/graph_import_typed_buffer.js +6 -5
  1307. package/src/shade/renderer/shader/pass/RenderPassColorAttachmentDescriptor.d.ts +7 -3
  1308. package/src/shade/renderer/shader/pass/RenderPassColorAttachmentDescriptor.d.ts.map +1 -1
  1309. package/src/shade/renderer/shader/pass/RenderPassColorAttachmentDescriptor.js +3 -2
  1310. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts +49 -23
  1311. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
  1312. package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +23 -20
  1313. package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.d.ts +6 -0
  1314. package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.d.ts.map +1 -1
  1315. package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.js +9 -0
  1316. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts +11 -2
  1317. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts.map +1 -1
  1318. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.js +7 -1
  1319. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts +10 -3
  1320. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  1321. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +9 -2
  1322. package/src/shade/renderer/shader/type/WGSLAttribute.d.ts +2 -2
  1323. package/src/shade/renderer/shader/type/WGSLAttribute.d.ts.map +1 -1
  1324. package/src/shade/renderer/shader/type/WGSLAttribute.js +1 -1
  1325. package/src/shade/renderer/shader/type/WGSLStructField.d.ts +6 -2
  1326. package/src/shade/renderer/shader/type/WGSLStructField.d.ts.map +1 -1
  1327. package/src/shade/renderer/shader/type/WGSLStructField.js +5 -1
  1328. package/src/shade/renderer/shader/type/WebGPUArray.d.ts +0 -2
  1329. package/src/shade/renderer/shader/type/WebGPUArray.d.ts.map +1 -1
  1330. package/src/shade/renderer/shader/type/WebGPUStruct.d.ts +2 -4
  1331. package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
  1332. package/src/shade/renderer/shader/type/WebGPUStruct.js +1 -1
  1333. package/src/shade/renderer/shader/type/WebGPUType.d.ts +5 -1
  1334. package/src/shade/renderer/shader/type/WebGPUType.d.ts.map +1 -1
  1335. package/src/shade/renderer/shader/type/WebGPUType.js +4 -0
  1336. package/src/shade/renderer/shadow/evsm/graph_evsm_render_cascade.d.ts +7 -3
  1337. package/src/shade/renderer/shadow/evsm/graph_evsm_render_cascade.d.ts.map +1 -1
  1338. package/src/shade/renderer/shadow/evsm/graph_evsm_render_cascade.js +3 -2
  1339. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +7 -0
  1340. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  1341. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +10 -0
  1342. package/src/shade/renderer/shadow/map/Shadowmap.d.ts +12 -0
  1343. package/src/shade/renderer/shadow/map/Shadowmap.d.ts.map +1 -1
  1344. package/src/shade/renderer/shadow/map/Shadowmap.js +8 -0
  1345. package/src/shade/renderer/shadow/map/SpotLightShadowmap.d.ts +2 -2
  1346. package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.d.ts +7 -3
  1347. package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.d.ts.map +1 -1
  1348. package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.js +3 -2
  1349. package/src/shade/renderer/shadow/map/csm_debug_draw_preview.d.ts +11 -5
  1350. package/src/shade/renderer/shadow/map/csm_debug_draw_preview.d.ts.map +1 -1
  1351. package/src/shade/renderer/shadow/map/csm_debug_draw_preview.js +5 -4
  1352. package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.d.ts +13 -6
  1353. package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.d.ts.map +1 -1
  1354. package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +6 -5
  1355. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.d.ts +9 -4
  1356. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.d.ts.map +1 -1
  1357. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +4 -3
  1358. package/src/shade/renderer/shadow/sdf/brixelizer/Brixelizer.d.ts +11 -5
  1359. package/src/shade/renderer/shadow/sdf/brixelizer/Brixelizer.d.ts.map +1 -1
  1360. package/src/shade/renderer/shadow/sdf/brixelizer/Brixelizer.js +5 -4
  1361. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts +1 -0
  1362. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
  1363. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +4 -0
  1364. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts +13 -6
  1365. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts.map +1 -1
  1366. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.js +6 -5
  1367. package/src/shade/renderer/texture/GPUTextureAllocator.d.ts +4 -0
  1368. package/src/shade/renderer/texture/GPUTextureAllocator.d.ts.map +1 -1
  1369. package/src/shade/renderer/texture/GPUTextureAllocator.js +4 -0
  1370. package/src/shade/renderer/texture/GPUTextureContext.d.ts +1 -0
  1371. package/src/shade/renderer/texture/GPUTextureContext.d.ts.map +1 -1
  1372. package/src/shade/renderer/texture/GPUTextureContext.js +4 -0
  1373. package/src/shade/renderer/texture/RenderTarget.d.ts +7 -3
  1374. package/src/shade/renderer/texture/RenderTarget.d.ts.map +1 -1
  1375. package/src/shade/renderer/texture/RenderTarget.js +3 -2
  1376. package/src/shade/renderer/texture/ShadeTexture.d.ts +2 -1
  1377. package/src/shade/renderer/texture/ShadeTexture.d.ts.map +1 -1
  1378. package/src/shade/renderer/texture/ShadeTexture.js +4 -0
  1379. package/src/shade/renderer/texture/TextureManager.d.ts +1 -0
  1380. package/src/shade/renderer/texture/TextureManager.d.ts.map +1 -1
  1381. package/src/shade/renderer/texture/TextureManager.js +4 -0
  1382. package/src/shade/renderer/texture/debug_draw_texture.d.ts +9 -4
  1383. package/src/shade/renderer/texture/debug_draw_texture.d.ts.map +1 -1
  1384. package/src/shade/renderer/texture/debug_draw_texture.js +4 -3
  1385. package/src/shade/renderer/texture/download_texture_data.d.ts +17 -6
  1386. package/src/shade/renderer/texture/download_texture_data.d.ts.map +1 -1
  1387. package/src/shade/renderer/texture/download_texture_data.js +10 -5
  1388. package/src/shade/renderer/texture/draw_texture_as_rgba.d.ts +26 -12
  1389. package/src/shade/renderer/texture/draw_texture_as_rgba.d.ts.map +1 -1
  1390. package/src/shade/renderer/texture/draw_texture_as_rgba.js +12 -10
  1391. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts.map +1 -1
  1392. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.js +5 -4
  1393. package/src/shade/renderer/texture/source/ShadeImage.d.ts +4 -2
  1394. package/src/shade/renderer/texture/source/ShadeImage.d.ts.map +1 -1
  1395. package/src/shade/renderer/texture/source/ShadeImage.js +5 -0
  1396. package/src/shade/renderer/texture/source/ShadeImageSerializationAdapter.d.ts +12 -0
  1397. package/src/shade/renderer/texture/source/ShadeImageSerializationAdapter.d.ts.map +1 -1
  1398. package/src/shade/renderer/texture/util/make_checkers_texture.d.ts +12 -5
  1399. package/src/shade/renderer/texture/util/make_checkers_texture.d.ts.map +1 -1
  1400. package/src/shade/renderer/texture/util/make_checkers_texture.js +5 -4
  1401. package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts +7 -2
  1402. package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
  1403. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +8 -0
  1404. package/src/shade/renderer/util/Uint32BufferSamplingStats.d.ts +2 -0
  1405. package/src/shade/renderer/util/Uint32BufferSamplingStats.d.ts.map +1 -1
  1406. package/src/shade/renderer/util/Uint32BufferSamplingStats.js +5 -0
  1407. package/src/shade/renderer/view/GPUViewContext.d.ts +4 -1
  1408. package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
  1409. package/src/shade/renderer/view/GPUViewContext.js +11 -5
  1410. package/src/shade/renderer/view/View.d.ts +6 -0
  1411. package/src/shade/renderer/view/View.d.ts.map +1 -1
  1412. package/src/shade/renderer/view/View.js +5 -0
  1413. package/src/shade/renderer/view/ViewManager.d.ts +11 -1
  1414. package/src/shade/renderer/view/ViewManager.d.ts.map +1 -1
  1415. package/src/shade/renderer/view/ViewManager.js +7 -0
  1416. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts +6 -0
  1417. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts.map +1 -1
  1418. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +5 -0
  1419. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +15 -6
  1420. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  1421. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +11 -5
  1422. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +5 -5
  1423. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  1424. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +1 -1
  1425. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts +4 -0
  1426. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts.map +1 -1
  1427. package/src/shade/renderer/volumetrics/SceneVolumetrics.js +4 -0
  1428. package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts +23 -11
  1429. package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts.map +1 -1
  1430. package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.js +11 -10
  1431. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +37 -18
  1432. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  1433. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +30 -26
  1434. package/src/view/View.d.ts +8 -3
  1435. package/src/view/View.d.ts.map +1 -1
  1436. package/src/view/View.js +7 -2
  1437. package/src/view/asset/AssetLoaderStatusView.d.ts +7 -3
  1438. package/src/view/asset/AssetLoaderStatusView.d.ts.map +1 -1
  1439. package/src/view/asset/AssetLoaderStatusView.js +3 -2
  1440. package/src/view/common/ListView.d.ts +21 -15
  1441. package/src/view/common/ListView.d.ts.map +1 -1
  1442. package/src/view/common/ListView.js +8 -7
  1443. package/src/view/common/LocalizedLabelView.d.ts +15 -7
  1444. package/src/view/common/LocalizedLabelView.d.ts.map +1 -1
  1445. package/src/view/common/LocalizedLabelView.js +7 -6
  1446. package/src/view/common/TabbedView.d.ts +14 -6
  1447. package/src/view/common/TabbedView.d.ts.map +1 -1
  1448. package/src/view/common/TabbedView.js +6 -4
  1449. package/src/view/controller/controls/BooleanVector3Control.d.ts +1 -1
  1450. package/src/view/controller/controls/BooleanVector3Control.d.ts.map +1 -1
  1451. package/src/view/controller/controls/GuiControl.d.ts +1 -1
  1452. package/src/view/controller/controls/GuiControl.d.ts.map +1 -1
  1453. package/src/view/controller/controls/NativeListController.d.ts +15 -7
  1454. package/src/view/controller/controls/NativeListController.d.ts.map +1 -1
  1455. package/src/view/controller/controls/NativeListController.js +7 -6
  1456. package/src/view/controller/controls/Vector1Control.d.ts +1 -1
  1457. package/src/view/controller/controls/Vector1Control.d.ts.map +1 -1
  1458. package/src/view/currency/CompositeCurrencyLabelView.d.ts +10 -5
  1459. package/src/view/currency/CompositeCurrencyLabelView.d.ts.map +1 -1
  1460. package/src/view/currency/CompositeCurrencyLabelView.js +4 -3
  1461. package/src/view/currency/CurrencyDenominationLabelView.d.ts +7 -3
  1462. package/src/view/currency/CurrencyDenominationLabelView.d.ts.map +1 -1
  1463. package/src/view/currency/CurrencyDenominationLabelView.js +3 -2
  1464. package/src/view/elements/CheckboxView.d.ts +7 -3
  1465. package/src/view/elements/CheckboxView.d.ts.map +1 -1
  1466. package/src/view/elements/CheckboxView.js +3 -2
  1467. package/src/view/elements/DropDownSelectionView.d.ts +9 -4
  1468. package/src/view/elements/DropDownSelectionView.d.ts.map +1 -1
  1469. package/src/view/elements/DropDownSelectionView.js +3 -2
  1470. package/src/view/elements/EmptyView.d.ts +29 -13
  1471. package/src/view/elements/EmptyView.d.ts.map +1 -1
  1472. package/src/view/elements/EmptyView.js +13 -11
  1473. package/src/view/elements/SimpleWindow.d.ts +1 -1
  1474. package/src/view/elements/SimpleWindow.d.ts.map +1 -1
  1475. package/src/view/elements/button/ButtonView.d.ts +15 -7
  1476. package/src/view/elements/button/ButtonView.d.ts.map +1 -1
  1477. package/src/view/elements/button/ButtonView.js +7 -6
  1478. package/src/view/elements/image/ImageView.d.ts +7 -3
  1479. package/src/view/elements/image/ImageView.d.ts.map +1 -1
  1480. package/src/view/elements/image/ImageView.js +3 -2
  1481. package/src/view/elements/image/SvgImageView.d.ts +5 -2
  1482. package/src/view/elements/image/SvgImageView.d.ts.map +1 -1
  1483. package/src/view/elements/image/SvgImageView.js +2 -1
  1484. package/src/view/elements/label/LabeledValueView.d.ts +14 -7
  1485. package/src/view/elements/label/LabeledValueView.d.ts.map +1 -1
  1486. package/src/view/elements/label/LabeledValueView.js +6 -5
  1487. package/src/view/elements/progress/SmoothProgressBar.d.ts +14 -7
  1488. package/src/view/elements/progress/SmoothProgressBar.d.ts.map +1 -1
  1489. package/src/view/elements/progress/SmoothProgressBar.js +6 -5
  1490. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +9 -4
  1491. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
  1492. package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +4 -3
  1493. package/src/view/elements/radial/RadialMenu.d.ts +19 -9
  1494. package/src/view/elements/radial/RadialMenu.d.ts.map +1 -1
  1495. package/src/view/elements/radial/RadialMenu.js +9 -8
  1496. package/src/view/elements/radial/RadialMenuElementDefinition.d.ts +63 -31
  1497. package/src/view/elements/radial/RadialMenuElementDefinition.d.ts.map +1 -1
  1498. package/src/view/elements/radial/RadialMenuElementDefinition.js +30 -28
  1499. package/src/view/elements/radial/RadialProgressView.d.ts +1 -1
  1500. package/src/view/elements/radial/RadialProgressView.d.ts.map +1 -1
  1501. package/src/view/elements/radial/RadialText.d.ts +18 -10
  1502. package/src/view/elements/radial/RadialText.d.ts.map +1 -1
  1503. package/src/view/elements/radial/RadialText.js +7 -6
  1504. package/src/view/elements/tiles2d/Tile.d.ts +12 -6
  1505. package/src/view/elements/tiles2d/Tile.d.ts.map +1 -1
  1506. package/src/view/elements/tiles2d/Tile.js +4 -3
  1507. package/src/view/elements/tiles2d/TileGrid.d.ts +23 -10
  1508. package/src/view/elements/tiles2d/TileGrid.d.ts.map +1 -1
  1509. package/src/view/elements/tiles2d/TileGrid.js +10 -9
  1510. package/src/view/elements/video/VideoView.d.ts +7 -3
  1511. package/src/view/elements/video/VideoView.d.ts.map +1 -1
  1512. package/src/view/elements/video/VideoView.js +3 -2
  1513. package/src/view/game/achievements/AchievementNotificationView.d.ts +7 -3
  1514. package/src/view/game/achievements/AchievementNotificationView.d.ts.map +1 -1
  1515. package/src/view/game/achievements/AchievementNotificationView.js +3 -2
  1516. package/src/view/graphics/GraphicsContextFailureView.d.ts +11 -5
  1517. package/src/view/graphics/GraphicsContextFailureView.d.ts.map +1 -1
  1518. package/src/view/graphics/GraphicsContextFailureView.js +5 -4
  1519. package/src/view/interaction/InteractionCommand.d.ts +11 -5
  1520. package/src/view/interaction/InteractionCommand.d.ts.map +1 -1
  1521. package/src/view/interaction/InteractionCommand.js +5 -4
  1522. package/src/view/interaction/InterfaceCommand.d.ts +32 -15
  1523. package/src/view/interaction/InterfaceCommand.d.ts.map +1 -1
  1524. package/src/view/interaction/InterfaceCommand.js +15 -13
  1525. package/src/view/interaction/createInterfaceCommandButton.d.ts +9 -4
  1526. package/src/view/interaction/createInterfaceCommandButton.d.ts.map +1 -1
  1527. package/src/view/interaction/createInterfaceCommandButton.js +4 -3
  1528. package/src/view/layout/DockPanel.d.ts +11 -5
  1529. package/src/view/layout/DockPanel.d.ts.map +1 -1
  1530. package/src/view/layout/DockPanel.js +5 -4
  1531. package/src/view/layout/DrawerView.d.ts +7 -3
  1532. package/src/view/layout/DrawerView.d.ts.map +1 -1
  1533. package/src/view/layout/DrawerView.js +3 -2
  1534. package/src/view/layout/FloatingPanelView.d.ts +7 -3
  1535. package/src/view/layout/FloatingPanelView.d.ts.map +1 -1
  1536. package/src/view/layout/FloatingPanelView.js +3 -2
  1537. package/src/view/layout/SplitView.d.ts +11 -5
  1538. package/src/view/layout/SplitView.d.ts.map +1 -1
  1539. package/src/view/layout/SplitView.js +5 -4
  1540. package/src/view/math/FunctionGraphView.d.ts +8 -4
  1541. package/src/view/math/FunctionGraphView.d.ts.map +1 -1
  1542. package/src/view/math/FunctionGraphView.js +3 -2
  1543. package/src/view/minimap/MinimapCanvasView.d.ts +10 -4
  1544. package/src/view/minimap/MinimapCanvasView.d.ts.map +1 -1
  1545. package/src/view/minimap/MinimapCanvasView.js +4 -3
  1546. package/src/view/minimap/dom/MinimapCameraView.d.ts +2 -1
  1547. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  1548. package/src/view/minimap/dom/MinimapMarkerView.d.ts +31 -9
  1549. package/src/view/minimap/dom/MinimapMarkerView.d.ts.map +1 -1
  1550. package/src/view/minimap/dom/MinimapTerrainView.d.ts +9 -4
  1551. package/src/view/minimap/dom/MinimapTerrainView.d.ts.map +1 -1
  1552. package/src/view/minimap/dom/MinimapTerrainView.js +3 -2
  1553. package/src/view/task/TaskProgressView.d.ts +7 -3
  1554. package/src/view/task/TaskProgressView.d.ts.map +1 -1
  1555. package/src/view/task/TaskProgressView.js +3 -2
  1556. package/src/view/tooltip/DomTooltipManager.d.ts +6 -0
  1557. package/src/view/tooltip/DomTooltipManager.d.ts.map +1 -1
  1558. package/src/view/tooltip/DomTooltipManager.js +5 -0
  1559. package/src/view/tooltip/DomTooltipObserver.d.ts +4 -0
  1560. package/src/view/tooltip/DomTooltipObserver.d.ts.map +1 -1
  1561. package/src/view/tooltip/DomTooltipObserver.js +4 -0
  1562. package/src/view/tooltip/TooltipManager.d.ts +6 -0
  1563. package/src/view/tooltip/TooltipManager.d.ts.map +1 -1
  1564. package/src/view/tooltip/TooltipManager.js +5 -0
  1565. package/src/view/tooltip/TooltipView.d.ts +7 -3
  1566. package/src/view/tooltip/TooltipView.d.ts.map +1 -1
  1567. package/src/view/tooltip/TooltipView.js +5 -1
  1568. package/src/view/tooltip/VisualTip.d.ts +6 -0
  1569. package/src/view/tooltip/VisualTip.d.ts.map +1 -1
  1570. package/src/view/tooltip/VisualTip.js +5 -0
  1571. package/src/view/tooltip/gml/GMLEngine.d.ts +14 -2
  1572. package/src/view/tooltip/gml/GMLEngine.d.ts.map +1 -1
  1573. package/src/view/tooltip/gml/GMLEngine.js +8 -0
  1574. package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.d.ts +10 -0
  1575. package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.d.ts.map +1 -1
  1576. package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.js +7 -0
  1577. package/src/view/util/DomSizeObserver.d.ts +9 -2
  1578. package/src/view/util/DomSizeObserver.d.ts.map +1 -1
  1579. package/src/view/util/DomSizeObserver.js +6 -1
  1580. package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.d.ts +0 -395
  1581. package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.d.ts.map +0 -1
  1582. package/src/shade/renderer/particles/ParticleRenderMode.d.ts +0 -19
  1583. package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +0 -1
  1584. package/src/shade/renderer/particles/ParticleRenderMode.js +0 -33
  1585. package/src/shade/renderer/particles/graph_particles_billboard.d.ts +0 -37
  1586. package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +0 -1
  1587. package/src/shade/renderer/particles/graph_particles_billboard.js +0 -93
  1588. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +0 -55
  1589. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +0 -1
  1590. package/src/shade/renderer/particles/sort/graph_particle_sort.js +0 -130
  1591. package/src/shade/renderer/particles/sort/particle_counting_sort.d.ts +0 -26
  1592. package/src/shade/renderer/particles/sort/particle_counting_sort.d.ts.map +0 -1
  1593. package/src/shade/renderer/particles/sort/particle_counting_sort.js +0 -51
  1594. package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts +0 -14
  1595. package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +0 -1
  1596. package/src/shade/renderer/particles/sort/shader_particle_sort.js +0 -223
@@ -0,0 +1,1581 @@
1
+ # Cloth — Design
2
+
3
+ > Design document. Written 2026-09-10; **M0 and M1 are implemented**, and every place they contradicted
4
+ > it has been corrected in place with the measurement named beside it. §17 says what is done and what
5
+ > is not; `MEASUREMENTS.md` is the evidence.
6
+ >
7
+ > Scope: a cloth and soft-chain simulator that lives inside `engine/physics`, collides against the
8
+ > `Collider` components the rest of the engine already authors, runs on a worker, and is safe to ship
9
+ > with its defaults untouched.
10
+
11
+ ---
12
+
13
+ ## 1. What this is
14
+
15
+ One solver over particles, driven by components:
16
+
17
+ - **`Cloth`** — the thing that simulates. Put it on an entity and that entity's transform subtree
18
+ becomes a simulated chain: a rope, a chain, a hanging sign, a mooring line.
19
+ - **`ClothRig`** — add it alongside `Cloth` and the particles are the **joints of a skinned model**
20
+ rather than the entity subtree. This is what makes a cape, a skirt, a banner on a character.
21
+ - **`ClothCollider`** — the marker that opts an existing `(Collider, Transform64)` entity into being
22
+ something cloth collides with. This is the `RigidBody`-analogue: it says *this collider participates*,
23
+ and carries only what cloth needs that `Collider` does not already say.
24
+
25
+ That last component follows a pattern the engine already has twice. `AcousticBody` opts a collider
26
+ into the acoustic simulation and carries an `AcousticMaterial`; `FluidObstacle` opts a collider into
27
+ the fluid simulation and carries an inflation radius. `ClothCollider` is the third instance of the
28
+ same idea, and it should read like a sibling of those two, not like a new invention.
29
+
30
+ The design commitments, in priority order, because they conflict and the ordering is the design:
31
+
32
+ 1. **It does not explode.** Not at 5 fps, not at 500, not when a parameter is absurd, not when a
33
+ character teleports, not when a collider is spawned inside the cloth.
34
+ 2. **It does not get stuck.** The set of configurations the simulation can reach is bounded around
35
+ the animated pose, and error cannot accumulate across steps.
36
+ 3. **It works untouched.** Adding a `Cloth` component with default values to a correctly authored
37
+ garment produces shippable motion. Tuning is an optimisation, never a prerequisite.
38
+ 4. **It is cheap.** A CPU worker budget measured in low single-digit milliseconds per character.
39
+ 5. **It is accurate.** Last, deliberately. Cloth that is 10% too stiff and never misbehaves beats
40
+ cloth that is correct and occasionally detonates.
41
+
42
+ ---
43
+
44
+ ## 2. Non-goals
45
+
46
+ - **Garment authoring.** No pattern cutting, no sewing, no pressure/inflation. Import a mesh.
47
+ - **Woven anisotropy.** No warp/weft/shear tensor. That needs UV-aligned quad topology and a
48
+ material model this design does not carry. Cloth here is isotropic with a bend modulus.
49
+ - **Penetration-free guarantees.** IPC-class methods (`C-IPC`, `GIPC`) guarantee no intersection ever,
50
+ at a cost per step this budget cannot pay. We guarantee bounded, self-correcting penetration.
51
+ - **Cloth pushing rigid bodies.** Coupling is one-way: colliders move cloth. Two-way coupling into
52
+ `PhysicsSystem`'s velocity solver is a later question and the constraint model leaves room for it
53
+ (§6), but it is not in scope.
54
+ - **Tearing, plasticity, burning.**
55
+ - **GPU simulation.** The engine has a mature WebGPU path and a particle VM that could host this, but
56
+ the requirement is a worker, and a worker is the cheaper, more portable, more debuggable answer.
57
+ Nothing in the data layout forecloses a GPU port; §12 keeps that door open.
58
+
59
+ ---
60
+
61
+ ## 3. Author-facing API
62
+
63
+ ```js
64
+ // An entity hierarchy — rope, chain, hanging sign, a prop built out of entities.
65
+ // Cloth simulates the transform subtree of the entity it is on. That entity is the anchor.
66
+ rope_top.add(Cloth.from(ClothDynamics.ROPE));
67
+
68
+ // A skinned model's garment — cape, skirt, banner, hair.
69
+ // Cloth simulates the JOINTS of the model instance this entity owns.
70
+ character.add(Cloth.from(ClothDynamics.SILK));
71
+ character.add(ClothRig.from(cape_proxy)); // cape_proxy: ClothProxy, built at import
72
+ ```
73
+
74
+ There is no mode enum and no discriminator field. **`Cloth` alone simulates the entity subtree;
75
+ `Cloth` + `ClothRig` simulates a skinned model's joints** — component presence doing the job an enum
76
+ would otherwise do badly. The solver is identical either way; only seeding and write-back differ.
77
+
78
+ Those are two cases rather than one because **the engine has two hierarchies, and that is a decision
79
+ rather than an accident**. `shade_node_to_entity_composition` expands a loaded model into entities and
80
+ gives a `ShadedGeometry` to every node that draws — except a skinned one, which "is not expanded, and
81
+ that is a boundary rather than an omission": it contributes its transform and its name and no
82
+ geometry, because its vertices deform against a skeleton the renderer owns and the GPU poses, and
83
+ making those joints entities is a design this program does not do (D47). A rope prop is entities all
84
+ the way down. A character's cape is not, and never will be. §11 is where that lands.
85
+
86
+ ### 3.1 `Cloth`
87
+
88
+ ```js
89
+ export class Cloth {
90
+ dynamics = new ClothDynamics(); // how it behaves — §3.3
91
+ blend = 1; // 0 = fully animated pose, 1 = fully simulated
92
+ layer = 1; // ClothCollider layer/mask filtering, RigidBody semantics
93
+ mask = 0xFFFFFFFF;
94
+ flags = ClothFlags.None;
95
+ }
96
+ ```
97
+
98
+ **The anchor is the entity the component is on**, and nothing names anything. Without a `ClothRig`
99
+ the particle set is the entity's own transform subtree, walked through
100
+ `TransformAttachmentSystem#findChildrenOf`/`#countChildrenOf` — the parent-to-children index the
101
+ engine already maintains. Put `Cloth` on the top link of a rope and you get the rope; put it on a
102
+ node with several chains under it and you get all of them in **one coupled solve**, which is what
103
+ makes self-collision between them work.
104
+
105
+ Two rules keep the walk unambiguous:
106
+
107
+ - **A nested `Cloth` claims its own subtree.** The walk stops when it meets another `Cloth`, so
108
+ independent hanging parts of one prop partition naturally.
109
+ - **`ClothExclude`** is a tag component that prunes a subtree from the walk, for the rig that has a
110
+ non-simulated attachment point in the middle of a chain.
111
+
112
+ With a `ClothRig`, the entity is instead the one that owns the skinned model instance, and the
113
+ subtree walk does not run at all — the particle set comes from the proxy's joint list (§3.2).
114
+
115
+ `blend` is the escape hatch for cinematics, LOD and "turn it off for this one shot". It is a lerp
116
+ between the animated pose and the simulated pose applied at write-back, not a solver parameter, so it
117
+ is free and always safe. **M1 note:** writing it wakes a sleeping cloth, because sleep skips the
118
+ write-back as well as the step (§7 P5) and a `blend` written to a sleeping cloth would otherwise take
119
+ effect at whatever later moment something else happened to wake it.
120
+
121
+ ### 3.2 `ClothRig`
122
+
123
+ ```js
124
+ export class ClothRig {
125
+ proxy = null; // ClothProxy — shared, immutable, built at import
126
+ skin = 0; // which of the instance's skins the proxy's joint indices are into
127
+ }
128
+ ```
129
+
130
+ A `ClothProxy` **object**, not a path. This is the convention the engine already uses for a component
131
+ that points at a built, shared, immutable asset: `Collider#shape` holds an `AbstractShape3D` and is
132
+ documented as *not* serialised because shapes are shared assets the pipeline wires up;
133
+ `ParticleEffect` holds a `ParticleLayout` and a `ParticleProgram` the same way. `ClothRig` serialises
134
+ the proxy's identity and the skin ordinal, and the asset pipeline resolves the rest.
135
+
136
+ **The proxy addresses joints by index, never by name.** A joint is a `Node3D` inside a
137
+ `SceneBundleInstance`, not an entity, so an `EntityReference` to one is impossible by construction —
138
+ and reintroducing strings at runtime to work around that would be the wrong answer. Instead the
139
+ binding is resolved **once, at import**: the builder has `SceneBundleInstance#nodes` (the by-name map
140
+ the engine keeps because sockets and effect anchors are authored as bone names) and turns names into
141
+ integer indices into `Skin#joints`. The runtime component holds integers.
142
+
143
+ ### 3.3 `ClothDynamics`
144
+
145
+ The parameters live in one value object, and the library is a set of instances of it.
146
+
147
+ ```js
148
+ export class ClothDynamics {
149
+ stretch = 0.7; // 0..1 normalised material coordinate
150
+ bend = 0.2; // 0..1
151
+ damping = 0.15; // 0..1
152
+ slack = 0.5; // 0..1 — how far the cloth may leave the animated pose (§3.4)
153
+ thickness = 0.02; // metres — particle radius, for collision offset and self-collision
154
+ inertia = 1; // 0..1 — how much of the anchor's world motion the cloth feels
155
+ drag = 0.1; // 0..1 — aerodynamic coupling to the air (§10)
156
+ substeps = 2; // solver budget
157
+ iterations = 4; // solver budget
158
+ flags = 0; // ClothDynamicsFlags.SelfCollision, ...
159
+ }
160
+ ```
161
+
162
+ The library is `ClothDynamics.SILK`, `.COTTON`, `.DENIM`, `.LEATHER`, `.ROPE`, `.CHAIN`, `.HAIR` —
163
+ frozen instances in `cloth_dynamics_library.js`. Assign one directly and it is shared, immutable and
164
+ free; call `.clone()` and you own a copy to edit. There is no field that silently rewrites other
165
+ fields, and no second "advanced" block: this *is* the parameter set, and the library is a set of
166
+ points in it that are known to be good rather than a mechanism.
167
+
168
+ The stiffnesses are normalised coordinates, not moduli in N/m — log-mapped internally so that `0.7`
169
+ means something an author can predict and `0.9` is not four orders of magnitude away from it. They are
170
+ independent, because the library carries the good combinations and that is protection enough; nothing
171
+ needs to be collapsed onto a single magic axis to keep an author out of trouble.
172
+
173
+ **M1 wrote that mapping (`cloth_dynamics_map.js`) and neither stiffness maps to newtons per metre.**
174
+ `stretch` maps to a *strain allowance*, because §6's measurement makes the fabric row hard and leaves
175
+ nothing for a stiffness to be. `bend` maps to a **ratio** of the row's own `m_eff/dt²` — at the fixed
176
+ step rather than the substep — for two reasons that are both wanted: the fabric's look becomes
177
+ invariant to how heavy the author made the particles, which is what a normalised knob should mean; and
178
+ since `k/(m/h²) = ratio/substeps²`, a bend row expressed that way is inside M0's dissipative band at
179
+ *any* substep count by construction, rather than by an author staying out of trouble. A stiffness in
180
+ N/m has neither property. The cost, stated: **bending saturates** at the top of that band, so a fabric
181
+ stiffer than `bend = 1` cannot be expressed as a soft row that also comes to rest.
182
+
183
+ `substeps` and `iterations` are budget rather than material, and they are here because a chain wants
184
+ more of both than a bedsheet does, so they are part of what "chain" means. Raising `iterations`
185
+ converges further toward the same answer (§5.1); raising `substeps` also reduces implicit Euler's
186
+ numerical damping, so it does change the drape slightly. Both are ordinary fields with ordinary
187
+ documentation, not hidden couplings.
188
+
189
+ `ClothDynamics` carries `equals` and `hash` like every other value type in the engine, so a component
190
+ holding one compares and hashes cheaply.
191
+
192
+ ### 3.4 Slack, and why there is no radius in metres
193
+
194
+ `slack` is dimensionless. Each particle's leash radius is derived, not authored:
195
+
196
+ ```
197
+ r_i = 2 · slack · d_geo,i
198
+ ```
199
+
200
+ **M1 corrected the factor of two, and it is a derivation rather than a fudge.** This paragraph
201
+ originally read `r_i = slack · d_geo,i`, which makes `slack = 1` a real and fairly tight constraint
202
+ instead of the absence of one: a rope hanging straight down cannot swing through ninety degrees,
203
+ because its tip has to travel `√2·d_geo` to get there and its leash is `d_geo`. The radius at which
204
+ the row is *provably* inert is `2·d_geo` — the tether already holds every particle within `d_geo` of
205
+ the anchor, the animated position it is leashed to is also within `d_geo` of the anchor since a chord
206
+ is never longer than the arc it subtends, so by the triangle inequality the two are never further
207
+ apart than that. With the factor of two in, `slack = 1` means exactly "no leash": the row cannot
208
+ bind, so it is not built at all, and there is no sentinel and no discontinuity to code around.
209
+ `MEASUREMENTS.md` §10.
210
+
211
+ where `d_geo,i` is the particle's baked geodesic distance to the fixed set. At `slack = 0` every
212
+ particle is welded to its animated position; at `slack = 1` a particle may be anywhere within its own
213
+ reach of that position. Three things fall out of that and none of them need a knob:
214
+
215
+ - **The profile is automatic.** A hem gets a long leash and a waistband gets a short one, because
216
+ that is what their geodesic depth says, not because someone painted it.
217
+ - **The fixed set falls out too.** A pinned particle has `d_geo = 0`, so `r_i = 0`, so the leash *is*
218
+ the pin. There is no separate attach constraint — one row covers both (§6).
219
+ - **There is no magic default.** The old formulation had a radius in metres with `0` meaning "derive
220
+ it from the mesh extent", which is the kind of overloaded sentinel that gets copied into a save file
221
+ and then means the wrong thing.
222
+
223
+ Slack is not a stretch allowance and does not govern inextensibility — the tether row does that, and
224
+ the two are different questions (§6). Slack asks how loosely the cloth is leashed to the animation;
225
+ the tether asks how far the fabric may extend from its anchor. A cape wants both: a moderate leash so
226
+ it follows the character, and a hard tether so it never becomes rubber.
227
+
228
+ ### 3.5 `ClothCollider`
229
+
230
+ ```js
231
+ export class ClothCollider {
232
+ inflation = 0; // extra thickness in metres, on top of ClothDynamics#thickness
233
+ friction_scale = 1; // multiplies the entity's Collider#friction
234
+ flags = 0; // ClothColliderFlags
235
+ }
236
+ ```
237
+
238
+ Three fields, and two of them are usually left alone. Everything else is read from components the
239
+ entity already has: geometry and friction from `Collider`, pose from `Transform64`, layer filtering
240
+ from the `Cloth` side.
241
+
242
+ **A `ClothCollider` does not require a `RigidBody`.** This is a deliberate divergence from
243
+ `FluidObstacle`, which does require one because it needs a wall velocity. Cloth's colliders are
244
+ overwhelmingly character bones — ordinary entities in a `TransformAttachment` hierarchy — and forcing
245
+ each of them to become a physics body to be seen by cloth would be a tax on the common case. Collider
246
+ velocity is derived from the pose delta between fixed steps, which the system caches anyway for swept
247
+ collision (§8.2). World props that *do* carry a `RigidBody` add a `ClothCollider` the same way and land
248
+ in the same index; the two cases are not distinguished.
249
+
250
+ ---
251
+
252
+ ## 4. Components and systems
253
+
254
+ ```
255
+ engine/physics/cloth/
256
+ ecs/
257
+ Cloth.js component: the simulated thing; anchor is its own entity
258
+ ClothFlags.js TeleportKeep, NeverSleep
259
+ ClothExclude.js tag: prune a subtree from the walk
260
+ ClothRig.js component: particles are a skinned model instance's joints
261
+ ClothDynamics.js value object: how it behaves
262
+ ClothDynamicsFlags.js SelfCollision, StrainLimit
263
+ cloth_dynamics_library.js SILK, COTTON, DENIM, LEATHER, ROPE, CHAIN, HAIR — frozen instances
264
+ cloth_dynamics_map.js normalised coordinates → row parameters; every constant measured
265
+ ClothCollider.js component: the RigidBody-analogue for collision
266
+ ClothColliderFlags.js
267
+ ClothSystem.js main-thread system: gather, step, write back
268
+ ClothInstance.js one live cloth: the binding between a subtree and a ClothState
269
+ cloth_seed_subtree.js the walk, the rows, and the ClothState it produces
270
+ cloth_write_back.js solved positions → Transform64, with the orientation swing
271
+ WorkerClothSystem.js drop-in worker variant (WorkerSystem subclass)
272
+ ClothWorkerCore.js
273
+ cloth.worker.js
274
+ makeClothWorker.js
275
+ cloth_worker_protocol.js
276
+ ClothSerializationAdapter.js
277
+ ClothRigSerializationAdapter.js
278
+ ClothColliderSerializationAdapter.js
279
+ collider/
280
+ ClothColliderIndex.js the index of live cloth colliders + their AABBs
281
+ ClothColliderRecord.js one packed collider: kind, params, world/inverse pose, prev pose
282
+ cloth_collider_pack.js AbstractShape3D → packed record
283
+ sdf/ closed-form SDF + gradient per packed kind
284
+ solver/
285
+ ClothState.js SoA particle + topology + constraint storage over one buffer
286
+ cloth_step.js the fixed step: predict, warm start, iterate, dual update, integrate
287
+ cloth_solve_vertex.js the per-vertex 3x3 block update
288
+ constraint/ one module per row type (§6)
289
+ cloth_color_particles.js graph colouring of the particle graph
290
+ constraint/cloth_leash_row.js §6's slack row and its tether row, which are one row model
291
+ build/
292
+ ClothProxy.js the built artefact + its binary codec
293
+ cloth_proxy_build.js source mesh → proxy (weld, simplify, extract, validate)
294
+ cloth_proxy_bind.js render mesh → proxy binding weights
295
+ cloth_geodesic_build.js distances to the fixed set — drives both tether and slack
296
+ ClothDiagnostics.js dev-build tripwires
297
+ ```
298
+
299
+ Two systems:
300
+
301
+ - **`ClothColliderSystem`** observes `(Collider, Transform64, ClothCollider)` and maintains a
302
+ `ClothColliderIndex` — a flat array of packed records plus world AABBs. This is the same shape as
303
+ `AcousticOccluderIndex`/`OccluderBody` in the sound simulation, and for the same reason: the
304
+ consumers need a compact, pose-cached, broadphase-able view of a set of colliders that is not the
305
+ physics BVH. It cannot be the physics BVH, because `ColliderObserverSystem` deliberately skips
306
+ colliders with no owning body, and bone colliders have no body.
307
+
308
+ - **`ClothSystem`** owns the simulation. Per fixed step: refresh the animated targets, gather the
309
+ overlapping colliders from the index, step, write back.
310
+
311
+ Cloth runs at the fixed rate and is interpolated for display, exactly as `PhysicsSystem` does — the
312
+ same producer/`__interp_restore` contract, so a cloth-driven `Transform64` is authoritative during the
313
+ fixed pass and interpolated outside it. Reusing the existing contract rather than inventing a second
314
+ one is what keeps a cloth-driven bone from fighting an animation-driven one.
315
+
316
+ ### 4.1 Ordering, and why the answer is not to be ordered
317
+
318
+ Cloth wants to read the skeleton *after* animation has posed it for this step and *before* anything
319
+ renders. The engine has exactly two ways to order systems: **registration order**, and what each
320
+ system declares in `components_used`, from which writers are sorted before readers. There is
321
+ deliberately no `runs_before`/`runs_after`, because naming other systems is the coupling that design
322
+ exists to avoid.
323
+
324
+ **Cloth both reads and writes `Transform64`**, which puts it on both sides of that component's own
325
+ rule, and M1 established that neither mechanism can express the relation — for a structural reason
326
+ rather than an arithmetic one. `updateExecutionOrder` scores a system as a **sum** over the components
327
+ it references and sorts descending, so a score can only be *raised* by touching more components or
328
+ touching them at a higher access level. The only way to sort **later** is therefore to touch strictly
329
+ less than the system you have to follow, and a consumer of a posed hierarchy touches strictly more.
330
+ Registration order cannot rescue it either: ties break by registration, and this is not a tie —
331
+ `ClothSystem` outscores `TransformAttachmentSystem` and any plausible poser outright, registered first
332
+ or last.
333
+
334
+ **So the answer is not a third mechanism. The answer is that cloth must not care.** An earlier draft
335
+ of M1 added an execution-phase number to `System`, which put the words "pose" and "animation" into a
336
+ layer of the engine that has no such vocabulary, and bought an ordering the design should not have
337
+ needed. What M1 ships instead is a write-back that is **idempotent under recomposition**: cloth writes
338
+ each node's local `TransformAttachment#transform` alongside its world `Transform64`, so a hierarchy
339
+ recomposition — which is what happens whenever anything announces on the anchor — reproduces the
340
+ simulated pose instead of replacing it with the authored one. Measured at **1.7e-15 m** across a
341
+ 16-link rope (`MEASUREMENTS.md` §15). With that, where cloth runs is a **quality** question.
342
+
343
+ And a small one. Running before the poser means reading last step's anchor pose, so the cloth's
344
+ *shape* is one fixed step stale; its *position* is not, because the attachment cascade carries the
345
+ whole subtree rigidly with the anchor from cloth's own local transforms. Measured on a 1.6 m rope: a
346
+ few centimetres under ordinary motion, up to a fifth of its own length at the sharpest velocity
347
+ reversal of a ±9 m/s square wave, and **not accumulating** — the same figure after fifteen seconds as
348
+ after two, because the leash and the tether bound the reachable set. `ClothSystem.spec.js` asserts the
349
+ idempotency, records the order the scheduler actually produces, and bounds that divergence.
350
+
351
+ What the declaration *does* buy is the half of the ordering that is real: cloth writes
352
+ `TransformAttachment#transform` and `TransformAttachmentSystem` reads it, so writer-before-reader puts
353
+ cloth first and the attachment system publishes its result. That falls out of `components_used` with
354
+ nothing else asked for.
355
+
356
+ **`InverseKinematicsSystem` is the same shape and reaches the same conclusion.** It reads world
357
+ `Transform64`s "the hierarchy has already composed" and writes local ones back — which is exactly the
358
+ arrangement above, and exactly why it is not fragile in the way its scoring suggests.
359
+
360
+ ---
361
+
362
+ ## 5. The solver
363
+
364
+ **Augmented Vertex Block Descent** (Giles, Diaz & Yuksel, SIGGRAPH 2025) — VBD's per-vertex
365
+ Gauss-Seidel block coordinate descent on the implicit-Euler variational energy, with an augmented
366
+ Lagrangian in place of pure penalties.
367
+
368
+ ### 5.1 Why this, and not XPBD
369
+
370
+ XPBD with small substeps is the incumbent: MagicaCloth2, Chaos Cloth, Blender, most of the field.
371
+ It works. Three properties push past it, and each maps onto a stated requirement:
372
+
373
+ - **Unconditional stability at any iteration count.** Every per-vertex update is a descent step on an
374
+ energy that is bounded below, so the update can be truncated at one iteration and the simulation is
375
+ still stable — just softer. That turns requirement 1 into a property of the update rule rather than
376
+ a property of tuning. XPBD is stable in practice, but its stability is a function of substep size
377
+ and stiffness; ours is not.
378
+ - **Parameters that keep their meaning.** AVBD targets the implicit-Euler solution, so a stiffness is
379
+ a material modulus and adding iterations moves the result *toward* the same answer rather than
380
+ changing which answer it is. Under XPBD, apparent stiffness and apparent damping both move when the
381
+ iteration budget moves, which is why cloth packages ship dozens of interacting sliders and
382
+ per-parameter animation curves to compensate. §3.3's small, independent parameter set is only
383
+ honest on a solver whose knobs are orthogonal to its budget.
384
+
385
+ This is iteration-count insensitivity, not substep insensitivity. Implicit Euler is numerically
386
+ damped by an amount that depends on `h`, so more substeps still means less artificial damping and
387
+ a livelier drape — which is why `substeps` is a documented field rather than a hidden constant.
388
+ - **Hard constraints without stiff penalties.** The augmented Lagrangian reaches effectively infinite
389
+ stiffness through an accumulating multiplier rather than a large `k`, so pins, tethers and slack
390
+ bounds are *hard* — enforced to convergence — while cloth stays soft, in the same sweep, without
391
+ the conditioning disaster a 10⁸ penalty would cause. VBD alone cannot do this; it is exactly the
392
+ limitation AVBD was written to fix.
393
+
394
+ Two smaller wins. Colouring the *particle* graph needs far fewer colours than colouring the
395
+ *constraint* graph — the VBD paper reports 8 colours for a 3,891-vertex tetrahedral mesh against 76
396
+ for its 14,802 tetrahedra — which matters for a future GPU port and for cache behaviour now. And the
397
+ per-vertex form is a natural fit for SoA typed arrays, which is what a worker needs anyway.
398
+
399
+ The cost is honest: more arithmetic per vertex than an XPBD projection, and a shorter track record
400
+ for cloth specifically. §18 carries both as risks with a measurement plan.
401
+
402
+ ### 5.2 The step
403
+
404
+ Per substep, with `h` the substep length, `m_i` particle mass, `y_i` the inertial target:
405
+
406
+ ```
407
+ predict y_i = x_i + h·v_i + h²·a_ext,i
408
+ x_i ← x_i + h·v_i + h²·ã_i (adaptive initialisation)
409
+
410
+ warm start for each HARD constraint c: (soft rows: k_c = stiffness, λ_c = 0)
411
+ λ_c ← λ_c · α · γ
412
+ k_c ← clamp(k_c · γ, k_min·s_c, k_max·s_c) s_c = the row's own m_eff/h²
413
+
414
+ iterate repeat `iterations` times:
415
+ for each colour: (parallel within a colour)
416
+ for each particle i in colour:
417
+ f = -(m_i/h²)(x_i - y_i)
418
+ H = (m_i/h²)·I
419
+ for each constraint c on i:
420
+ C = C_c(x); g = ∂C_c/∂x_i
421
+ fu = k_c·C + λ_c
422
+ fc = clamp(fu, fmin_c, fmax_c)
423
+ f -= fc·g
424
+ if fc > 0: (row in tension)
425
+ H += (fc/L)·(I − g gᵀ) (geometric stiffness, PSD part)
426
+ if fc == fu: (row active — not at a clamp)
427
+ H += k_c·(g gᵀ)
428
+ x_i += H⁻¹·f (3×3 LDLᵀ, capped at the shortest incident row)
429
+
430
+ dual update, for each HARD constraint c:
431
+ λ_c ← clamp(k_c·C_c + λ_c, fmin_c, fmax_c)
432
+ k_c ← min(k_c + β·|C_c|, k_max·s_c)
433
+
434
+ integrate v_i = (x_i - x_i^prev)/h
435
+ ```
436
+
437
+ The Hessian contribution is gated on the row being *active*. A clamped row's force is constant with
438
+ respect to position, so its true second derivative is zero; adding `k·ggᵀ` anyway would make an
439
+ inactive unilateral constraint resist motion it should not touch. It contributes its (constant) force
440
+ to `f` and nothing to `H`.
441
+
442
+ `α ∈ [0,1]` regularises the multiplier carried between steps, `γ ∈ [0,1)` decays warm-started duals so
443
+ a resting configuration bleeds off accumulated force instead of ringing, and `β` is the penalty ramp.
444
+ These are solver internals, global, and deliberately **not** on `ClothDynamics` — they are not a
445
+ property of a fabric. The reference 2D implementation's defaults are a rigid-body tuning and will not
446
+ transfer; §17 M0 makes picking cloth values a measured step with its own spec, not a copied constant.
447
+
448
+ **M0 measured them, and four things about this pseudocode were wrong.** The sweep and its full grids
449
+ are in `MEASUREMENTS.md`; the corrections are folded into the listing above and are, in short:
450
+
451
+ 1. **The five constants only govern *hard* rows.** A row whose material stiffness is finite is
452
+ representable as a plain penalty, and a plain penalty at the material stiffness *is* the material
453
+ law — there is nothing for a multiplier to add. Carrying one anyway drives `C` to zero and makes
454
+ every fabric inextensible regardless of what it was authored as: a 1 kN/m spring measured 100×
455
+ stiffer than Hooke. So a soft row is a pure penalty at its material stiffness and reads dead flat
456
+ against all five constants, which is what makes them honest as global internals. A row is **hard**
457
+ exactly when its stiffness is `Infinity` — §6's table already says `hard` in that column, and this
458
+ makes it literal rather than a threshold.
459
+ 2. **`k_min` and `k_max` are ratios of `m/h²`, not stiffnesses in N/m.** Held at a fixed multiple of
460
+ the row's own inertial scale, a 20-link hard chain produced the same residual column across five
461
+ decades of particle mass; held at a fixed stiffness it produced a different answer for every mass.
462
+ This paragraph's own reasoning already names `k_max/(m/h²)` as the quantity that matters — it just
463
+ stopped one step short of making the ratio the parameter.
464
+ 3. **`α` and `γ` act only through their product, and `α·γ ≥ 0.5` diverges.** At `α·γ ≤ 0.3` a 20-link
465
+ hard chain settles to rest with kinetic energy at 1e-9 J; at 0.5 it jitters; at 0.6 it detonates.
466
+ Residual improves monotonically towards that cliff, so the value is a margin decision:
467
+ **α·γ = 0.25**, a factor of two clear.
468
+ 4. **`β` could not be chosen from M0 data.** Above about 1e4 every M0 scenario gives an identical
469
+ answer, and with `k_min = k_max` — which measured as good as any ramp for M0's persistent rows —
470
+ it has no effect at all. The ramp exists for **transient** rows, a contact that should arrive soft
471
+ rather than shock the mesh on its first frame, and M0 has none. M2 has to measure it.
472
+
473
+ Chosen: **α = 0.25, γ = 1, β = 1e5 (unexercised), k_min = k_max = 8·(m/h²)**. γ sits at 1 because its
474
+ second job — decaying the penalty — has nothing to do while the band is a single point, so the whole
475
+ decay lives in α, whose only job is the multiplier. When M2's contacts make the band real, γ becomes
476
+ live and has to be re-measured.
477
+
478
+ **Adaptive initialisation** is VBD's: seed the iteration at `x + h·v + h²·ã` where `ã` interpolates
479
+ between zero and full external acceleration according to whether the previous step looked like free
480
+ fall or like resting contact. Without it, a low iteration count over-stretches under gravity on the
481
+ first iteration and the tethers spend the rest of the budget pulling it back.
482
+
483
+ **Chebyshev acceleration** (`ω₁ = 1`, `ω₂ = 2/(2−ρ²)`, `ωₙ = 4/(4−ρ²ωₙ₋₁)`) is available and
484
+ **disabled for any particle in contact this step**, per the VBD paper — accelerating a vertex whose
485
+ constraint set just changed is where the method's stability argument stops applying. It is off by
486
+ default and turned on per-dynamics only where it measurably helps.
487
+
488
+ ### 5.3 Why the update never explodes
489
+
490
+ `H = (m/h²)·I + Σ_tension (fc/L)·(I − g gᵀ) + Σ_active k_c·(g gᵀ)`. The mass term is positive
491
+ definite; every `k_c·g gᵀ` is a positive semidefinite rank-one term; every `(fc/L)·(I − g gᵀ)` with
492
+ `fc > 0` is positive semidefinite too. So `H` is symmetric positive definite by construction — for any
493
+ topology, any parameter values, any degenerate configuration, and regardless of how many rows are
494
+ clamped out. `H⁻¹f` is always a descent direction.
495
+
496
+ **Three things M0 measured changed this paragraph.** They are corrections to the mechanism, not to the
497
+ goal; the full evidence is in `MEASUREMENTS.md`.
498
+
499
+ **The geometric-stiffness term is kept where it is positive semidefinite, not dropped wholesale.**
500
+ For a distance row `∂²C/∂x² = (I − g gᵀ)/L`, which is PSD exactly when the row is in tension, so
501
+ `max(fc, 0)·∂²C/∂x²` can be added without touching the SPD argument — every term in `H` is still PSD
502
+ on top of a PD mass term, and there is still no threshold. Dropping it *all* was measured to make the
503
+ update overshoot sideways whenever `fc/L` passes `m/h²`, raising the vertex energy by 20% at a ratio
504
+ of 4 and by a factor of 40 at a ratio of 7e4. This is not "adding the indefinite term back": the
505
+ negative-semidefinite half, where the row is in compression, is still dropped, and dropping it there
506
+ is conservative rather than dangerous. Note the term is added whether or not the row is at a clamp —
507
+ a saturated row applies a constant-magnitude force that still swings as the row rotates.
508
+
509
+ **The 3×3 solve is an LDLᵀ factorisation, not a cofactor inverse.** They agree in exact arithmetic
510
+ and do not agree in `Float64`. A vertex carrying one very stiff row against a small mass term
511
+ assembles an `H` with a condition number in the billions, and the cofactor determinant — a sum of
512
+ triple products that has to cancel by that ratio squared — comes out **negative** on a matrix whose
513
+ eigenvalues are all positive (measured: eigenvalues 0.12, 0.12, 5.4e8; determinant −4.8e8 against a
514
+ true 7.75e6). The factorisation never forms those products; its pivots stayed positive throughout the
515
+ fuzz, and their product is the determinant to full precision. The dev-build assertion checks the
516
+ pivots, which *is* the positive-definiteness claim rather than a proxy for it.
517
+
518
+ **Positive definiteness gives a descent direction, not a monotone step.** `Δ = H⁻¹f` satisfies
519
+ `f·Δ > 0`, so the energy falls for a small enough step — and the update takes a full step of 1. Where
520
+ the quadratic model stops resembling the energy, a full step overshoots and climbs: measured falling
521
+ monotonically out to `t ≈ 0.001` of one step and then rising to 40× the starting energy at `t = 1`.
522
+ The step is therefore capped at the **shortest row incident on the particle** — the distance over
523
+ which "the direction to a neighbour" means anything, which is the mesh's own geometry rather than a
524
+ tuned constant, and which never binds for cloth in ordinary motion. With all three corrections in,
525
+ full-step energy increases on a realistic cape are 0.004% of updates and never exceed a fifth of the
526
+ local energy scale; across deliberately absurd cloth they are 1.5% and never exceed 1.0. §7 P1 states
527
+ the gate that follows from this.
528
+
529
+ A dev-build tripwire mirrors `find_non_finite_physics_state.js`: a post-step sweep for non-finite
530
+ particle state that names the first offender. It sits behind `assert.*` so it compiles out of consumer
531
+ bundles — the engine ships raw source, and a check moved out of `assert.*` stops being strippable.
532
+
533
+ ### 5.4 Colouring
534
+
535
+ The particle graph is coloured so no constraint touches two particles of the same colour, using the
536
+ existing `core/graph/coloring/colorizeGraphGreedy.js` and checked by the existing
537
+ `validateGraphColoring.js`. Bending stencils span four particles, so the graph is the mesh graph plus
538
+ the bend diagonals — around 8–10 colours for typical garment topology. Colouring runs once, on a
539
+ `Graph` object, and is baked into the `ClothProxy` as colour ranges over a permuted particle order;
540
+ for a chain it runs at link time on a graph of a few dozen nodes. Nothing colours per step and the
541
+ runtime never sees a graph object.
542
+
543
+ Contacts and self-collision rows appear and vanish per step and cannot be pre-coloured. They are
544
+ accumulated into a per-particle scratch buffer and applied Jacobi-style within the sweep — the same
545
+ mixed Gauss-Seidel/Jacobi treatment VBD uses for dynamic collisions, and the reason a step is
546
+ deterministic regardless of how many contacts a particle picked up.
547
+
548
+ ---
549
+
550
+ ## 6. Everything is one constraint row
551
+
552
+ Every feature in this system is a row in one table. A row is `(C(x), f_min, f_max, stiffness)`, and
553
+ the solver in §5.2 knows nothing else about it.
554
+
555
+ | Row | `C(x)` | `f_min` | `f_max` | Stiffness | Gives you |
556
+ |---|---|---|---|---|---|
557
+ | Stretch | `‖x_i − x_j‖ − L₀` | −∞ | +∞ | `k_stretch` | fabric that resists stretching |
558
+ | Bend | quadratic stencil `Σ w_k·x_k` | −∞ | +∞ | `k_bend` | fabric that resists folding |
559
+ | Slack | `‖x_i − s_i‖ − 2·slack·d_geo,i` | 0 | +∞ | hard | follows the animation; pins at `d_geo = 0` |
560
+ | Tether (LRA) | `‖x_i − p_anchor‖ − d_geo,i` | 0 | +∞ | hard | no rubber-band stretch |
561
+ | Backstop | `r_b − (x_i − b_i)·n_i` | 0 | +∞ | hard | never inside the body |
562
+ | Collision | `(r_i + infl) − sdf_c(x_i)` | 0 | +∞ | `k_contact` | colliders push cloth |
563
+ | Friction | tangential slip magnitude | `−μ·f_n` | `+μ·f_n` | `k_friction` | cloth grips |
564
+ | Self-collision | `‖x_i − x_j‖ − (r_i + r_j)` | −∞ | 0 | `k_self` | cloth doesn't pass through itself |
565
+ | Strain limit | `‖x_i − x_j‖ − L_max` | 0 | +∞ | hard | hard cap on elongation |
566
+
567
+ Unilateral rows fall out of the clamp: **`[0, +∞)` admits only forces that reduce `C`, `(−∞, 0]` only
568
+ forces that increase it**, and `(−∞, +∞)` is bilateral.
569
+
570
+ **M1 corrected three of those clamps and the sentence above them.** An earlier draft glossed the rule
571
+ as "`[0, +∞)` is push-only, `(−∞, 0]` is pull-only", which is true only relative to a particular sign
572
+ of `C` — the collision row writes `C` as `r − sdf` and the distance rows write it as `‖·‖ − r`, so the
573
+ same clamp means opposite things on them. Following the gloss rather than the rule gave Slack, Tether
574
+ and Strain limit `(−∞, 0]`, which under the solver's own `f -= fc·g` is the force that pushes a
575
+ distance row *apart*. Such a row does not bind weakly; it never binds at all, and it would drive a
576
+ particle away from the leash centre it is supposed to hold it near. `cloth_leash_row.spec.js`
577
+ demonstrates it directly and `MEASUREMENTS.md` §10 carries the derivation. **A row is hard exactly when its stiffness is `Infinity`** — the word in the table above,
578
+ made literal. A hard row's penalty lives in `[k_min, k_max]·(m/h²)` and its multiplier carries the
579
+ load; a soft row is a pure penalty at its material stiffness and carries no multiplier at all. M0
580
+ measured why it has to be one or the other rather than a sliding scale (§5.2), and measured what the
581
+ multiplier actually buys: not a smaller residual — at a fixed budget a stiff penalty is comparable —
582
+ but **settling**. A hard 20-link chain comes to rest with 1e-14 J of kinetic energy where the same
583
+ chain on a penalty of any stiffness sits in a limit cycle at 1e-4 J. That is §7 P5, and it is the
584
+ augmented Lagrangian's real return.
585
+
586
+ `C` for a bending row is a **vector** — the discrete mean-curvature vector — so that row carries three
587
+ multipliers against one penalty, and its clamps are absent because a bending moment has no sign to be
588
+ one-sided about. Every other row in the table is scalar.
589
+
590
+ **There is no separate attach row.** A pinned particle is a slack row with `d_geo = 0`: the constraint
591
+ becomes `‖x_i − s_i‖ ≤ 0` under a pull-only clamp, which welds it. One row, one code path, and the
592
+ distinction between "pinned" and "loosely following" is a number rather than a branch. (The gradient of
593
+ `‖x − s‖` is undefined at `x = s`; the row is skipped below an epsilon, which is the standard guard and
594
+ is also exactly when it has nothing to do.)
595
+
596
+ **Slack and tether are different questions, and a cape needs both.** Slack bounds distance to the
597
+ particle's *animated position*; the tether bounds distance to the *anchor*. Slack alone implies a
598
+ tether bound of `(1 + slack)·d_geo` — enough to stop a catastrophe, not enough to stop visible rubber —
599
+ and for a garment with no meaningful animated pose to follow (a flag, a curtain, where `slack` is near
600
+ 1 by necessity) the tether is doing all the inextensibility work on its own.
601
+
602
+ This mirrors the doctrine already written into `physics/constraint/solve_constraints.js`, whose
603
+ 6-DOF joints are "one row model, parameterised by mode", with LOCKED and LIMITED differing only in
604
+ bias and clamp. Same idea, position level instead of velocity level. A reader who knows one knows the
605
+ other, and a new cloth feature is a new row rather than a new pass.
606
+
607
+ Two rows deserve a note.
608
+
609
+ **Bend is the quadratic model**, not a dihedral angle. Its Hessian is constant for a fixed rest shape,
610
+ so the stencil weights are precomputed at build time, `C` is linear in `x`, and `g` is a constant read
611
+ from the proxy — bending costs almost nothing per iteration, and M0 measured it at an eighth of a
612
+ stretch row per visit despite touching twice as many particles. The weights annihilate the rest shape
613
+ and every affine image of it, which is every in-plane deformation to first order; they do *not*
614
+ annihilate an arbitrary planar configuration, and that is the precise content of the near-isometric
615
+ assumption below. More importantly, it has **no singularity
616
+ at 0° or 180°**. Dihedral bending needs a normal, an angle and a sign, all of which degenerate when two
617
+ triangles become coplanar or invert, and that degeneracy is a classic source of exactly the twitching
618
+ this design exists to eliminate. The cost is that the quadratic model assumes a near-flat rest shape
619
+ and near-isometric deformation; a garment with a strongly curved rest shape it wants to hold will
620
+ under-resist. §18 carries that.
621
+
622
+ **Stretch is per-edge.** Edge springs on a triangle mesh do not resist shear on their own; the bend
623
+ rows and the slack bound between them keep the mesh from collapsing in practice, and a triangle-area
624
+ row is available for the cases where they do not. Full in-plane anisotropy is a non-goal (§2).
625
+
626
+ **A chain bends through a skip row, not through the quadratic stencil.** M1 found there is nothing to
627
+ build a hinge on: the stencil is a discrete mean curvature over a *surface*, four particles across the
628
+ diamond either side of a shared edge, and a rope has no diamond — `bt_edge_read_diamond` declines a
629
+ wire edge for exactly that reason and is right to. What a chain gets instead is an ordinary stretch
630
+ row between a node and its **grandparent**, at whatever distance the authored pose puts them. That is
631
+ this section's own doctrine applied once more, it costs no new row kind, and it keeps both properties
632
+ the quadratic model was chosen for: no normal, no angle and no sign, so nothing degenerates at 0° or
633
+ 180°, and a fold is high energy rather than a singular configuration. It also does something the
634
+ quadratic stencil explicitly cannot (§18) — because its rest length is read from the authored pose
635
+ rather than assumed flat, **it holds a curved rest shape**. `MEASUREMENTS.md` §9.
636
+
637
+ **And a stretch row has to be hard, which this table's `k_stretch` does not say.** M0 measured that a
638
+ *penalty* stiffer than about `8·(m/h²)` makes the step add energy rather than dissipate it — the cloth
639
+ sustains a limit cycle forever, and raising the iteration count shrinks it without removing it. For a
640
+ half-gram particle at 60 Hz × 2 substeps that boundary sits near 60 N/m, which is a rubber band rather
641
+ than a fabric, so every stiffness an author would reach for is on the wrong side of it. The augmented
642
+ Lagrangian is therefore not a refinement over a stiff penalty for this row: it is the only formulation
643
+ of it that comes to rest, because its penalty is capped at the top of the dissipative band and the
644
+ multiplier carries the rest. M1's normalised `ClothDynamics#stretch` should map to `Infinity` with a
645
+ strain-limit row governing extension, not to a large finite `k`. `MEASUREMENTS.md` §6.
646
+
647
+ **M1 built that and measured what the strain-limit row is actually worth, and the answer is "a
648
+ third".** It removes 34–38% of the peak over-stretch, consistently, at every budget — and it **never
649
+ reaches its own allowance**: at `stretch = 1` it asks for 0.1% of strain and delivers 5.9% at one
650
+ iteration per substep, 2.2% at 2×2 and 0.9% at 2×4. The reason is structural. A strain-limit row is a
651
+ *second hard row on the same edge with the same gradient*, so it competes for the same trust region
652
+ and the same penalty band as the fabric row it is backing up; it can add force in a direction force is
653
+ already being added in, and nothing more. Below about `stretch = 0.35` its allowance is looser than
654
+ what the fabric row does unaided and it is simply inert.
655
+
656
+ So **`stretch` is the weakest field in §3.3's parameter set**, and the honest statement is that at low
657
+ budgets the bound belongs to the budget rather than to the fabric. The row is worth its 13–15% of a
658
+ garment frame where the residual is visible and is not worth it where the residual is already around
659
+ one per cent, which is why it is a flag — `ClothDynamicsFlags.StrainLimit` — rather than always on,
660
+ and why the library entries at 2×4 clear it. `MEASUREMENTS.md` §11.
661
+
662
+ ---
663
+
664
+ ## 7. Pathology budget
665
+
666
+ The requirement was cloth that does not fold up, get stuck, or spaz out. Each failure mode below gets
667
+ a named mechanism and a spec that fails without it. This table is the acceptance criterion for the
668
+ whole system, and every row's spec is a standing gate, not a one-off.
669
+
670
+ **P1 — Blow-up, NaN, unbounded velocity.**
671
+ *Mechanism:* SPD Hessian by construction (§5.3), so every update is a descent direction; the step
672
+ capped at the shortest incident row so a full Newton step cannot leave the region its model describes;
673
+ a per-particle velocity clamp; the `assert.*` non-finite tripwire.
674
+
675
+ **M1 landed the clamp and it is not derived from `thickness`.** This row asked for one "derived from
676
+ `thickness` and `h`", and `thickness` turns out to be the wrong length scale: it is a *contact*
677
+ radius, so a clamp built from it is a **tunnelling** bound, and a tunnelling bound sits below ordinary
678
+ cloth speeds rather than above them. Silk is 4 mm thick, so "a particle may not cross its own radius
679
+ in a step" is 0.24 m/s at 60 Hz — against the 29 m/s the same silk reaches behind a sprinting anchor.
680
+ Any multiple large enough to stop the clamp being a *behaviour* for silk is large enough to be
681
+ meaningless for leather, whose thickness is five times silk's and whose speeds are not.
682
+
683
+ The scale that works is the solver's own **correction authority**,
684
+ `shortest_row · substeps · iterations / dt` — the trust region caps a vertex update at the shortest
685
+ row incident on the particle, so that product is the whole of what one fixed step can undo. M1
686
+ measured a cloth losing its bounds past it (§7 P2 below), and the clamp is four times it: a bound on
687
+ the solver being asked to do more than it can, scaling with the mesh and the budget rather than with a
688
+ radius nothing reads until M2. The smallest headroom over it in the library is 5.7×. M2 still needs
689
+ the tunnelling bound — it is a different number for a different job and it arrives with the contacts.
690
+ `MEASUREMENTS.md` §13.
691
+ *Spec:* fuzz over random topologies and random `ClothDynamics` values including absurd ones, 10,000
692
+ steps, assert every particle finite. **M0 corrected the second half of this.** "The per-vertex energy
693
+ never increases across an update" does not follow from an SPD Hessian and is not true — SPD buys a
694
+ descent direction, and the update takes a full step (§5.3). What is asserted instead, and holds:
695
+ every LDLᵀ pivot positive on every update (which *is* positive definiteness, checked where it is
696
+ used); nothing non-finite across 10,000 steps of absurd cloth; and full-step energy increases bounded
697
+ and rare — 0.004% of updates on a realistic cape, never above a fifth of the local energy scale, and
698
+ 1.5% / 1.0 across the absurd fuzz. Those measured figures are the thresholds the standing gate holds
699
+ the solver to, so a change that makes it worse fails.
700
+
701
+ **P2 — Over-stretch, the rubber cape.**
702
+ *Mechanism:* long-range attachments (Kim et al. 2012). Each particle carries the geodesic distance to
703
+ its nearest fixed particle, baked once, enforced as a hard unilateral row. Because it is hard rather
704
+ than a penalty, one iteration enforces it almost exactly — this is the row that makes low iteration
705
+ counts viable.
706
+ *Spec:* a 30-link × 3-strand rig at one iteration per substep, dropped through ninety degrees; assert
707
+ `max‖x − p_anchor‖ ≤ d_geo·(1+ε)` for every particle across 600 steps, and assert the same rig without
708
+ the rows does not hold.
709
+ *Measured, M1:* **1.0155 with the tether against 1.4650 without**, at 1×1. Four times the budget takes
710
+ the untethered rig to 1.0199, which is still worse than one iteration *with* tethers — so the tether
711
+ is not a cheaper way to buy convergence, it answers a question the per-edge rows cannot.
712
+
713
+ *Limit, stated, and M1 found it:* **the bound is conditional on the solver's correction authority.**
714
+ The trust region caps a vertex update at the shortest row incident on the particle (§5.3), so one
715
+ fixed step can move a particle at most `shortest_row · substeps · iterations`, and a displacement
716
+ larger than that is not one the tether has been given a chance to answer for. Measured: a 30-link
717
+ chain kicked at 16 m/s against 3.0 m/s of authority reaches **6.9× its own reach**, and the same kick
718
+ against 24 m/s of authority reaches 1.06×. Both recover — the excursion is transient, which is P4(c)
719
+ holding — but "no particle is ever further from the anchor than `d_geo`" is true only while the
720
+ velocity clamp of P1 keeps a particle inside what the solve can undo, and that is the reason the clamp
721
+ is built out of the same quantity. `MEASUREMENTS.md` §10.
722
+
723
+ **P3 — Tunnelling through the character.**
724
+ *Mechanism:* three layers. (a) Collision rows evaluate against the collider pose *interpolated to the
725
+ substep*, from the previous and current poses the index caches — cheap swept collision. (b) The slack
726
+ bound stops a particle long before it can travel far enough to cross a limb. (c) Substepping shrinks
727
+ per-step travel.
728
+ *Limit, stated:* this is swept in translation, not in rotation. A collider spinning fast enough that a
729
+ point on its surface travels more than its own radius within one substep can still be missed. Full CCD
730
+ for cloth is out of scope.
731
+ *Spec:* a capsule swept through a sheet at 20 m/s; assert no particle's `sdf` sign flips across a step.
732
+
733
+ **P4 — Folds, tangles, and stays stuck.** The named requirement, so four mechanisms:
734
+
735
+ *(a) No history-dependent normals.* Self-collision and collision normals are derived from the
736
+ proxy's own surface orientation and the collider's SDF gradient at the current position — never from
737
+ "which side was this on last frame". A history-based scheme latches onto a wrong side and stays
738
+ wrong indefinitely; an orientation-based one resolves a tangle as soon as the surrounding geometry
739
+ permits. This is the "predefined surface orientation" branch of the untangling literature, chosen
740
+ specifically because it has no state that *can* get stuck.
741
+
742
+ *(b) No degenerate fold state.* Quadratic bending (§6) means a fully inverted 180° fold is not a
743
+ singular configuration — it is simply high energy, and high energy relaxes.
744
+
745
+ *(c) The slack bound bounds the reachable set.* Every particle is under a hard leash of radius
746
+ `slack·d_geo,i` around its animated position, so the set of configurations the simulation can occupy
747
+ is a bounded neighbourhood of the animation. **Error cannot accumulate** — however bad a step is, the
748
+ next step starts inside that same neighbourhood, and there is no drift mode that walks the cloth
749
+ somewhere it cannot return from. That is the guarantee, and note what it does *not* claim: the
750
+ animated pose itself can be imperfect. It is collision-free in the bind pose (the build validates
751
+ exactly that, §11.3, and fails loudly with the offending vertex and collider named), but an extreme
752
+ animation pose can skin a garment slightly into a thigh. When that happens the attractor is slightly
753
+ wrong and the cloth is slightly wrong with it — bounded and self-limiting, not divergent.
754
+
755
+ This is also why `slack` is the one number worth reaching for when a garment misbehaves: it is
756
+ literally the size of the neighbourhood the simulation is allowed to explore. **M1 note:** with §3.4's
757
+ corrected factor of two, `slack = 1` makes that neighbourhood the whole of what the tether already
758
+ allows, so the guarantee at `slack = 1` is the tether's rather than the leash's — which is the right
759
+ answer for a rope, and is why every chain in the library sits there.
760
+
761
+ *(d) A bounded escape hatch.* If a particle's constraint residual stays above a threshold for N
762
+ consecutive steps, it blends to its animated position over a short window. Local, bounded, on by
763
+ default with a conservative threshold, and counted in `ClothDiagnostics` so that a garment relying on
764
+ it is visible rather than silently rescued.
765
+
766
+ *Spec:* deliberately invert half a sheet through itself, run, assert the residual falls below threshold
767
+ and the mesh is self-intersection-free within N steps; separately assert the escape hatch is not
768
+ triggered by a correctly authored garment under normal animation.
769
+
770
+ **P5 — Jitter at rest.**
771
+ *Mechanism:* the multiplier decay `α·γ < 1` bleeds accumulated force out of a resting configuration so
772
+ it cannot ring; per-cloth sleep when the maximum particle displacement over a window falls below a
773
+ threshold; wake on collider motion, anchor motion, wind change, or a `ClothDynamics` change.
774
+ *M0 found the gap, and it is wider than "nothing is damping it".* The mechanism reaches **hard** rows
775
+ only, because a soft row has no multiplier to decay — and a soft row whose penalty exceeds about
776
+ `8·(m/h²)` does not merely fail to dissipate, it makes the step **add** energy. Measured on a hanging
777
+ sheet: total mechanical energy climbing +6.8 J against a system whose entire gravitational potential
778
+ is 1.2 J, sustained indefinitely, and shrinking but never vanishing as iterations or substeps go up.
779
+ Below that ratio the same row is dissipative and settles. What stops it is `ClothDynamics#damping`,
780
+ which arrives with the component in M1 — so **damping is load-bearing for P5 rather than a taste
781
+ control**, and the M1 spec has to gate on a soft cloth actually settling. `MEASUREMENTS.md` §6.
782
+ *Spec:* a settled cloth reaches sleep within a bounded number of steps and its positions are bit-identical
783
+ across the following 300.
784
+ *M1 landed both halves and measured them.* Every library fabric, on a 12-link chain set swinging at
785
+ 3 m/s, sleeps: **220 steps for denim, 770 for silk**, everything else between, and the order is the
786
+ damping order. Sleep stops the **write-back** as well as the step, which is what makes "bit-identical"
787
+ a fact rather than a hope — a pose that is not rewritten cannot drift, and one rewritten from unchanged
788
+ inputs is only *probably* identical. A cloth wakes on anchor motion, on a `ClothDynamics` change, on a
789
+ `blend` change, and on an explicit `ClothSystem#wake` for anything it cannot see.
790
+
791
+ And the damping gate, on the configuration §6 measured the limit cycle in — a 16-link rope with its
792
+ stretch rows forced soft at 1e5 N/m, a ratio of about 350 — after 1,500 steps: **2.90e-3 J undamped,
793
+ 1.28e-6 J at the library's own `damping = 0.12`**, 1.82e-12 J at the top of the range. Three orders of
794
+ magnitude from a field the design first described as a taste control. Note what damping does *not* do:
795
+ it does not stop the step adding energy, it removes energy faster than the step adds it, which is why
796
+ the numbers keep falling to `damping = 1` instead of hitting a floor. `MEASUREMENTS.md` §12.
797
+
798
+ **P6 — Teleport and cut.**
799
+ *Mechanism:* anchor motion above a threshold in one step is a teleport — `Reset` (re-seed at the
800
+ animated pose, zero velocity) or `Keep` (carry the shape across). Default `Reset`, followed by a short
801
+ stabilisation window in which the velocity limit ramps back from nothing, so the first steps after a
802
+ reset cannot produce a whip.
803
+ *Spec:* teleport 1 km mid-swing; assert bounded velocity every step and convergence to the animated pose.
804
+ *Measured, M1:* `Reset` peaks at **0.000 m/s** across the 240 steps after the jump and lands on the
805
+ animated pose; `Keep` peaks at 5.58 m/s, which is the swing it was already carrying, and shifts by
806
+ 0.078 m in local coordinates against 1.489 m for the reset. The threshold is `max(4·reach, 2 m)` per
807
+ step, and a 9 m/s sprint does not reach it for any library fabric.
808
+
809
+ **M1 named the mode differently and found `Keep` is free.** There is no `ClothTeleportMode`: the choice
810
+ is binary, so it is `ClothFlags.TeleportKeep`, one bit on the component that already carries the
811
+ cloth's own switches — a mode enum for two values is the discriminator field §3.1 exists to avoid. And
812
+ `Keep` is *literally* free: MagicaCloth2 applies the anchor delta rigidly to every particle, but in a
813
+ frame anchored to the cloth's own entity the particles are already anchor-relative, so "apply the
814
+ delta" is doing nothing. The implementation is a `return`.
815
+
816
+ **P7 — Fast locomotion: whipping, lag, centrifugal spray.**
817
+ *Mechanism:* the simulation runs in a **local frame anchored to the cloth's own entity**, with
818
+ `ClothDynamics#inertia` controlling how much of the anchor's world motion the cloth is allowed to
819
+ feel, plus anchor linear and angular speed limits. This is MagicaCloth2's `InertiaConstraint` idea and
820
+ it is the correct one: it makes "character sprints, cape behaves" a default rather than a tuning
821
+ exercise.
822
+ *Spec:* drive the anchor along a step-function velocity profile; assert bounded particle speed throughout.
823
+ *Measured, M1:* a square wave of ±9 m/s, one second a phase. Peak local particle speed runs 11.3 to
824
+ 29.3 m/s across the library against clamps of 96 to 288, so the smallest headroom is **5.7×**; nothing
825
+ teleports, and nothing leaves its own reach by more than 0.35%. The anchor limits are derived rather
826
+ than authored — half a reach of travel and half a radian of rotation per fixed step, both expressed
827
+ against the cloth's own geometry so a 3 cm pendant and a 30 m mooring line get the same treatment.
828
+ `inertia` measures monotone and exactly zero at zero: 0, 0.20, 0.37, 0.52, 0.65 m of tip lag across
829
+ its range, which is what makes it a dial rather than a switch with a meaningless middle.
830
+ `MEASUREMENTS.md` §13.
831
+
832
+ **P8 — Degenerate authoring.**
833
+ *Mechanism:* build-time validation, not runtime tolerance. The proxy builder welds duplicates, drops
834
+ zero-area triangles, and refuses non-manifold and inconsistently-wound configurations. The existing
835
+ `bt_edge_read_diamond` already declines every configuration a bending stencil cannot be built on —
836
+ wire edges, boundary edges, non-manifold edges, non-triangular neighbours, inconsistent winding, and a
837
+ "diamond" that is really one doubled triangle — so the degenerate cases are rejected by a function that
838
+ has already thought about them rather than by new code.
839
+ *Spec:* a corpus of deliberately broken meshes, each producing a specific diagnostic and no proxy.
840
+
841
+ ---
842
+
843
+ ## 8. Collision against the physics world
844
+
845
+ ### 8.1 The index
846
+
847
+ `ClothColliderSystem` maintains `ClothColliderIndex`: a flat array of packed records, each holding the
848
+ shape kind and its parameters, the world matrix, its cached inverse, the previous step's matrix, the
849
+ world AABB, friction and inflation. `OccluderBody` in the acoustic simulator is the same record and is
850
+ the shape to copy — including its precondition that the pose is rigid, so a distance in the shape's
851
+ local frame equals a distance in world space.
852
+
853
+ Per step, `ClothSystem` queries the index with the cloth's own fattened AABB and gets the overlapping
854
+ records. That set is packed into shared memory for the worker; nothing on the far side of the worker
855
+ boundary is an object.
856
+
857
+ ### 8.2 Evaluating a collision
858
+
859
+ The collision row needs `sdf_c(x_i)` and its gradient. Bring the particle into the collider's local
860
+ frame with the cached inverse, evaluate the closed-form SDF and gradient there, rotate the gradient
861
+ back. Swept behaviour comes from interpolating the collider's pose between the previous and current
862
+ matrices at the substep's fraction.
863
+
864
+ **Supported kinds are analytic primitives**: sphere, capsule, box, cylinder, and a plane. That
865
+ restriction is universal in shipping cloth systems — MagicaCloth2 offers sphere, capsule and plane;
866
+ Chaos Cloth adds tapered capsules and convex hulls — and it is what makes the inner loop a handful of
867
+ arithmetic instead of a BVH descent. A `Collider` carrying a mesh or heightmap shape is **skipped with
868
+ one warning naming the entity**, and the documented answer is to add primitive `ClothCollider` children,
869
+ which is what an author would do anyway for a character.
870
+
871
+ The engine's shapes already carry the closed-form SDFs — `CapsuleShape3D#signed_distance_at_point`,
872
+ `BoxShape3D#signed_distance_at_point` and the rest are exact and inline. Their *gradients* are not:
873
+ `signed_distance_gradient_at_point` on capsule, box and cylinder all fall back to
874
+ `compute_signed_distance_gradient_by_sampling`, which is four SDF evaluations and a normalise. That is
875
+ fine for voxelising a fluid obstacle once per step. It is not fine in a per-particle, per-iteration
876
+ loop, so §14 makes the analytic gradients shared code that both sides use.
877
+
878
+ ### 8.3 Friction
879
+
880
+ Coulomb friction as a row with clamps at `±μ·f_n`, where `f_n` is the collision row's converged
881
+ multiplier from this step and `μ` combines `Collider#friction` with `ClothCollider#friction_scale`.
882
+ The combine rule is the one `physics/contact/combine_material.js` already applies, so cloth and rigid
883
+ bodies agree about what a surface feels like. Static/dynamic separation follows the smooth transition
884
+ VBD uses, which avoids the high-order derivatives that make a hard Coulomb switch jitter.
885
+
886
+ ---
887
+
888
+ ## 9. Self-collision
889
+
890
+ Off by default — `ClothDynamicsFlags.SelfCollision`, set on the library entries that need it (skirts,
891
+ long coats, hair) and clear on the ones that do not (capes, ponytails, banners). It is the most
892
+ expensive part of every cloth system that has it — MagicaCloth2's self-collision constraint is 2,564
893
+ lines against 606 for distance — and the pathology guarantees in §7 do not depend on it.
894
+
895
+ Two tiers:
896
+
897
+ **M4a — particle-particle repulsion.** A uniform hash grid over particles in the cloth's local frame;
898
+ pairs closer than `r_i + r_j` get the unilateral row from §6. Pairs sharing a triangle or an edge are
899
+ excluded, since they are already governed by stretch and bend rows and would otherwise fight them.
900
+ O(n) with a small constant, and it prevents the great majority of visible interpenetration.
901
+
902
+ *This tier cannot see cloth passing between particles.* A sheet thinner than its particle spacing can
903
+ still slip through itself. Stated, not hidden.
904
+
905
+ **M4b — point-triangle and edge-edge.** The full stencil set, which closes that gap, over the same
906
+ grid. Deferred behind measurement: it roughly triples the self-collision cost and the benefit is
907
+ garment-dependent.
908
+
909
+ Both tiers derive their normals from the proxy's surface orientation, per P4(a).
910
+
911
+ There is no 3D uniform hash grid in `core` today; there is a well-tested 2D one
912
+ (`core/geom/2d/hash-grid/SpatialHashGrid.js`) whose structure is the template. §14.
913
+
914
+ ---
915
+
916
+ ## 10. Wind and aerodynamics
917
+
918
+ Cloth that does not move with the air reads as dead, and this engine has something better than a wind
919
+ zone: a **fluid simulator**. `FluidField` exposes `sampleVelocity(out, x, y, z)` with trilinear
920
+ filtering over a MAC grid, `fluid_build_world_to_grid` builds the world→grid transform, and
921
+ `FluidObstacle` already voxelises physics colliders into the field so the air is genuinely disturbed by
922
+ the bodies in the scene.
923
+
924
+ So the design is: **a cloth overlapping a `FluidComponent` samples its velocity field per particle and
925
+ applies aerodynamic drag against it**, scaled by `ClothDynamics#drag`. The term is an external
926
+ acceleration, `a_drag = drag · (u_air − v) · |n·û|`, with the normal-facing factor making a sheet catch
927
+ the wind broadside and slice through it edge-on — the difference between a flag and a rope.
928
+
929
+ The payoff is that a character running past a cape gets a wake, because the fluid solver already
930
+ produces one; a fire's convection lifts a banner; a door slamming pushes a curtain. None of that needs
931
+ cloth-specific authoring, and none of it needs a wind system that duplicates what the fluid system
932
+ already does.
933
+
934
+ Fallback when there is no fluid field in range: a `GlobalFluidEffector`-shaped ambient term — a
935
+ constant `wind` vector plus a small band-limited noise for gusting — read from the same interface, so
936
+ the cloth code has one path and does not branch on whether a simulation is present.
937
+
938
+ Cost control: sampling is per particle per *step*, not per iteration, and a cloth outside every fluid
939
+ field's bounds skips it entirely. Sleep (P5) wakes on a wind change so a settled banner does not stay
940
+ asleep through a gust.
941
+
942
+ This is deferred to M6 — it is the feature most likely to be cut for schedule, and nothing else depends
943
+ on it.
944
+
945
+ ---
946
+
947
+ ## 11. Geometry in, results out
948
+
949
+ **Cloth moves joints. It does not produce vertices.** The mapping from a simulated particle to a
950
+ render vertex already exists in this engine and it is the **skin**: a `Skin` holds `joints: Node3D[]`
951
+ plus inverse-bind matrices, every render vertex carries a four-entry weight palette into that joint
952
+ list, and `node.global · inverse_bind` is what the GPU blends every frame. Cloth writes joint
953
+ transforms; the existing skinning pass does the rest — including bounds refresh and BLAS refit, which
954
+ a bespoke vertex-deformation path would have to reimplement.
955
+
956
+ That is the whole relation, and it is why there is no cloth-owned render mesh anywhere in this design.
957
+
958
+ ### 11.1 Entity hierarchies — `Cloth` alone
959
+
960
+ One particle per entity in the transform subtree of the entity the component is on, walked through
961
+ `TransformAttachmentSystem#findChildrenOf`, stopping at a nested `Cloth` or a `ClothExclude`. Stretch
962
+ rows along parent-child links, bend rows along each chain, and the anchor entity itself is the fixed
963
+ set — so `d_geo` is hop distance from the anchor and every derived quantity in §3.4 works unchanged.
964
+
965
+ Output is written back to the subtree entities' `Transform64` — position directly, rotation derived
966
+ from the direction to the child, interpolated between parent-driven and child-driven orientation, which
967
+ is what keeps a two-link chain from looking hinged.
968
+
969
+ **M1 made three of those words exact.**
970
+
971
+ *Both transforms are written: the world `Transform64` and the local
972
+ `TransformAttachment#transform`.* Writing only the world one is cheaper and is a trap — the attachment
973
+ system recomposes a child from its local whenever the parent announces, so any announcement arriving
974
+ after cloth had written would replace the simulated pose with the authored one, and where in the fixed
975
+ step cloth ran would be a *correctness* question. With the local written too, a recomposition
976
+ reproduces exactly what cloth just wrote (measured at 1.7e-15 m), and §4.1's ordering problem stops
977
+ being one. It is also the engine's own precedent: `InverseKinematicsSystem` reads world transforms the
978
+ hierarchy has composed and writes local ones back, and §11.2's rig path writes `Node3D.transform_local`
979
+ for the same reason — a local transform is what a joint angle *is*.
980
+
981
+ The authored pose is not lost by being overwritten. It is captured once, when the cloth seeds, and
982
+ lives in the cloth from then on — which is what `blend = 0` returns to, what the leash centres are
983
+ measured from, and what a re-seed of a live cloth reads instead of the shape the solver left behind.
984
+ The consequence, stated: **in the entity path the animated pose is constant in the anchor's frame.**
985
+ That is a property of the case rather than a limitation of the code — a subtree's authored pose is
986
+ rigid relative to its anchor — but it does mean a subtree whose *links* are independently animated is
987
+ not an M1 case. That is the rig path, where the animated pose comes from the skeleton and is live.
988
+
989
+ *The rotation is a **swing** on top of the animated orientation*, `q = swing(d_animated → d_simulated)
990
+ ⊗ q_animated`, using the minimal (twist-free) arc. Twist is inherited from the animation rather than
991
+ invented, because a chain of particles carries no twist degree of freedom and any twist this code
992
+ produced would be a fabrication — and the whole thing degenerates correctly, since at `blend = 0` the
993
+ simulated direction *is* the animated one and the swing is the identity. A node with both a parent and
994
+ children takes the half-way rotation between the two swings; a leaf takes its parent's. The shortest
995
+ arc had no primitive in `core` and now does (`quat3_shortest_arc`), which is §14's doctrine turning up
996
+ a fourth time.
997
+
998
+ *Nothing is announced on a simulated node, and every pruned boundary is.* A `TRANSFORM64_EVENT_CHANGE`
999
+ on a simulated node would make the attachment system recompose its children from the authored pose —
1000
+ undoing the write that was just made, and cascading, for a chain, quadratically. But the root of a
1001
+ `ClothExclude` subtree, and a nested `Cloth`'s anchor, are *not* particles and still have to move: the
1002
+ write-back poses each of them by hand against the link it hangs from and announces exactly there, which
1003
+ reaches everything below the cut through the ordinary cascade and reaches nothing above it.
1004
+
1005
+ This is the path for props that genuinely *are* entity hierarchies: a rope, a chain, a hanging sign, a
1006
+ mooring line, a rigid model whose parts were expanded into entities and each drew as a
1007
+ `ShadedGeometry`. It needs no new rendering code, because moving an entity's `Transform64` is already
1008
+ how anything moves.
1009
+
1010
+ ### 11.2 Skinned garments — `Cloth` + `ClothRig`
1011
+
1012
+ A character's cape is not an entity hierarchy and cannot be made into one.
1013
+ `shade_node_to_entity_composition` expands a model into entities and attaches a `ShadedGeometry` to
1014
+ each node that draws — but a skinned node contributes its transform and its name and **no geometry**,
1015
+ because its vertices deform against a skeleton the renderer owns and the GPU poses. Its joints are
1016
+ `Node3D`s inside the entity's `SceneBundleInstance`, and making them entities is explicitly a design
1017
+ this program does not do (D47). So for a skinned garment there is no `ShadedGeometry` component and no
1018
+ bone entities: the geometry is registered with `GPUAnimationManager` through
1019
+ `register_instance_animation`, and the only writable handle is the joint's `Node3D.transform_local` —
1020
+ the same handle the animation systems write.
1021
+
1022
+ Cloth therefore drives joints, and the proxy names which ones. **Three resolutions, deliberately:**
1023
+
1024
+ | tier | order of magnitude, skirt | what it is | who owns it |
1025
+ |---|---|---|---|
1026
+ | render mesh | ~5,000 vertices | `MeshletGeometry`, GPU-resident, never touched by cloth | the asset |
1027
+ | sim proxy | ~400 particles | what the solver steps | `ClothProxy` |
1028
+ | output joints | ~60 | what `Skin#joints` holds; the palette binds render vertices to these | `ClothProxy` |
1029
+
1030
+ Decoupling the middle tier from the bottom one is the point. Simulation wants enough particles to
1031
+ drape; skinning wants only enough joints to *describe* the drape, and a four-weight palette blends
1032
+ smoothly between far fewer of them than the simulation needs. Each output joint takes its position and
1033
+ its frame from a small neighbourhood of particles — a triangle fan or a fitted patch — so the joint
1034
+ count is a build-time choice about deformation fidelity rather than a consequence of solver
1035
+ resolution. That is also what disposes of the "one node per particle" cost worry: nothing requires
1036
+ one node per particle.
1037
+
1038
+ Two cases, and they differ only in where the joints and weights came from:
1039
+
1040
+ - **The garment is already rigged** — an artist made 8–20 cape joints and skinned the cape to them.
1041
+ This is the common case and by far the cheapest. The proxy is thin: joint indices, the topology
1042
+ connecting them, rest lengths, `d_geo`. **There is no binding step and no generated geometry — the
1043
+ artist's skin is the relation.** A cape, a ponytail, a coat tail, a loincloth: all of this.
1044
+ - **The garment has no usable rig** and wants per-vertex drape — a full skirt. The importer generates
1045
+ the joint set and generates a skin binding render vertices to it, then bakes both into the proxy.
1046
+ At runtime this is *indistinguishable* from the rigged case: the GPU sees an ordinary skin, the
1047
+ solver sees an ordinary particle set.
1048
+
1049
+ Animated targets — the `s_i` that the slack row, blending and P4 all need — come from
1050
+ `mesh_apply_skeletal_vertex_skinning`, which already takes flat positions, weights, indices and 4×3
1051
+ bone matrices and writes flat output. Typed arrays in, typed arrays out, no objects: it crosses the
1052
+ worker boundary as-is.
1053
+
1054
+ **What was rejected.** A dedicated deformation pass — cloth writing vertex positions into a dynamic
1055
+ geometry buffer, with render vertices bound barycentrically to proxy triangles — is the obvious
1056
+ alternative and is genuinely simpler *as a deformation*: one frame per triangle rather than per joint,
1057
+ no palette width to respect. It loses because `MeshletGeometry` is meshlet-clustered and BLAS-backed,
1058
+ so a new path has to reimplement per-frame vertex upload, meshlet bounds refresh, normal
1059
+ recomputation and BLAS refit — all of which the skinning path already does and has playgrounds for.
1060
+ It stays written down as the fallback if M3's measurements go badly.
1061
+
1062
+ ### 11.3 Building a `ClothProxy`
1063
+
1064
+ At import, producing the object `ClothRig#proxy` points at. Almost entirely existing code.
1065
+
1066
+ For a **rigged** garment, only steps 5–8 run, over the joint graph rather than a mesh:
1067
+
1068
+ 1. Load the source garment into a `BinaryTopology` (`bt_mesh_from_indexed_geometry`).
1069
+ 2. Weld and clean (`geometry_deduplicate_vertices`, drop degenerate faces).
1070
+ 3. Decimate to the target particle count with `bt_mesh_simplify_by_error` — quadric error metric, via
1071
+ `bt_mesh_compute_vertex_quadrics`. This is the standard distance-based reduction every cloth package
1072
+ does, with a principled metric instead of a hand-rolled one.
1073
+ 4. Extract stretch rows from edges, bend stencils from `bt_edge_read_diamond`, and the boundary from
1074
+ `bt_collect_boundary_segments`.
1075
+ 5. Derive the **fixed set automatically**: particles whose skin weights are dominated by joints
1076
+ *outside* the garment's own joint set are pinned. This is what makes "works untouched" true — a
1077
+ cape pinned at the shoulders needs no painting, because the skin data already says where the cape
1078
+ stops being cape.
1079
+ 6. Bake `d_geo` — geodesic distance from every particle to the fixed set. This one array drives the
1080
+ tether row, the slack profile, and the pinning, so the three cannot disagree.
1081
+ 7. Colour the particle graph (`colorizeGraphGreedy`, checked by `validateGraphColoring`), and permute
1082
+ the particle order so each colour is a contiguous range.
1083
+ 8. Resolve joint **names to indices** into `Skin#joints`, using `SceneBundleInstance#nodes`. This is
1084
+ the only place a name appears anywhere in the system.
1085
+ 9. **Unrigged only:** choose the output joint set, fit each joint's neighbourhood and bind pose, and
1086
+ generate the skin's weights and inverse-bind matrices for the render mesh.
1087
+ 10. **Validate**: manifoldness, no zero-length edges, and — the P4(c) precondition — that the skinned
1088
+ bind pose is collision-free against the character's `ClothCollider` set.
1089
+
1090
+ Vertex painting (per-vertex stiffness or slack multiplier) is supported through an optional texture or
1091
+ vertex-colour channel and is never required. Steps 5 and 6 are the default, and the intent is that most
1092
+ garments never override them.
1093
+
1094
+ ---
1095
+
1096
+ ## 12. Data layout, threading, the worker
1097
+
1098
+ **One `SharedArrayBuffer` for the whole cloth world**, not one per instance. `WorkerSystem`'s model is
1099
+ a single shared buffer, a single command region and a single atomic publishing one in-flight step, and
1100
+ `WorkerFluidSystem` already shows how a variable set of simulated things fits that model: the command
1101
+ region carries a count and then a list of ids to step. Cloth does the same — each instance gets a
1102
+ region inside the buffer, and the command region names which instances are live this step, so sleeping
1103
+ (P5) and culled (§12.1) instances cost nothing but their absence from a list.
1104
+
1105
+ SoA throughout:
1106
+
1107
+ | Region | Type | Contents |
1108
+ |---|---|---|
1109
+ | particle state | `Float32Array` | `x`, `x_prev`, `v`, `y`, inverse mass, radius |
1110
+ | animated targets | `Float32Array` | `s`, backstop origin + normal |
1111
+ | topology | `Int32Array` | edge pairs, bend stencils, colour ranges, tether anchors |
1112
+ | rest data | `Float32Array` | rest lengths, bend weights, `d_geo` |
1113
+ | duals | `Float32Array` | `λ` and `k` per persistent constraint |
1114
+ | colliders | `Float32Array` | packed records for this step |
1115
+ | contacts | `Float32Array` | transient rows + their warm-start `λ`, keyed by (particle, collider slot) |
1116
+
1117
+ `ClothDynamics` reaches the worker through the command region, written every step — a dozen words into
1118
+ memory the worker already shares, cheaper than tracking dirtiness, and it keeps
1119
+ `cloth.dynamics.slack = 0.2` working live, which is the point of a value object rather than a preset
1120
+ that has to be re-applied.
1121
+
1122
+ `Float32` for particle state, not `Float64`. The simulation runs in the cloth's **local frame**, so
1123
+ coordinates are garment-sized rather than world-sized and f32 has ample precision; the payoff is half
1124
+ the bandwidth in the loop that dominates. The local frame is not a memory optimisation that happens to
1125
+ help — it is the same choice that makes P7's inertia handling natural, and the precision win follows.
1126
+ Write-back converts local f32 to world `Transform64` at the boundary, once per particle per step.
1127
+
1128
+ Transient contact rows need their multipliers warm-started across steps to be worth anything, so they
1129
+ are keyed by `(particle index, collider slot)` and matched on the next step. A collider that leaves the
1130
+ index drops its slot and its contacts start cold, which is correct.
1131
+
1132
+ **The worker.** `WorkerClothSystem` is a `WorkerSystem` subclass and follows `WorkerFluidSystem`
1133
+ exactly, because that pattern is already proven in this repo: `collect` packs colliders and animated
1134
+ targets into shared memory and writes the command words, a single `Atomics.store` publishes the step,
1135
+ `apply` reads the result on the next tick, and the fixed-step gate guarantees the worker is idle during
1136
+ every system's `fixedUpdate`. The split is the same shape too — arbitrary user-facing work (component
1137
+ reads, `Transform64` sync, index queries) stays on the main thread; the pure numeric step crosses.
1138
+
1139
+ The standing gate is the one the fluid system already holds itself to: **`ClothSystem` and
1140
+ `WorkerClothSystem` must produce bit-identical results.** Identical code over identical data in an
1141
+ identical order. That is what makes the worker a deployment choice rather than a behavioural fork, and
1142
+ it is why the core is a pure function over typed arrays from milestone zero even though the worker does
1143
+ not arrive until milestone five.
1144
+
1145
+ Testing the bridge needs no worker: `SystemWorkerLoopback` gives a real `SystemWorkerHost`, a real
1146
+ `SharedArrayBuffer` and real `Atomics` in-process, with message delivery and step execution as explicit
1147
+ events a spec can order. Only the thread is faked.
1148
+
1149
+ `SharedArrayBuffer` requires a cross-origin isolated page (`COOP`/`COEP`), which `WorkerFluidSystem`
1150
+ already documents. The main-thread `ClothSystem` is the fallback where that is not available, and it is
1151
+ not a degraded mode — it is the same code.
1152
+
1153
+ ### 12.1 Culling
1154
+
1155
+ Cloth outside the view frustum stops stepping, which for a crowd is the difference between a budget and
1156
+ a problem. Resuming without a pop means blending from the animated pose back to the simulated one over
1157
+ a short window rather than snapping — the same `blend` machinery from §3.1, driven by the system
1158
+ instead of the author.
1159
+
1160
+ ---
1161
+
1162
+ ## 13. Reuse ledger
1163
+
1164
+ What this design takes from the engine rather than building:
1165
+
1166
+ | Need | Existing code |
1167
+ |---|---|
1168
+ | Vector and quaternion math | `core/geom/vec3/*` (95 functions), `core/geom/3d/quaternion/*` |
1169
+ | Mesh topology, adjacency, bending stencils | `core/geom/3d/topology/struct/binary/` — `BinaryTopology`, `bt_edge_read_diamond`, `bt_edge_is_boundary`, `bt_collect_boundary_segments` |
1170
+ | Proxy decimation | `bt_mesh_simplify_by_error`, `bt_mesh_compute_vertex_quadrics` |
1171
+ | Mesh cleanup | `geometry_deduplicate_vertices` |
1172
+ | Graph colouring | `core/graph/coloring/colorizeGraphGreedy.js`, `validateGraphColoring.js` |
1173
+ | Collider shapes and their SDFs | `core/geom/3d/shape/*` — closed-form `signed_distance_at_point` on every primitive |
1174
+ | Collider AABBs, pose caching | `core/geom/3d/aabb/*`, `aabb3_matrix4_project` |
1175
+ | Collider ECS wiring | `Collider`, `ColliderFlags`, `ColliderObserverSystem` (as the pattern) |
1176
+ | "Opt a collider into a second simulation" | `FluidObstacle` + `FluidObstacleSystem`, `AcousticBody` |
1177
+ | Collider index shape | `AcousticOccluderIndex` + `OccluderBody` |
1178
+ | Component holds a built shared asset | `Collider#shape`, `ParticleEffect#program` — the convention `ClothRig#proxy` follows |
1179
+ | Surface material combination | `physics/contact/combine_material.js` |
1180
+ | Constraint-row doctrine | `physics/constraint/solve_constraints.js` |
1181
+ | Subtree walk | `TransformAttachmentSystem#findChildrenOf` / `#countChildrenOf`, `TransformAttachment` |
1182
+ | Animated targets | `mesh_apply_skeletal_vertex_skinning` (flat arrays, worker-safe) |
1183
+ | Wind / aerodynamics | `FluidField#sampleVelocity`, `fluid_build_world_to_grid`, `GlobalFluidEffector` |
1184
+ | Worker offload | `ecs/async/WorkerSystem.js`, `SystemWorkerHost`, `SystemWorkerLoopback`, `WorkerFluidSystem` as the worked example |
1185
+ | Fixed step + render interpolation | `PhysicsSystem`'s producer/`__interp_restore` contract |
1186
+ | Transforms | `Transform64`, `Node3D` |
1187
+ | Particle → render-vertex mapping | `Skin` — joints + inverse-bind matrices + the four-weight palette; cloth writes joints and the existing pass does the rest |
1188
+ | Reaching a model's joints from its entity | `SceneBundleInstance` (`skins`, `nodes` by name), `register_instance_animation` |
1189
+ | Deformation, bounds refresh, BLAS refit | `GPUMeshSkinningContext`, `shader_skin_matrix_prep`, `bounds_refresh/` — all of it inherited by driving joints rather than vertices |
1190
+ | Non-finite tripwire pattern | `find_non_finite_physics_state.js` |
1191
+ | Strippable assertions | `core/assert.js` |
1192
+ | Serialisation | the `*SerializationAdapter` pattern and its binary codecs |
1193
+
1194
+ ---
1195
+
1196
+ ## 14. New shared code this justifies
1197
+
1198
+ Three pieces belong in `core`, not in `cloth`, because the cloth need exposes a gap the engine has
1199
+ anyway:
1200
+
1201
+ 1. **Analytic SDF gradients** for sphere, capsule, box, cylinder and plane, as free functions in
1202
+ `core/geom/3d/shape/sdf/`. Today `signed_distance_gradient_at_point` on capsule, box and cylinder is
1203
+ `compute_signed_distance_gradient_by_sampling` — four SDF evaluations plus a normalise, for shapes
1204
+ whose gradients are two lines of algebra. The shape classes call the new functions, cloth calls them
1205
+ directly on packed data, and there is one implementation rather than two. This makes the existing
1206
+ shapes faster as a side effect.
1207
+
1208
+ 2. **A 3D uniform hash grid**, modelled on `core/geom/2d/hash-grid/SpatialHashGrid.js`. Needed for
1209
+ self-collision; useful anywhere a broadphase over many small equal-sized things is wanted, which the
1210
+ 2D one already demonstrates.
1211
+
1212
+ 3. **`PlaneShape3D`.** There is no infinite plane shape. Cloth wants one for ground and for author-placed
1213
+ cut planes, and its absence today is worked around with large boxes.
1214
+
1215
+ 4. **A shortest-arc quaternion**, `core/geom/3d/quaternion/quat3_shortest_arc.js` — the minimal,
1216
+ twist-free rotation carrying one unit vector onto another. **M1 needed it and the family did not
1217
+ have it**: `quat3_*` had `multiply`, `integrate`, `nlerp` and the uint32 codecs but nothing that
1218
+ answers "orient this bone along that direction", which is the whole of §11.1's write-back. It is
1219
+ also the one place in the family with a genuine discontinuity — no continuous choice of axis exists
1220
+ on the whole sphere, so an antipodal pair has to pick one — and having it in `core` with a spec
1221
+ around that case is better than having it inlined in a write-back loop without.
1222
+
1223
+ Test helpers for all of it live inside the `.spec.js` files or in `__fixtures__`, per the repo rule —
1224
+ a shared helper module would ship on npm.
1225
+
1226
+ ---
1227
+
1228
+ ## 15. MagicaCloth2: what we take, what we leave
1229
+
1230
+ MagicaCloth2 is the reference and it is a good one. It has shipped, it is fast, and its feature set is
1231
+ the accumulated answer to a decade of production complaints. Taken:
1232
+
1233
+ - **Two cloth kinds over one solver.** MeshCloth and BoneCloth differ only in how particles are seeded
1234
+ and how results are written back. This is right and §11 copies it — expressed as component presence
1235
+ rather than an enum.
1236
+ - **A proxy mesh decoupled from the render mesh**, with distance-based reduction and custom skinning
1237
+ back to the render vertices. Also right; §11.3 does the same thing with `bt_mesh_simplify_by_error`.
1238
+ - **The inertia model.** World and local inertia fractions, movement and rotation speed limits, an
1239
+ anchor that cancels inertia for a character on a moving vehicle, teleport detection with Reset/Keep
1240
+ modes, and a stabilisation window after reset. This is the least glamorous part of the package and
1241
+ the most valuable; P6 and P7 are it, nearly verbatim.
1242
+ - **Max-distance and backstop** as first-class constraints rather than debugging aids. P3 and P4 lean on
1243
+ them harder than MagicaCloth does — here the leash is the correctness argument, not a polish pass.
1244
+ - **Tether/LRA** as the answer to over-stretch at low iteration counts.
1245
+
1246
+ Left:
1247
+
1248
+ - **The parameter surface.** MagicaCloth2's serialised data is a dozen constraint blocks, several of them
1249
+ animation curves over "depth", and its per-constraint files run to hundreds of lines of tuning. That is
1250
+ the direct consequence of a PBD solver whose apparent stiffness depends on iteration count: when the
1251
+ physical meaning of a slider moves with the budget, you end up shipping a curve per slider. AVBD's
1252
+ parameters do not move that way, so §3.3 can be one small value object — and the per-particle profile
1253
+ that MagicaCloth authors with curves falls out of `d_geo` instead (§3.4).
1254
+ - **Angle restoration and angle limit constraints.** These exist to give PBD chains a restoring force
1255
+ that bending alone cannot supply at low iteration counts. With a solver that converges, bend rows plus
1256
+ tethers cover the same ground with less to configure.
1257
+ - **A separate spring constraint.** Subsumed by the slack row with a non-zero radius.
1258
+ - **A distance constraint solved twice per substep** (before and after collision). An artefact of the
1259
+ Gauss-Seidel ordering; the augmented Lagrangian's dual update does this work.
1260
+ - **Its collision layering model.** We already have `Collider`, layers and masks; a parallel system would
1261
+ be a second thing to keep in sync.
1262
+ - **Its wind zones.** We have a fluid simulator (§10).
1263
+
1264
+ ---
1265
+
1266
+ ## 16. State of the art
1267
+
1268
+ **The line this design sits on.** PBD → XPBD → substepped XPBD → VBD → AVBD.
1269
+
1270
+ - **XPBD** (Macklin, Müller & Chentanez) made PBD stiffness independent of iteration count by
1271
+ introducing compliance and a per-constraint multiplier. **Small Steps in Physics Simulation**
1272
+ (Macklin et al. 2019) then showed that *n* substeps with one iteration each beats one step with *n*
1273
+ iterations — less constraint error, far less artificial damping, and better behaviour across a wider
1274
+ stiffness range than Krylov-based implicit solvers. Together these are the state of practice: Chaos
1275
+ Cloth, MagicaCloth2 and Blender's cloth all sit here.
1276
+ - **Vertex Block Descent** (Chen, Liu, Yang & Yuksel, SIGGRAPH 2024) reframed the step as block
1277
+ coordinate descent on implicit Euler's variational form, solving one 3×3 system per vertex per
1278
+ iteration. Unconditionally stable at any iteration count, no line search, and it colours the vertex
1279
+ graph rather than the constraint graph. Its reported failure mode is exactly the one that matters here:
1280
+ it struggles to converge under high stiffness ratios and has no mechanism for enforcing hard
1281
+ constraints — which is what a pinned garment on a rigid body *is*.
1282
+ - **Augmented Vertex Block Descent** (Giles, Diaz & Yuksel, SIGGRAPH 2025) fixes precisely that with an
1283
+ augmented Lagrangian: hard constraints at effectively infinite stiffness without the instability, plus
1284
+ substantially better convergence under high stiffness ratios. Reference implementations exist in 2D,
1285
+ in Metal, in PhysX, in Houdini, and — relevant to this engine — as a WebGPU solver.
1286
+ - **Going Further With Vertex Block Descent** (Saillant et al., 2025) extends VBD to higher-order
1287
+ elements and confirms that substepping improves its convergence — which is why §5.2 substeps rather
1288
+ than only iterating.
1289
+
1290
+ **The line this design does not sit on.** **Incremental Potential Contact** and its descendants —
1291
+ **C-IPC** for codimensional objects, **GIPC** and **AGIPC** on GPU — guarantee intersection-free,
1292
+ inversion-free results through log-barrier contact and continuous collision detection. They are the
1293
+ correct answer when correctness is the requirement, and they are the wrong answer at a millisecond
1294
+ budget. We take one idea from that family: IPC's smooth static/dynamic friction transition, which VBD
1295
+ also adopts.
1296
+
1297
+ **Self-collision** is where the field is currently moving, because parallel position solvers have made
1298
+ it the bottleneck rather than the solve. **Air Meshes** (Müller et al. 2015) tessellate the space
1299
+ between objects and prevent element inversion, which handles untangling robustly and automatically but
1300
+ requires maintaining a volumetric mesh. **Global Intersection Analysis** (Baraff, Witkin & Kass,
1301
+ "Untangling Cloth", 2003) is history-free and resolves tangles as soon as geometry permits — the
1302
+ property P4(a) is built on, even though we implement a far cheaper approximation of it. Recent work on
1303
+ hierarchical culling via discrete curvature targets the same bottleneck.
1304
+
1305
+ **Industry.** Chaos Cloth (Unreal) is substepped XPBD with long-range attachments, max distance and
1306
+ backstop distance/radius — the same safety constraints §7 relies on, which is useful independent
1307
+ confirmation that they are what production actually needs. Comparative studies of VBD against PBD in
1308
+ Unity report parity at low vertex counts and a widening VBD advantage as the count rises, which matches
1309
+ the per-iteration cost story: VBD does more arithmetic per vertex and far less coordination.
1310
+
1311
+ Sources:
1312
+ [Vertex Block Descent](https://arxiv.org/abs/2403.06321) ·
1313
+ [VBD project page](https://graphics.cs.utah.edu/research/projects/vbd/) ·
1314
+ [Augmented Vertex Block Descent](https://graphics.cs.utah.edu/research/projects/avbd/) ·
1315
+ [AVBD reference implementation](https://github.com/savant117/avbd-demo2d) ·
1316
+ [WebGPU AVBD](https://github.com/jure/webphysics) ·
1317
+ [Going Further With Vertex Block Descent](https://onlinelibrary.wiley.com/doi/10.1002/cav.70039) ·
1318
+ [XPBD](https://matthias-research.github.io/pages/publications/XPBD.pdf) ·
1319
+ [Small Steps in Physics Simulation](https://mmacklin.com/smallsteps.pdf) ·
1320
+ [Untangling Cloth](https://dl.acm.org/doi/10.1145/882262.882357) ·
1321
+ [Air Meshes for Robust Collision Handling](https://dl.acm.org/doi/10.1145/2766907) ·
1322
+ [Codimensional IPC](https://arxiv.org/pdf/2012.04457) ·
1323
+ [Efficient Self-Collision Culling via Discrete Curvature](https://www.mdpi.com/2227-7390/14/9/1504) ·
1324
+ [VBD vs PBD in Unity](https://www.mdpi.com/2076-3417/14/23/11072) ·
1325
+ [Chaos Cloth](https://dev.epicgames.com/documentation/en-us/unreal-engine/clothing-tool-in-unreal-engine)
1326
+
1327
+ ---
1328
+
1329
+ ## 17. Milestones
1330
+
1331
+ Each milestone is shippable and each `done` names evidence that ran. Nothing is reported complete on
1332
+ the strength of code existing.
1333
+
1334
+ **M0 — the solver core. DONE, 2026-09-10.** `ClothState`, `cloth_step`, the vertex update, stretch and
1335
+ bend rows, colouring. Pure functions over typed arrays; no ECS, no worker, no rendering.
1336
+ *Proofs, all green:* finite-difference agreement between each row's analytic gradient and its numerical
1337
+ gradient; the P1 property test (see the correction in §7 P1 — strict per-update energy monotonicity is
1338
+ not true and the gate is what replaced it); a measured choice of α, β, γ and `k_min`/`k_max` with the
1339
+ sweep recorded in `MEASUREMENTS.md`, nothing copied; the performance budget measured on real topology.
1340
+ 43 tests across six spec files.
1341
+
1342
+ **M0 changed the design in six places**, each with the measurement behind it in `MEASUREMENTS.md` and
1343
+ each folded back into §5.2, §5.3, §6, §7 P1 and §7 P5 above. In one line each: the multiplier and the
1344
+ penalty band apply only to *hard* rows; the band is a ratio of `m/h²` rather than a stiffness; the PSD
1345
+ half of the geometric-stiffness term has to be kept; the 3×3 solve has to be an LDLᵀ; an SPD Hessian
1346
+ gives a descent direction rather than a monotone step; and P5's jitter mechanism does not reach soft
1347
+ rows, which need M1's damping.
1348
+
1349
+ **Deliberately not in M0:** Chebyshev acceleration (§5.2) is gated on a particle not being in contact,
1350
+ and contacts arrive at M2, so there is nothing here to measure it against. The velocity clamp named in
1351
+ P1 is derived from `ClothDynamics#thickness` and belongs with the component that carries it — and it
1352
+ would have masked the property M0 exists to measure.
1353
+
1354
+ **M1 — chains end to end. DONE, 2026-09-10.** `Cloth`, `ClothFlags`, `ClothExclude`, `ClothDynamics`,
1355
+ `ClothDynamicsFlags`, `cloth_dynamics_library.js`, `ClothSystem`, subtree seeding and write-back, the
1356
+ slack and tether rows, the strain-limit row, the inertia model, teleport handling, sleep, and the
1357
+ velocity clamp P1 deferred. No collision.
1358
+ *Proofs, all green:* P2, P5, P6 and P7, each with a companion test that runs the same scenario with the
1359
+ mechanism switched off; `ClothDynamics` value semantics and the measured mapping; three ordering tests
1360
+ — the derived order, the recomposition idempotency that makes it not matter, and a bound on the
1361
+ divergence when it is inverted; a second playground page, `playground/rig.html`, driving the real
1362
+ ECS with a rope, a chain, a five-strand rig under one `Cloth`, a hanging sign with a `ClothExclude`,
1363
+ and a nested pair. **43 tests across four spec files** — the leash row's 8, the system's 9, the
1364
+ pathology budget's 11, the value semantics and the mapping's 15 — plus 5 for the shortest-arc
1365
+ primitive and 4 more in `system_execution_order.spec.js`, for 52 in all. The engine suite is green
1366
+ at 18,179.
1367
+
1368
+ **M1 changed the design in seven places**, each with the measurement behind it in `MEASUREMENTS.md`
1369
+ §9–15 and each folded back above. In one line each: three of §6's clamps had the wrong sign and would
1370
+ never have bound; §3.4's leash radius needs a factor of two before `slack = 1` means "no leash"; §7
1371
+ P1's velocity clamp cannot be derived from `thickness`, because that is a tunnelling bound and a
1372
+ tunnelling bound is *below* ordinary cloth speeds; §11.1's chain bending has no diamond to build a
1373
+ hinge on and uses a skip row instead; §11.1's write-back has to write the **local** transform as well
1374
+ as the world one; the levers no longer close the frame budget one at a time; and the strain-limit row
1375
+ buys a third of the over-stretch rather than the allowance it asks for, which makes `stretch` the
1376
+ weakest field in the parameter set.
1377
+
1378
+ **And one thing M1 got wrong before it got it right, which is worth recording because the wrong answer
1379
+ was plausible.** §4.1 correctly identified that neither of the engine's two ordering mechanisms can
1380
+ place cloth after a poser, and the first attempt was to add a third — an execution-phase number on
1381
+ `System`, with a `PostPose` value. That put the vocabulary of animation into `engine/ecs`, which has
1382
+ none, to buy an ordering the design should not have needed in the first place. Removing the need was
1383
+ both smaller and better: writing the local transform makes the write-back idempotent, which turns the
1384
+ placement into a bounded quality question and leaves the scheduler alone.
1385
+
1386
+ **Deliberately not in M1:** P4(d)'s bounded escape hatch, which needs a per-particle residual monitor
1387
+ and belongs with the collision rows that make a particle get *stuck* in the first place — a chain has
1388
+ no configuration to be stuck in. Chebyshev acceleration, still gated on contacts that arrive at M2. `β`,
1389
+ which M0 could not choose and M1 has no transient rows to choose it with either — every row M1 adds is
1390
+ persistent. `ClothSerializationAdapter` and its siblings: nothing in M1's scope list names them, and a
1391
+ codec written before `ClothRig` exists would be revised by M3 before it was ever loaded.
1392
+ Interpolation: cloth writes `Transform64` at the fixed rate and §12's producer/`__interp_restore`
1393
+ contract is not wired, which shows as a cloth updating at the fixed rate rather than the frame rate
1394
+ and is a visible-but-not-wrong gap. M5 is where it belongs, with the worker.
1395
+ **This is the first shippable feature.**
1396
+
1397
+ **M2 — collision.** `ClothCollider`, `ClothColliderFlags`, `ClothColliderSystem`, `ClothColliderIndex`,
1398
+ packed records, analytic SDF gradients (§14.1), collision and friction rows, backstop.
1399
+ *Proofs:* P3 and P4 specs green; playground with a cape over an animated character.
1400
+
1401
+ **M3 — skinned garments.** `ClothRig`, `ClothProxy`, the import build, joint write-back into
1402
+ `Node3D.transform_local`. **Rigged garments first** — no generated skin, no binding step, which is
1403
+ most of the value for a fraction of the work — then the unrigged path (steps 9 of §11.3) behind its
1404
+ own measurement.
1405
+ *Proofs:* P8 corpus green; a rigged cape over an animated character in a playground; for the unrigged
1406
+ path, the joint-count-to-fidelity curve measured before a joint budget is fixed, and the deformation
1407
+ compared against the source garment simulated at full resolution.
1408
+
1409
+ **M4 — self-collision.** The 3D hash grid (§14.2), particle-particle repulsion, exclusion of
1410
+ topologically adjacent pairs.
1411
+ *Proofs:* the P4 tangle spec extended to self-intersection counts; a measured cost delta that justifies
1412
+ which library entries set `ClothDynamicsFlags.SelfCollision`.
1413
+
1414
+ **M5 — the worker.** `WorkerClothSystem`, `ClothWorkerCore`, `cloth.worker.js`, the protocol.
1415
+ *Proofs:* bit-parity between `ClothSystem` and `WorkerClothSystem` as a standing gate; loopback specs
1416
+ covering step ordering, message ordering and shutdown; a measured main-thread cost reduction.
1417
+
1418
+ **M6 — wind.** Fluid-field sampling, aerodynamic drag, the ambient fallback.
1419
+ *Proofs:* a playground with a banner in a simulated wake; a measured cost showing the per-step sampling
1420
+ stays inside budget. Cuttable without affecting anything else.
1421
+
1422
+ **Performance budget — measured at M0, re-measured at M1, and it still does not hold on its own.** One
1423
+ character's full cloth complement — 1,024 particles at 2 substeps × 4 iterations, on a triangulated
1424
+ patch carrying 16.8 row incidences per particle — cost **3.50 ms per frame** at best at M0, against a
1425
+ 2 ms target. **M1's rows made it 4.61 ms**: the strain limit is 0.73 ms (it doubles the stretch table,
1426
+ and the stretch rows are already 69% of the frame), the tether 0.36 ms, the slack row 0.10 ms. What
1427
+ that costs the plan is stated below.
1428
+
1429
+ The estimate was wrong in its reasoning as well as its number: **gathering neighbour positions is not
1430
+ what dominates.** The controlled test is to relabel the source vertices at random, which destroys the
1431
+ locality `cloth_color_order` provides and changes nothing else — same colouring, same rows, same
1432
+ arithmetic. It costs nothing measurable at the 1,024 particles §17 budgets for (the whole state fits in
1433
+ L2) and 11% at four times that size. So the *entire* memory-locality component of the gather is a few
1434
+ per cent of the frame, and a layout optimisation has at most 11% to win.
1435
+
1436
+ Deleting the workload piece by piece puts 69% of the frame in the stretch rows, 18% in the bend rows
1437
+ and 7% in everything else. That is a split of what each row kind *causes*, not of the arithmetic in
1438
+ its accumulate: the variants sit in different physical states, and an isolated loop over one accumulate
1439
+ measures a converged mesh rather than a moving one and disagrees with the deletion by a factor of five
1440
+ on the stretch row. `MEASUREMENTS.md` §7 carries the discrepancy rather than a story that resolves it.
1441
+
1442
+ The levers, priced at M0 (`MEASUREMENTS.md` §7) and again on M1's row set (§14):
1443
+
1444
+ | Lever | M0's rows | M1's rows |
1445
+ |---|---|---|
1446
+ | Fewer iterations — 1,024 at 2×**2** | **1.69 ms** inside | **2.38 ms** over |
1447
+ | Fewer substeps — 1,024 at 1×4 | **1.68 ms** inside | **2.40 ms** over |
1448
+ | Fewer particles — ~500 at 2×4 | **1.54 ms** inside | **2.53 ms** over |
1449
+
1450
+ **No single lever reaches 2 ms any more.** Each of them lands inside when a second is spent alongside
1451
+ it — 400 particles at 2×4 is 1.72 ms, 576 at 2×2 is 1.28 ms, 1,024 at 1×2 is 1.17 ms — so this is a
1452
+ sizing decision rather than a wall, and it is one the library now makes explicitly: every garment entry
1453
+ spends two levers and says which two. The barycentric binding fallback from §11.2 is still not needed.
1454
+
1455
+ Every figure here is the best of four independent rounds, which agree to ±5%. Cost is close to linear
1456
+ in both particles and sweeps, so any one lever is enough on its own and they compose. **Note what the worker does not do:** §12 moves this off the main thread, it does
1457
+ not make it cheaper, so "2 ms on the worker" with several characters in flight is a scheduling question
1458
+ this measurement does not answer.
1459
+
1460
+ Re-measure at M2, M4 and M5.
1461
+
1462
+ ---
1463
+
1464
+ ## 18. Risks and open questions
1465
+
1466
+ **AVBD has a short track record for cloth. — MEASURED, and the risk was real.** VBD's paper covers
1467
+ cloth; AVBD's public reference implementations are 2D and rigid-body-focused. The augmented Lagrangian
1468
+ layer is well understood in the abstract, but its interaction with cloth's particular constraint mix —
1469
+ many soft rows, a few hard ones, transient contacts — is not something anyone has published numbers on.
1470
+ M0 found exactly that interaction to be where the design was wrong: **the multiplier must not touch a
1471
+ soft row at all** (it drove a 1 kN/m spring 100× stiffer than Hooke), and **the penalty band is only
1472
+ meaningful relative to `m/h²`**, which is a cloth-specific statement because cloth's mass term is four
1473
+ orders of magnitude below a rigid body's. Both are fixed and measured (§5.2, `MEASUREMENTS.md` §3–4).
1474
+ The core is now stable across 10,000 steps of deliberately absurd cloth, settles a hard chain to 1e-14 J
1475
+ at 80 links deep, and reproduces Hooke exactly on a soft row. The §6 row abstraction still means the
1476
+ descent loop could be replaced with substepped XPBD without touching the constraint definitions, and
1477
+ that fallback still costs one module — but nothing measured so far argues for taking it.
1478
+
1479
+ **Per-vertex Hessian assembly in JavaScript may not hit the budget. — MEASURED, and it does not.**
1480
+ 3.50 ms against a 2 ms target for 1,024 particles at 2×4. *Resolved by:* the plan's own first lever —
1481
+ half the iteration count, or half the particles, lands inside — so this is a sizing decision for M1's
1482
+ library and M3's proxy rather than an open risk. What is *not* resolved is that the cost is
1483
+ concentrated in the stretch row and only a third of that is the gather, so the obvious memory-layout
1484
+ optimisation is aimed at the smaller half. `MEASUREMENTS.md` §7.
1485
+
1486
+ **System ordering. — DISSOLVED rather than resolved.** §4.1 carries the reasoning; in short, the
1487
+ derived score is a *sum* over what a system references, so touching more can only move a system
1488
+ **earlier**, and a consumer of a posed hierarchy touches strictly more than the poser. There is no
1489
+ declaration cloth could have made, and registration order does not break a non-tie. The engine has two
1490
+ ordering mechanisms and neither expresses this.
1491
+
1492
+ The answer is not a third mechanism, it is not needing one: cloth writes each node's **local**
1493
+ transform alongside its world one, so a hierarchy recomposition reproduces the simulated pose rather
1494
+ than replacing it — measured at 1.7e-15 m — and the placement stops being a correctness question.
1495
+ *What is left, and it is a real cost:* running before the poser means the cloth's shape is one fixed
1496
+ step stale, which measures at a few centimetres on a 1.6 m rope under ordinary motion and up to a
1497
+ fifth of its own length at the sharpest reversal of a ±9 m/s square wave. It does not accumulate.
1498
+ An application that cares registers accordingly and gets nothing, because this is not a tie; an
1499
+ application that does not care is unaffected, which is the common case and the one this trades for.
1500
+ `MEASUREMENTS.md` §15.
1501
+
1502
+ **The unrigged path's joint budget is unknown.** A rigged garment costs nothing new — its joints
1503
+ already exist. An unrigged one needs a generated joint set, and how many joints it takes to represent
1504
+ a skirt's drape through a four-weight palette is an open empirical question: too few and the garment
1505
+ reads as faceted, too many and every instance pays for rows in a transforms table shared with the
1506
+ whole scene. *Mitigation:* M3 measures the fidelity curve before fixing a budget, and ships the rigged
1507
+ path first so the feature is useful whatever the answer. The barycentric deformation pass (§11.2) is a
1508
+ designed fallback, not an improvisation.
1509
+
1510
+ **Per-joint frames are the real cost of the unrigged path.** A particle has a position; a joint needs
1511
+ an orientation, fitted from a neighbourhood of particles every frame. That fit is the part with no
1512
+ existing implementation to lean on and the part most likely to be a source of artefacts when the
1513
+ neighbourhood degenerates — a fold that collapses a triangle fan has no well-defined frame.
1514
+ *Mitigation:* it is confined to the unrigged path, which M3 sequences last.
1515
+
1516
+ **Quadratic bending cannot hold a curved rest shape.** A garment authored with a strong permanent curve
1517
+ will relax flatter than intended. M0 measured the exact boundary: the stencil annihilates the rest shape
1518
+ and **every affine image of it** — which is every in-plane deformation to first order, so a flat sheet
1519
+ being sheared, stretched or rotated stays at zero bending energy — but it does *not* annihilate an
1520
+ arbitrary planar configuration. Four coplanar particles that are not an affine image of the rest four
1521
+ read as bent. *Mitigation:* accepted for the fabrics the library targets. If a case appears, the fix is
1522
+ a rest-curvature offset in the stencil, which is a change to one row and not to the solver.
1523
+
1524
+ **Swept collision is translation-only.** P3 states the limit. A fast-spinning collider can still be
1525
+ missed. *Mitigation:* more substeps in the affected `ClothDynamics`; genuine CCD stays out of scope.
1526
+
1527
+ **A soft-row cloth does not come to rest. — CLOSED by M1's damping, and the size is measured.** M0
1528
+ measured a soft chain landing in a bounded limit cycle that 2,000 further steps do not move, and no
1529
+ solver constant reaches it, because `α·γ` decays a multiplier and a soft row has none. `damping` does
1530
+ reach it: on the configuration §6 measured, 2.90e-3 J undamped against 1.28e-6 J at the library's own
1531
+ `damping = 0.12`, and 1.82e-12 J at the top of the range. `cloth_pathology.spec.js` gates on exactly
1532
+ that pair.
1533
+ *What this does not claim:* damping does not stop the step adding energy, it removes energy faster than
1534
+ the step adds it. The equilibrium is bounded rather than zero — which is why the numbers keep falling
1535
+ all the way to `damping = 1` instead of hitting a floor — and a cloth whose rows are soft and far above
1536
+ the dissipative band is still a cloth being rescued rather than a cloth behaving. M1's mapping does not
1537
+ produce one; the gate exists so a future mapping that does is caught. `MEASUREMENTS.md` §12.
1538
+
1539
+ **The escape hatch could mask authoring errors.** P4(d) rescues a stuck particle, which means a badly
1540
+ authored garment can look acceptable while relying on it. *Mitigation:* `ClothDiagnostics` counts
1541
+ escape-hatch activations per cloth and surfaces them, so "this garment is being rescued 30 times a
1542
+ second" is visible rather than invisible.
1543
+
1544
+ **Open — two-way coupling.** Cloth does not push rigid bodies. The row model could carry it (the
1545
+ collision row's multiplier is a force, and applying its negation to the collider's body is mechanically
1546
+ straightforward), but the stability of that loop across two solvers with different time discretisations
1547
+ is a real question and is not answered here.
1548
+
1549
+ **Open — the fixed set for an unskinned surface.** Step 5 of §11.3 derives the fixed set from skin
1550
+ weights, which is right for a garment on a skeleton and has no answer for a flag, a curtain or a
1551
+ banner that is not skinned at all. Those also sit at `slack ≈ 1` by necessity (there is no meaningful
1552
+ animated pose to follow), so the tether carries all the inextensibility — which works, but the fixed
1553
+ set still has to come from the mesh boundary or from authoring. M3 needs a second rule.
1554
+
1555
+ **Open — LOD.** Distance-based particle-count reduction would need either multiple baked proxies per
1556
+ garment or a runtime hierarchy. Culling (§12.1) covers the off-screen case; the far-but-visible case is
1557
+ unaddressed.
1558
+
1559
+ **Open — `stretch` is a weak control, and it is not obvious what would make it a strong one.** M1
1560
+ measured the strain-limit row removing about a third of the peak over-stretch and never reaching its
1561
+ own allowance, because it is a second hard row competing with the first for the same trust region and
1562
+ the same penalty band (§6). A fabric's *extension* is therefore governed by the iteration budget more
1563
+ than by the fabric, and the library says so by which entries build the row at all. Three things might
1564
+ change that and none is free: a soft fabric row inside the dissipative band with the hard row acting
1565
+ only as the limit (which reintroduces M0's settling problem at any realistic stiffness); a per-row
1566
+ penalty band, making `k_max/(m/h²)` a material property rather than a global (which `MEASUREMENTS.md`
1567
+ §4 shows trades stretchiness against settling); or accepting that near-inextensibility is what fabric
1568
+ *is* and demoting `stretch` to a documented weak knob. M2's contacts do not bear on it either way.
1569
+
1570
+ **Open — the write-back has no interpolation.** §12 gives cloth `PhysicsSystem`'s producer /
1571
+ `__interp_restore` contract, and M1 does not wire it: cloth writes `Transform64` at the fixed rate and
1572
+ nothing blends between ticks, so a cloth updates at 60 Hz on a 165 Hz display. That is visible and it
1573
+ is not wrong — the poses are authoritative, they are simply held. It lands with M5, where the worker
1574
+ makes the fixed-step producer contract load-bearing for a second reason.
1575
+
1576
+ **Open — the subtree is walked once.** A rope's links do not come and go, so `cloth_seed_subtree` runs
1577
+ on first step and `ClothSystem#reseed` is how a caller says the structure changed. That is the same
1578
+ contract `TransformAttachment#parent` already carries, and it is the right default; what it does not
1579
+ have is a way to *notice*. An entity added under a live `Cloth` is silently not simulated until
1580
+ someone re-seeds, which is a class of authoring mistake with no diagnostic behind it. `ClothDiagnostics`
1581
+ is where one would go.