@woosh/meep-engine 3.23.0 → 3.25.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 (812) hide show
  1. package/editor/entity_world_bounds.d.ts +9 -3
  2. package/editor/entity_world_bounds.d.ts.map +1 -1
  3. package/editor/entity_world_bounds.js +61 -4
  4. package/package.json +1 -1
  5. package/src/core/binary/allocator/OffsetAllocator.d.ts +40 -2
  6. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  7. package/src/core/binary/allocator/OffsetAllocator.js +124 -29
  8. package/src/core/collection/map/u32_index.d.ts +83 -0
  9. package/src/core/collection/map/u32_index.d.ts.map +1 -0
  10. package/src/core/collection/map/u32_index.js +247 -0
  11. package/src/engine/asset/loaders/GLTFSceneBundleAssetLoader.d.ts +2 -2
  12. package/src/engine/asset/loaders/GLTFSceneBundleAssetLoader.js +2 -2
  13. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts +1 -2
  14. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts.map +1 -1
  15. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.js +4 -12
  16. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts +55 -0
  17. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts.map +1 -0
  18. package/src/engine/ecs/gpu/GPUStateAuthority.js +72 -0
  19. package/src/engine/ecs/gpu/GPUStateAuthorityFlags.d.ts +40 -0
  20. package/src/engine/ecs/gpu/GPUStateAuthorityFlags.d.ts.map +1 -0
  21. package/src/engine/ecs/gpu/GPUStateAuthorityFlags.js +79 -0
  22. package/src/engine/ecs/gpu/gpu_authority_assert_cpu.d.ts +18 -0
  23. package/src/engine/ecs/gpu/gpu_authority_assert_cpu.d.ts.map +1 -0
  24. package/src/engine/ecs/gpu/gpu_authority_assert_cpu.js +27 -0
  25. package/src/engine/ecs/gpu/gpu_authority_declare.d.ts +23 -0
  26. package/src/engine/ecs/gpu/gpu_authority_declare.d.ts.map +1 -0
  27. package/src/engine/ecs/gpu/gpu_authority_declare.js +39 -0
  28. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts +15 -0
  29. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts.map +1 -0
  30. package/src/engine/ecs/gpu/gpu_authority_grant.js +38 -0
  31. package/src/engine/ecs/gpu/gpu_authority_has.d.ts +18 -0
  32. package/src/engine/ecs/gpu/gpu_authority_has.d.ts.map +1 -0
  33. package/src/engine/ecs/gpu/gpu_authority_has.js +28 -0
  34. package/src/engine/ecs/gpu/gpu_authority_revoke.d.ts +24 -0
  35. package/src/engine/ecs/gpu/gpu_authority_revoke.d.ts.map +1 -0
  36. package/src/engine/ecs/gpu/gpu_authority_revoke.js +49 -0
  37. package/src/engine/ecs/ik/IKProblem.d.ts +14 -0
  38. package/src/engine/ecs/ik/IKProblem.d.ts.map +1 -1
  39. package/src/engine/ecs/ik/IKProblem.js +16 -0
  40. package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +1 -1
  41. package/src/engine/ecs/ik/InverseKinematicsSystem.js +19 -0
  42. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +2 -2
  43. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +2 -2
  44. package/src/engine/ecs/ik/ik_bone_chain.d.ts +11 -2
  45. package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +1 -1
  46. package/src/engine/ecs/ik/ik_bone_chain.js +47 -2
  47. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  48. package/src/engine/ecs/ik/ik_write_local_rotation.js +6 -0
  49. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  50. package/src/engine/ecs/speaker/VoiceSystem.js +6 -0
  51. package/src/engine/ecs/transform/T64WorldCache.d.ts +50 -0
  52. package/src/engine/ecs/transform/T64WorldCache.d.ts.map +1 -0
  53. package/src/engine/ecs/transform/T64WorldCache.js +139 -0
  54. package/src/engine/ecs/transform/t64_evaluate_world.d.ts +31 -0
  55. package/src/engine/ecs/transform/t64_evaluate_world.d.ts.map +1 -0
  56. package/src/engine/ecs/transform/t64_evaluate_world.js +126 -0
  57. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts +8 -0
  58. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  59. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +59 -30
  60. package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts.map +1 -1
  61. package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +4 -11
  62. package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.d.ts +14 -0
  63. package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.d.ts.map +1 -0
  64. package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.js +13 -0
  65. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +2 -14
  66. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts.map +1 -1
  67. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +11 -21
  68. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.d.ts +1 -0
  69. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +7 -0
  70. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts +5 -6
  71. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts.map +1 -1
  72. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.js +13 -11
  73. package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.d.ts +14 -0
  74. package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.d.ts.map +1 -0
  75. package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.js +21 -0
  76. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +1 -1
  77. package/src/engine/graphics/ecs/particles/ParticleEffect.js +1 -1
  78. package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.d.ts +1 -1
  79. package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.js +1 -1
  80. package/src/engine/graphics3/AnimationGraphSystem.js +3 -3
  81. package/src/engine/graphics3/AnimationSystem.js +2 -2
  82. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  83. package/src/engine/graphics3/DebugDrawSystem.js +2 -4
  84. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +34 -27
  85. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  86. package/src/engine/graphics3/GPUParticleEmitterSystem.js +185 -85
  87. package/src/engine/graphics3/HighlightOutlineSystem.d.ts +4 -3
  88. package/src/engine/graphics3/HighlightOutlineSystem.d.ts.map +1 -1
  89. package/src/engine/graphics3/HighlightOutlineSystem.js +7 -9
  90. package/src/engine/graphics3/LightSystem.d.ts +7 -5
  91. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  92. package/src/engine/graphics3/LightSystem.js +36 -22
  93. package/src/engine/graphics3/MeshSystem.d.ts +43 -39
  94. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  95. package/src/engine/graphics3/MeshSystem.js +324 -331
  96. package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -1
  97. package/src/engine/graphics3/PathDisplaySystem.js +2 -4
  98. package/src/engine/graphics3/PickingQuery.d.ts +15 -21
  99. package/src/engine/graphics3/PickingQuery.d.ts.map +1 -1
  100. package/src/engine/graphics3/PickingQuery.js +21 -25
  101. package/src/engine/graphics3/PickingSystem.d.ts +60 -31
  102. package/src/engine/graphics3/PickingSystem.d.ts.map +1 -1
  103. package/src/engine/graphics3/PickingSystem.js +413 -273
  104. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +22 -12
  105. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  106. package/src/engine/graphics3/ShadedGeometrySystem.js +309 -174
  107. package/src/engine/graphics3/TerrainSystem.d.ts +19 -11
  108. package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -1
  109. package/src/engine/graphics3/TerrainSystem.js +102 -53
  110. package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -1
  111. package/src/engine/graphics3/TooltipComponentSystem.js +2 -14
  112. package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -1
  113. package/src/engine/graphics3/Trail3DSystem.js +2 -4
  114. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +4 -4
  115. package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
  116. package/src/engine/graphics3/animation/ClipListPlayer.js +2 -2
  117. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts +9 -11
  118. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts.map +1 -1
  119. package/src/engine/graphics3/highlight/pack_highlight_table.js +11 -18
  120. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +4 -3
  121. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  122. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +75 -74
  123. package/src/engine/graphics3/prefab/Prefab.d.ts +130 -0
  124. package/src/engine/graphics3/prefab/Prefab.d.ts.map +1 -0
  125. package/src/engine/graphics3/prefab/Prefab.js +162 -0
  126. package/src/engine/graphics3/prefab/PrefabInstance.d.ts +72 -0
  127. package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -0
  128. package/src/engine/graphics3/prefab/PrefabInstance.js +80 -0
  129. package/src/engine/graphics3/prefab/prefab_compile.d.ts +23 -0
  130. package/src/engine/graphics3/prefab/prefab_compile.d.ts.map +1 -0
  131. package/src/engine/graphics3/prefab/prefab_compile.js +334 -0
  132. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +46 -0
  133. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -0
  134. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -0
  135. package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.d.ts +70 -0
  136. package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.d.ts.map +1 -0
  137. package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.js +210 -0
  138. package/src/engine/graphics3/prefab/prefab_place.d.ts +60 -0
  139. package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -0
  140. package/src/engine/graphics3/prefab/prefab_place.js +130 -0
  141. package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.d.ts +60 -0
  142. package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.d.ts.map +1 -0
  143. package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.js +128 -0
  144. package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts +40 -0
  145. package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts.map +1 -0
  146. package/src/engine/graphics3/prefab/prefab_skin_frame.js +116 -0
  147. package/src/engine/graphics3/preview/make_model_preview_scene.d.ts +16 -14
  148. package/src/engine/graphics3/preview/make_model_preview_scene.d.ts.map +1 -1
  149. package/src/engine/graphics3/preview/make_model_preview_scene.js +126 -154
  150. package/src/engine/graphics3/preview/make_model_thumbnail.js +1 -1
  151. package/src/engine/graphics3/register_instance_animation.d.ts +6 -6
  152. package/src/engine/graphics3/register_instance_animation.d.ts.map +1 -1
  153. package/src/engine/graphics3/register_instance_animation.js +4 -4
  154. package/src/engine/graphics3/shade_bundle_bounds.d.ts +2 -6
  155. package/src/engine/graphics3/shade_bundle_bounds.d.ts.map +1 -1
  156. package/src/engine/graphics3/shade_bundle_bounds.js +47 -55
  157. package/src/engine/graphics3/shader_picking_gather.d.ts +40 -0
  158. package/src/engine/graphics3/shader_picking_gather.d.ts.map +1 -0
  159. package/src/engine/graphics3/shader_picking_gather.js +120 -0
  160. package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts +11 -18
  161. package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts.map +1 -1
  162. package/src/engine/graphics3/terrain/pack_terrain_row_table.js +48 -53
  163. package/src/engine/physics/cloth/MEASUREMENTS.md +1050 -0
  164. package/src/engine/physics/cloth/PLAN.md +411 -49
  165. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +17 -2
  166. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  167. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +284 -256
  168. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts +52 -0
  169. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts.map +1 -0
  170. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.js +70 -0
  171. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts +12 -3
  172. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts.map +1 -1
  173. package/src/engine/physics/cloth/ecs/ClothDynamics.js +340 -331
  174. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +49 -37
  175. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  176. package/src/engine/physics/cloth/ecs/ClothInstance.js +50 -37
  177. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +7 -8
  178. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
  179. package/src/engine/physics/cloth/ecs/ClothRig.js +7 -8
  180. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts +84 -0
  181. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts.map +1 -0
  182. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.js +141 -0
  183. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +51 -81
  184. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  185. package/src/engine/physics/cloth/ecs/ClothSystem.js +81 -870
  186. package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts +48 -0
  187. package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts.map +1 -0
  188. package/src/engine/physics/cloth/ecs/ClothWorkerCore.js +107 -0
  189. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +286 -0
  190. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -0
  191. package/src/engine/physics/cloth/ecs/ClothWorld.js +1104 -0
  192. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +182 -0
  193. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -0
  194. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +562 -0
  195. package/src/engine/physics/cloth/ecs/cloth.worker.d.ts +2 -0
  196. package/src/engine/physics/cloth/ecs/cloth.worker.d.ts.map +1 -0
  197. package/src/engine/physics/cloth/ecs/cloth.worker.js +12 -0
  198. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  199. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +2 -1
  200. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +58 -0
  201. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  202. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +341 -271
  203. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +20 -2
  204. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
  205. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +39 -15
  206. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +19 -23
  207. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  208. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +201 -199
  209. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  210. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +8 -0
  211. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts +29 -0
  212. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts.map +1 -0
  213. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.js +78 -0
  214. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +18 -34
  215. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
  216. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +58 -115
  217. package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts +17 -0
  218. package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts.map +1 -0
  219. package/src/engine/physics/cloth/ecs/makeClothWorker.js +18 -0
  220. package/src/engine/physics/cloth/playground/README.md +84 -13
  221. package/src/engine/physics/cloth/playground/garment_build.d.ts +0 -1
  222. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
  223. package/src/engine/physics/cloth/playground/garment_build.js +64 -58
  224. package/src/engine/physics/cloth/playground/garment_main.js +59 -33
  225. package/src/engine/physics/cloth/playground/wind.html +166 -0
  226. package/src/engine/physics/cloth/playground/wind_build.d.ts +81 -0
  227. package/src/engine/physics/cloth/playground/wind_build.d.ts.map +1 -0
  228. package/src/engine/physics/cloth/playground/wind_build.js +141 -0
  229. package/src/engine/physics/cloth/playground/wind_main.d.ts +2 -0
  230. package/src/engine/physics/cloth/playground/wind_main.d.ts.map +1 -0
  231. package/src/engine/physics/cloth/playground/wind_main.js +681 -0
  232. package/src/engine/physics/cloth/solver/ClothState.d.ts +134 -79
  233. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  234. package/src/engine/physics/cloth/solver/ClothState.js +273 -12
  235. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +33 -0
  236. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  237. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +34 -0
  238. package/src/engine/physics/cloth/solver/cloth_step.d.ts +21 -2
  239. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  240. package/src/engine/physics/cloth/solver/cloth_step.js +173 -4
  241. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +40 -0
  242. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -0
  243. package/src/engine/physics/cloth/solver/cloth_step_instance.js +284 -0
  244. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts +107 -0
  245. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts.map +1 -0
  246. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.js +263 -0
  247. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +88 -0
  248. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts.map +1 -0
  249. package/src/engine/physics/cloth/wind/AbstractClothWind.js +100 -0
  250. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts +85 -0
  251. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts.map +1 -0
  252. package/src/engine/physics/cloth/wind/ClothAmbientWind.js +182 -0
  253. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +79 -0
  254. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -0
  255. package/src/engine/physics/cloth/wind/ClothFluidWind.js +210 -0
  256. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +101 -0
  257. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -0
  258. package/src/engine/physics/cloth/wind/cloth_sample_air.js +290 -0
  259. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  260. package/src/shade/RENDERER_CONTRACT.md +85 -53
  261. package/src/shade/device/ShadeGPUCommandContext.d.ts +23 -0
  262. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  263. package/src/shade/device/ShadeGPUCommandContext.js +36 -0
  264. package/src/shade/device/mock/texture_copy.d.ts.map +1 -1
  265. package/src/shade/device/mock/texture_copy.js +28 -0
  266. package/src/shade/playground/add_random_meshes.d.ts +4 -4
  267. package/src/shade/playground/add_random_meshes.d.ts.map +1 -1
  268. package/src/shade/playground/add_random_meshes.js +20 -16
  269. package/src/shade/playground/avboit/main.d.ts +1 -0
  270. package/src/shade/playground/avboit/main.d.ts.map +1 -1
  271. package/src/shade/playground/avboit/main.js +916 -875
  272. package/src/shade/playground/basis_textures/main.d.ts.map +1 -1
  273. package/src/shade/playground/basis_textures/main.js +22 -8
  274. package/src/shade/playground/basis_textures/texture_inventory.d.ts +2 -2
  275. package/src/shade/playground/basis_textures/texture_inventory.d.ts.map +1 -1
  276. package/src/shade/playground/basis_textures/texture_inventory.js +6 -7
  277. package/src/shade/playground/ground_seam/main.d.ts.map +1 -1
  278. package/src/shade/playground/ground_seam/main.js +13 -4
  279. package/src/shade/playground/ground_seam/make_ground.d.ts +13 -4
  280. package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -1
  281. package/src/shade/playground/ground_seam/make_ground.js +21 -16
  282. package/src/shade/playground/particle_ecs/bonfire_editor.js +3 -3
  283. package/src/shade/playground/particle_system/main.js +11 -10
  284. package/src/shade/playground/particle_system/particle_prototype.d.ts +15 -10
  285. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  286. package/src/shade/playground/particle_system/particle_prototype.js +56 -15
  287. package/src/shade/playground/particle_system/particle_scene.d.ts +68 -28
  288. package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
  289. package/src/shade/playground/particle_system/particle_scene.js +149 -53
  290. package/src/shade/playground/readback_crossover/index.html +41 -0
  291. package/src/shade/playground/readback_crossover/main.d.ts +2 -0
  292. package/src/shade/playground/readback_crossover/main.d.ts.map +1 -0
  293. package/src/shade/playground/readback_crossover/main.js +372 -0
  294. package/src/shade/playground/skinned_blas_refit/README.md +11 -7
  295. package/src/shade/playground/skinned_blas_refit/add_floor.d.ts +13 -44
  296. package/src/shade/playground/skinned_blas_refit/add_floor.d.ts.map +1 -1
  297. package/src/shade/playground/skinned_blas_refit/add_floor.js +19 -59
  298. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  299. package/src/shade/playground/skinned_blas_refit/main.js +67 -58
  300. package/src/shade/playground/skinned_blas_refit/place_character.d.ts +40 -54
  301. package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
  302. package/src/shade/playground/skinned_blas_refit/place_character.js +47 -74
  303. package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts +3 -3
  304. package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts.map +1 -1
  305. package/src/shade/playground/skinned_blas_refit/sweep_views.js +4 -3
  306. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts +3 -3
  307. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts.map +1 -1
  308. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.js +11 -4
  309. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.d.ts.map +1 -1
  310. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.js +38 -9
  311. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts +3 -3
  312. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
  313. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +9 -6
  314. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts +3 -3
  315. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts.map +1 -1
  316. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +3 -3
  317. package/src/shade/playground/skinned_mesh_soup/README.md +6 -6
  318. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  319. package/src/shade/playground/skinned_mesh_soup/main.js +44 -102
  320. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts +5 -5
  321. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
  322. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +42 -33
  323. package/src/shade/playground/sponza_path_trace/main.d.ts +1 -0
  324. package/src/shade/playground/sponza_path_trace/main.d.ts.map +1 -1
  325. package/src/shade/playground/sponza_path_trace/main.js +393 -363
  326. package/src/shade/playground/ssr_reprojection/main.js +11 -9
  327. package/src/shade/playground/ssr_reprojection/scene.d.ts +15 -4
  328. package/src/shade/playground/ssr_reprojection/scene.d.ts.map +1 -1
  329. package/src/shade/playground/ssr_reprojection/scene.js +32 -11
  330. package/src/shade/playground/ssr_variance/main.js +1 -1
  331. package/src/shade/playground/ssr_variance/scene.d.ts +10 -4
  332. package/src/shade/playground/ssr_variance/scene.d.ts.map +1 -1
  333. package/src/shade/playground/ssr_variance/scene.js +39 -15
  334. package/src/shade/playground/vgeo_runtime/README.md +94 -0
  335. package/src/shade/playground/vgeo_runtime/index.html +62 -0
  336. package/src/shade/playground/vgeo_runtime/main.d.ts +2 -0
  337. package/src/shade/playground/vgeo_runtime/main.d.ts.map +1 -0
  338. package/src/shade/playground/vgeo_runtime/main.js +399 -0
  339. package/src/shade/playground/vgeo_viewer/main.js +6 -2
  340. package/src/shade/playground/vgeo_viewer/sample_asset.js +1 -1
  341. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  342. package/src/shade/playground/volumetrics_froxel/main.js +936 -922
  343. package/src/shade/renderer/GraphicsContext.d.ts +7 -0
  344. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  345. package/src/shade/renderer/GraphicsContext.js +11 -0
  346. package/src/shade/renderer/Renderer.d.ts +3 -2
  347. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  348. package/src/shade/renderer/Renderer.js +3 -2
  349. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +39 -47
  350. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  351. package/src/shade/renderer/animation/GPUAnimationManager.js +319 -256
  352. package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts +26 -22
  353. package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts.map +1 -1
  354. package/src/shade/renderer/animation/ShadeAnimationChannel.js +28 -23
  355. package/src/shade/renderer/animation/ShadeAnimationClip.d.ts +14 -6
  356. package/src/shade/renderer/animation/ShadeAnimationClip.d.ts.map +1 -1
  357. package/src/shade/renderer/animation/ShadeAnimationClip.js +20 -8
  358. package/src/shade/renderer/animation/Skin.d.ts +19 -19
  359. package/src/shade/renderer/animation/Skin.d.ts.map +1 -1
  360. package/src/shade/renderer/animation/Skin.js +15 -13
  361. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts +6 -5
  362. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts.map +1 -1
  363. package/src/shade/renderer/animation/pose/pose_evaluate_local.js +9 -9
  364. package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts +5 -59
  365. package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts.map +1 -1
  366. package/src/shade/renderer/animation/skin_clip_scale_conflicts.js +8 -132
  367. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +65 -62
  368. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  369. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +148 -194
  370. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.d.ts.map +1 -1
  371. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +4 -7
  372. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.d.ts +2 -2
  373. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +2 -2
  374. package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts +74 -0
  375. package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts.map +1 -0
  376. package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.js +240 -0
  377. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +14 -0
  378. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  379. package/src/shade/renderer/buffer/table/GPUDatabase.js +64 -6
  380. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts +190 -0
  381. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts.map +1 -0
  382. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.js +1323 -0
  383. package/src/shade/renderer/buffer/table/GPUPageMetadata.d.ts +10 -0
  384. package/src/shade/renderer/buffer/table/GPUPageMetadata.d.ts.map +1 -1
  385. package/src/shade/renderer/buffer/table/GPUPageMetadata.js +12 -0
  386. package/src/shade/renderer/buffer/table/GPUReadbackStatus.d.ts +15 -0
  387. package/src/shade/renderer/buffer/table/GPUReadbackStatus.d.ts.map +1 -0
  388. package/src/shade/renderer/buffer/table/GPUReadbackStatus.js +34 -0
  389. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +75 -7
  390. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  391. package/src/shade/renderer/buffer/table/GPUTypedTable.js +518 -135
  392. package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.d.ts +19 -0
  393. package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.d.ts.map +1 -0
  394. package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.js +18 -0
  395. package/src/shade/renderer/buffer/table/WordViews.d.ts +39 -0
  396. package/src/shade/renderer/buffer/table/WordViews.d.ts.map +1 -0
  397. package/src/shade/renderer/buffer/table/WordViews.js +62 -0
  398. package/src/shade/renderer/buffer/table/gpu_table_gather_shader.d.ts +27 -0
  399. package/src/shade/renderer/buffer/table/gpu_table_gather_shader.d.ts.map +1 -0
  400. package/src/shade/renderer/buffer/table/gpu_table_gather_shader.js +117 -0
  401. package/src/shade/renderer/buffer/table/serde/generate_record_writer.d.ts +121 -0
  402. package/src/shade/renderer/buffer/table/serde/generate_record_writer.d.ts.map +1 -0
  403. package/src/shade/renderer/buffer/table/serde/generate_record_writer.js +395 -0
  404. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  405. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +70 -20
  406. package/src/shade/renderer/camera/Camera.d.ts +14 -0
  407. package/src/shade/renderer/camera/Camera.d.ts.map +1 -1
  408. package/src/shade/renderer/camera/Camera.js +7 -1
  409. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +1 -1
  410. package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.d.ts.map +1 -1
  411. package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.js +16 -1
  412. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  413. package/src/shade/renderer/geometry/GPUGeometryManager.js +29 -9
  414. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts +10 -0
  415. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts.map +1 -1
  416. package/src/shade/renderer/geometry/GPUGeometryMetadata.js +13 -0
  417. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  418. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +6 -5
  419. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +3 -3
  420. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  421. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +15 -11
  422. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +46 -18
  423. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +70 -22
  424. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +97 -19
  425. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +12 -2
  426. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  427. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +14 -3
  428. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +2 -2
  429. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
  430. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +124 -6
  431. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +22 -0
  432. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +1 -0
  433. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.js +53 -0
  434. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +8 -1
  435. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  436. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +8 -1
  437. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts +16 -0
  438. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts.map +1 -0
  439. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.js +15 -0
  440. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts +54 -0
  441. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts.map +1 -0
  442. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.js +53 -0
  443. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +13 -2
  444. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
  445. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +14 -2
  446. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +100 -0
  447. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  448. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +113 -0
  449. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  450. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +5 -0
  451. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  452. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +108 -0
  453. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  454. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +23 -0
  455. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  456. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +40 -0
  457. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +228 -0
  458. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -0
  459. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +932 -0
  460. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +176 -0
  461. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -0
  462. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +425 -0
  463. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +241 -0
  464. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +574 -0
  465. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +120 -0
  466. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -0
  467. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +674 -0
  468. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +287 -0
  469. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -0
  470. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +976 -0
  471. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +42 -0
  472. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -0
  473. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +96 -0
  474. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts +16 -0
  475. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts.map +1 -0
  476. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.js +15 -0
  477. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts +19 -0
  478. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -0
  479. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +83 -0
  480. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts +9 -0
  481. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts.map +1 -0
  482. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.js +8 -0
  483. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +19 -0
  484. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -0
  485. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +160 -0
  486. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts +3 -0
  487. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -0
  488. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +255 -0
  489. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts +3 -0
  490. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -0
  491. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +80 -0
  492. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts +3 -0
  493. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -0
  494. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +144 -0
  495. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts +3 -0
  496. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -0
  497. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +530 -0
  498. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +39 -0
  499. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -0
  500. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +54 -0
  501. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts +41 -0
  502. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts.map +1 -0
  503. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.js +56 -0
  504. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts +49 -0
  505. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -0
  506. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +328 -0
  507. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +10 -0
  508. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts.map +1 -0
  509. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +51 -0
  510. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +13 -0
  511. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -0
  512. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +12 -0
  513. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +17 -0
  514. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts.map +1 -0
  515. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +99 -0
  516. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts +9 -0
  517. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts.map +1 -0
  518. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +8 -0
  519. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +7 -0
  520. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts.map +1 -0
  521. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +27 -0
  522. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts +14 -0
  523. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts.map +1 -0
  524. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.js +13 -0
  525. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts +7 -0
  526. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts.map +1 -0
  527. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.js +35 -0
  528. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts +9 -0
  529. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts.map +1 -0
  530. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.js +8 -0
  531. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts +15 -0
  532. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts.map +1 -0
  533. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.js +14 -0
  534. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +7 -0
  535. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts.map +1 -0
  536. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +36 -0
  537. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +10 -0
  538. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -0
  539. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +9 -0
  540. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts +11 -0
  541. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts.map +1 -0
  542. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.js +54 -0
  543. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts +9 -0
  544. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts.map +1 -0
  545. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.js +8 -0
  546. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts +11 -0
  547. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts.map +1 -0
  548. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.js +10 -0
  549. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts +7 -0
  550. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts.map +1 -0
  551. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.js +30 -0
  552. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts +9 -0
  553. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts.map +1 -0
  554. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.js +8 -0
  555. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts +13 -0
  556. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts.map +1 -0
  557. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.js +12 -0
  558. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts +14 -0
  559. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts.map +1 -0
  560. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.js +13 -0
  561. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +11 -0
  562. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts.map +1 -0
  563. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +61 -0
  564. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts +9 -0
  565. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -0
  566. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +8 -0
  567. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts +13 -0
  568. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts.map +1 -0
  569. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.js +12 -0
  570. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts +9 -0
  571. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts.map +1 -0
  572. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.js +8 -0
  573. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts +20 -0
  574. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts.map +1 -0
  575. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.js +19 -0
  576. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts +23 -0
  577. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -0
  578. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +70 -0
  579. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +18 -0
  580. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -0
  581. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +25 -0
  582. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +35 -0
  583. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -0
  584. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +41 -0
  585. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +32 -0
  586. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -0
  587. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +138 -0
  588. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.d.ts +1 -1
  589. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.js +4 -4
  590. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts +1 -3
  591. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts.map +1 -1
  592. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.js +5 -4
  593. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +1 -1
  594. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  595. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +1 -4
  596. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts +8 -3
  597. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts.map +1 -1
  598. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.js +19 -14
  599. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts.map +1 -1
  600. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +9 -1
  601. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts +3 -3
  602. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts.map +1 -1
  603. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.js +12 -5
  604. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +1 -1
  605. package/src/shade/renderer/light/GPULightCollection.d.ts +29 -0
  606. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  607. package/src/shade/renderer/light/GPULightCollection.js +444 -329
  608. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.d.ts.map +1 -1
  609. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.js +7 -1
  610. package/src/shade/renderer/light/LightCollection.d.ts +29 -1
  611. package/src/shade/renderer/light/LightCollection.d.ts.map +1 -1
  612. package/src/shade/renderer/light/LightCollection.js +50 -1
  613. package/src/shade/renderer/light/make_sunlight.js +2 -2
  614. package/src/shade/renderer/light/model/Light.d.ts +29 -2
  615. package/src/shade/renderer/light/model/Light.d.ts.map +1 -1
  616. package/src/shade/renderer/light/model/Light.js +30 -2
  617. package/src/shade/renderer/light/model/io/light_record_directional.d.ts +3 -1
  618. package/src/shade/renderer/light/model/io/light_record_directional.d.ts.map +1 -1
  619. package/src/shade/renderer/light/model/io/light_record_directional.js +8 -5
  620. package/src/shade/renderer/light/model/io/light_record_point.d.ts +3 -1
  621. package/src/shade/renderer/light/model/io/light_record_point.d.ts.map +1 -1
  622. package/src/shade/renderer/light/model/io/light_record_point.js +5 -2
  623. package/src/shade/renderer/light/model/io/light_record_spot.d.ts +4 -1
  624. package/src/shade/renderer/light/model/io/light_record_spot.d.ts.map +1 -1
  625. package/src/shade/renderer/light/model/io/light_record_spot.js +10 -6
  626. package/src/shade/renderer/light/place_light.d.ts +16 -0
  627. package/src/shade/renderer/light/place_light.d.ts.map +1 -0
  628. package/src/shade/renderer/light/place_light.js +36 -0
  629. package/src/shade/renderer/light/shader_refresh_light_poses.d.ts +44 -0
  630. package/src/shade/renderer/light/shader_refresh_light_poses.d.ts.map +1 -0
  631. package/src/shade/renderer/light/shader_refresh_light_poses.js +154 -0
  632. package/src/shade/renderer/lightmap/GPULightMap.js +1 -1
  633. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
  634. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +12 -14
  635. package/src/shade/renderer/loader/SceneBundle.d.ts +53 -28
  636. package/src/shade/renderer/loader/SceneBundle.d.ts.map +1 -1
  637. package/src/shade/renderer/loader/SceneBundle.js +111 -56
  638. package/src/shade/renderer/loader/SceneNode.d.ts +81 -0
  639. package/src/shade/renderer/loader/SceneNode.d.ts.map +1 -0
  640. package/src/shade/renderer/loader/SceneNode.js +114 -0
  641. package/src/shade/renderer/loader/gltf/load_gltf.d.ts +3 -2
  642. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  643. package/src/shade/renderer/loader/gltf/load_gltf.js +110 -142
  644. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  645. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.d.ts +4 -4
  646. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.d.ts.map +1 -1
  647. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.js +2 -2
  648. package/src/shade/renderer/loader/usd/load_usd.d.ts +3 -2
  649. package/src/shade/renderer/loader/usd/load_usd.d.ts.map +1 -1
  650. package/src/shade/renderer/loader/usd/load_usd.js +4 -5
  651. package/src/shade/renderer/loader/usd/usd_build_scene.d.ts +3 -3
  652. package/src/shade/renderer/loader/usd/usd_build_scene.d.ts.map +1 -1
  653. package/src/shade/renderer/loader/usd/usd_build_scene.js +47 -55
  654. package/src/shade/renderer/material/GPUMaterialManager.js +1 -1
  655. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +5 -4
  656. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  657. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +8 -15
  658. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts +15 -13
  659. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts.map +1 -1
  660. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.js +40 -21
  661. package/src/shade/renderer/particles/DESIGN.md +53 -50
  662. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +31 -17
  663. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  664. package/src/shade/renderer/particles/GPUParticleSystem.js +54 -91
  665. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +12 -11
  666. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  667. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +12 -11
  668. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +13 -19
  669. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -1
  670. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +19 -25
  671. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +34 -24
  672. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  673. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +53 -40
  674. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +1 -1
  675. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +1 -1
  676. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  677. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  678. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +9 -0
  679. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts.map +1 -1
  680. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.js +2 -1
  681. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.d.ts.map +1 -1
  682. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.js +5 -2
  683. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  684. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +13 -2
  685. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +1 -1
  686. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +1 -1
  687. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +1 -1
  688. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  689. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +12 -1
  690. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  691. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +10 -0
  692. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +1 -1
  693. package/src/shade/renderer/scene/DynamicMesh.d.ts +13 -4
  694. package/src/shade/renderer/scene/DynamicMesh.d.ts.map +1 -1
  695. package/src/shade/renderer/scene/DynamicMesh.js +14 -4
  696. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +38 -18
  697. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  698. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +112 -60
  699. package/src/shade/renderer/scene/GPUSceneContext.d.ts +69 -44
  700. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  701. package/src/shade/renderer/scene/GPUSceneContext.js +244 -525
  702. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +5 -5
  703. package/src/shade/renderer/scene/NODE3D_STRUCT.js +5 -5
  704. package/src/shade/renderer/scene/Scene.d.ts +18 -60
  705. package/src/shade/renderer/scene/Scene.d.ts.map +1 -1
  706. package/src/shade/renderer/scene/Scene.js +53 -146
  707. package/src/shade/renderer/scene/bvh/StaticSceneBVH.d.ts +24 -3
  708. package/src/shade/renderer/scene/bvh/StaticSceneBVH.d.ts.map +1 -1
  709. package/src/shade/renderer/scene/bvh/StaticSceneBVH.js +53 -13
  710. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts +5 -6
  711. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts.map +1 -1
  712. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.js +5 -6
  713. package/src/shade/renderer/scene/optimization/scene_optimize.d.ts +10 -2
  714. package/src/shade/renderer/scene/optimization/scene_optimize.d.ts.map +1 -1
  715. package/src/shade/renderer/scene/optimization/scene_optimize.js +266 -230
  716. package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.d.ts +53 -0
  717. package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.d.ts.map +1 -0
  718. package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.js +144 -0
  719. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +227 -0
  720. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -0
  721. package/src/shade/renderer/scene/rows/GPUSceneRows.js +1158 -0
  722. package/src/shade/renderer/scene/rows/place_primitive.d.ts +48 -0
  723. package/src/shade/renderer/scene/rows/place_primitive.d.ts.map +1 -0
  724. package/src/shade/renderer/scene/rows/place_primitive.js +98 -0
  725. package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts +10 -8
  726. package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts.map +1 -1
  727. package/src/shade/renderer/scene/serialization/deserialize_scene.js +24 -27
  728. package/src/shade/renderer/scene/serialization/serialize_scene.d.ts +9 -2
  729. package/src/shade/renderer/scene/serialization/serialize_scene.d.ts.map +1 -1
  730. package/src/shade/renderer/scene/serialization/serialize_scene.js +25 -4
  731. package/src/shade/renderer/scene/verify_gpu_tlas_build.js +2 -2
  732. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts +35 -0
  733. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts.map +1 -0
  734. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.js +91 -0
  735. package/src/shade/renderer/shader/chunk/light/DIRECTIONAL_LIGHT_STRUCT.d.ts.map +1 -1
  736. package/src/shade/renderer/shader/chunk/light/DIRECTIONAL_LIGHT_STRUCT.js +5 -0
  737. package/src/shade/renderer/shader/chunk/light/POINT_LIGHT_STRUCT.d.ts.map +1 -1
  738. package/src/shade/renderer/shader/chunk/light/POINT_LIGHT_STRUCT.js +5 -0
  739. package/src/shade/renderer/shader/chunk/light/SPOT_LIGHT_STRUCT.d.ts.map +1 -1
  740. package/src/shade/renderer/shader/chunk/light/SPOT_LIGHT_STRUCT.js +5 -0
  741. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts +39 -0
  742. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
  743. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +112 -64
  744. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +7 -0
  745. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  746. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +1541 -1352
  747. package/src/shade/renderer/shadow/map/PointLightShadowmap.js +1 -1
  748. package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +1 -1
  749. package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +1 -1
  750. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts +29 -0
  751. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts.map +1 -0
  752. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.js +43 -0
  753. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.d.ts +13 -0
  754. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.d.ts.map +1 -0
  755. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.js +12 -0
  756. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts +49 -0
  757. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts.map +1 -0
  758. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.js +194 -0
  759. package/src/shade/renderer/shadow/map/csm_debug_draw_preview.js +1 -1
  760. package/src/shade/renderer/shadow/map/shadowmap_update_score.js +1 -1
  761. package/src/shade/renderer/shadow/ray/RTXShadows.js +1 -1
  762. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +1 -1
  763. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
  764. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +3 -1
  765. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +8 -8
  766. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  767. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +4 -3
  768. package/src/engine/graphics3/instantiate_scene_bundle.d.ts +0 -54
  769. package/src/engine/graphics3/instantiate_scene_bundle.d.ts.map +0 -1
  770. package/src/engine/graphics3/instantiate_scene_bundle.js +0 -164
  771. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts +0 -39
  772. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts.map +0 -1
  773. package/src/engine/graphics3/shade_node_to_entity_composition.js +0 -88
  774. package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts +0 -35
  775. package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts.map +0 -1
  776. package/src/shade/renderer/animation/compute_skin_world_bounds.js +0 -146
  777. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts +0 -96
  778. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts.map +0 -1
  779. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.js +0 -531
  780. package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts +0 -20
  781. package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts.map +0 -1
  782. package/src/shade/renderer/animation/pose/pose_evaluate_world.js +0 -76
  783. package/src/shade/renderer/animation/skin_bind_transform.d.ts +0 -25
  784. package/src/shade/renderer/animation/skin_bind_transform.d.ts.map +0 -1
  785. package/src/shade/renderer/animation/skin_bind_transform.js +0 -33
  786. package/src/shade/renderer/animation/skin_frame_defect.d.ts +0 -34
  787. package/src/shade/renderer/animation/skin_frame_defect.d.ts.map +0 -1
  788. package/src/shade/renderer/animation/skin_frame_defect.js +0 -132
  789. package/src/shade/renderer/animation/skin_joint_matrix.d.ts +0 -24
  790. package/src/shade/renderer/animation/skin_joint_matrix.d.ts.map +0 -1
  791. package/src/shade/renderer/animation/skin_joint_matrix.js +0 -46
  792. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts +0 -70
  793. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts.map +0 -1
  794. package/src/shade/renderer/animation/skin_normalize_mesh_frame.js +0 -216
  795. package/src/shade/renderer/scene/InstanceBatch.d.ts +0 -92
  796. package/src/shade/renderer/scene/InstanceBatch.d.ts.map +0 -1
  797. package/src/shade/renderer/scene/InstanceBatch.js +0 -235
  798. package/src/shade/renderer/scene/Mesh.d.ts +0 -55
  799. package/src/shade/renderer/scene/Mesh.d.ts.map +0 -1
  800. package/src/shade/renderer/scene/Mesh.js +0 -168
  801. package/src/shade/renderer/scene/Node3D.d.ts +0 -140
  802. package/src/shade/renderer/scene/Node3D.d.ts.map +0 -1
  803. package/src/shade/renderer/scene/Node3D.js +0 -263
  804. package/src/shade/renderer/scene/SceneNodeBinding.d.ts +0 -52
  805. package/src/shade/renderer/scene/SceneNodeBinding.d.ts.map +0 -1
  806. package/src/shade/renderer/scene/SceneNodeBinding.js +0 -56
  807. package/src/shade/renderer/scene/SkinnedMesh.d.ts +0 -110
  808. package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +0 -1
  809. package/src/shade/renderer/scene/SkinnedMesh.js +0 -170
  810. package/src/shade/renderer/scene/TransformAuthority.d.ts +0 -19
  811. package/src/shade/renderer/scene/TransformAuthority.d.ts.map +0 -1
  812. package/src/shade/renderer/scene/TransformAuthority.js +0 -33
