@woosh/meep-engine 3.42.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 (345) hide show
  1. package/editor/prototypeEditorShell.d.ts.map +1 -1
  2. package/editor/prototypeEditorShell.js +4 -2
  3. package/package.json +91 -96
  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/playground/vgeo_runtime/README.md +5 -4
  177. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  178. package/src/shade/renderer/Renderer.js +6 -5
  179. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +45 -14
  180. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  181. package/src/shade/renderer/animation/GPUAnimationManager.js +316 -64
  182. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +5 -0
  183. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  184. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -1
  185. package/src/shade/renderer/atmosphere/GPUSky.d.ts +12 -0
  186. package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
  187. package/src/shade/renderer/atmosphere/GPUSky.js +162 -147
  188. package/src/shade/renderer/geometry/BoxGeometry.d.ts +1 -11
  189. package/src/shade/renderer/geometry/BoxGeometry.d.ts.map +1 -1
  190. package/src/shade/renderer/geometry/BoxGeometry.js +6 -13
  191. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts +19 -0
  192. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts.map +1 -0
  193. package/src/shade/renderer/geometry/CapsuleGeometry.js +24 -0
  194. package/src/shade/renderer/geometry/ConeGeometry.d.ts +20 -0
  195. package/src/shade/renderer/geometry/ConeGeometry.d.ts.map +1 -0
  196. package/src/shade/renderer/geometry/ConeGeometry.js +33 -0
  197. package/src/shade/renderer/geometry/CylinderGeometry.d.ts +21 -0
  198. package/src/shade/renderer/geometry/CylinderGeometry.d.ts.map +1 -0
  199. package/src/shade/renderer/geometry/CylinderGeometry.js +35 -0
  200. package/src/shade/renderer/geometry/PlaneGeometry.d.ts +17 -0
  201. package/src/shade/renderer/geometry/PlaneGeometry.d.ts.map +1 -0
  202. package/src/shade/renderer/geometry/PlaneGeometry.js +22 -0
  203. package/src/shade/renderer/geometry/TorusGeometry.d.ts +18 -0
  204. package/src/shade/renderer/geometry/TorusGeometry.d.ts.map +1 -0
  205. package/src/shade/renderer/geometry/TorusGeometry.js +23 -0
  206. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts +21 -0
  207. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts.map +1 -0
  208. package/src/shade/renderer/geometry/UVSphereGeometry.js +34 -0
  209. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts +19 -0
  210. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts.map +1 -0
  211. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.js +205 -0
  212. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts +21 -0
  213. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts.map +1 -0
  214. package/src/shade/renderer/geometry/primitives/make_cone_geometry.js +36 -0
  215. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts +1 -1
  216. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts.map +1 -1
  217. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +44 -9
  218. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts +20 -0
  219. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts.map +1 -0
  220. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.js +190 -0
  221. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  222. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +7 -2
  223. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +26 -8
  224. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  225. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +56 -39
  226. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts +7 -0
  227. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts.map +1 -1
  228. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js +46 -4
  229. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.d.ts.map +1 -1
  230. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.js +4 -2
  231. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +2 -2
  232. package/src/shade/renderer/gpu_primitive/sort/defs.js +79 -79
  233. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +1 -1
  234. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  235. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +7 -3
  236. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.d.ts.map +1 -1
  237. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +10 -3
  238. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  239. package/src/shade/renderer/particles/DESIGN.md +13 -9
  240. package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
  241. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -3
  242. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
  243. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +200 -194
  244. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  245. package/src/shade/renderer/particles/graph_particles.js +6 -2
  246. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +1 -1
  247. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +1 -1
  248. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
  249. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +334 -329
  250. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  251. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  252. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +7 -2
  253. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  254. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +16 -4
  255. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +3 -2
  256. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  257. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +3 -2
  258. package/src/shade/renderer/scene/GPUSceneContext.d.ts +9 -1
  259. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  260. package/src/shade/renderer/scene/GPUSceneContext.js +23 -1
  261. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +2444 -2345
  262. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.d.ts.map +1 -1
  263. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.js +312 -310
  264. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts +3 -3
  265. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts.map +1 -1
  266. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.js +383 -375
  267. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.d.ts.map +1 -1
  268. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.js +349 -346
  269. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts +58 -0
  270. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts.map +1 -0
  271. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.js +536 -0
  272. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts +21 -7
  273. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts.map +1 -1
  274. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js +291 -327
  275. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts +25 -0
  276. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts.map +1 -0
  277. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.js +99 -0
  278. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts +5 -3
  279. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts.map +1 -1
  280. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.js +47 -71
  281. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts +10 -0
  282. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts.map +1 -0
  283. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.js +50 -0
  284. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts +4 -5
  285. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts.map +1 -1
  286. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.js +7 -8
  287. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +4 -1
  288. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  289. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +74 -3
  290. package/src/shade/renderer/volumetrics/NOTES.md +1023 -957
  291. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts +5 -4
  292. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts.map +1 -1
  293. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.js +5 -4
  294. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +1 -1
  295. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +1 -1
  296. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +1 -1
  297. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +1 -1
  298. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +41 -0
  299. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -0
  300. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +112 -0
  301. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +9 -23
  302. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  303. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +18 -126
  304. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +22 -0
  305. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +1 -0
  306. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +228 -0
  307. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  308. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +0 -53
  309. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  310. package/src/shade/renderer/water/chunk_water_transport.js +7 -5
  311. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  312. package/src/shade/renderer/water/medium/GPUWaterBodies.js +8 -2
  313. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +3 -2
  314. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  315. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +3 -2
  316. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  317. package/src/shade/renderer/water/shader_water.js +3 -1
  318. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
  319. package/src/shade/renderer/water/surface/GPUWaterSurface.js +3 -1
  320. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +4 -3
  321. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -1
  322. package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +17 -7
  323. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
  324. package/src/shade/renderer/water/surface/graph_water_tessellation.js +11 -4
  325. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
  326. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +93 -30
  327. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts.map +1 -1
  328. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js +13 -5
  329. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts +29 -8
  330. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -1
  331. package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +155 -30
  332. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts +6 -1
  333. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -1
  334. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +157 -39
  335. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts +91 -21
  336. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts.map +1 -1
  337. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +442 -70
  338. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +11 -3
  339. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  340. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +3 -0
  341. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  342. package/src/shade/wgsl/validate_wgsl_source.js +74 -3
  343. package/src/engine/graphics3/register_instance_animation.d.ts +0 -114
  344. package/src/engine/graphics3/register_instance_animation.d.ts.map +0 -1
  345. package/src/engine/graphics3/register_instance_animation.js +0 -201
@@ -4114,3 +4114,798 @@ clip keying the cape carries it as its rest.
4114
4114
  is two disjoint ranges of one row, which the partial upload shader spec already
4115
4115
  lands under the emulator; and the worker path writes nothing after a release,
4116
4116
  because a join for a cloth unlinked or reseeded since its dispatch is dropped.
