@woosh/meep-engine 3.43.0 → 3.44.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 (287) hide show
  1. package/editor/prototypeEditorShell.d.ts.map +1 -1
  2. package/editor/prototypeEditorShell.js +4 -2
  3. package/package.json +1 -1
  4. package/src/engine/Clock.d.ts +15 -0
  5. package/src/engine/Clock.d.ts.map +1 -1
  6. package/src/engine/Clock.js +29 -5
  7. package/src/engine/Engine.d.ts.map +1 -1
  8. package/src/engine/Engine.js +11 -19
  9. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts +57 -0
  10. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts.map +1 -0
  11. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.js +84 -0
  12. package/src/engine/graphics3/AnimationGraphSystem.d.ts +23 -13
  13. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
  14. package/src/engine/graphics3/AnimationGraphSystem.js +61 -64
  15. package/src/engine/graphics3/AnimationSystem.d.ts +24 -15
  16. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
  17. package/src/engine/graphics3/AnimationSystem.js +67 -61
  18. package/src/engine/graphics3/MeshSkinSystem.d.ts +56 -0
  19. package/src/engine/graphics3/MeshSkinSystem.d.ts.map +1 -0
  20. package/src/engine/graphics3/MeshSkinSystem.js +317 -0
  21. package/src/engine/graphics3/MeshSystem.d.ts +15 -35
  22. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  23. package/src/engine/graphics3/MeshSystem.js +21 -298
  24. package/src/engine/graphics3/RowChains.d.ts +76 -0
  25. package/src/engine/graphics3/RowChains.d.ts.map +1 -0
  26. package/src/engine/graphics3/RowChains.js +347 -0
  27. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -0
  28. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  29. package/src/engine/graphics3/ShadedGeometrySystem.js +329 -309
  30. package/src/engine/graphics3/animation/AnimationClips.d.ts +56 -0
  31. package/src/engine/graphics3/animation/AnimationClips.d.ts.map +1 -0
  32. package/src/engine/graphics3/animation/AnimationClips.js +79 -0
  33. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +13 -14
  34. package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
  35. package/src/engine/graphics3/animation/ClipListPlayer.js +262 -263
  36. package/src/engine/graphics3/animation/write_clip_playback.d.ts +3 -3
  37. package/src/engine/graphics3/animation/write_clip_playback.js +4 -4
  38. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +5 -0
  39. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  40. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +80 -75
  41. package/src/engine/graphics3/prefab/PrefabInstance.d.ts +4 -24
  42. package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -1
  43. package/src/engine/graphics3/prefab/PrefabInstance.js +60 -80
  44. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +16 -3
  45. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -1
  46. package/src/engine/graphics3/prefab/prefab_instantiate.js +49 -12
  47. package/src/engine/graphics3/prefab/prefab_place.d.ts +31 -17
  48. package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -1
  49. package/src/engine/graphics3/prefab/prefab_place.js +175 -130
  50. package/src/engine/graphics3/register_clips.d.ts +64 -0
  51. package/src/engine/graphics3/register_clips.d.ts.map +1 -0
  52. package/src/engine/graphics3/register_clips.js +114 -0
  53. package/src/engine/physics/cloth/MEASUREMENTS.md +795 -0
  54. package/src/engine/physics/cloth/PLAN.md +339 -9
  55. package/src/engine/physics/cloth/build/ClothProxy.d.ts +113 -61
  56. package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -1
  57. package/src/engine/physics/cloth/build/ClothProxy.js +142 -77
  58. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +22 -0
  59. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -0
  60. package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +75 -0
  61. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +43 -30
  62. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  63. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +357 -284
  64. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts +62 -0
  65. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -0
  66. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +280 -0
  67. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +1 -1
  68. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +1 -1
  69. package/src/engine/physics/cloth/ecs/Cloth.d.ts +17 -9
  70. package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -1
  71. package/src/engine/physics/cloth/ecs/Cloth.js +220 -212
  72. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +6 -0
  73. package/src/engine/physics/cloth/ecs/ClothHold.d.ts +91 -0
  74. package/src/engine/physics/cloth/ecs/ClothHold.d.ts.map +1 -0
  75. package/src/engine/physics/cloth/ecs/ClothHold.js +103 -0
  76. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +254 -48
  77. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  78. package/src/engine/physics/cloth/ecs/ClothInstance.js +277 -47
  79. package/src/engine/physics/cloth/ecs/ClothPin.d.ts +73 -0
  80. package/src/engine/physics/cloth/ecs/ClothPin.d.ts.map +1 -0
  81. package/src/engine/physics/cloth/ecs/ClothPin.js +92 -0
  82. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts +36 -0
  83. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts.map +1 -0
  84. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.js +61 -0
  85. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +23 -17
  86. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
  87. package/src/engine/physics/cloth/ecs/ClothRig.js +29 -27
  88. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +12 -14
  89. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  90. package/src/engine/physics/cloth/ecs/ClothSystem.js +20 -15
  91. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +57 -36
  92. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  93. package/src/engine/physics/cloth/ecs/ClothWorld.js +816 -179
  94. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +12 -13
  95. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
  96. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +20 -14
  97. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +63 -11
  98. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  99. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +321 -84
  100. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +9 -7
  101. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  102. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +9 -7
  103. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +3 -3
  104. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +30 -30
  105. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +37 -0
  106. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -0
  107. package/src/engine/physics/cloth/ecs/cloth_geodesic.js +142 -0
  108. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts +97 -0
  109. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -0
  110. package/src/engine/physics/cloth/ecs/cloth_holds.js +608 -0
  111. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +2 -2
  112. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
  113. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +160 -9
  114. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +17 -22
  115. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  116. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +55 -117
  117. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -6
  118. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  119. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +44 -15
  120. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +5 -0
  121. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  122. package/src/engine/physics/cloth/ecs/cloth_write_back.js +60 -16
  123. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
  124. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +65 -58
  125. package/src/engine/physics/cloth/playground/collide_main.js +1 -1
  126. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
  127. package/src/engine/physics/cloth/playground/garment_build.js +17 -5
  128. package/src/engine/physics/cloth/playground/garment_main.js +1 -1
  129. package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -1
  130. package/src/engine/physics/cloth/playground/rig_build.js +302 -296
  131. package/src/engine/physics/cloth/solver/ClothState.d.ts +45 -7
  132. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  133. package/src/engine/physics/cloth/solver/ClothState.js +63 -7
  134. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +6 -1
  135. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  136. package/src/engine/physics/cloth/solver/cloth_contact_find.js +7 -2
  137. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts +114 -0
  138. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -0
  139. package/src/engine/physics/cloth/solver/cloth_hold_line.js +362 -0
  140. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +6 -2
  141. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  142. package/src/engine/physics/cloth/solver/cloth_self_find.js +13 -13
  143. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +24 -12
  144. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  145. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +24 -12
  146. package/src/engine/physics/cloth/solver/cloth_step.d.ts +16 -0
  147. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  148. package/src/engine/physics/cloth/solver/cloth_step.js +183 -20
  149. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +1 -0
  150. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  151. package/src/engine/physics/cloth/solver/cloth_step_instance.js +10 -3
  152. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +1 -1
  153. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -1
  154. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +353 -346
  155. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +7 -5
  156. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
  157. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +7 -5
  158. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +9 -9
  159. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
  160. package/src/engine/physics/cloth/wind/cloth_sample_air.js +26 -26
  161. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  162. package/src/engine/simulation/Ticker.d.ts +13 -0
  163. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  164. package/src/engine/simulation/Ticker.js +43 -8
  165. package/src/shade/RENDERER_CONTRACT.md +8 -2
  166. package/src/shade/playground/mesh_row_ceiling/main.js +2 -1
  167. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  168. package/src/shade/playground/skinned_blas_refit/main.js +11 -19
  169. package/src/shade/playground/skinned_blas_refit/place_character.d.ts +6 -3
  170. package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
  171. package/src/shade/playground/skinned_blas_refit/place_character.js +90 -90
  172. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  173. package/src/shade/playground/skinned_mesh_soup/main.js +502 -509
  174. package/src/shade/playground/texture_encode/README.md +129 -109
  175. package/src/shade/playground/texture_encode/main.js +1430 -1430
  176. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +45 -14
  177. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  178. package/src/shade/renderer/animation/GPUAnimationManager.js +316 -64
  179. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +5 -0
  180. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  181. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -1
  182. package/src/shade/renderer/geometry/BoxGeometry.d.ts +1 -11
  183. package/src/shade/renderer/geometry/BoxGeometry.d.ts.map +1 -1
  184. package/src/shade/renderer/geometry/BoxGeometry.js +6 -13
  185. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts +19 -0
  186. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts.map +1 -0
  187. package/src/shade/renderer/geometry/CapsuleGeometry.js +24 -0
  188. package/src/shade/renderer/geometry/ConeGeometry.d.ts +20 -0
  189. package/src/shade/renderer/geometry/ConeGeometry.d.ts.map +1 -0
  190. package/src/shade/renderer/geometry/ConeGeometry.js +33 -0
  191. package/src/shade/renderer/geometry/CylinderGeometry.d.ts +21 -0
  192. package/src/shade/renderer/geometry/CylinderGeometry.d.ts.map +1 -0
  193. package/src/shade/renderer/geometry/CylinderGeometry.js +35 -0
  194. package/src/shade/renderer/geometry/PlaneGeometry.d.ts +17 -0
  195. package/src/shade/renderer/geometry/PlaneGeometry.d.ts.map +1 -0
  196. package/src/shade/renderer/geometry/PlaneGeometry.js +22 -0
  197. package/src/shade/renderer/geometry/TorusGeometry.d.ts +18 -0
  198. package/src/shade/renderer/geometry/TorusGeometry.d.ts.map +1 -0
  199. package/src/shade/renderer/geometry/TorusGeometry.js +23 -0
  200. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts +21 -0
  201. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts.map +1 -0
  202. package/src/shade/renderer/geometry/UVSphereGeometry.js +34 -0
  203. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts +19 -0
  204. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts.map +1 -0
  205. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.js +205 -0
  206. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts +21 -0
  207. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts.map +1 -0
  208. package/src/shade/renderer/geometry/primitives/make_cone_geometry.js +36 -0
  209. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts +1 -1
  210. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts.map +1 -1
  211. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +44 -9
  212. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts +20 -0
  213. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts.map +1 -0
  214. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.js +190 -0
  215. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  216. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +7 -2
  217. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +26 -8
  218. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  219. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +56 -39
  220. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts +7 -0
  221. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts.map +1 -1
  222. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js +46 -4
  223. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.d.ts.map +1 -1
  224. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.js +4 -2
  225. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +2 -2
  226. package/src/shade/renderer/gpu_primitive/sort/defs.js +79 -79
  227. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +1 -1
  228. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  229. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +7 -3
  230. package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
  231. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -3
  232. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
  233. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +200 -194
  234. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  235. package/src/shade/renderer/particles/graph_particles.js +6 -2
  236. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
  237. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +334 -329
  238. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  239. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +7 -2
  240. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  241. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +16 -4
  242. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +2444 -2345
  243. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.d.ts.map +1 -1
  244. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.js +312 -310
  245. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts +3 -3
  246. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts.map +1 -1
  247. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.js +383 -375
  248. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.d.ts.map +1 -1
  249. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.js +349 -346
  250. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts +58 -0
  251. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts.map +1 -0
  252. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.js +536 -0
  253. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts +21 -7
  254. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts.map +1 -1
  255. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js +291 -327
  256. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts +25 -0
  257. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts.map +1 -0
  258. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.js +99 -0
  259. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts +5 -3
  260. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts.map +1 -1
  261. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.js +47 -71
  262. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts +10 -0
  263. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts.map +1 -0
  264. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.js +50 -0
  265. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts +4 -5
  266. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts.map +1 -1
  267. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.js +7 -8
  268. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  269. package/src/shade/renderer/water/chunk_water_transport.js +7 -5
  270. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  271. package/src/shade/renderer/water/medium/GPUWaterBodies.js +8 -2
  272. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +3 -2
  273. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  274. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +3 -2
  275. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  276. package/src/shade/renderer/water/shader_water.js +3 -1
  277. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
  278. package/src/shade/renderer/water/surface/GPUWaterSurface.js +3 -1
  279. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
  280. package/src/shade/renderer/water/surface/graph_water_tessellation.js +11 -4
  281. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
  282. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +37 -20
  283. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  284. package/src/shade/wgsl/validate_wgsl_source.js +74 -3
  285. package/src/engine/graphics3/register_instance_animation.d.ts +0 -114
  286. package/src/engine/graphics3/register_instance_animation.d.ts.map +0 -1
  287. package/src/engine/graphics3/register_instance_animation.js +0 -201