@@ -1,7 +1,8 @@
1
1
  # Cloth — Design
2
2
 
3
- > Design document. Written 2026-09-10; **M0, M1, M2 and M3's rigged path are implemented**, and
4
- > every place they contradicted it has been corrected in place with the measurement named beside it.
3
+ > Design document. Written 2026-09-10; **M0 through M5 are implemented** — the solver, chains,
4
+ > collision, the rigged path, self-collision and the worker — and every place they contradicted it has
5
+ > been corrected in place with the measurement named beside it.
5
6
  > §17 says what is done and what is not; `MEASUREMENTS.md` is the evidence.
6
7
  >
7
8
  > Scope: a cloth and soft-chain simulator that lives inside `engine/physics`, collides against the
@@ -271,7 +272,8 @@ engine/physics/cloth/
271
272
  cloth_dynamics_map.js normalised coordinates → row parameters; every constant measured
272
273
  ClothCollider.js component: the RigidBody-analogue for collision
273
274
  ClothColliderFlags.js
274
- ClothSystem.js main-thread system: gather, step, write back
275
+ ClothWorld.js every cloth in a scene, and everything that is not arithmetic
276
+ ClothSystem.js main-thread system: a ClothWorld stepped inline
275
277
  ClothInstance.js one live cloth: the binding between a subtree and a ClothState