4117
+
4118
+ ## 62. Attachment points: holds instead of an anchor
4119
+
4120
+ M7 took the fixed set off the `Cloth` entity and gave it to `ClothPin`s (PLAN §19). Three
4121
+ commits before this one carry the parts that change no behaviour on their own: the rows from a
4122
+ particle graph, the solver's kinematic targets and sourced leash rows, and a rename. Every
4123
+ number below was taken on this machine with 23 other node processes running.
4124
+
4125
+ ### The design was reviewed before it was built
4126
+
4127
+ Three adversarial reviewers read the first draft against the code — the solver and the
4128
+ pathology budget, the ECS and the worker, the topology and the output. Their findings changed
4129
+ the design in these places, each folded into PLAN §19:
4130
+
4131
+ | Finding | Change | Measured or argued |
4132
+ |---|---|---|
4133
+ | Up to four hard tethers per particle, one per island (Chaos's rule), go infeasible when two holders separate past the fabric between them, and the idle slots cost a sqrt each per iteration | One tether, to the nearest held particle | argued; the cost is below |
4134
+ | A leash centre written once a step sits a step behind a held particle that moves inside the step | `leash_source` + offset, re-centred every substep | measured: `cloth_held.spec.js` |
4135
+ | `x += w·(T − x)` with `w = (i+1)/n` is not equal shares for `n ≥ 3` | `x += (T − x)/(n − i)` | measured: same spec, 1–4 substeps |
4136
+ | `slack = 0` times an unreachable particle's `d_geo = ∞` is NaN | radius `∞` where `d_geo` is; leash loops test `radius === ∞` first | measured: a zero-floor leash row went NaN on the previous solver |
4137
+ | A cloth a holder drags has no velocity, so contact discovery and the gather do not reach for what it is dragged into | `KINEMATIC_TRAVEL` in both reaches | measured: `cloth_held.spec.js` |
4138
+ | A hold taken mid-run switches on tethers the fabric already exceeds | tethers start at the larger of `d_geo` and where the particle is, and only come in | measured: catching a falling rope, no particle faster than it was falling |
4139
+ | Removing the frame particle costs every strand its first free link | the `Cloth` entity stays particle 0, held by a pin on itself | measured: equivalence below |
4140
+ | `Cloth` on a bone: transient, not found by `instance_of`, a GPU parent under the subtree path | `Cloth`/`ClothRig` stay on the model root; the rig's frame is a proxy joint | argued from the code |
4141
+ | A saved rope reloads without its pin and falls | `ClothPinSerializationAdapter` | measured: round trip |
4142
+ | Self-collision is blind to a held particle, and `closest_free_pair` goes stale on release | held–free pairs; the pair measured over every particle | measured: two specs rewritten red-to-green |
4143
+
4144
+ Kept against the review: the subtree's walk order as the particle numbering (a single chain is
4145
+ numbered by depth whatever the ids; a branching subtree's siblings ascend by entity id), and a
4146
+ hold beginning where its particle is.
4147
+
4148
+ ### What it costs
4149
+
4150
+ `bench_holds.mjs` (scratchpad): the previous build and this one in one process, each building the
4151
+ same rig through its own `ClothSystem`, the rope tops pinned in the new arm, a walk with a turn
4152
+ in it driving the frame every step, 400 warm-up frames then 2,000 measured, alternating which
4153
+ arm goes first.
4154
+
4155
+ | scene | min | p10 | median |
4156
+ |---|---|---|---|
4157
+ | 8 strips × 16, silk (129 particles) | 1.028 | 1.012 | 1.014 |
4158
+ | 32 strips × 32, rope (1,025) | 1.017 | 1.023 | 1.028 |
4159
+
4160
+ Before the per-step hold pass learned to skip when no holder had moved in the frame, the same
4161
+ rows read 1.046 / 1.046 / 1.032 and 1.055 / 1.052 / 1.062. What is left is the substep loop that
4162
+ re-centres sourced leash rows and the two leash rows the frame's own particle now carries.
4163
+
4164
+ ### It is the same cloth
4165
+
4166
+ `equiv_holds.mjs`: both arms stepped together, the worst particle-to-particle distance printed.
4167
+ A nudged copy of the previous build against itself (`chaos_control.mjs`, one particle moved
4168
+ 1e-7 m) is the control.
4169
+
4170
+ | step | M7 against the anchor | the anchor against itself, nudged |
4171
+ |---|---|---|
4172
+ | 1 | 1.9e-7 m | 1.3e-7 m |
4173
+ | 5 | 2.3e-6 | 4.6e-7 |
4174
+ | 10 | 1.3e-5 | 1.8e-5 |
4175
+ | 30 | 1.8e-2 | 1.6e-2 |
4176
+ | 60 | 1.9e-1 | 2.1e-1 |
4177
+
4178
+ The difference starts at rounding — stage one's row order and a geodesic summed in double — and
4179
+ grows exactly as fast as a nudge does in a rig driven this hard. Chaos, not a change.
4180
+
4181
+ ### One spec read the row order
4182
+
4183
+ Building the rows per kind rather than per node changed the order a particle's rows are summed
4184
+ in. `cloth_collision.spec.js`'s replaced-collider test then saw the particle it picks slide
4185
+ 14.7 mm in the step its contact is rediscovered, from a rope at rest (0.23 mm/s) — it had held
4186
+ the fresh friction anchor to half a millimetre. The defect it guards puts the anchor 700 mm off,
4187
+ so the tolerance is 50 mm. With the old row order restored the spec passed, so the slide is the
4188
+ order, not the graph.
4189
+
4190
+ ### Gates
4191
+
4192
+ Cloth suite 327 (from 297), slow 7, the whole physics suite 1,861, extended physics including the
4193
+ allocation budgets, `check-types` 18 against a budget of 19. The worker parity gate gained a run
4194
+ in which a second holder drags a rope's tip, lets go at step 80 and takes hold again at 160:
4195
+ bit-identical, every step, for 240.
4196
+
4197
+ ---
4198
+
4199
+ ## 63. Sheets: a proxy from triangles, and a flag that turns on its pole
4200
+
4201
+ The third stage of M7 (PLAN §19.5). `cloth_proxy_from_mesh` builds a proxy from a skin with one
4202
+ joint per vertex and the triangles over them, the rows take its hinges, and a joint with
4203
+ triangles round it is turned by its surface. The numbers below are from `cloth_sheet.spec.js`'s
4204
+ own scenes, with a probe printing what its assertions bound.
4205
+
4206
+ ### Every library fabric comes to rest on a sheet
4207
+
4208
+ A 6 × 6 sheet, 0.1 m apart, lying flat and held along one edge by a pin on a rail entity. It
4209
+ swings down about the held edge, which gravity restores.
4210
+
4211
+ | fabric | asleep at step | far edge dropped, of 0.5 m |
4212
+ |---|---|---|
4213
+ | silk | 568 | 0.50 |
4214
+ | cotton | 73 | 0.48 |
4215
+ | denim | 76 | 0.37 |
4216
+ | leather | 72 | 0.29 |
4217
+ | rope | 512 | 0.50 |
4218
+ | chain | 280 | 0.50 |
4219
+ | hair | 66 | 0.46 |
4220
+
4221
+ ### A flag on a pole does not, and it is the solver's
4222
+
4223
+ Stand the same sheet up and hold it along its hoist — a vertical column — on a pole. With three
4224
+ centimetres of curve across it, so that it buckles out of its plane rather than folding inside it
4225
+ (§7 P4), rope and chain never sleep inside 4,000 steps; silk, cotton, denim, leather and hair
4226
+ sleep at 1,261, 751, 572, 226 and 976.
4227
+
4228
+ It is not jitter. The flag turns about the pole as a rigid body, and its angular momentum about
4229
+ the pole, `Σ (r × v)·ŷ` per unit mass, holds to four figures from step 300 to step 3,000: −0.1894
4230
+ at rope's settings, about ten degrees a second. A turn about a vertical hold line is the one
4231
+ motion nothing restores — gravity is parallel to the axis, and every row either ends on it or is
4232
+ an equal and opposite pair — so the true answer is a flag that stays where it stops, and a
4233
+ steady turn is something the step puts there.
4234
+
4235
+ | rope on the flag, one change at a time | `Ly` at step 3,000 |
4236
+ |---|---|
4237
+ | as shipped: 2 × 4, `damping` 0.1 | −0.1894 |
4238
+ | `damping` 1 | −0.0203 |
4239
+ | no tethers (every radius ∞) | −0.1836 |
4240
+ | no tethers and no strain-limit row | −0.1757 |
4241
+ | no hinges (`bend` 0) | −0.2226 |
4242
+ | no curve | 0 — it folds in its own plane instead |
4243
+ | the curve mirrored | +0.1894 |
4244
+
4245
+ Ten times the damping rate is a tenth of the speed: a constant torque, balanced rather than
4246
+ removed. None of the rows M7 added carries it. On the solver directly — a `ClothState` of the
4247
+ flag's hard stretch rows and nothing else, the hoist at inverse mass zero, damping applied by
4248
+ hand between steps:
4249
+
4250
+ | iterations | held along a vertical column | held along the top row |
4251
+ |---|---|---|
4252
+ | 2 | −0.0843 | 0 |
4253
+ | 4 | −0.1998 | 0 |
4254
+ | 8 | −0.3499 | 0 |
4255
+
4256
+ The solver as it stood before holds existed (`3654c0949`) prints the same numbers to every
4257
+ digit. Through `ClothSystem` the torque goes to zero with the iteration count, but not
4258
+ monotonically — 0 at 1, −0.0039 at 2, −0.1894 at 4, −0.3981 at 8, −0.0670 at 16, +0.0562 at 32,
4259
+ +0.0020 at 128 — so this is AVBD stopped short of convergence, and the step's fixed point at a
4260
+ fabric's budget is a steady turn rather than rest. Two repairs inside the step were tried, and
4261
+ neither is one:
4262
+
4263
+ | sweep order, rope | 2 iterations | 4 | 8 |
4264
+ |---|---|---|---|
4265
+ | colours forward (shipped) | −0.0039 | −0.1894 | −0.3981 |
4266
+ | direction alternating each sweep | −0.0792 | +0.2403 | +0.0669 |
4267
+
4268
+ | warm start `α`, rope at 2 × 4 | `Ly` | peak speed, m/s |
4269
+ |---|---|---|
4270
+ | 0.25 (shipped) | −0.1894 | 0.065 |
4271
+ | 0.6 | −0.1354 | 0.044 |
4272
+ | 0.9 | +0.4459 | 2.18 |
4273
+ | 1 | −88.1 | 119 — it blew up |
4274
+
4275
+ The fabrics that sleep do so because a slack row catches the turn, not because it stopped. At
4276
+ step 3,000 the fly end of a silk flag rests 123° round the pole from where it was hung, cotton's
4277
+ 74.5°, denim's 8.7°. Recorded in PLAN §18 rather than fixed: the levers are §5.2's, and every
4278
+ library entry's measurements rest on them.
4279
+
4280
+ ### Joint normals are exact; the twist is not measured
4281
+
4282
+ A 15 × 15 cotton sheet held by nothing falls half a metre onto a 0.4 m sphere and drapes; its
4283
+ middle rests 7.6 mm off the surface, cotton's thickness being 8 mm. Every interior joint's turn
4284
+ takes the rest normal onto its surface's area-weighted normal to within a hundredth of a degree.
4285
+ That is the construction — the swing is normal onto normal — so the spec now bounds it at half a
4286
+ degree, and what it guards is the plumbing: the winding's sign, the frame, the write-back. The
4287
+ twist about the normal comes from one fixed neighbour and nothing measures it. It matters to
4288
+ tangent space — a normal map, an anisotropic sheen — and not to a vertex normal.
4289
+
4290
+ ### What a sheet costs to write back
4291
+
4292
+ One joint per vertex is one main-thread write per vertex per step, and under `WorkerClothSystem`
4293
+ it is the part that stays on the main thread. Cotton held at its hoist and moving; the whole step
4294
+ and `cloth_write_back_rig` alone timed in alternating blocks of ten, the median of ten blocks
4295
+ each, two runs:
4296
+
4297
+ | sheet | joints | whole step | write-back | a joint |
4298
+ |---|---|---|---|---|
4299
+ | 11 × 11 | 121 | 0.85 ms | 0.075 ms | 620 ns |
4300
+ | 21 × 21 | 441 | 3.17 | 0.27 | 600 |
4301
+ | 41 × 41 | 1,681 | 12.6–13.0 | 1.09–1.12 | 650–670 |
4302
+
4303
+ Linear, and about 8.5 % of the main-thread step at every size. At the library's 400-particle
4304
+ garment budget that is 0.25 ms of main thread every fixed step, against 0.18 ms for the main
4305
+ thread's whole share of the §17 workload (§41). Where the 620 ns goes — the reconstruction,
4306
+ composing the local pose, the change event — is not broken down.
4307
+
4308
+ ### Gates
4309
+
4310
+ Cloth suite 338 (from 327): `cloth_proxy_from_mesh.spec.js` 7, `cloth_sheet.spec.js` 4. The whole
4311
+ physics suite with its slow, bench and extended specs (`--mode all`): 185 files and 1,891 tests,
4312
+ green. `check-types` 18 against a budget of 19.
4313
+
4314
+ ---
4315
+
4316
+ ## 64. Three more sheets, and a fold resting on a fold that never comes to rest
4317
+
4318
+ The three sheet scenes M7's third stage was approved with and did not land: a draped sheet on a
4319
+ sphere that turns, a pile of ribbons dropped on a floor, and a circle skirt on a body that turns.
4320
+ The sphere and the skirt are specs in `cloth_sheet.slow.spec.js` — seconds of simulation each, so
4321
+ they run with the extended set — and their numbers are below. The ribbons
4322
+ found a defect in §9's self-collision row instead: a self-collision pair that carries weight adds
4323
+ energy to the step. PLAN §18 records it. Every number here comes from `ClothSystem` scenes driven
4324
+ the way the specs drive them, read back from the joints' world transforms.
4325
+
4326
+ ### A sheet on a turning sphere is carried round by friction
4327
+
4328
+ §63's scene: 15 × 15 cotton at 0.1 m, nothing holding it, draped for 600 steps on a 0.4 m sphere
4329
+ with friction 0.5. Then the sphere is turned about its vertical axis at a quarter turn a second for
4330
+ four seconds, one whole turn. The "turn" is the sheet's mean change of azimuth, summed a step at a
4331
+ time, over the particles more than 10 cm from the axis.
4332
+
4333
+ | | measured |
4334
+ |---|---|
4335
+ | the sheet's turn when the sphere stops, at 360° | 337.4° |
4336
+ | two seconds later | 359.8° |
4337
+ | closest any particle comes to the surface, at any step | 0.57 mm outside it |
4338
+ | the middle's height above the sphere's top | 7.5 mm, as before the turn |
4339
+
4340
+ The turn reaches the cloth through the friction anchor. `cloth_contact_find` stores a contact's
4341
+ anchor in the collider's own frame, so it turns with the collider. The sheet lags by what friction
4342
+ lets slip while it is spun up, then catches up. A frictionless sphere is no control: the sheet slides
4343
+ off it while it drapes, and is 25 m down by step 600.
4344
+
4345
+ ### A circle skirt on a turning body flares, and settles
4346
+
4347
+ The skirt is cut flat: an annulus 32 particles round and 7 out, 6 cm apart from a 15 cm waist, so
4348
+ the hem hangs 36 cm below the waistband. It is cotton, and its waistband is pinned by a `ClothPin`
4349
+ on a waist entity at 1 m. The body is a vertical capsule, radius 0.18 and cylinder 0.5, centred at
4350
+ 0.6 m, so the hips are wider than the waist and the skirt drapes over them. The body and the waist
4351
+ are turned together once a second for two seconds, then stopped.
4352
+
4353
+ | phase | hem radius | hem height | hem off the vertical |
4354
+ |---|---|---|---|
4355
+ | draped, asleep at step 164 | 0.293 m | 0.673 m | 24° |
4356
+ | the second second of the turn, mean | 0.402 | 0.791 | 50° |
4357
+ | the turn's peak | 0.488 | 0.881 | |
4358
+ | ten seconds after it stops | 0.278 | 0.673 | |
4359
+
4360
+ After the stop, no particle moves more than 0.60 mm over the last five seconds. The hem's height
4361
+ comes back to within 0.7 mm, and its radius to 14 mm inside where it was, because its folds fall
4362
+ differently. Nothing goes inside the hips at any step: the closest is 4.6 mm off the surface,
4363
+ against cotton's 8 mm.
4364
+
4365
+ It settles and does not sleep. Before the turn the folds did not touch, and it slept at step 164.
4366
+ After the turn the search finds eight self-collision pairs every step. The cloth holds a jitter of a few
4367
+ tenths of a millimetre per 300 steps, at up to 0.037 m/s, and never passes the sleep test in 4,000
4368
+ steps. That is the defect below.
4369
+
4370
+ ### A fold resting on a fold never comes to rest
4371
+
4372
+ The ribbons are silk strips 16 × 3 at 3 cm, all in one cloth. The self-collision radius is 15 mm,
4373
+ so the diameter is one spacing. They lie on a floor plane with friction 0.5. The lowest ribbon starts
4374
+ 5 mm up, each next one a gap above it, turned by an angle about the pile's middle. A run lasts 2,400
4375
+ steps or until the cloth sleeps. Where a gap is 3.2 cm, §37's ceiling takes the radius down to
4376
+ 12.8 mm, because the bind pose has the ribbons that close. The ratio was varied in a probe build whose
4377
+ `cloth_step` read it from the probe. "Crossings" is §31's metric, as §33 counts it: edges passing
4378
+ through triangles they share no vertex with, over the whole cloth, read at the end of the run.
4379
+ "Peak" is the fastest particle at any step. Free fall from the top ribbon's height bounds what the
4380
+ drop alone can give it.
4381
+
4382
+ ```
4383
+ scene free fall CLOTH_SELF_RATIO: asleep at step / peak m/s / crossings at the end
4384
+
4385
+ 1 2 4 8
4386
+
4387
+ 2 parallel, gap 3.2 cm 0.85 m/s 143 / 0.54 / 0 156 / 0.63 / 0 353 / 0.77 / 0 - / 1.51 / 0
4388
+ 2 parallel, gap 8 cm 1.29 174 / 0.93 / 0 183 / 0.93 / 2 - / 0.93 / 0 - / 3.00 / 14
4389
+ 2 at 90°, gap 3.2 cm 0.85 101 / 0.63 / 0 107 / 0.64 / 0 - / 0.65 / 0 - / 1.55 / 0
4390
+ 2 at 90°, gap 8 cm 1.29 198 / 1.08 / 0 83 / 1.08 / 0 - / 1.08 / 0 159 / 1.08 / 0
4391
+ 3 at 90°, gap 3.2 cm 1.16 211 / 0.79 / 2 296 / 0.79 / 5 1165 / 0.79 / 0 - / 4.40 / 14
4392
+ 3 at 90°, gap 8 cm 1.80 253 / 1.50 / 0 - / 1.50 / 8 - / 2.24 / 0 - / 2.94 / 19
4393
+ 3 at 30°, gap 3.2 cm 1.16 205 / 0.99 / 0 199 / 0.95 / 0 248 / 0.94 / 0 - / 1.72 / 11
4394
+ 3 at 30°, gap 8 cm 1.80 257 / 1.81 / 0 224 / 1.69 / 4 237 / 1.71 / 0 - / 2.33 / 17
4395
+ 6 at 30°, gap 3.2 cm 1.80 304 / 1.63 / 20 398 / 1.66 / 55 264 / 1.72 / 20 - / 4.64 / 139
4396
+ 6 at 30°, gap 6 cm 2.45 367 / 2.79 / 0 - / 3.04 / 38 1664 / 4.30 / 84 - / 5.74 / 44
4397
+
4398
+ "-" is "still awake at step 2,400". The shipped ratio is 8.
4399
+ ```
4400
+
4401
+ **At the shipped ratio no pile comes to rest, and a pile of three or more gains energy.** Every
4402
+ three- and six-ribbon pile ends awake. Each moves 1.3 to 3.8 times faster than its drop could make
4403
+ it, and ends with 11 to 139 crossings. Nine three-ribbon piles were tried at 8, fanned 30°, 60° and
4404
+ 90° apart from gaps of 3.2, 5 and 8 cm, and all nine cross and none sleeps. Two ribbons do not
4405
+ sleep either. Two crossed at 90° were dropped from gaps of 4 to 12 cm in 1 cm steps, and only the 6
4406
+ and 8 cm drops sleep, at steps 127 and 159. The others creep 3 to 56 mm every five seconds for as
4407
+ long as they run, and the 10 cm drop ends with 8 crossings. One ribbon alone sleeps at step 32.
4408
+ Two ribbons with the flag clear pass through each other and sleep at steps 41 and 42.
4409
+
4410
+ **At ratio 1 every scene in the table sleeps**, by step 367 at the latest, and the draped and
4411
+ twirled scenes below sleep too. Where the energy comes from was located by elimination rather than
4412
+ derived. Between the columns only the self row's stiffness changes. Between the rows what changes
4413
+ is how many self pairs carry weight. In a stack a pair stays in contact, so it is a spring that is
4414
+ on every step. That is the case M0's dissipative band was measured on, and §32's sweep did not
4415
+ contain it: §32 drove a folding sheet whose contacts come and go, and its "no energy growth" holds
4416
+ there. Averaging each particle's share of the Jacobi scratch over its pairs, at ratio 8, was tried
4417
+ and is not the fix. Two ribbons crossed at 90° then sleep, at steps 77 and 78, but the parallel
4418
+ pair and every three- and six-ribbon pile still never sleep.
4419
+
4420
+ **The same defect reaches the scenes above.** The draped sheet of §63 never sleeps on its sphere at
4421
+ ratio 8, though nothing turns it. The search finds 14 to 18 pairs every step where its hanging
4422
+ edges fold onto themselves, and over 4,000 steps those edges wander up to 50 mm in half a second.
4423
+ At ratio 1 it sleeps at step 386. The skirt sleeps at ratio 1 too, 267 steps after its twirl stops.
4424
+
4425
+ **"No crossings at rest" does not mean nothing passed through.** A ribbon can go right through
4426
+ another while landing, then lie under it with nothing crossing. At ratio 1, four of the nine
4427
+ three-ribbon piles end asleep in the wrong order. The 30° fan from 8 cm is one of them: asleep at
4428
+ step 257 with no crossings at the end, and its top ribbon on the floor beneath the other two. Only
4429
+ the 60° fan, from 3.2 or 5 cm, is clean at every step at all three of ratios 1, 2 and 4. From 5 cm it keeps its order and sleeps at
4430
+ steps 189, 165 and 212; at 8 its first crossing comes at step 452 and it never sleeps. That pile,
4431
+ asserting no crossing at any step and the order kept, is the proof a change to the ratio needs. It
4432
+ was kept out of this change because it is red on the shipped one.
4433
+
4434
+ **Ratio 1 does not stop a pile landing through itself.** Six ribbons 30° apart still cross while
4435
+ they land: 109 crossings in the worst step from a 3.2 cm gap, and 20 left at the end. That residue
4436
+ is §35's: the pair set is found from where the previous step left the particles, and the search
4437
+ carries no travel term.
4438
+
4439
+ **What ratio 1 costs is §32's own table.** On the folding sheet the mean is 3.42 crossings a
4440
+ sample against 2.03 at 8, and the worst is 51 against 71. Not changed here: the ratio is §32's
4441
+ measured choice for silk, cotton and hair, and changing it wants §32, §33 and the library bench
4442
+ measured again, at each candidate ratio, against these standing contacts.
4443
+
4444
+ ### Gates
4445
+
4446
+ Cloth suite 338, unchanged; the extended cloth specs 9 (from 7): `cloth_sheet.slow.spec.js` 2, whose
4447
+ `grid()` also builds an annulus. The whole physics suite with its slow, bench and extended specs
4448
+ (`--mode all`): 186 files and 1,893 tests, green. `check-types` 18 against a budget of 19.
4449
+
4450
+ ---
4451
+
4452
+ ## 65. The self-collision row ships at 2, so a fold resting on a fold comes to rest
4453
+
4454
+ §64 found that at `CLOTH_SELF_RATIO = 8` a self-collision pair that carries weight adds energy to the
4455
+ step, and that at 1 everything it tried sleeps. Ratio 1 costs §32's folding sheet, which is what 8
4456
+ was chosen on, so this measures the ratios between them against both. The ratio was fed to
4457
+ `cloth_step` through a probe that was never committed. Everything below is today's code, and §32's
4458
+ own numbers were re-measured rather than quoted.
4459
+
4460
+ ### The folding sheet, at 48 gusts
4461
+
4462
+ §32's sheet and §33's library bends, through the same `fold()` as `cloth_m4_measure.mjs`. Twelve
4463
+ realisations were not enough: at twelve, silk read 1.44 crossings a sample at ratio 6 and 2.64 at 8,
4464
+ and no column was in order. So each row here is 48 realisations: §32's twelve integer gust phases
4465
+ and the quarter phases between them, which is the same family of gusts sampled more finely. The
4466
+ figure is the mean crossings a sample, ± its standard error.
4467
+
4468
+ ```
4469
+ ratio sheet (bend 1e-7) SILK 0.04 HAIR 0.20 COTTON 0.25 mean of 4
4470
+
4471
+ 0 9.50 ± 0.59 9.28 ± 0.63 8.96 ± 0.57 8.95 ± 0.51 9.17
4472
+ 1 3.62 ± 0.40 3.80 ± 0.34 4.13 ± 0.37 3.41 ± 0.30 3.74
4473
+ 1.5 3.44 ± 0.33 3.27 ± 0.32 3.44 ± 0.44 2.80 ± 0.31 3.24
4474
+ 2 2.77 ± 0.27 3.43 ± 0.34 3.05 ± 0.35 2.67 ± 0.33 2.98
4475
+ 3 2.65 ± 0.30 2.56 ± 0.24 2.65 ± 0.29 2.89 ± 0.29 2.69
4476
+ 4 2.89 ± 0.28 2.31 ± 0.29 2.13 ± 0.24 2.16 ± 0.24 2.37
4477
+ 6 1.90 ± 0.23 2.40 ± 0.32 2.10 ± 0.24 2.23 ± 0.24 2.16
4478
+ 8 1.98 ± 0.22 2.52 ± 0.28 2.01 ± 0.29 1.84 ± 0.22 2.09
4479
+ ```
4480
+
4481
+ At 48 the trend §32 chose 8 on is there: a stiffer row passes the sheet through itself less while it
4482
+ moves. The row removes 73% to 79% of the crossings at 8, 63% to 71% at 2, and 54% to 62% at 1. The
4483
+ worst realisation lies between 62 and 134 crossings at every ratio, with no trend. At rest the
4484
+ sheet is clean at every ratio, and its kinetic energy at the end of the run moves between 4.5e-3
4485
+ and 6.4e-3 J with no trend either. This sheet still cannot see the defect.
4486
+
4487
+ The row's code has moved since M4. At twelve realisations, with no row, it reads exactly §32's
4488
+ 11.39 / 146 and §33's 8.08, 10.62 and 9.36. With the row it reads 1.84 / 63 at 8 and 3.27 / 67 at 1,
4489
+ against §32's 2.03 / 71 and 3.42 / 51.
4490
+
4491
+ ### Piles of ribbons, 75 per fabric
4492
+
4493
+ §64's ribbons: strips 16 × 3 at 3 cm, all in one cloth through `ClothSystem`, on a floor with
4494
+ friction 0.5, run for 2,400 steps or until the cloth sleeps. Each pile is 2, 3 or 4 ribbons fanned
4495
+ 0°, 30°, 45°, 60° or 90° apart and dropped from gaps of 3.2, 4, 5, 6 or 8 cm. That is 75 piles, for
4496
+ silk, cotton and hair, the three entries that set the flag. "Clean" means no crossing at any step.
4497
+ "Swapped" means two ribbons whose middles still lie over each other ended in the wrong order: one
4498
+ landed right through the other.
4499
+
4500
+ ```
4501
+ fabric ratio asleep clean: asleep / of landed through: asleep / of swapped
4502
+
4503
+ SILK 1 73 32 / 32 41 / 43 27
4504
+ SILK 1.25 72 39 / 39 33 / 36 23
4505
+ SILK 1.5 69 33 / 34 36 / 41 20
4506
+ SILK 2 68 38 / 38 30 / 37 16
4507
+ SILK 3 66 42 / 43 24 / 32 13
4508
+ SILK 4 50 33 / 38 17 / 37 7
4509
+ SILK 8 3 2 / 16 1 / 59 1
4510
+ COTTON 1 74 35 / 36 39 / 39 24
4511
+ COTTON 1.5 67 41 / 44 26 / 31 15
4512
+ COTTON 2 74 45 / 45 29 / 30 13
4513
+ COTTON 3 70 49 / 49 21 / 26 10
4514
+ HAIR 1 75 47 / 47 28 / 28 8
4515
+ HAIR 1.5 73 50 / 52 23 / 23 7
4516
+ HAIR 2 74 51 / 52 23 / 23 7
4517
+ HAIR 3 68 56 / 58 12 / 17 5
4518
+ ```
4519
+
4520
+ **A clean pile comes to rest from 1 to 3 and stops doing so above.** Over the three fabrics, the
4521
+ clean piles left awake are 1 of 115 at ratio 1, 6 of 130 at 1.5, 1 of 135 at 2 and 3 of 150 at 3. At
4522
+ 4, five of 38 clean silk piles never sleep, all of them two-ribbon piles. At 8, 14 of 16 never
4523
+ sleep. Clean piles at 1 to 3 move no faster than their drop can make them, at most 1.07 times their
4524
+ free-fall speed, except one hair pile at ratio 1 at 1.28. Clean piles at 8 reach 1.82 times it, and
4525
+ §64's piles up to 3.8. At 1.5 the six awake
4526
+ are all four-ribbon stacks with 78 to 133 standing pairs, still moving at 0.15 to 0.32 m/s. Whether
4527
+ one particular pile sleeps does not follow the ratio. The four-ribbon 45° fan from 4 cm lands clean
4528
+ and sleeps at 1.25, 2 and 3, and never at 1.5. The fraction over 75 piles is the measurement.
4529
+
4530
+ **At 3 and below, every crossing starts while the pile is landing.** All 406 of them start by step
4531
+ 119, two seconds in, and 95% by step 64. That is §35's missing travel term, not the energy defect.
4532
+ At 8, ten of the 59 piles that cross do so first after step 100, as late as step 1,862. A softer row lets more piles land through themselves (110 of 225 at 1,
4533
+ 90 at 2, 75 at 3) and swaps more of them (59, 36, 28). In exchange it lets more of those tangled
4534
+ piles come to rest anyway (108 of 110 at 1, 82 of 90 at 2, 57 of 75 at 3).
4535
+
4536
+ ### The draped sheet, the skirt and the turning sphere
4537
+
4538
+ §63's sheet, 15 × 15 cotton draped on a 0.4 m sphere, run up to 4,000 steps. The step it sleeps at:
4539
+
4540
+ ```
4541
+ ratio 1 1.25 1.5 1.75 2 2.25 2.5 3 4 5 6 8
4542
+ asleep 386 299 309 357 299 300 723 298 326 never 462 never
4543
+ ```
4544
+
4545
+ Its middle rests 7.5 mm above the sphere's top at every ratio, and its corners hang 0.58 to 0.78 m
4546
+ below the middle. At 8 the search finds 17 pairs a step and the hanging edges
4547
+ wander 116 mm. At 5 it finds 12.
4548
+
4549
+ The circle skirt from §64 twirls identically at every ratio: the hem 0.109 m further out and
4550
+ 0.118 m higher over the second second. After the stop it sleeps within 600 steps at 1, 1.25, 1.5,
4551
+ 1.75, 2, 2.25, 2.5, 3 and 4, and never at 5, 6 or 8, where the search finds six or seven pairs a
4552
+ step. At 2 it sleeps 270 steps after the stop, its hem 0.9 mm from its old height and 13 mm in
4553
+ from its old radius.
4554
+
4555
+ The sheet a turning sphere carries round (§64) is carried at every ratio, to between 335° and 343°
4556
+ of the sphere's 360° when the sphere stops. Two seconds later it stops at a different angle at
4557
+ each ratio, by how far short of a whole turn it ends:
4558
+
4559
+ ```
4560
+ ratio 1 1.25 1.5 1.75 2 2.25 2.5 3 3.5 4 5 6 8
4561
+ short ° 0.6 0.1 2.4 0.3 8.4 1.3 -2.8 9.1 0.8 -0.6 -0.1 -0.6 0.3
4562
+ ```
4563
+
4564
+ At 2 the whole sheet sits behind the sphere: the cap by 8.6°, the sides by 8.9° and the hanging
4565
+ edges by 8.0°. That is a net slip, not the folds rearranging. Nine spins at each of 1, 2, 3 and 8 —
4566
+ 0.2, 0.25 and 0.3 turns a second, for 3, 4 and 5 seconds — share one 600-step drape per ratio, and
4567
+ they agree with each other: 2.8° to 8.4° short at 2, 1.4° to 9.1° at 3, within 1° at 1 and 8. So where the sheet stops
4568
+ is set by which folds the drape formed, and that changes with the ratio in no order. The spec
4569
+ asserted 2° from 359.8°, one realisation at 8. It now asserts what holds at every ratio: the sheet
4570
+ turns further after the stop than before it, and ends within 10° of the whole turn.
4571
+
4572
+ ### What the step costs
4573
+
4574
+ `cloth_library_bench.mjs`'s sheets for the three entries, at their own budgets, driven by its
4575
+ folding gust. Each pair of arms is stepped alternately in one process, the order alternating every
4576
+ frame, and the figure is each arm's fastest step over three rounds of 1,500.
4577
+
4578
+ ```
4579
+ entry 8 against 8 8 against 2 8 against 1 pairs a step at 8 / 2 / 1
4580
+
4581
+ SILK 1.026 0.995 0.987 372 / 452 / 534
4582
+ COTTON 1.003 1.016 1.022 365 / 426 / 542
4583
+ HAIR 0.982 0.984 1.013 366 / 439 / 533
4584
+ ```
4585
+
4586
+ Every ratio is inside the control's 3%: the cost does not move. The search finds 17% to 22% more
4587
+ pairs a step at 2, but §34 says the cost is in the search, not the pairs.
4588
+
4589
+ ### A pair on its own does not do it
4590
+
4591
+ Two particles with no rows between them, pressed together by equal and opposite accelerations, so
4592
+ the self-collision row is all that holds them apart, come to rest at every ratio from 0.5 to 8. So
4593
+ does a column of three. The energy needs the cloth's own rows around the pair, and this section does
4594
+ not claim a mechanism for it. §64's "averaging a particle's Jacobi share over its pairs is not the
4595
+ fix" stands.
4596
+
4597
+ ### Why 2
4598
+
4599
+ It is the stiffest ratio at which cloth resting on itself reliably comes to rest. The clean piles
4600
+ sleep, 134 of 135, and so do the draped sheet, at step 299, the skirt after its twirl, and §64's
4601
+ proof pile, at step 166 with no crossing at any step. Above 2.25 the draped sheet's sleep turns
4602
+ erratic, and at 4 clean two-ribbon piles stop sleeping. Below 2 the folding sheet only gets worse:
4603
+ 3.24 crossings a sample at 1.5 and 3.74 at 1, against 2.98. Between 2 and 3 the folding sheet
4604
+ cannot tell the two apart, 2.98 against 2.69 with a combined error of about 0.2. Across all three
4605
+ fabrics, 216 of 225 piles sleep at 2 against 204 at 3.
4606
+
4607
+ What it costs is §32's sheet: 2.98 crossings a sample against 2.09 at 8, and the row removes 63% to
4608
+ 71% of the unaided crossings rather than 73% to 79%. Ratio 1 would be the answer if a pile that
4609
+ lands through itself must come to rest anyway. It sleeps 222 of 225 piles, but the folding sheet
4610
+ gets 25% worse than at 2 and 59 piles swap against 36.
4611
+
4612
+ ### Gates
4613
+
4614
+ Cloth suite 338, unchanged: `cloth_sheet.spec.js`'s draped sheet now asserts it sleeps. The
4615
+ extended cloth specs 10 (from 9): `cloth_sheet.slow.spec.js` gains the ribbon pile, and its skirt
4616
+ asserts it sleeps after the twirl. All three are red on 8, where none of them sleeps. The whole
4617
+ physics suite with its slow, bench and extended specs (`--mode all`): 186 files and 1,894 tests,
4618
+ green. `check-types` 18 against a budget of 19.
4619
+
4620
+ ---
4621
+
4622
+ ## 66. A flag stops turning on its pole: the turn about a hold line is a block of the descent
4623
+
4624
+ §63's flag turned about its pole for as long as it was run. A side session measured why, at
4625
+ `d9a51a8ce`, and built the repair as a probe; this section is the repair as landed. The first two
4626
+ subsections are the side session's measurements at that commit. Between it and this one's parent the
4627
+ self-collision row went from 8 to 2 (§65), so everything from "What landed" on was measured again:
4628
+ "before" is the parent, `0e20799be`, on this machine, with about 30 other node processes running.
4629
+
4630
+ ### Why it turned
4631
+
4632
+ These are the side session's measurements, on a bare `ClothState` flag: 9 × 9 at 0.1 m, curved by
4633
+ `0.0005·x²`, hard stretch rows only, the hoist column held, 2 substeps, rope's damping applied between
4634
+ steps.
4635
+
4636
+ - **Only the vertex updates change the angular momentum about the pole.** The predict, the dual
4637
+ updates and the integrate change it by exactly zero: gravity is parallel to the axis, and the holds
4638
+ sit on it.
4639
+ - **Over a substep it changes by `h·Σ x_prev × R`**, `R` the step energy's gradient left when the
4640
+ iterations stop. At 2 × 4 the identity predicts −2.6036e-3 a substep and −2.6036e-3 is measured.
4641
+ Implicit Euler's own term is +1.2e-5. The moment sits on the middle colours: colour 1 +1.49e-2,
4642
+ colour 2 −1.78e-2, the last ≈ 0.
4643
+ - **It never stops** because the warm start keeps `α·γ = 0.25` of each hard multiplier, so every
4644
+ substep re-solves three quarters of the hanging weight and a cloth at rest is never a fixed point.
4645
+ Carrying a quarter reads −0.1588; carrying half, −0.0874.
4646
+ - **It is not sweep order.** At 8 iterations:
4647
+
4648
+ | sweep order | `L_y` |
4649
+ |---|---|
4650
+ | forward (shipped) | −0.4656 |
4651
+ | backward | −0.4629 |
4652
+ | alternating each step | −0.4640 |
4653
+ | alternating each substep | −0.5013 |
4654
+ | forward then backward each iteration, twice the cost | −0.4034 |
4655
+
4656
+ ### What was tried first, and dropped
4657
+
4658
+ AVBD's `α` is two mechanisms. Eq. 18 regularises the hard constraint, `C*(x) = C(x) − α·C(xᵗ)`; Eq. 19
4659
+ is the warm start, `λ ← αγλ`. §5.2 has only Eq. 19. The reference 2D code carries `λ` whole and adds one
4660
+ `α = 0` pass that moves positions and not velocity, which is post-stabilisation. All three were built in
4661
+ the probe and measured on the 345 cloth gates of the time:
4662
+
4663
+ | variant | stops the turn | gates failed | and |
4664
+ |---|---|---|---|
4665
+ | Eq. 18 on the stretch table, `α` 0.98 | yes: every flag sleeps, rope at 459 | 6 of 345 | silk on the bench's sheet blows up at step 722 |
4666
+ | Eq. 18 on every hard row | only at `α` ≥ 0.98; rope −0.0153 at 0.9 | not run | cotton and hair lying sheets never sleep at `α` ≥ 0.8 |
4667
+ | post-stabilisation | after 1,300–2,200 steps of creep | 10 of 345 | diverges in the same scene |
4668
+
4669
+ The six Eq. 18 failures: P6's TeleportKeep shift 0.24 against `< 0.2`, P7's locomotion at the velocity
4670
+ clamp, the write-back lag 0.18 against `< 0.15`, a rig offset of 0.1013 against `0.1 ± 0.0005`, and two
4671
+ collision specs. The divergence is where Eq. 18's rows meet rows still on the old warm start: it
4672
+ corrects only `1 − α` of an old error a substep, which makes a hard row soft against a transient.
4673
+
4674
+ ### What landed
4675
+
4676
+ `cloth_hold_line.js`, called from `cloth_step`. PLAN §5.2 has it in the listing.
4677
+
4678
+ - **The block.** In the last iteration of each substep, after the sweep and before the dual update: one
4679
+ Newton step of the step's energy along the rotation about the line through the held particles,
4680
+ `θ = −g/H`, then every free particle turned by `θ`.
4681
+ - **What enters.** `g = Σ (a × r_i)·∇E_i` and `H = Σ tᵀH_i t + max(0, Σ ∇E_i·(a(a·r_i) − r_i))`, with
4682
+ `∇E_i` and `H_i` the vertex update's own assembly of the inertial term, the leash rows, the backstop
4683
+ rows and the contacts. The internal rows are invariant under the turn and are left out.
4684
+ - **When it runs.** When the held particles lie on one line at that substep, at two distinct points or
4685
+ more. The predict lists the held particles as it carries them, so the test is a pass over the held
4686
+ particles. A particle is on the line within `2⁻¹⁶` of the largest held coordinate.
4687
+
4688
+ What the probe had that this does not: a scan of every particle for the held ones each substep, a
4689
+ fixed 1e-4 m collinearity tolerance, and the rotation pass run when `θ` is zero.
4690
+
4691
+ ### The bare flag
4692
+
4693
+ `cloth_hold_line.spec.js`'s scene, read at step 3,000.
4694
+
4695
+ | iterations | `L_y` before | `L_y` now | worst stretch row's `C/L₀`, both |
4696
+ |---|---|---|---|
4697
+ | 1 | 0.0002 | 0.0000 | 6.0e-2 |
4698
+ | 2 | 0.0519 | 0.0000 | 4.5e-2 |
4699
+ | 4 | −0.1588 | 0.0000 | 3.4e-2 |
4700
+ | 8 | −0.4656 | 0.0000 | 2.4e-2 |
4701
+ | 16 | 0.3783 | 0.0000 | 1.7e-2 |
4702
+
4703
+ Before, `L_y` is the same to four figures at steps 1,000, 2,000 and 3,000: a steady turn. The same
4704
+ sheet held along its top row, a line gravity restores, reads the same `L_y`, worst `C/L₀` and fly-end
4705
+ position to every digit printed in both builds. Run in every iteration rather than the last, the
4706
+ block reads 0.0000 to 0.0001 — no better.
4707
+
4708
+ **The tolerance.** Turn the same flag 0.7 rad about `(1, 2, 3)`, turn gravity with it, and move it
4709
+ `d` metres from the origin. It is the same flag, but its hoist no longer lies along an axis, so its
4710
+ `Float32` coordinates carry rounding off the line. At 4 iterations, over 1,000 steps:
4711
+
4712
+ | `d`, m | worst held particle off the line, m | over the largest held coordinate | `L_y` before | `L_y` now |
4713
+ |---|---|---|---|---|
4714
+ | 0 | 7.8e-9 | 1.2e-8 | −0.1586 | −0.0003 |
4715
+ | 1 | 5.8e-8 | 4.2e-8 | −0.1587 | 0.0006 |
4716
+ | 10 | 6.5e-7 | 6.3e-8 | −0.1558 | 0.0064 |
4717
+ | 100 | 3.7e-6 | 3.6e-8 | −0.2266 | −0.0478 |
4718
+ | 1,000 | 3.7e-5 | 3.7e-8 | −0.5235 | −0.5690 |
4719
+ | 4,000 | 1.5e-4 | 3.7e-8 | 0.1921 | −0.0723 |
4720
+
4721
+ Relative to its own magnitude the rounding never passes 6.3e-8, half a unit in the last place, and
4722
+ `2⁻¹⁶` is 240 times that. In metres it grows with `d`, and the probe's fixed 1e-4 m refuses the line at
4723
+ 4 km. Through `ClothSystem`, the hoists of the 6 × 6 flags below were sampled at every step of every
4724
+ run, driven and turned poles included: none was off its line by more than 3e-16 of its size. The cloth
4725
+ steps in its own frame, and those hoists were authored along an axis of it.
4726
+
4727
+ **Far from the origin the turn comes back.** At 10 m the turn holds at 0.004 to 0.007 through 3,000
4728
+ steps. At 100 m it grows: −0.025 at step 500, −0.048, −0.065, −0.074, −0.093 and −0.136 at 3,000,
4729
+ against −0.18 to −0.23 before. The block turns the flag 5.6e-6 rad a substep at the origin and 7.2e-6
4730
+ at 100 m, the median over the last 500 steps. That is 2.8 to 3.6 µm of travel at half a metre. A unit
4731
+ in the last place is 0.06 µm at the origin, 0.95 µm at 10 m and 7.6 µm at 100 m, so at 100 m the
4732
+ correction is smaller than the rounding of the coordinates it moves. PLAN §18 keeps this open.
4733
+
4734
+ ### Flags through `ClothSystem`
4735
+
4736
+ §63's sheet: 6 × 6 at 0.1 m, three centimetres of curve, held by a `ClothPin` on a pole. "Turn" is the
4737
+ fly end's azimuth about the pole at step 3,000, from where it was hung.
4738
+
4739
+ | fabric | asleep at, before | `L_y` at 3,000, before | turn, before | asleep at, now | `L_y` at 3,000, now | turn, now |
4740
+ |---|---|---|---|---|---|---|
4741
+ | silk | 618 | −0.0038 | −24.8° | 507 | −0.0004 | 30.7° |
4742
+ | cotton | never | 0.0117 | −57.0° | 336 | −0.0005 | 29.5° |
4743
+ | denim | 480 | 0.0021 | 21.7° | 246 | 0.0000 | 29.8° |
4744
+ | leather | 227 | 0.0000 | −0.6° | 216 | 0.0000 | −0.6° |
4745
+ | rope | never | 0.1809 | 103.9° | 416 | 0.0004 | −15.6° |
4746
+ | chain | never | 0.0406 | 94.6° | 250 | 0.0001 | 0.2° |
4747
+ | hair | 799 | 0.0022 | 59.4° | 527 | 0.0003 | 33.8° |
4748
+
4749
+ Denim, leather, rope and chain are the side session's numbers to every digit. Silk, cotton and hair
4750
+ self-collide, and at the row's old stiffness of 8 the probe read 1,164, 2,685 and 742 before and 593,
4751
+ 597 and 446 after. Asleep, the top of the fly end has come down 0.11 to 0.22 m; leather's has come
4752
+ down 3 mm, because a leather flag stands out from its pole like a board. `cloth_sheet.spec.js` holds
4753
+ the rest claim for every fabric.
4754
+
4755
+ `cloth_sheet.spec.js`'s first flag, 9 × 9 with `0.0005·x²` of curve, asleep at: silk 1,613 → 649,
4756
+ cotton never → 377, denim 472 → 307, leather 195 → 195, rope never → 431, chain never → 268, hair never
4757
+ → 303.
4758
+
4759
+ ### What else it moves
4760
+
4761
+ **Held along a line gravity restores.** §63's lying sheet, held along one edge, asleep at:
4762
+
4763
+ | fabric | before | now |
4764
+ |---|---|---|
4765
+ | silk | 568 | 598 |
4766
+ | cotton | 73 | 68 |
4767
+ | denim | 76 | 68 |
4768
+ | leather | 72 | **165** |
4769
+ | rope | 512 | 507 |
4770
+ | chain | 280 | 271 |
4771
+ | hair | 66 | 65 |
4772
+
4773
+ The far edge drops as far in both. The flag on an entity turned 30° about x and then 40° about y, so
4774
+ that its hoist leans 30° from gravity, sleeps at: rope 474 → 574, silk 574 → 571, chain 264 → 312.
4775
+ The regressions are leather's lying sheet, more than twice as long, the leaning rope and chain, a fifth
4776
+ longer, and silk's lying sheet, 5% longer. Why is not measured.
4777
+
4778
+ **A driven pole.** The 6 × 6 flag, the pole swayed 0.3 m at 1.5 Hz, bobbed, turned about its own
4779
+ vertical at half a turn a second, or teleported a kilometre. Each runs to step 900, then stops; the
4780
+ teleport is at step 600. "Peak" is the fastest particle while driven; "asleep" counts from step 900.
4781
+
4782
+ | fabric | motion | peak, before | asleep, before | peak, now | asleep, now |
4783
+ |---|---|---|---|---|---|
4784
+ | rope | sway | 7.40 m/s | never | 6.45 | 1,397 |
4785
+ | rope | bob | 7.89 | never | 6.71 | 1,383 |
4786
+ | rope | spin | 0.94 | never | 0.94 | 929 |
4787
+ | rope | teleport | 0.94 | never | 0.94 | never |
4788
+ | silk | sway | 6.47 | 1,903 | 6.30 | 1,542 |
4789
+ | silk | bob | 6.52 | 2,141 | 8.18 | 1,498 |
4790
+ | silk | spin | 2.10 | 2,218 | 2.04 | 1,488 |
4791
+ | silk | teleport | 1.21 | never | 1.21 | never |
4792
+ | leather | sway | 4.48 | 1,172 | 4.16 | 1,189 |
4793
+ | leather | bob | 4.61 | 1,196 | 5.11 | 1,163 |
4794
+ | leather | spin | 2.78 | 1,005 | 2.63 | 1,003 |
4795
+ | leather | teleport | 0.24 | 901 | 0.23 | 901 |
4796
+ | hair | sway | 8.89 | 1,269 | 5.29 | 1,235 |
4797
+ | hair | bob | 7.14 | 1,194 | 6.51 | 1,198 |
4798
+ | hair | spin | 2.50 | 1,684 | 2.48 | 1,162 |
4799
+ | hair | teleport | 0.92 | never | 0.89 | never |
4800
+ | chain | sway | 6.06 | never | 6.75 | 1,205 |
4801
+ | chain | bob | 6.20 | never | 5.92 | 1,168 |
4802
+ | chain | spin | 0.75 | never | 0.75 | 929 |
4803
+ | chain | teleport | 0.75 | never | 0.75 | never |
4804
+
4805
+ Every run is finite. The peaks move both ways, by as much as hair's sway, 8.89 → 5.29 m/s, and silk's
4806
+ bob, 6.52 → 8.18. After the teleport neither build sleeps within 2,400 steps, except leather; the cause
4807
+ is not measured.
4808
+
4809
+ **Wind.** The flag in a steady 6 m/s breeze across it: the fly end's azimuth about the pole at steps
4810
+ 600, 1,200 and 1,800 is the same in both builds to 0.4° — silk 94.7° → 95.1°, cotton 77.2°, rope
4811
+ 100.6° → 100.8°, hair 70.2°. Cotton sleeps at step 1,333, where before it did not within 1,800.
4812
+
4813
+ **One held point, or a line the cloth hangs on.** §53's sleep table and the P5 12-link swing sleep at
4814
+ the same step in both builds, every cell: a rig held at one point has no line, and the block never
4815
+ runs. So does a sheet hung from one corner, and its `L_y` is the same: silk awake at 3,000, `L_y` at
4816
+ most 0.004. An 8-link rope held at its top two particles hangs and swings in a plane through its own
4817
+ hold line, which has no moment about it, so the block takes no step. It sleeps at the same step in
4818
+ both builds, leaning 2% or not.
4819
+
4820
+ ### Two hands, and the one scene the block keeps awake
4821
+
4822
+ The 6 × 6 flag held by two hands at its two top corners — two held points, so always a line — either
4823
+ still from the start, or after the hands see-saw 0.15 m at 1.2 Hz for 900 steps and stop. Asleep at:
4824
+
4825
+ | fabric | still, before | still, now | after the see-saw, before | after the see-saw, now |
4826
+ |---|---|---|---|---|
4827
+ | silk | 328 | 395 | 1,504 | 1,547 |
4828
+ | cotton | 234 | 242 | 1,378 | **never** — 1.71 mm per 30 steps at 8,000 |
4829
+ | denim | 141 | 142 | 1,076 | 1,081 |
4830
+ | leather | 91 | 84 | 1,034 | 1,031 |
4831
+ | rope | 286 | 268 | never — 4.62 mm | never — 2.06 mm |
4832
+ | chain | 175 | 199 | 1,122 | 1,102 |
4833
+ | hair | 185 | 183 | 1,152 | 1,198 |
4834
+
4835
+ Cotton after the see-saw is the block's doing, and not the history's. With a copy of the block that can
4836
+ be switched at step 901, cotton sleeps at 1,378 with it off throughout, at 1,409 switched off at 901,
4837
+ and never while it is on after 901, whether or not it was on before. Its turn there is about 7e-7 rad a
4838
+ substep, median −6.8e-7 over steps 3,000 to 6,000. The corner line is horizontal, so gravity restores
4839
+ the turn; the block removes what is left of it rigidly each substep, and the sweeps put it back near a
4840
+ corner, unevenly. Rope never sleeps after the see-saw in either build, and silk and hair sleep at
4841
+ about the same step whichever way the block is switched.
4842
+
4843
+ ### The adversarial review
4844
+
4845
+ Before this landed, a review drove the side session's probe of the block, at `d9a51a8ce` and at the
4846
+ self-collision row's old stiffness, against the cases a rigid turn could get wrong. Its numbers for
4847
+ silk, cotton and hair predate §65. What it found:
4848
+
4849
+ - **Every block step reduced the gradient along the turn**: none of more than 50,000 calls left it
4850
+ larger.
4851
+ - **Wind.** Across, along and against the wind, the fly end's mean direction was within 0.3° of the
4852
+ probe's shipped arm and its flutter as large. Into a headwind silk swung round to trail at −171°,
4853
+ where shipped stalled side-on at −94°.
4854
+ - **Contacts.** A flag pressed onto a sphere by a 4 or 8 m/s wind penetrated 0.38–1.45 mm at worst,
4855
+ against 0.50–1.88 mm.
4856
+ - **A leaning pole, 1° to 60°.** Finite at every lean, and asleep at every lean but the chain's at 1°,
4857
+ still awake at 2,400 steps: a slow decaying swing towards hanging downhill, where shipped had come to
4858
+ rest 13° short of it.
4859
+ - **A curtain** held along a straight top, in wind: the same mean deflection to 0.1 mm, and the same
4860
+ flutter. **Two hands** moving apart and together, or one twirling: finite, and asleep as shipped is.
4861
+ - **Placement.** Before the last sweep instead of after it, the flag still turns: rope −0.162, chain
4862
+ −0.040. In every iteration, the same open items as in the last, at 13–17% of a step.
4863
+ - **Considered and not done:** running the block only on hold lines near the vertical would take away
4864
+ both open items. It needs a tolerance constant and a test against gravity.
4865
+
4866
+ The two-corner see-saw, a cross wind, a pole leaning 30° and a rope on its own hold line are measured
4867
+ again on the parent elsewhere in this section.
4868
+
4869
+ ### What it costs
4870
+
4871
+ `ab_cost.mjs` (scratchpad), from the side session's harness: the parent and this tree in one process,
4872
+ the library's claims, 600 warm-up frames, then 1,500 interleaved frames × 3 rounds with the order
4873
+ alternating per frame. The control is the parent against a second checkout of the parent. "Sheet" is the
4874
+ bench's sheet, top row held, which never leaves its plane: the turn is exactly zero, the builds stay
4875
+ bit-identical, and what is priced is the line test and the `g`, `H` pass. "Flag" is the same sheet held
4876
+ along its left column with a centimetre of curve and the fabric's damping applied between steps, as
4877
+ `ClothSystem` applies it. Its turn is not zero, so the rotation pass runs and the builds part.
4878
+
4879
+ | entry | budget | control, min / median | sheet, min / median | flag, min / median |
4880
+ |---|---|---|---|---|
4881
+ | silk | 2 × 4 | 1.004 / 1.001 | 1.029 / 1.031 | 1.032 / 1.044 |
4882
+ | cotton | 2 × 4 | 1.006 / 1.000 | 1.035 / 1.031 | 1.036 / 1.044 |
4883
+ | denim | 2 × 2 | 1.008 / 0.999 | 1.046 / 1.050 | 1.069 / 1.061 |
4884
+ | leather | 2 × 2 | 1.000 / 1.001 | 1.050 / 1.051 | 1.059 / 1.061 |
4885
+ | rope | 2 × 4 | 1.000 / 1.002 | 1.003 / 1.002 | 1.005 / 1.007 |
4886
+ | chain | 2 × 6 | 1.007 / 1.002 | 0.997 / 0.997 | 0.998 / 1.008 |
4887
+ | hair | 2 × 4 | 0.995 / 1.003 | 1.036 / 1.031 | 1.037 / 1.038 |
4888
+
4889
+ The control on the flag read 0.995 to 1.006. A first run of the same harness the same day, against
4890
+ `5e75c1654` — whose step differs from the parent's only in the self-collision row, which neither scene
4891
+ has — read 1.034–1.077 at the minimum on the sheet and 1.042–1.073 on the flag, with its controls at
4892
+ 0.975–1.016. **3–9% on a sheet held along a line, then, and 3–7% in this run.** It is dearest at 2
4893
+ iterations, where one block is a larger share of the step. Rope and chain are held at one point and pay
4894
+ for the predict's list and nothing else. The flag without damping is no measure: the parent's flag spins
4895
+ up, and a flag spinning taut costs more to step than one at rest, so the block's arm read 0.63 to 0.83
4896
+ of the parent's.
4897
+
4898
+ Run in every iteration, the block costs 1.110–1.133 at the minimum on the sheet and 1.086–1.157 on the
4899
+ flag; the first run read 1.099–1.132 and 1.126–1.183.
4900
+
4901
+ ### Gates
4902
+
4903
+ Cloth suite 342 (from 339 at the parent): `cloth_hold_line.spec.js` 1, the rest claim for every
4904
+ fabric's flag in `cloth_sheet.spec.js`, and a flag on a swaying pole in `WorkerClothSystem.spec.js`'s
4905
+ parity gate. The first two are red on the parent: the bare flag turns at 0.0519 at 2 iterations, and
4906
+ cotton's, rope's and chain's flags never sleep. The parity run is the first in the gate whose holds
4907
+ are more than two points on a line; until it, only the run in which a hand holds the rope's tip
4908
+ reached the block. A mutant that changes `θ` by a part in a thousand in one arm and not the other
4909
+ fails those two runs and no other. The extended cloth specs 10, unchanged. The whole physics suite
4910
+ with its slow, bench and extended specs (`--mode all`): 187 files and 1,898 tests, green,
4911
+ `cloth_pathology` among them. `check-types` 18 against a budget of 19.