@@ -0,0 +1,362 @@
1
+ import { cloth_backstop_accumulate } from "./constraint/cloth_backstop_row.js";
2
+ import { cloth_contact_accumulate } from "./constraint/cloth_contact_row.js";
3
+ import { cloth_leash_accumulate } from "./constraint/cloth_leash_row.js";
4
+ import {
5
+ CVA_F_X,
6
+ CVA_F_Y,
7
+ CVA_F_Z,
8
+ CVA_H_XX,
9
+ CVA_H_XY,
10
+ CVA_H_XZ,
11
+ CVA_H_YY,
12
+ CVA_H_YZ,
13
+ CVA_H_ZZ,
14
+ CVA_STRIDE,
15
+ CVA_TRUST
16
+ } from "./cloth_vertex_accumulator.js";
17
+
18
+ /**
19
+ * # The turn about a hold line — one more block of the descent
20
+ *
21
+ * VBD is block coordinate descent on the step's energy, one 3×3 block per
22
+ * particle. A cloth whose held particles lie on one line has a motion no such
23
+ * block can make: turning the whole cloth about that line as a rigid body. Every
24
+ * internal row is unchanged by it — its ends turn together, or one of them is on
25
+ * the axis — so the only parts of the energy that see the turn are the inertial
26
+ * term and the rows measured from outside the cloth. When the line is vertical
27
+ * nothing outside restores it either, because gravity is parallel to the axis.
28
+ *
29
+ * A vertex update moves one particle, so every update adds `x_i × m·Δx_i` of
30
+ * angular momentum about the line, and the step stopped at a fabric's iteration
31
+ * count leaves a residual whose moment about it is not zero. The warm start keeps
32
+ * a quarter of each hard multiplier (§5.2), so a cloth at rest re-solves three
33
+ * quarters of its weight every substep, is never a fixed point, and leaves that
34
+ * residual every substep. A flag on a pole turned at ten degrees a second for as
35
+ * long as it was run (PLAN §18, `MEASUREMENTS.md` §63).
36
+ *
37
+ * So the turn gets a block of its own: **one Newton step of the substep's energy
38
+ * along the rotation about the hold line**, then every free particle turned by
39
+ * the angle it gives. It is a descent step on the same energy as the vertex
40
+ * updates, so §5.3 is untouched, and it changes no row, multiplier or constant.
41
+ *
42
+ * ## What enters
43
+ *
44
+ * With `a` the line's unit direction, `r_i` a particle's offset from the line's
45
+ * origin and `t_i = a × r_i` its velocity under a unit turn, along the path
46
+ * `x_i(θ) = o + R(θ)·r_i`:
47
+ *
48
+ * g = dE/dθ = Σ t_i·∇E_i
49
+ * H = d²E/dθ² = Σ t_iᵀ·H_i·t_i + Σ ∇E_i·(a(a·r_i) − r_i)
50
+ * θ = −g/H
51
+ *
52
+ * - `∇E_i` and `H_i` are the vertex update's own assembly with the internal rows
53
+ * left out: the inertial term `(m/h²)(x − y)`, the leash rows, the backstop
54
+ * rows and the contacts. Stretch, bend and self-collision rows are invariant
55
+ * under the turn: a row's energy does not change along the path, so its share
56
+ * of `g` is zero and its two shares of `H` cancel, and leaving it out is
57
+ * leaving out a zero. A tether is invariant too, since it is measured from a
58
+ * held particle and that is on the axis, but it shares its accumulation with
59
+ * the slack row, which is not. It enters, and it can only shorten the step.
60
+ * - The last sum is the path's own curvature, `d²x/dθ² = −r⊥`. About a vertical
61
+ * axis gravity has no part in it and what is left is close to zero; about a
62
+ * horizontal one it is the pendulum's gravity stiffness. It is added only where
63
+ * it is positive, which keeps `H` at least the first sum, positive definite
64
+ * through the mass term: a step no longer than the one without it.
65
+ *
66
+ * ## When it runs
67
+ *
68
+ * When the held particles lie on one line **at this substep**, at two or more
69
+ * distinct points — a fact about the holds the predict already has in hand,
70
+ * since it carries every held particle. A single held point has three free turns
71
+ * and a cloth nothing holds has six; this block is the line's, and neither of
72
+ * those is handled here. It runs on a line gravity restores too, a horizontal
73
+ * one included, and there it has slowed some sleeps and kept one cloth awake
74
+ * (PLAN §18).
75
+ *
76
+ * It runs once a substep, in the **last** iteration, after the sweep and before
77
+ * that iteration's dual update. Run in every iteration it measured no better on
78
+ * a flag and cost 9–19% of a step rather than 3–9% (`MEASUREMENTS.md` §66).
79
+ *
80
+ * @author Alex Goldring
81
+ * @copyright Company Named Limited (c) 2026
82
+ */
83
+
84
+ /**
85
+ * How far a held particle may sit off the line and still be on it, as a
86
+ * fraction of the largest coordinate among the held particles.
87
+ *
88
+ * Relative, because what it separates is rounding from geometry, and rounding is
89
+ * a proportion of magnitude. Held positions are `Float32` and are carried through
90
+ * the step in double and stored again at each substep. A flag turned off every
91
+ * axis, whose hoist is straight in exact arithmetic, measured at most 6.3e-8 of
92
+ * its largest coordinate off its own line — half a unit in the last place —
93
+ * from the origin out to four kilometres. This is 240 times that, and 15 µm at a
94
+ * metre. `MEASUREMENTS.md` §66.
95
+ *
96
+ * @type {number}
97
+ */
98
+ export const CLOTH_HOLD_LINE_TOLERANCE = 2 ** -16;
99
+
100
+ /**
101
+ * Words of a hold line: the origin, then the unit direction.
102
+ * @type {number}
103
+ */
104
+ export const CLOTH_HOLD_LINE_WORDS = 6;
105
+
106
+ /**
107
+ * Whether the held particles lie on one line, and which: written to `line` as
108
+ * the origin then the unit direction.
109
+ *
110
+ * The origin is the first held particle and the direction runs to the one
111
+ * furthest from it, which spans at least half of the set. Every held particle is
112
+ * then measured off that line.
113
+ *
114
+ * @param {Float64Array} line out, {@link CLOTH_HOLD_LINE_WORDS}
115
+ * @param {Float32Array} position
116
+ * @param {Int32Array} held particle indices
117
+ * @param {number} held_count
118
+ * @returns {boolean} `false` when there are fewer than two distinct held points
119
+ * or they are not on one line; `line` is then not written
120
+ */
121
+ export function cloth_hold_line_fit(line, position, held, held_count) {
122
+ if (held_count < 2) {
123
+ return false;
124
+ }
125
+
126
+ const o = held[0] * 3;
127
+
128
+ const ox = position[o];
129
+ const oy = position[o + 1];
130
+ const oz = position[o + 2];
131
+
132
+ let scale = Math.max(Math.abs(ox), Math.abs(oy), Math.abs(oz));
133
+
134
+ let far = o;
135
+ let far_squared = 0;
136
+
137
+ for (let k = 1; k < held_count; k++) {
138
+ const p = held[k] * 3;
139
+
140
+ const x = position[p];
141
+ const y = position[p + 1];
142
+ const z = position[p + 2];
143
+
144
+ const size_x = Math.abs(x);
145
+ const size_y = Math.abs(y);
146
+ const size_z = Math.abs(z);
147
+
148
+ if (size_x > scale) {
149
+ scale = size_x;
150
+ }
151
+
152
+ if (size_y > scale) {
153
+ scale = size_y;
154
+ }
155
+
156
+ if (size_z > scale) {
157
+ scale = size_z;
158
+ }
159
+
160
+ const dx = x - ox;
161
+ const dy = y - oy;
162
+ const dz = z - oz;
163
+
164
+ const d_squared = dx * dx + dy * dy + dz * dz;
165
+
166
+ if (d_squared > far_squared) {
167
+ far_squared = d_squared;
168
+ far = p;
169
+ }
170
+ }
171
+
172
+ const tolerance = CLOTH_HOLD_LINE_TOLERANCE * scale;
173
+
174
+ const far_distance = Math.sqrt(far_squared);
175
+
176
+ if (!(far_distance > tolerance)) {
177
+ // One point, however many particles are held at it.
178
+ return false;
179
+ }
180
+
181
+ const inverse = 1 / far_distance;
182
+
183
+ const ax = (position[far] - ox) * inverse;
184
+ const ay = (position[far + 1] - oy) * inverse;
185
+ const az = (position[far + 2] - oz) * inverse;
186
+
187
+ const tolerance_squared = tolerance * tolerance;
188
+
189
+ for (let k = 1; k < held_count; k++) {
190
+ const p = held[k] * 3;
191
+
192
+ const rx = position[p] - ox;
193
+ const ry = position[p + 1] - oy;
194
+ const rz = position[p + 2] - oz;
195
+
196
+ const along = rx * ax + ry * ay + rz * az;
197
+
198
+ const qx = rx - along * ax;
199
+ const qy = ry - along * ay;
200
+ const qz = rz - along * az;
201
+
202
+ if (qx * qx + qy * qy + qz * qz > tolerance_squared) {
203
+ return false;
204
+ }
205
+ }
206
+
207
+ line[0] = ox;
208
+ line[1] = oy;
209
+ line[2] = oz;
210
+ line[3] = ax;
211
+ line[4] = ay;
212
+ line[5] = az;
213
+
214
+ return true;
215
+ }
216
+
217
+ /**
218
+ * Take one Newton step of the substep's energy along the turn about `line`, and
219
+ * turn every free particle by the angle it gives — see the module docblock.
220
+ *
221
+ * @param {ClothState} state
222
+ * @param {Float64Array} line from {@link cloth_hold_line_fit}
223
+ * @param {number} inverse_h_squared `1/h²` for the substep in progress
224
+ * @param {Float32Array|Float64Array|null} collider_table as the vertex update
225
+ * takes it; `null` skips the contact rows
226
+ * @returns {number} the angle turned, radians; `0` when there is nothing to turn
227
+ */
228
+ export function cloth_hold_line_turn(state, line, inverse_h_squared, collider_table) {
229
+ const particle_count = state.particle_count;
230
+
231
+ const position = state.position;
232
+ const inertial = state.inertial;
233
+ const mass_inverse = state.mass_inverse;
234
+
235
+ const ox = line[0];
236
+ const oy = line[1];
237
+ const oz = line[2];
238
+ const ax = line[3];
239
+ const ay = line[4];
240
+ const az = line[5];
241
+
242
+ const accumulator = ACCUMULATOR;
243
+
244
+ let gradient = 0;
245
+ let curvature = 0;
246
+ let path = 0;
247
+
248
+ for (let i = 0; i < particle_count; i++) {
249
+ const inverse_mass = mass_inverse[i];
250
+
251
+ if (inverse_mass === 0) {
252
+ continue;
253
+ }
254
+
255
+ const p = i * 3;
256
+
257
+ const x = position[p];
258
+ const y = position[p + 1];
259
+ const z = position[p + 2];
260
+
261
+ const rx = x - ox;
262
+ const ry = y - oy;
263
+ const rz = z - oz;
264
+
265
+ const tx = ay * rz - az * ry;
266
+ const ty = az * rx - ax * rz;
267
+ const tz = ax * ry - ay * rx;
268
+
269
+ // The vertex update's assembly, seeded the same way, with only the rows
270
+ // the turn can see.
271
+ const mass_over_h_squared = inverse_h_squared / inverse_mass;
272
+
273
+ accumulator[CVA_F_X] = -mass_over_h_squared * (x - inertial[p]);
274
+ accumulator[CVA_F_Y] = -mass_over_h_squared * (y - inertial[p + 1]);
275
+ accumulator[CVA_F_Z] = -mass_over_h_squared * (z - inertial[p + 2]);
276
+
277
+ accumulator[CVA_H_XX] = mass_over_h_squared;
278
+ accumulator[CVA_H_YY] = mass_over_h_squared;
279
+ accumulator[CVA_H_ZZ] = mass_over_h_squared;
280
+ accumulator[CVA_H_XY] = 0;
281
+ accumulator[CVA_H_XZ] = 0;
282
+ accumulator[CVA_H_YZ] = 0;
283
+ accumulator[CVA_TRUST] = Infinity;
284
+
285
+ cloth_leash_accumulate(accumulator, state, i);
286
+ cloth_backstop_accumulate(accumulator, state, i);
287
+
288
+ if (collider_table !== null) {
289
+ cloth_contact_accumulate(accumulator, state, i, collider_table);
290
+ }
291
+
292
+ // `f = −∇E_i`
293
+ const fx = accumulator[CVA_F_X];
294
+ const fy = accumulator[CVA_F_Y];
295
+ const fz = accumulator[CVA_F_Z];
296
+
297
+ gradient -= tx * fx + ty * fy + tz * fz;
298
+
299
+ const h_xx = accumulator[CVA_H_XX];
300
+ const h_yy = accumulator[CVA_H_YY];
301
+ const h_zz = accumulator[CVA_H_ZZ];
302
+ const h_xy = accumulator[CVA_H_XY];
303
+ const h_xz = accumulator[CVA_H_XZ];
304
+ const h_yz = accumulator[CVA_H_YZ];
305
+
306
+ curvature += tx * (h_xx * tx + h_xy * ty + h_xz * tz)
307
+ + ty * (h_xy * tx + h_yy * ty + h_yz * tz)
308
+ + tz * (h_xz * tx + h_yz * ty + h_zz * tz);
309
+
310
+ // `∇E_i·(a(a·r) − r)`, which is `f·r⊥`
311
+ const along = ax * rx + ay * ry + az * rz;
312
+
313
+ path += fx * (rx - along * ax) + fy * (ry - along * ay) + fz * (rz - along * az);
314
+ }
315
+
316
+ if (path > 0) {
317
+ curvature += path;
318
+ }
319
+
320
+ if (!(curvature > 0)) {
321
+ // Every free particle is on the axis: there is no turn to take.
322
+ return 0;
323
+ }
324
+
325
+ const theta = -gradient / curvature;
326
+
327
+ if (theta === 0) {
328
+ return 0;
329
+ }
330
+
331
+ // Rodrigues, about the line through `o`.
332
+ const cos = Math.cos(theta);
333
+ const sin = Math.sin(theta);
334
+ const versine = 1 - cos;
335
+
336
+ for (let i = 0; i < particle_count; i++) {
337
+ if (mass_inverse[i] === 0) {
338
+ continue;
339
+ }
340
+
341
+ const p = i * 3;
342
+
343
+ const rx = position[p] - ox;
344
+ const ry = position[p + 1] - oy;
345
+ const rz = position[p + 2] - oz;
346
+
347
+ const along = (ax * rx + ay * ry + az * rz) * versine;
348
+
349
+ position[p] = ox + rx * cos + (ay * rz - az * ry) * sin + ax * along;
350
+ position[p + 1] = oy + ry * cos + (az * rx - ax * rz) * sin + ay * along;
351
+ position[p + 2] = oz + rz * cos + (ax * ry - ay * rx) * sin + az * along;
352
+ }
353
+
354
+ return theta;
355
+ }
356
+
357
+ /**
358
+ * The `(f, H)` scratch, laid out as the vertex update's. Module-level and reused.
359
+ * @type {Float64Array}
360
+ * @private
361
+ */
362
+ const ACCUMULATOR = new Float64Array(CVA_STRIDE);
@@ -28,8 +28,12 @@ export function cloth_self_exclusions(state: ClothState): {
28
28
  * measured left the settled cape with three permanently active pairs.
29
29
  * `MEASUREMENTS.md` §37.
30
30
  *
31
- * Pinned particles are skipped, exactly as {@link cloth_self_find} skips them,
32
- * so this measures the pairs the row can actually act on and nothing else.
31
+ * **Every particle is measured, held or not.** Which particles are held changes
32
+ * while a cloth runs — a hand lets go, a hook catches — and this is measured
33
+ * once, when the rows are built; a ceiling that left out the particles held at
34
+ * that moment would be too generous for the cloth once they were let go, which
35
+ * is §36's permanently active pair. {@link cloth_self_find} pairs a held
36
+ * particle with a free one for the same reason.
33
37
  *
34
38
  * @param {ClothState} state
35
39
  * @param {{offset: Int32Array, partner: Int32Array}} exclusions from {@link cloth_self_exclusions}
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_self_find.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_self_find.js"],"names":[],"mappings":"AA4DA;;;;;GAKG;AACH,0DAFa;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAC,CA0DrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,4EANW;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAC,UACzC,MAAM,GAGJ,MAAM,CAoHlB;AAED;;;;;;GAMG;AACH,+DAHW;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAC,GACvC,MAAM,CAyJlB;AA1aD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,4CAFU,MAAM,CAE+B"}
1
+ {"version":3,"file":"cloth_self_find.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_self_find.js"],"names":[],"mappings":"AA4DA;;;;;GAKG;AACH,0DAFa;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAC,CA0DrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,4EANW;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAC,UACzC,MAAM,GAGJ,MAAM,CAgHlB;AAED;;;;;;GAMG;AACH,+DAHW;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAC,GACvC,MAAM,CAyJlB;AA1aD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,4CAFU,MAAM,CAE+B"}
@@ -142,8 +142,12 @@ export function cloth_self_exclusions(state) {
142
142
  * measured left the settled cape with three permanently active pairs.
143
143
  * `MEASUREMENTS.md` §37.
144
144
  *
145
- * Pinned particles are skipped, exactly as {@link cloth_self_find} skips them,
146
- * so this measures the pairs the row can actually act on and nothing else.
145
+ * **Every particle is measured, held or not.** Which particles are held changes
146
+ * while a cloth runs — a hand lets go, a hook catches — and this is measured
147
+ * once, when the rows are built; a ceiling that left out the particles held at
148
+ * that moment would be too generous for the cloth once they were let go, which
149
+ * is §36's permanently active pair. {@link cloth_self_find} pairs a held
150
+ * particle with a free one for the same reason.
147
151
  *
148
152
  * @param {ClothState} state
149
153
  * @param {{offset: Int32Array, partner: Int32Array}} exclusions from {@link cloth_self_exclusions}
@@ -179,10 +183,6 @@ export function cloth_self_closest_free_pair(state, exclusions, search) {
179
183
  let closest_squared = search * search;
180
184
 
181
185
  for (let i = 0; i < particle_count; i++) {
182
- if (mass_inverse[i] === 0) {
183
- continue;
184
- }
185
-
186
186
  const a = i * 3;
187
187
 
188
188
  const x = position[a];
@@ -224,7 +224,7 @@ export function cloth_self_closest_free_pair(state, exclusions, search) {
224
224
  for (let at = grid_offset[bucket]; at < end; at++) {
225
225
  const j = grid_point[at];
226
226
 
227
- if (j <= i || mass_inverse[j] === 0) {
227
+ if (j <= i) {
228
228
  continue;
229
229
  }
230
230
 
@@ -308,11 +308,11 @@ export function cloth_self_find(state, exclusions) {
308
308
  const radius_squared = radius * radius;
309
309
 
310
310
  for (let i = 0; i < particle_count; i++) {
311
- if (mass_inverse[i] === 0) {
312
- // A pinned particle cannot be pushed, so a pair on it is a force
313
- // assembled and thrown away for one end and doubled for the other.
314
- continue;
315
- }
311
+ // A held particle is paired with free ones and not with another held
312
+ // one: it cannot be pushed, but it can be carried through the fabric —
313
+ // a grabbed corner swept across the sheet — and the free end of the
314
+ // pair is what has to get out of its way.
315
+ const i_held = mass_inverse[i] === 0;
316
316
 
317
317
  const a = i * 3;
318
318
 
@@ -365,7 +365,7 @@ export function cloth_self_find(state, exclusions) {
365
365
  continue;
366
366
  }
367
367
 
368
- if (mass_inverse[j] === 0) {
368
+ if (i_held && mass_inverse[j] === 0) {
369
369
  continue;
370
370
  }
371
371
 
@@ -145,18 +145,30 @@ export const CLOTH_CONTACT_K_MIN_RATIO: number;
145
145
  * sees anything of the kind: what it holds apart weighs grams and is moving at
146
146
  * the speed cloth moves relative to itself.
147
147
  *
148
- * **Eight, and the dissipative band is not the reason.** Eight is where M0's
149
- * band tops out and it would be natural to read this as the same ceiling, but
150
- * `MEASUREMENTS.md` §32 swept the ratio from 1 to 64 and found no energy growth
151
- * anywhere: the band was measured on rows that are *on every step*, and a
152
- * one-sided row that vanishes the instant it is satisfied has no standing spring
153
- * to pump. What picks eight is the crossing count — it is the joint minimum of
154
- * the mean, and a stiffer row makes the *worst* case steadily worse by throwing
155
- * a particle hard enough to put the sheet through itself elsewhere.
156
- *
157
- * The consequence is a row with no multiplier, no warm start and no identity
158
- * across steps, which is what makes rebuilding the pair list from scratch every
159
- * step affordable. `MEASUREMENTS.md` §33.
148
+ * **Two: the stiffest ratio at which cloth resting on itself comes to rest.**
149
+ * The ratio trades two measured things against each other.
150
+ *
151
+ * - **A stiffer row passes through itself less while the cloth moves.** On
152
+ * §32's folding sheet, over 48 gusts, silk, cotton, hair and a sheet with no
153
+ * bending average 2.09 crossings a sample at 8, 2.98 at 2 and 3.74 at 1,
154
+ * against 9.17 with no row. That is why §32 shipped 8.
155
+ * - **A pair that carries weight is a spring that is on every step**, which is
156
+ * the case M0's dissipative band was measured on. §32's sheet never had one,
157
+ * because its contacts come and go, so its "no energy growth anywhere" held
158
+ * only for that sheet. A fold resting on a fold has one. At 8, piles of
159
+ * ribbons, a sheet draped on a sphere and a skirt after a twirl never sleep,
160
+ * and piles reach 3.8 times the speed their drop could give them (§64).
161
+ *
162
+ * At 2 all three sleep. Of 225 ribbon piles in three fabrics, 135 land without
163
+ * passing through themselves and 134 of those come to rest. At 4, five of 38
164
+ * clean silk piles never do. The draped sheet sleeps by step 386 at every
165
+ * ratio up to 2.25 and is erratic above it, never sleeping at 5 or 8. Below 2
166
+ * the folding sheet only gets worse, and more piles land through themselves.
167
+ * The library bench cannot tell 2 from 8. `MEASUREMENTS.md` §65.
168
+ *
169
+ * It stays a plain penalty: no multiplier, no warm start and no identity across
170
+ * steps, which is what makes rebuilding the pair list from scratch every step
171
+ * affordable. `MEASUREMENTS.md` §33.
160
172
  * @type {number}
161
173
  */
162
174
  export const CLOTH_SELF_RATIO: number;
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_solver_constants.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_solver_constants.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AAEH;;;GAGG;AACH,0BAFU,MAAM,CAEgB;AAEhC;;;;GAIG;AACH,yBAFU,MAAM,CAEc;AAE9B;;;GAGG;AACH,0BAFU,MAAM,CAEa;AAE7B;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wCAFU,MAAM,CAE8B;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,+BAFU,MAAM,CAEkB;AAElC;;;;;;;;;GASG;AACH,0CAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,0CAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,mCAFU,MAAM,CAEuB;AAEvC;;;;GAIG;AACH,kCAFU,SAAS;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,CAAC,CAQvG"}
1
+ {"version":3,"file":"cloth_solver_constants.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_solver_constants.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AAEH;;;GAGG;AACH,0BAFU,MAAM,CAEgB;AAEhC;;;;GAIG;AACH,yBAFU,MAAM,CAEc;AAE9B;;;GAGG;AACH,0BAFU,MAAM,CAEa;AAE7B;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wCAFU,MAAM,CAE8B;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,+BAFU,MAAM,CAEkB;AAElC;;;;;;;;;GASG;AACH,0CAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,0CAFU,MAAM,CAE+B;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,mCAFU,MAAM,CAEuB;AAEvC;;;;GAIG;AACH,kCAFU,SAAS;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,CAAC,CAQvG"}
@@ -152,21 +152,33 @@ export const CLOTH_CONTACT_K_MIN_RATIO = 0.25;
152
152
  * sees anything of the kind: what it holds apart weighs grams and is moving at
153
153
  * the speed cloth moves relative to itself.
154
154
  *
155
- * **Eight, and the dissipative band is not the reason.** Eight is where M0's
156
- * band tops out and it would be natural to read this as the same ceiling, but
157
- * `MEASUREMENTS.md` §32 swept the ratio from 1 to 64 and found no energy growth
158
- * anywhere: the band was measured on rows that are *on every step*, and a
159
- * one-sided row that vanishes the instant it is satisfied has no standing spring
160
- * to pump. What picks eight is the crossing count — it is the joint minimum of
161
- * the mean, and a stiffer row makes the *worst* case steadily worse by throwing
162
- * a particle hard enough to put the sheet through itself elsewhere.
155
+ * **Two: the stiffest ratio at which cloth resting on itself comes to rest.**
156
+ * The ratio trades two measured things against each other.
163
157
  *
164
- * The consequence is a row with no multiplier, no warm start and no identity
165
- * across steps, which is what makes rebuilding the pair list from scratch every
166
- * step affordable. `MEASUREMENTS.md` §33.
158
+ * - **A stiffer row passes through itself less while the cloth moves.** On
159
+ * §32's folding sheet, over 48 gusts, silk, cotton, hair and a sheet with no
160
+ * bending average 2.09 crossings a sample at 8, 2.98 at 2 and 3.74 at 1,
161
+ * against 9.17 with no row. That is why §32 shipped 8.
162
+ * - **A pair that carries weight is a spring that is on every step**, which is
163
+ * the case M0's dissipative band was measured on. §32's sheet never had one,
164
+ * because its contacts come and go, so its "no energy growth anywhere" held
165
+ * only for that sheet. A fold resting on a fold has one. At 8, piles of
166
+ * ribbons, a sheet draped on a sphere and a skirt after a twirl never sleep,
167
+ * and piles reach 3.8 times the speed their drop could give them (§64).
168
+ *
169
+ * At 2 all three sleep. Of 225 ribbon piles in three fabrics, 135 land without
170
+ * passing through themselves and 134 of those come to rest. At 4, five of 38
171
+ * clean silk piles never do. The draped sheet sleeps by step 386 at every
172
+ * ratio up to 2.25 and is erratic above it, never sleeping at 5 or 8. Below 2
173
+ * the folding sheet only gets worse, and more piles land through themselves.
174
+ * The library bench cannot tell 2 from 8. `MEASUREMENTS.md` §65.
175
+ *
176
+ * It stays a plain penalty: no multiplier, no warm start and no identity across
177
+ * steps, which is what makes rebuilding the pair list from scratch every step
178
+ * affordable. `MEASUREMENTS.md` §33.
167
179
  * @type {number}
168
180
  */
169
- export const CLOTH_SELF_RATIO = 8;
181
+ export const CLOTH_SELF_RATIO = 2;
170
182
 
171
183
  /**
172
184
  * Smallest radius a self-collision row is written at, as a multiple of the
@@ -11,6 +11,7 @@
11
11
  * warm start λ ← λ·α·γ ; k ← clamp(k·γ, k_min, k_max) (hard rows only)
12
12
  * iterate × iterations:
13
13
  * for each colour: for each particle: vertex update
14
+ * last iteration, held particles on one line: turn about it
14
15
  * dual update: λ ← clamp(k·C + λ, f_min, f_max)
15
16
  * k ← min(k + β·|C|, min(k_max, stiffness))
16
17
  * integrate v = (x − x_prev)/h
@@ -54,6 +55,21 @@
54
55
  * which is what makes "no wind produces the bytes M5 measured" a fact about the
55
56
  * code rather than a claim about floating point.
56
57
  *
58
+ * ## One more block when the holds are a line
59
+ *
60
+ * Every vertex update is a 3×3 block of the descent, and a cloth held along one
61
+ * line has a motion no such block can make: turning about the line as a rigid
62
+ * body. About a vertical line nothing restores that turn, and the step stopped
63
+ * at a fabric's iteration count left a moment about it every substep — a flag
64
+ * turned on its pole for as long as it was run. So the turn is a block of its
65
+ * own, `cloth_hold_line.js`: one Newton step along it, in the last iteration,
66
+ * after the sweep and before the dual update.
67
+ *
68
+ * Whether the held particles are on a line is decided at every substep, from
69
+ * where the predict has just carried them. The predict lists them as it goes,
70
+ * so the question costs a pass over the held particles rather than over the
71
+ * cloth.
72
+ *
57
73
  * ## What each piece is for
58
74
  *
59
75
  * **Warm start** carries the multipliers into the next substep so a hard row
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_step.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_step.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgHG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,kDAfW,MAAM,kBACN,MAAM,kBAEN,MAAM,kBACN,MAAM,YACN,MAAM,cACN,MAAM,mBACN,YAAY,GAAC,YAAY,GAAC,IAAI,mBAE9B,MAAM,WACN;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAC,aAC3G,YAAY,GAAC,IAAI,QAsG3B"}
1
+ {"version":3,"file":"cloth_step.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_step.js"],"names":[],"mappings":"AAgCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgIG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,kDAfW,MAAM,kBACN,MAAM,kBAEN,MAAM,kBACN,MAAM,YACN,MAAM,cACN,MAAM,mBACN,YAAY,GAAC,YAAY,GAAC,IAAI,mBAE9B,MAAM,WACN;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAC,aAC3G,YAAY,GAAC,IAAI,QAkI3B"}