276
278
  cloth_seed_subtree.js §11.1's walk: entities → node_parent + animated_position
277
279
  cloth_seed_rig.js §11.2's proxy: joints → node_parent + animated_position
@@ -280,14 +282,14 @@ engine/physics/cloth/
280
282
  cloth_write_back.js that pose → Transform64 + TransformAttachment
281
283
  cloth_write_back_rig.js that pose → Node3D.transform_local
282
284
  cloth_gather_colliders.js the index's overlapping records, in the cloth's own frame
283
- WorkerClothSystem.js drop-in worker variant (WorkerSystem subclass)
284
- ClothWorkerCore.js
285
- cloth.worker.js
286
- makeClothWorker.js
287
- cloth_worker_protocol.js
288
- ClothSerializationAdapter.js
289
- ClothRigSerializationAdapter.js
290
- ClothColliderSerializationAdapter.js
285
+ WorkerClothSystem.js drop-in worker variant: the same ClothWorld, stepped over there
286
+ ClothWorkerCore.js worker side: a ClothState view per registered cloth
287
+ cloth.worker.js the entry point, a real module worker
288
+ makeClothWorker.js the spawn expression, isolated because it needs import.meta
289
+ cloth_worker_protocol.js the command region: a count, then a block per cloth
290
+ ClothSerializationAdapter.js the component + its ClothDynamics, by value
291
+ ClothColliderSerializationAdapter.js five authored scalars, the same way
292
+ ClothRigSerializationAdapter.js NOT BUILT — §3.2's asset identity, and the proxy codec
291
293
  collider/
292
294
  ClothColliderIndex.js the index of live cloth colliders + their swept AABBs
293
295
  ClothColliderRecord.js the packed layout: kind, params, both poses, bounds, interpolated pose
@@ -295,10 +297,17 @@ engine/physics/cloth/
295
297
  cloth_collider_pack.js AbstractShape3D → packed record
296
298
  cloth_collider_bounds.js the swept AABB, shared by the index and each cloth's own table
297
299
  cloth_collider_sdf.js pose interpolation, localisation, and the field dispatch
300
+ wind/
301
+ AbstractClothWind.js §10's one interface: sample the air, and say whether it varies
302
+ ClothAmbientWind.js a constant plus a band-limited gust — the air where no field is
303
+ ClothFluidWind.js every live FluidComponent, with the ambient underneath it
304
+ cloth_sample_air.js the air into the cloth's own frame, on the main thread
298
305
  solver/
299
306
  ClothState.js SoA particle + topology + constraint storage over one buffer
307
+ cloth_step_instance.js one cloth, one step, over nothing but memory — what crosses
300
308
  cloth_step.js the fixed step: predict, warm start, iterate, dual update, integrate
301
309
  cloth_solve_vertex.js the per-vertex 3x3 block update
310
+ cloth_wind_accelerate.js §10's aerodynamic term, and the factor that makes a flag a flag
302
311
  constraint/ one module per row type (§6)
303
312
  cloth_color_particles.js graph colouring of the particle graph
304
313
  constraint/cloth_leash_row.js §6's slack row and its tether row, which are one row model
@@ -340,10 +349,19 @@ Two systems:
340
349
  - **`ClothSystem`** owns the simulation. Per fixed step: refresh the animated targets, gather the
341
350
  overlapping colliders from the index, step, write back.
342
351
 
343
- Cloth runs at the fixed rate and is interpolated for display, exactly as `PhysicsSystem` does — the
344
- same producer/`__interp_restore` contract, so a cloth-driven `Transform64` is authoritative during the
345
- fixed pass and interpolated outside it. Reusing the existing contract rather than inventing a second
346
- one is what keeps a cloth-driven bone from fighting an animation-driven one.
352
+ **M5 note: it owns it jointly with `WorkerClothSystem`, and "two systems" is now three.** The two
353
+ are interchangeable — same components, same declared access, same position in the derived order —
354
+ and they share a `ClothWorld`, which is the registry and every phase of a step that is not
355
+ arithmetic. `ClothSystem` calls `cloth_step_instance` between the two halves; `WorkerClothSystem`
356
+ puts a thread there. §12 has why that is what makes the bit-parity gate structural.
357
+
358
+ Cloth runs at the fixed rate and its poses are **held** between ticks rather than interpolated, which
359
+ on a display faster than the fixed step is visible and is not wrong. The first draft of this paragraph
360
+ said cloth reuses `PhysicsSystem`'s producer/`__interp_restore` contract; M5 measured that it cannot —
361
+ that contract is entity-keyed and a rigged garment's joints are not entities — and §13.1 and §18 carry
362
+ what the cloth-shaped version would be and what it would cost. What keeps a cloth-driven bone from
363
+ fighting an animation-driven one is not interpolation but `TransformAuthority`, which `cloth_seed_rig`
364
+ claims (§11.2, `MEASUREMENTS.md` §25).
347
365
 
348
366
  ### 4.1 Ordering, and why the answer is not to be ordered
349
367
 
@@ -874,6 +892,15 @@ which arrives with the component in M1 — so **damping is load-bearing for P5 r
874
892
  control**, and the M1 spec has to gate on a soft cloth actually settling. `MEASUREMENTS.md` §6.
875
893
  *Spec:* a settled cloth reaches sleep within a bounded number of steps and its positions are bit-identical
876
894
  across the following 300.
895
+ **M6 note: a cloth also wakes on the air changing, and the test has one sample in it.** §10's "sleep
896
+ wakes on a wind change" is the same shape as the collider test beside it — ask a question three orders
897
+ of magnitude cheaper than the step it decides whether to skip — and the question is the air at the
898
+ cloth's own centre against the air the last *applied* step saw. The last applied rather than the last
899
+ sampled, so a gust that builds slowly accumulates instead of being reset by every step that declined
900
+ to act on it. *Its limit, stated:* one point. A gust that reaches only the hem of a sleeping banner
901
+ and leaves its middle still will not wake it. The collider test has no such gap because a collider's
902
+ pose is seven exact numbers and a field is a continuum.
903
+
877
904
  *M1 landed both halves and measured them.* Every library fabric, on a 12-link chain set swinging at
878
905
  3 m/s, sleeps: **220 steps for denim, 770 for silk**, everything else between, and the order is the
879
906
  damping order. Sleep stops the **write-back** as well as the step, which is what makes "bit-identical"
@@ -1090,8 +1117,7 @@ the bodies in the scene.
1090
1117
 
1091
1118
  So the design is: **a cloth overlapping a `FluidComponent` samples its velocity field per particle and
1092
1119
  applies aerodynamic drag against it**, scaled by `ClothDynamics#drag`. The term is an external
1093
- acceleration, `a_drag = drag · (u_air − v) · |n·û|`, with the normal-facing factor making a sheet catch
1094
- the wind broadside and slice through it edge-on — the difference between a flag and a rope.
1120
+ acceleration, `a_drag = response · facing · (u_air − v)`.
1095
1121
 
1096
1122
  The payoff is that a character running past a cape gets a wake, because the fluid solver already
1097
1123
  produces one; a fire's convection lifts a banner; a door slamming pushes a curtain. None of that needs
@@ -1106,8 +1132,69 @@ Cost control: sampling is per particle per *step*, not per iteration, and a clot
1106
1132
  field's bounds skips it entirely. Sleep (P5) wakes on a wind change so a settled banner does not stay
1107
1133
  asleep through a gust.
1108
1134
 
1109
- This is deferred to M6 — it is the feature most likely to be cut for schedule, and nothing else depends
1110
- on it.
1135
+ **M6 built it and corrected this section in four places.**
1136
+
1137
+ **The factor above is not `|n·û|`, because half of what this system simulates has no `n`.** This
1138
+ paragraph originally wrote the term as `a_drag = drag · (u_air − v) · |n·û|`, "with the normal-facing
1139
+ factor making a sheet catch the wind broadside and slice through it edge-on — the difference between a
1140
+ flag and a rope". It is right about what it wants and wrong that a normal is available to want it
1141
+ with. A chain's particles span a **line** — every direction perpendicular to it is equally a normal,
1142
+ so picking one is the history-dependent fabrication §7 P4(a) exists to keep out — and a rope's
1143
+ aerodynamics are the *complement* of a sheet's anyway: it catches the flow across it and slices along
1144
+ it. Both are one quantity, **the part of the flow the particle's own incident rows cannot let past**:
1145
+ take the span `T` of the directions to its stretch-row neighbours in the current configuration, and
1146
+ `facing = ‖û − proj_T(û)‖`.
1147
+
1148
+ | rank of `T` | what the particle is | the factor |
1149
+ |---|---|---|
1150
+ | 2 | a point on a surface | `\|û·n\|` with `n = b₁×b₂` — this paragraph's own expression |
1151
+ | 1 | a link of a chain | `√(1 − (û·t)²)` — the cross-flow, which is the rope's answer |
1152
+ | 0 | an isolated particle | `1` — a bead has no preferred direction |
1153
+
1154
+ One expression, three topologies, no stored normal, no orientation, no sign, nothing carried between
1155
+ steps. `MEASUREMENTS.md` §47.
1156
+
1157
+ **And the factor's headline claim is about *laminar* air, which is a limit rather than a fault.** On
1158
+ the playground's banner, turning a uniform wind through ninety degrees takes the mean factor from
1159
+ 0.221 to **0.000** and the aerodynamic acceleration from 43.2 m/s² to 0.08 — a flag becoming a rope,
1160
+ exactly as promised. Turning a **wake** through ninety degrees does nothing at all: 0.216 to 0.280. A
1161
+ wake has velocity in every direction, so no orientation of a surface is edge-on to one, and the factor
1162
+ is correctly reporting that there is nothing to slice through. That makes this section's argument for
1163
+ reading a simulation *stronger* than this section knew. `MEASUREMENTS.md` §51.
1164
+
1165
+ **`drag` is not what multiplies the flow, and the difference is a stability argument.** One external
1166
+ acceleration is held for the whole fixed step, so an explicit `rate · (u_air − v)` overshoots the air
1167
+ once `rate·dt > 1` and diverges past 2 — and §1's first commitment is "not at 5 fps", which is a `dt`
1168
+ of 0.2 s and a rate of 10. What the step multiplies by is the **per-step response**
1169
+ `(1 − e^(−rate·dt))/dt` (`cloth_drag_response`), the exact solution of the same linear ODE, which
1170
+ closes a fraction of the gap that is strictly below one for every rate and every step length. It is
1171
+ also the step `GlobalFluidEffector` already takes for the air itself, which is a symmetry rather than
1172
+ a coincidence: both are relaxations toward a velocity. `MEASUREMENTS.md` §49.
1173
+
1174
+ **The field answers in grid cells per second and cloth needs metres.** `FluidField#sampleVelocity`
1175
+ documents that it deliberately does not rescale, "on the assumption that callers (vegetation sway,
1176
+ dust drift) interpret the field as a direction × magnitude wind". Cloth is not such a caller: its row
1177
+ is a relaxation toward a velocity, so without the multiply by `cell_size` the same wind voxelised at
1178
+ 0.25 m instead of 1 m blows a garment four times as hard. `ClothFluidWind` converts.
1179
+ `MEASUREMENTS.md` §46.
1180
+
1181
+ **And this section never said which thread samples, which M5 made a question.** It cannot be the
1182
+ worker's: a fluid field is a hundred thousand floats its own solver rewrites every step and may itself
1183
+ live on another worker, while the *answer* is three floats a particle. So `cloth_sample_air` runs on
1184
+ the **main thread** in both systems and writes into `ClothState#air_velocity` — a region of the
1185
+ cloth's own `SharedArrayBuffer`, so nothing is copied — and everything built from it runs in
1186
+ `cloth_step_instance` with the rest of the arithmetic, which is what keeps §12's parity structural.
1187
+ Measured: 58–62 ns a particle for a field sample, a twenty-fifth of that for the ambient (one sample
1188
+ for the whole cloth, which is what §10's "skips it entirely" is worth), and one per cent of a step for
1189
+ the term itself. `MEASUREMENTS.md` §48, §49.
1190
+
1191
+ **Where the air comes from is a scene's choice and there is no default.** `ClothWorld#wind` is `null`
1192
+ until something assigns a source, exactly as the collider index is: a scene without one gets M5's
1193
+ cloth rather than an error. Null rather than a still-air ambient, because a source answering zero
1194
+ everywhere is not "no wind" — the row is a relaxation toward the air, so still air still resists a
1195
+ *moving* cloth, anisotropically. That is better physics than `ClothDynamics#damping`'s isotropic decay
1196
+ and it is not free, so it is a thing a scene asks for. What a cloth does in air that is not moving is
1197
+ `damping`'s job (§7 P5, where it is load-bearing); what it does in air that *is* is this.
1111
1198
 
1112
1199
  ---
1113
1200
 
@@ -1299,12 +1386,19 @@ garments never override them.
1299
1386
 
1300
1387
  ## 12. Data layout, threading, the worker
1301
1388
 
1302
- **One `SharedArrayBuffer` for the whole cloth world**, not one per instance. `WorkerSystem`'s model is
1303
- a single shared buffer, a single command region and a single atomic publishing one in-flight step, and
1304
- `WorkerFluidSystem` already shows how a variable set of simulated things fits that model: the command
1305
- region carries a count and then a list of ids to step. Cloth does the same — each instance gets a
1306
- region inside the buffer, and the command region names which instances are live this step, so sleeping
1307
- (P5) and culled (§12.1) instances cost nothing but their absence from a list.
1389
+ **One `SharedArrayBuffer` per cloth**, and the command region names which cloths are live this step —
1390
+ so sleeping (P5) and culled (§12.1) cloths cost nothing but their absence from a list. `WorkerSystem`'s
1391
+ model is a single shared buffer, a single command region and a single atomic publishing one in-flight
1392
+ step, and `WorkerFluidSystem` shows how a variable set of simulated things fits it.
1393
+
1394
+ **M5 corrected "one buffer for the whole cloth world", and `reseed` is why.** A `ClothState` is sized
1395
+ at seed from *that cloth's* particle and row counts, and `ClothSystem#reseed` — a chain gaining a link,
1396
+ a `ClothDynamics` change the row tables depend on, a rigged garment whose model has just loaded —
1397
+ builds a different one while other cloths have steps in flight. A world buffer would therefore need an
1398
+ allocator with relocation, and a relocation invalidates every view of every region on both threads at
1399
+ once. One buffer per cloth costs one cold-plane message per seed (`add_cloth` / `remove_cloth`, the
1400
+ shape `WorkerFluidSystem` already has) and makes a re-seed a re-registration, which is the same code
1401
+ path as a first seed. `MEASUREMENTS.md` §39.
1308
1402
 
1309
1403
  SoA throughout:
1310
1404
 
@@ -1315,13 +1409,40 @@ SoA throughout:
1315
1409
  | topology | `Int32Array` | edge pairs, bend stencils, colour ranges, tether anchors |
1316
1410
  | rest data | `Float32Array` | rest lengths, bend weights, `d_geo` |
1317
1411
  | duals | `Float32Array` | `λ` and `k` per persistent constraint |
1318
- | colliders | `Float32Array` | packed records for this step |
1412
+ | colliders | `Float32Array` | packed records for this step — `CLOTH_COLLIDER_SLOTS` of them |
1319
1413
  | contacts | `Float32Array` | transient rows + their warm-start `λ`, keyed by (particle, collider slot) |
1320
1414
 
1321
- `ClothDynamics` reaches the worker through the command region, written every step — a dozen words into
1322
- memory the worker already shares, cheaper than tracking dirtiness, and it keeps
1415
+ The **step's parameters** reach the worker through the command region, written every step — fourteen
1416
+ words into memory the worker already shares, cheaper than tracking dirtiness, and it keeps
1323
1417
  `cloth.dynamics.slack = 0.2` working live, which is the point of a value object rather than a preset
1324
- that has to be re-applied.
1418
+ that has to be re-applied. (Thirteen at M5; M6's §10 adds the drag response, and the air itself
1419
+ travels as a region of the same buffer rather than as words — `ClothState#air_velocity`, written by
1420
+ the main thread and read by the step, which is the one direction the buffer could always carry and
1421
+ nothing had used.)
1422
+
1423
+ **M5 corrected "`ClothDynamics` reaches the worker".** By the time the step can use them a cloth's
1424
+ dynamics have been through `cloth_dynamics_map.js` — a damping retention, a velocity clamp, a
1425
+ self-collision radius, gravity rotated into the local frame — and sending the raw component would mean
1426
+ running that mapping a second time on the far side, with no way to prove the two copies agreed. What
1427
+ crosses is `ClothStepParam`: `dt`, local gravity, substeps, iterations, retention, clamp, contact
1428
+ radius, self radius, collider count, and whether self-collision is on. `Float64` throughout, so the
1429
+ round trip is exact — an `f32` command region would round the clamp, and a clamp that rounds is a
1430
+ velocity that rounds. `MEASUREMENTS.md` §40.
1431
+
1432
+ The same block is what makes the parity gate below structural rather than aspirational:
1433
+ `ClothSystem` fills the words of a private scratch array and calls `cloth_step_instance`;
1434
+ `WorkerClothSystem` fills the same words of the shared command region and the worker calls the same
1435
+ function. Neither system computes a step parameter of its own, so neither can compute one differently.
1436
+
1437
+ **M6 found the one thing that is not a parameter and still differs: the clock.** A gust is a function
1438
+ of time, and a worker cloth is not advanced until its registration is acknowledged — so the two
1439
+ systems reach a cloth's *first step* at different tick counts, and a clock that counted ticks hands
1440
+ that cloth a different gust on the same step. Measured with the clock put back on ticks, the gate
1441
+ fails at step 1, byte 0, which is the step's own result word. `ClothWorld#time` therefore counts the
1442
+ steps the world has taken rather than the ticks it has been asked about: it advances at the first
1443
+ `advance` of a tick, so a tick in which nothing is advanced does not move the weather. That is also
1444
+ the right semantic on its own terms — a paused simulation should not have the wind move.
1445
+ `MEASUREMENTS.md` §50.
1325
1446
 
1326
1447
  `Float32` for particle state, not `Float64`. The simulation runs in the cloth's **local frame**, so
1327
1448
  coordinates are garment-sized rather than world-sized and f32 has ample precision; the payoff is half
@@ -1340,6 +1461,16 @@ fixed `CLOTH_CONTACT_SLOTS` per particle inside `ClothState`'s single buffer —
1340
1461
  saturate on a twenty-collider scene and to average a tenth of one — which keeps §12's one-allocation
1341
1462
  property and bounds the worst case at the four *most violated* colliders, which is the four that matter.
1342
1463
 
1464
+ **And M5 moved the per-step collider table itself into that buffer**, at a fixed
1465
+ `CLOTH_COLLIDER_SLOTS`, which is where the table above always put it. M2 kept it on `ClothInstance`
1466
+ and grew it by doubling, on the correct grounds that its size is a property of the world rather than of
1467
+ the cloth; what decides is that an array which can be *replaced* mid-run is memory the worker has to be
1468
+ told about again before it can name it. So the size stays a property of the world and the region gets a
1469
+ capacity. **Sixty-four**, because the measurement showed the bound is a *scene* rather than a garment —
1470
+ a cloth's table holds every collider on every character standing inside its query box, which is ten for
1471
+ one body and thirty for three — and because an overflow discards colliders in the index's own order
1472
+ rather than in order of how much they matter. It warns once. `MEASUREMENTS.md` §41.
1473
+
1343
1474
  **The worker.** `WorkerClothSystem` is a `WorkerSystem` subclass and follows `WorkerFluidSystem`
1344
1475
  exactly, because that pattern is already proven in this repo: `collect` packs colliders and animated
1345
1476
  targets into shared memory and writes the command words, a single `Atomics.store` publishes the step,
@@ -1353,6 +1484,15 @@ identical order. That is what makes the worker a deployment choice rather than a
1353
1484
  it is why the core is a pure function over typed arrays from milestone zero even though the worker does
1354
1485
  not arrive until milestone five.
1355
1486
 
1487
+ **M5 measured it and the number is zero**, at every step of a run rather than at the end of one: the
1488
+ whole `ClothState` buffer — particles, velocities, every dual and penalty, the collider table, the
1489
+ warm-started contact multipliers, the self-collision pair list — compared byte for byte after each of
1490
+ 420 steps across two scenes, one with a walking anchor and one with colliders and self-collision live.
1491
+ What the scene sees differs by exactly one tick: the pose written at tick `T` is step `T − 1`'s. That
1492
+ is §4.1's own sentence in a second setting — the cloth's *shape* is one fixed step stale and its
1493
+ *position* is not, because the attachment cascade carries the subtree rigidly with the anchor.
1494
+ `MEASUREMENTS.md` §40.
1495
+
1356
1496
  Testing the bridge needs no worker: `SystemWorkerLoopback` gives a real `SystemWorkerHost`, a real
1357
1497
  `SharedArrayBuffer` and real `Atomics` in-process, with message delivery and step execution as explicit
1358
1498
  events a spec can order. Only the thread is faked.
@@ -1391,9 +1531,9 @@ What this design takes from the engine rather than building:
1391
1531
  | Constraint-row doctrine | `physics/constraint/solve_constraints.js` |
1392
1532
  | Subtree walk | `TransformAttachmentSystem#findChildrenOf` / `#countChildrenOf`, `TransformAttachment` |
1393
1533
  | Animated targets | `mesh_apply_skeletal_vertex_skinning` (flat arrays, worker-safe) |
1394
- | Wind / aerodynamics | `FluidField#sampleVelocity`, `fluid_build_world_to_grid`, `GlobalFluidEffector` |
1534
+ | Wind / aerodynamics | `FluidField#sampleVelocity` (in grid cells a second — §10 converts), `fluid_build_world_to_grid`, `GlobalFluidEffector` as the shape of the ambient *and* as the exact-ODE relaxation step `cloth_drag_response` copies |
1395
1535
  | Worker offload | `ecs/async/WorkerSystem.js`, `SystemWorkerHost`, `SystemWorkerLoopback`, `WorkerFluidSystem` as the worked example |
1396
- | Fixed step + render interpolation | `PhysicsSystem`'s producer/`__interp_restore` contract |
1536
+ | Fixed step | `EntityManager`'s fixed-step loop, gate and `fixedStepTick` |
1397
1537
  | Transforms | `Transform64`, `Node3D` |
1398
1538
  | Particle → render-vertex mapping | `Skin` — joints + inverse-bind matrices + the four-weight palette; cloth writes joints and the existing pass does the rest |
1399
1539
  | Reaching a model's joints from its entity | `SceneBundleInstance` (`skins`, `nodes` by name), `register_instance_animation` |
@@ -1404,6 +1544,24 @@ What this design takes from the engine rather than building:
1404
1544
 
1405
1545
  ---
1406
1546
 
1547
+ ### 13.1 What is *not* reusable — render interpolation
1548
+
1549
+ `PhysicsSystem`'s producer/`__interp_restore` contract was in the ledger above and M5 took it out,
1550
+ because it cannot express a rigged garment. `Interpolated` is an **entity-keyed marker**: the
1551
+ `InterpolationSystem` files snapshots under a `key` it assigns from the entity id at link time. A
1552
+ rope's links are entities and a skinned garment's joints are not — `shade_node_to_entity_composition`
1553
+ does not expand a skinned node, "and that is a boundary rather than an omission" (§3) — so half the
1554
+ feature has nothing to put the component on.
1555
+
1556
+ Cloth also needs only half of what that contract does. `__interp_restore` exists to hand the
1557
+ simulation its authoritative pose back before it integrates, because the render blend writes into the
1558
+ components the simulation reads. Cloth's state is `ClothState.position` in the cloth's local frame and
1559
+ its write-back never touches the anchor it reads, so **cloth never reads back what it writes** and has
1560
+ nothing to restore. It needs the publish half, over a pose per node rather than a component per entity.
1561
+ §18 carries what that would cost. `MEASUREMENTS.md` §43.
1562
+
1563
+ ---
1564
+
1407
1565
  ## 14. New shared code this justifies
1408
1566
 
1409
1567
  Three pieces belong in `core`, not in `cloth`, because the cloth need exposes a gap the engine has
@@ -1623,13 +1781,36 @@ placement into a bounded quality question and leaves the scheduler alone.
1623
1781
  and belongs with the collision rows that make a particle get *stuck* in the first place — a chain has
1624
1782
  no configuration to be stuck in. Chebyshev acceleration, still gated on contacts that arrive at M2. `β`,
1625
1783
  which M0 could not choose and M1 has no transient rows to choose it with either — every row M1 adds is
1626
- persistent. `ClothSerializationAdapter` and its siblings: nothing in M1's scope list names them, and a
1627
- codec written before `ClothRig` exists would be revised by M3 before it was ever loaded.
1784
+ persistent. The serialization adapters: nothing in M1's scope list names them, and a codec written
1785
+ before `ClothRig` exists would be revised by M3 before it was ever loaded — **true of one of the three;
1786
+ the correction follows this block.**
1628
1787
  Interpolation: cloth writes `Transform64` at the fixed rate and §12's producer/`__interp_restore`
1629
1788
  contract is not wired, which shows as a cloth updating at the fixed rate rather than the frame rate
1630
1789
  and is a visible-but-not-wrong gap. M5 is where it belongs, with the worker.
1631
1790
  **This is the first shippable feature.**
1632
1791
 
1792
+ **Corrected 2026-09-13: the deferral above only ever fitted `ClothRig`'s adapter, and it was applied to
1793
+ all three of them from here to the end of the plan.** It fits `ClothRigSerializationAdapter`, whose
1794
+ component points at a built, shared, immutable asset and therefore needs the asset-identity story §3.2
1795
+ only gestures at; and it fits `ClothProxy`'s own codec, which genuinely does depend on what §11.3
1796
+ step 9 adds to a proxy. It never fitted `Cloth` or `ClothCollider`. Those two are scalars — `blend`,
1797
+ `layer`, `mask`, `flags` and a `ClothDynamics` value object of ten more; `inflation`,
1798
+ `friction_scale`, `layer`, `mask`, `flags` — and neither holds a proxy, a skin, or anything either
1799
+ geometry path introduces. The evidence that the revision this sentence feared was never coming is M3
1800
+ itself: it changed the design in four places (`MEASUREMENTS.md` §24–29) and not one of them was a
1801
+ field on either component.
1802
+
1803
+ What turned a sequencing call into a hole is that it was **re-deferred rather than re-examined**. M2
1804
+ deferred all three "per M1's own reasoning"; M3 deferred them again for M1's reason while, in the same
1805
+ list, deferring the unrigged path that the reason had just been made to wait on; and §11.3 step 9 is
1806
+ in no milestone at all. A wait with no scheduled end is not a sequencing decision, and what it cost is
1807
+ that M6 closed this plan with a subsystem a scene could not contain: a `Cloth` could be added from
1808
+ code and from nowhere else. `ClothSerializationAdapter` and `ClothColliderSerializationAdapter` are
1809
+ built and specced as of 2026-09-13, outside any milestone and with no `MEASUREMENTS.md` section,
1810
+ because there is no measurement behind them — a codec has nothing to measure, and that file's sections
1811
+ belong to milestones. `ClothRigSerializationAdapter` and the proxy codec stay deferred, on the reason
1812
+ as narrowed here.
1813
+
1633
1814
  **M2 — collision. DONE, 2026-09-10.** `ClothCollider`, `ClothColliderFlags`, `ClothColliderSystem`,
1634
1815
  `ClothColliderIndex`, the packed record and its swept bounds, analytic SDF gradients and
1635
1816
  `PlaneShape3D` in `core` (§14.1, §14.3), the contact row and its friction row, the backstop row, and a
@@ -1659,8 +1840,10 @@ particle get stuck, and also measured the one stuck configuration whose *residua
1659
1840
  the quantity the escape hatch was to watch (§7 P4). It belongs with the self-collision of M4, where a
1660
1841
  particle can be pinched between two rows rather than merely held by one. The backstop row is built,
1661
1842
  specced and driven by the playground, but nothing **authors** one: its plane comes from a garment's own
1662
- skinned surface and a skinned garment is M3. Two-way coupling, per §2. `ClothSerializationAdapter` and
1663
- its siblings, per M1's own reasoning.
1843
+ skinned surface and a skinned garment is M3. Two-way coupling, per §2. The serialization adapters, per
1844
+ M1's own reasoning — which, as M1 now records, reached only `ClothRig`'s. The other two were not
1845
+ blocked by anything M2 had in hand or M3 was about to add, and this line is the first of the two
1846
+ restatements that carried them anyway.
1664
1847
 
1665
1848
  **M3 — skinned garments, the rigged path. DONE, 2026-09-10.** `ClothRig`, `ClothProxy`,
1666
1849
  `cloth_proxy_from_joints` (§11.3 steps 5–8), the rig seeder, and joint write-back into
@@ -1695,7 +1878,13 @@ budget. §11.3 step 10's bind-pose collision validation, which `cloth_proxy_from
1695
1878
  because it has a joint tree and no collider set — and which `MEASUREMENTS.md` §29 makes the argument
1696
1879
  for, because a garment authored inside its own body reads as a *tether* failure and costs an hour to
1697
1880
  diagnose. `ClothProxy`'s binary codec and `ClothRigSerializationAdapter`, for M1's own reason: a
1698
- codec written before the unrigged path exists would be revised before it was ever loaded.
1881
+ codec written before the unrigged path exists would be revised before it was ever loaded. **Those two
1882
+ only, corrected 2026-09-13.** As written this sentence carried `Cloth`'s and `ClothCollider`'s
1883
+ adapters with them, over a set of three, for a reason that held for one — and it did so in the same
1884
+ list that defers the unrigged path the reason had just been made to wait on, which is what closed the
1885
+ loop: the dependency and the thing depending on it were deferred by the same paragraph. Neither scalar
1886
+ component holds a proxy, so §3.2's asset-identity question — the real content of M1's reason — was
1887
+ never theirs to answer. Both adapters were built on 2026-09-13; M1 carries the full correction.
1699
1888
 
1700
1889
  **M4 — self-collision. DONE, 2026-09-11.** `core/geom/3d/hash-grid/PointHashGrid3.js`, the
1701
1890
  particle-particle row (`solver/constraint/cloth_self_row.js`), the pair search
@@ -1762,13 +1951,110 @@ realisations, a self-tangled sheet unties itself every time the gust stops, so M
1762
1951
  configuration to escape from. The case P4(d) names is a particle wedged between a collider *and* a
1763
1952
  fold, which is collision and self-collision together, and M4 has not measured it.
1764
1953
 
1765
- **M5 — the worker.** `WorkerClothSystem`, `ClothWorkerCore`, `cloth.worker.js`, the protocol.
1766
- *Proofs:* bit-parity between `ClothSystem` and `WorkerClothSystem` as a standing gate; loopback specs
1767
- covering step ordering, message ordering and shutdown; a measured main-thread cost reduction.
1768
-
1769
- **M6 — wind.** Fluid-field sampling, aerodynamic drag, the ambient fallback.
1770
- *Proofs:* a playground with a banner in a simulated wake; a measured cost showing the per-step sampling
1771
- stays inside budget. Cuttable without affecting anything else.
1954
+ **M5 — the worker. DONE, 2026-09-12.** `WorkerClothSystem`, `ClothWorkerCore`, `cloth.worker.js`,
1955
+ `makeClothWorker` and the protocol — plus the two pieces that had to exist for the parity gate to be
1956
+ structural rather than hopeful: `ClothWorld`, which is every cloth in a scene and everything about
1957
+ stepping one that is not arithmetic, owned by *both* systems; and `cloth_step_instance`, which is the
1958
+ arithmetic, driven by a `Float64` parameter block that is also the command region's per-cloth record.
1959
+ `ClothState` gains shared-memory backing, a descriptor, the collider table and a result region.
1960
+ *Proofs, all green:* bit-parity over the **whole `ClothState` buffer at every step** of two runs — a
1961
+ walking anchor for 240 steps, and colliders plus self-collision for 180 — with the write-back's
1962
+ one-tick lag pinned tick by tick rather than asserted at the end; the state a worker steps being the
1963
+ main thread's memory rather than a copy; a cloth being neither stepped **nor advanced** until its
1964
+ registration is acknowledged, which is what keeps the two systems' step *sequences* identical rather
1965
+ than merely similar; a re-seed retiring its registration and waiting again; a despawn between dispatch
1966
+ and step not failing the bridge; sleep removing a cloth from the dispatch and `wake` putting it back;
1967
+ shutdown settling the step in flight, releasing the gate and dropping the worker; and the derived
1968
+ execution order landing `WorkerClothSystem` exactly where `ClothSystem` lands. **10 tests in one new
1969
+ spec file**, with the M0–M4 suites unchanged at 183. The engine suite is green at 18,579.
1970
+
1971
+ **M5 changed the design in four places**, each with the measurement behind it in `MEASUREMENTS.md`
1972
+ §38–44 and each folded back above. In one line each: §12's one buffer for the whole cloth world is one
1973
+ buffer per cloth, because `reseed` resizes one while others are in flight; §12's collider table does
1974
+ belong in that buffer and therefore needs a capacity rather than a growth policy, and the capacity is
1975
+ bounded by the *scene* — thirty records for three characters — rather than by the garment; §12's
1976
+ "`ClothDynamics` reaches the worker through the command region" is the *mapped* step parameters rather
1977
+ than the component, because mapping them twice is two copies that cannot be proved equal; and §13's
1978
+ reuse of `PhysicsSystem`'s interpolation contract does not hold, because that contract is entity-keyed
1979
+ and a rigged garment's joints are not entities.
1980
+
1981
+ **And the strongest result is again a number rather than a correction.** §12 asks the two systems for
1982
+ bit-identical results. Over 420 steps across two scenes, comparing the entire state buffer after every
1983
+ one of them, the number of differing bytes is **zero** — and it is zero by construction rather than by
1984
+ luck, because there is one `ClothWorld`, one `cloth_step_instance`, and one parameter block that both
1985
+ systems fill and neither system interprets. The main thread's share of a thousand-particle garment goes
1986
+ from 3.62 ms to 0.18 ms; across the library's shapes, 92% to 96% of it crosses. `MEASUREMENTS.md` §40,
1987
+ §41.
1988
+
1989
+ **Deliberately not in M5:** **render interpolation**, which §18 said would land here and which M5
1990
+ decided against with three findings rather than a deferral — the named contract is entity-keyed and
1991
+ cannot reach a rigged garment's joints, cloth needs only the half of it that has no name, and the
1992
+ worker removes the cheap implementation by owning `ClothState` outside the fixed pass. What it needs
1993
+ instead is a published pose slot, and §18 now carries what that costs (about 0.12 ms a frame on the
1994
+ §17 workload, which roughly triples the main thread's share of cloth and leaves it at a seventh of
1995
+ its pre-M5 cost) and what it buys (half a link length a step at a walk, a whole one at a sprint).
1996
+ `MEASUREMENTS.md` §43. **A playground page**, for a reason about the dev server rather than the cloth:
1997
+ `SharedArrayBuffer` needs a cross-origin isolated page, and adding `COOP`/`COEP` to
1998
+ `vite.config.mjs` changes how every other playground page in the package loads its subresources —
1999
+ to demonstrate a bridge `SystemWorkerLoopback` already tests more precisely than a page could.
2000
+ **Culling (§12.1)**, which is a policy over the same dispatch list sleep already uses and belongs with
2001
+ a camera. And **a deeper pipeline**: `WorkerSystem` allows one step in flight and the fixed-step gate
2002
+ means a cloth could not use a second.
2003
+
2004
+ **M6 — wind. DONE, 2026-09-13.** §10 end to end: `wind/AbstractClothWind.js` and the two sources
2005
+ behind it (`ClothAmbientWind`, `ClothFluidWind`), `wind/cloth_sample_air.js`,
2006
+ `solver/cloth_wind_accelerate.js`, `ClothState`'s air and external-acceleration regions,
2007
+ `cloth_drag_response`, the parameter block's fourteenth word, and `ClothWorld`'s wind source, clock
2008
+ and wake test.
2009
+ *Proofs, all green:* the normal-facing factor on both topologies, which is the whole of what M6 adds
2010
+ to the physics — a sheet reading 1.000 broadside and 0.000 edge-on, a chain reading the reverse, and
2011
+ neither a skip row nor a strain-limit row able to fabricate a plane out of a line; the two sources
2012
+ through the interface, including a field answering in metres rather than grid cells and `varies()`
2013
+ being a promise the sampler acts on; the ECS path end to end — a garment blown downwind, one inside a
2014
+ `FluidComponent` reading the simulation while one ten metres away reads the weather, a settled banner
2015
+ sleeping in a steady wind and waking on a gust, and a scene with no source producing the cloth M5
2016
+ shipped **byte for byte** across 120 steps; the drag response closing a fraction of the gap to the
2017
+ air that is strictly below one at every step length from 1/240 s to 1 s; and §12's parity gate
2018
+ extended to a third run with wind live. **25 tests across three new spec files** — the term's 9, the
2019
+ sources' 10, the ECS path's 6 — plus the parity spec's eleventh, for 26 in all, with the M0–M5
2020
+ suites unchanged at 193. The engine suite is green at **18,638**, and the same suite run against M5's
2021
+ own commit in a detached worktree reads 18,612 on this machine, so the difference is exactly M6's
2022
+ twenty-six. A fifth playground page, `playground/wind.html`, with a banner hanging in a real
2023
+ `FluidSimulator`'s wake.
2024
+
2025
+ **M6 changed the design in five places**, each with the measurement behind it in `MEASUREMENTS.md`
2026
+ §45–§52 and each folded back above. In one line each: §10's `|n·û|` cannot be written for a chain,
2027
+ which has no normal and wants the complementary factor anyway, so both are one expression over the
2028
+ span of the incident rows; §10's "samples its velocity field" needs a unit conversion, because
2029
+ `FluidField` answers in grid cells a second and a garment blowing at a speed that depends on the
2030
+ voxel size is not a garment; §10 never said which thread samples and it cannot be the worker's, so
2031
+ the field stays where it is and three floats a particle cross in the cloth's own buffer; `drag`
2032
+ cannot multiply the flow directly, because one acceleration held for a whole fixed step overshoots
2033
+ the air once `rate·dt > 1`; and §12's thirteen-word block is fourteen, with a clock that has to count
2034
+ steps rather than ticks or the two systems' weather diverges at step 1.
2035
+
2036
+ **And the strongest result is again a number rather than a correction.** §10 offers the normal-facing
2037
+ factor as the difference between a flag and a rope. In uniform air it is: turning the wind ninety
2038
+ degrees at the same speed takes the banner's aerodynamic acceleration from **43.2 m/s² to 0.08**, a
2039
+ factor of five hundred. In a **wake** it does nothing at all — 0.216 against 0.280 — because a wake
2040
+ has velocity in every direction and no orientation of a surface is edge-on to one. That is not a
2041
+ failure of the factor; it is the measurement saying §10's argument for reading a simulation is
2042
+ stronger than §10 knew, and that the flag-versus-rope claim is a statement about laminar air.
2043
+ `MEASUREMENTS.md` §51.
2044
+
2045
+ **Deliberately not in M6:** **a spatially varying ambient.** The gust is uniform in space, so a long
2046
+ banner does not see it arrive at one end before the other — and that is what makes the no-simulation
2047
+ case cost one sample for a whole garment instead of one a particle (§48). Spatial structure is what a
2048
+ fluid field is *for*, and a second, worse one inside the fallback is the duplication §10 exists to
2049
+ avoid. **A blend at a field's edge**: a point inside a volume reads the volume and a point outside
2050
+ reads the ambient, so a garment straddling the boundary sees a step rather than a ramp. Where the
2051
+ ambient is the far field the volume relaxes toward — `GlobalFluidEffector`'s own `wind` — the step is
2052
+ small and is mostly the disturbance the volume exists to carry; where it is not, the answer is a
2053
+ volume large enough to hold what moves through it. **Two-way coupling into the fluid**, per §2's
2054
+ one-way rule: cloth reads the air and does not disturb it, and anything that should has
2055
+ `FluidObstacle`. And **per-substep sampling**, because §10 says per step and §48 measures the sample
2056
+ at 58 ns a particle — the one part of this that is not free is the one part per-substep sampling
2057
+ would double.
1772
2058
 
1773
2059
  **Performance budget — measured at M0, re-measured at M1, and it still does not hold on its own.** One
1774
2060
  character's full cloth complement — 1,024 particles at 2 substeps × 4 iterations, on a triangulated
@@ -1818,7 +2104,31 @@ attributing cost by deletion applies unchanged. What it licenses is that the col
1818
2104
  between nothing and a quarter of a frame and does not scale with the collider count over the range a
1819
2105
  character occupies. Every library entry's own budget is untouched. `MEASUREMENTS.md` §23.
1820
2106
 
1821
- Re-measure at M4 and M5.
2107
+ **Re-measured at M5, and no entry is re-sized — but not for the reason the table reads.** The absolute
2108
+ column came back 15% to 25% above M4's, on a machine carrying nineteen other node processes at 30–38%
2109
+ background CPU, which is exactly the swing M4's own lesson predicts. What licenses leaving the library
2110
+ alone is a *paired* measurement instead: `cloth_library_bench.mjs` never touches
2111
+ `WorkerClothSystem` — it drives `cloth_step` over a `ClothState` directly — so the only thing M5
2112
+ changed that it can see is the buffer layout, and an interleaved A/B of the two layouts in one process
2113
+ reads 0.95 to 0.98 with the two states staying bit-identical for 1,600 steps. §33's ordering stands
2114
+ entry for entry. `MEASUREMENTS.md` §39, §42.
2115
+
2116
+ **Re-measured at M6, and no entry is re-sized — now with a measured reason rather than only a
2117
+ disclaimer.** §10's aerodynamic term, priced in the bench's own §33 scenario, moves each entry by
2118
+ −2.7% to +9.3% across three runs, with the sign not monotone in `drag`; and with the *physics* held fixed so the two
2119
+ sides simulate the same cloth, the whole feature is **one per cent of a step**. The rest of that
2120
+ column is a different cloth — a rope blown horizontal costs 3.24× a rope hanging straight down, which
2121
+ is §7's warning arriving in a new setting and is about the rope. Three runs of the same bench within
2122
+ an hour put the §17 baseline row at 3.49, 3.83 and 4.26 ms, so the absolute column is still the
2123
+ machine: M5's advice to re-measure it quietly stands, and M6 adds that a process count is a proxy for
2124
+ load rather than a measure of it. `MEASUREMENTS.md` §49, §52.
2125
+
2126
+ **And the budget now means something slightly different.** The worker moves the cost rather than
2127
+ reducing it, so 2 ms is still 2 ms — but it is 2 ms on a thread that is not drawing the frame, and the
2128
+ question it answers has become "does all the cloth in the scene fit in one worker tick" rather than
2129
+ "does one garment fit in a frame". The main thread's share of the §17 workload is 0.18 ms.
2130
+ `MEASUREMENTS.md` §41. Re-measure the absolute column on a quiet machine, and check the process count
2131
+ first.
1822
2132
 
1823
2133
  ---
1824
2134
 
@@ -1942,6 +2252,33 @@ set.
1942
2252
  garment or a runtime hierarchy. Culling (§12.1) covers the off-screen case; the far-but-visible case is
1943
2253
  unaddressed.
1944
2254
 
2255
+ **Open — a wake has no direction, and the aerodynamic model has only one term. — MEASURED.** §10's
2256
+ normal-facing factor is the whole of M6's aerodynamics, and in uniform air it does exactly what §10
2257
+ promises: ninety degrees of flow angle is a factor of five hundred in the force a banner feels. In a
2258
+ fluid wake it does nothing — 0.216 against 0.280 — because a wake has velocity in every direction.
2259
+ What that leaves open is whether a cloth *in* a wake wants something the linear drag row does not
2260
+ carry: the fluttering a real flag does in one comes from a pressure difference across the sheet and a
2261
+ shed vortex, not from a relaxation toward a local velocity, and this design has no term for either.
2262
+ *Mitigation:* none is needed for what M6 claims — the cloth reads the air the simulation produces and
2263
+ is moved by it. It is named because "a banner in a wake looks alive" is what a reader will expect from
2264
+ §10 and is not what a drag row alone produces. `MEASUREMENTS.md` §51.
2265
+
2266
+ **Open — the ambient is uniform in space and the field boundary is a step.** Two limits of §10's
2267
+ fallback, both deliberate and both cheap to see: a gust lifts a whole banner at once rather than
2268
+ travelling along it, and a garment carried out of a fluid volume crosses a discontinuity rather than a
2269
+ ramp. The first is what makes the no-simulation case cost one sample rather than one a particle; the
2270
+ second is small where the ambient is the far field the volume relaxes toward and visible where it is
2271
+ not. A blend would want a falloff distance, which is an authored quantity of exactly the kind §3.4
2272
+ spent a section removing.
2273
+
2274
+ **Open — a fluid volume's wake is steady at a grid a frame can afford. — MEASURED, and it is the
2275
+ fluid system's rather than cloth's.** At 18, 26 and 34 cells across, with the simulator's damping and
2276
+ vorticity confinement at both ends of their range, the air a banner's width behind a solid post varies
2277
+ by under 0.03 m/s: a velocity deficit, not a shedding street. The deficit is real and is a third of
2278
+ the free stream, which is what the cloth reads; what is not there is the unsteadiness. Resolving a
2279
+ shedding shear layer costs 15 ms a step at 26 cells and 35 at 34, against 5 ms at 18.
2280
+ `MEASUREMENTS.md` §51.
2281
+
1945
2282
  **Open — `stretch` is a weak control, and it is not obvious what would make it a strong one.** M1
1946
2283
  measured the strain-limit row removing about a third of the peak over-stretch and never reaching its
1947
2284
  own allowance, because it is a second hard row competing with the first for the same trust region and
@@ -1953,11 +2290,36 @@ penalty band, making `k_max/(m/h²)` a material property rather than a global (w
1953
2290
  §4 shows trades stretchiness against settling); or accepting that near-inextensibility is what fabric
1954
2291
  *is* and demoting `stretch` to a documented weak knob. M2's contacts do not bear on it either way.
1955
2292
 
1956
- **Open — the write-back has no interpolation.** §12 gives cloth `PhysicsSystem`'s producer /
1957
- `__interp_restore` contract, and M1 does not wire it: cloth writes `Transform64` at the fixed rate and
1958
- nothing blends between ticks, so a cloth updates at 60 Hz on a 165 Hz display. That is visible and it
1959
- is not wrong — the poses are authoritative, they are simply held. It lands with M5, where the worker
1960
- makes the fixed-step producer contract load-bearing for a second reason.
2293
+ **Open — the write-back has no interpolation, and M5 decided it does not land with the worker.** Cloth
2294
+ writes `Transform64` at the fixed rate and nothing blends between ticks, so a cloth updates at 60 Hz on
2295
+ a 165 Hz display — 105 of every 165 frames repeat a pose. That is visible and it is not wrong: the
2296
+ poses are authoritative, they are simply held. **How** visible is now measured, on M3's cape geometry:
2297
+ a node covers 0.47 link lengths in a fixed step at a walk and 1.33 at a sprint (`MEASUREMENTS.md` §43).
2298
+
2299
+ What M5 changed is the shape of the remaining work, in three findings that between them delete the
2300
+ sentence this note used to end with.
2301
+
2302
+ - **`PhysicsSystem`'s producer / `__interp_restore` contract cannot express half the feature.**
2303
+ `Interpolated` is an entity-keyed marker and a rigged garment's joints are `Node3D`s, not entities
2304
+ (§13.1). There is nothing to put the component on and no key to file a snapshot under.
2305
+ - **Cloth needs only the publish half.** `__interp_restore` undoes render-time writes before the
2306
+ simulation reads them; cloth's state is its particle array and its write-back never touches the
2307
+ anchor it reads, so there is nothing to restore. The restore it *does* depend on — an anchor on a
2308
+ physics-driven character — it already gets from `PhysicsSystem`.
2309
+ - **The worker removes the cheap implementation.** A render-time pass cannot read
2310
+ `ClothState.position`, because the worker owns it from dispatch until the next tick's join, which is
2311
+ essentially all of the time outside the fixed pass. What is needed is a **published pose slot**: the
2312
+ last two steps' node poses, copied out at join and blended at render time — the same double-buffered
2313
+ publish slot `WorkerFluidSystem` names as the unbuilt prerequisite for its own render-time reads.
2314
+
2315
+ The slot is nearly free to fill, because `cloth_write_back` already computes every node's local TRS
2316
+ and would only have to keep it; what costs is the per-frame pass. For the §17 workload that is about
2317
+ 0.12 ms a frame — 20.5 ms a second at 165 Hz, against the 10.9 ms a second M5 leaves on the main
2318
+ thread and the 217 ms a second it cost before. **Interpolating a cloth would roughly triple the main
2319
+ thread's share of it and leave it at a seventh of what it was**, which is the honest shape of the
2320
+ trade: the feature is affordable because M5 happened, and it is not free. The cloth-shaped version is
2321
+ *simpler* than the engine's, not harder: no restore pass, no serialization adapters, no log, and it
2322
+ covers the rigged and entity paths identically because both end in a pose per node.
1961
2323
 
1962
2324
  **Open — the subtree is walked once.** A rope's links do not come and go, so `cloth_seed_subtree` runs
1963
2325
  on first step and `ClothSystem#reseed` is how a caller says the structure changed. That is the same