@woosh/meep-engine 3.43.0 → 3.45.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 (466) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/editor/prototypeEditorShell.d.ts.map +1 -1
  3. package/editor/prototypeEditorShell.js +4 -2
  4. package/package.json +1 -1
  5. package/src/core/collection/array/array_sort_insertion_ascending.d.ts +19 -0
  6. package/src/core/collection/array/array_sort_insertion_ascending.d.ts.map +1 -0
  7. package/src/core/collection/array/array_sort_insertion_ascending.js +31 -0
  8. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts +27 -0
  9. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts.map +1 -0
  10. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.js +39 -0
  11. package/src/core/geom/3d/aabb/aabb3_from_v3_array.d.ts.map +1 -1
  12. package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +4 -1
  13. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts +2 -2
  14. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -1
  15. package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +1 -1
  16. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts +21 -0
  17. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts.map +1 -0
  18. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.js +36 -0
  19. package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts +25 -0
  20. package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts.map +1 -0
  21. package/src/core/geom/3d/pose/pose3_apply_point_array.js +40 -0
  22. package/src/core/geom/3d/pose/pose3_compose_array.d.ts +28 -0
  23. package/src/core/geom/3d/pose/pose3_compose_array.d.ts.map +1 -0
  24. package/src/core/geom/3d/pose/pose3_compose_array.js +41 -0
  25. package/src/core/geom/3d/pose/pose3_to_local_array.d.ts +29 -0
  26. package/src/core/geom/3d/pose/pose3_to_local_array.d.ts.map +1 -0
  27. package/src/core/geom/3d/pose/pose3_to_local_array.js +42 -0
  28. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts +28 -0
  29. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts.map +1 -0
  30. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.js +66 -0
  31. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts +22 -0
  32. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts.map +1 -0
  33. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.js +30 -0
  34. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts +23 -0
  35. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts.map +1 -0
  36. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.js +31 -0
  37. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts +26 -0
  38. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts.map +1 -0
  39. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.js +46 -0
  40. package/src/core/geom/vec3/v3_distance_array.d.ts +11 -0
  41. package/src/core/geom/vec3/v3_distance_array.d.ts.map +1 -0
  42. package/src/core/geom/vec3/v3_distance_array.js +19 -0
  43. package/src/core/geom/vec3/v3_normalize_array_checked.d.ts +23 -0
  44. package/src/core/geom/vec3/v3_normalize_array_checked.d.ts.map +1 -0
  45. package/src/core/geom/vec3/v3_normalize_array_checked.js +49 -0
  46. package/src/core/geom/vec3/v3_reject_array.d.ts +15 -0
  47. package/src/core/geom/vec3/v3_reject_array.d.ts.map +1 -0
  48. package/src/core/geom/vec3/v3_reject_array.js +32 -0
  49. package/src/core/graph/csr/csr_build_incidence.d.ts +26 -0
  50. package/src/core/graph/csr/csr_build_incidence.d.ts.map +1 -0
  51. package/src/core/graph/csr/csr_build_incidence.js +71 -0
  52. package/src/core/graph/csr/csr_graph_color_greedy.d.ts +25 -0
  53. package/src/core/graph/csr/csr_graph_color_greedy.d.ts.map +1 -0
  54. package/src/core/graph/csr/csr_graph_color_greedy.js +83 -0
  55. package/src/core/graph/csr/csr_graph_validate_coloring.d.ts +15 -0
  56. package/src/core/graph/csr/csr_graph_validate_coloring.d.ts.map +1 -0
  57. package/src/core/graph/csr/csr_graph_validate_coloring.js +33 -0
  58. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts +26 -0
  59. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts.map +1 -0
  60. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.js +71 -0
  61. package/src/core/math/max2_exact.d.ts +15 -0
  62. package/src/core/math/max2_exact.d.ts.map +1 -0
  63. package/src/core/math/max2_exact.js +30 -0
  64. package/src/core/math/min2_exact.d.ts +20 -0
  65. package/src/core/math/min2_exact.d.ts.map +1 -0
  66. package/src/core/math/min2_exact.js +35 -0
  67. package/src/engine/Clock.d.ts +15 -0
  68. package/src/engine/Clock.d.ts.map +1 -1
  69. package/src/engine/Clock.js +29 -5
  70. package/src/engine/Engine.d.ts.map +1 -1
  71. package/src/engine/Engine.js +11 -19
  72. package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -1
  73. package/src/engine/ecs/ik/IKGoalSystem.js +3 -19
  74. package/src/engine/ecs/parent/parent_entity_model_of.d.ts +17 -0
  75. package/src/engine/ecs/parent/parent_entity_model_of.d.ts.map +1 -0
  76. package/src/engine/ecs/parent/parent_entity_model_of.js +26 -0
  77. package/src/engine/ecs/transform/t64_read_pose_array.d.ts +15 -0
  78. package/src/engine/ecs/transform/t64_read_pose_array.d.ts.map +1 -0
  79. package/src/engine/ecs/transform/t64_read_pose_array.js +24 -0
  80. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts +57 -0
  81. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts.map +1 -0
  82. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.js +84 -0
  83. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts +2 -0
  84. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts.map +1 -1
  85. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.js +10 -21
  86. package/src/engine/graphics3/AnimationGraphSystem.d.ts +28 -13
  87. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
  88. package/src/engine/graphics3/AnimationGraphSystem.js +107 -64
  89. package/src/engine/graphics3/AnimationSystem.d.ts +29 -15
  90. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
  91. package/src/engine/graphics3/AnimationSystem.js +112 -61
  92. package/src/engine/graphics3/MeshSkinSystem.d.ts +56 -0
  93. package/src/engine/graphics3/MeshSkinSystem.d.ts.map +1 -0
  94. package/src/engine/graphics3/MeshSkinSystem.js +317 -0
  95. package/src/engine/graphics3/MeshSystem.d.ts +15 -35
  96. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  97. package/src/engine/graphics3/MeshSystem.js +21 -298
  98. package/src/engine/graphics3/RowChains.d.ts +76 -0
  99. package/src/engine/graphics3/RowChains.d.ts.map +1 -0
  100. package/src/engine/graphics3/RowChains.js +347 -0
  101. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -0
  102. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  103. package/src/engine/graphics3/ShadedGeometrySystem.js +329 -309
  104. package/src/engine/graphics3/animation/AnimationClips.d.ts +56 -0
  105. package/src/engine/graphics3/animation/AnimationClips.d.ts.map +1 -0
  106. package/src/engine/graphics3/animation/AnimationClips.js +79 -0
  107. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +13 -14
  108. package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
  109. package/src/engine/graphics3/animation/ClipListPlayer.js +262 -263
  110. package/src/engine/graphics3/animation/write_clip_playback.d.ts +3 -3
  111. package/src/engine/graphics3/animation/write_clip_playback.js +4 -4
  112. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +5 -0
  113. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  114. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +80 -75
  115. package/src/engine/graphics3/prefab/PrefabInstance.d.ts +4 -24
  116. package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -1
  117. package/src/engine/graphics3/prefab/PrefabInstance.js +60 -80
  118. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +16 -3
  119. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -1
  120. package/src/engine/graphics3/prefab/prefab_instantiate.js +49 -12
  121. package/src/engine/graphics3/prefab/prefab_place.d.ts +31 -17
  122. package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -1
  123. package/src/engine/graphics3/prefab/prefab_place.js +175 -130
  124. package/src/engine/graphics3/register_clips.d.ts +93 -0
  125. package/src/engine/graphics3/register_clips.d.ts.map +1 -0
  126. package/src/engine/graphics3/register_clips.js +166 -0
  127. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +9 -0
  128. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -1
  129. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +3 -1
  130. package/src/engine/physics/cloth/MEASUREMENTS.md +795 -0
  131. package/src/engine/physics/cloth/PLAN.md +349 -17
  132. package/src/engine/physics/cloth/build/ClothProxy.d.ts +113 -61
  133. package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -1
  134. package/src/engine/physics/cloth/build/ClothProxy.js +142 -77
  135. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +44 -0
  136. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -0
  137. package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +107 -0
  138. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +43 -30
  139. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  140. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +371 -284
  141. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts +62 -0
  142. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -0
  143. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +275 -0
  144. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +7 -0
  145. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
  146. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +85 -67
  147. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -1
  148. package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +19 -101
  149. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +2 -5
  150. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -1
  151. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +7 -15
  152. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +1 -1
  153. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -1
  154. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +17 -62
  155. package/src/engine/physics/cloth/ecs/Cloth.d.ts +17 -9
  156. package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -1
  157. package/src/engine/physics/cloth/ecs/Cloth.js +220 -212
  158. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +0 -1
  159. package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +6 -19
  160. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +1 -2
  161. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
  162. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +3 -12
  163. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +6 -0
  164. package/src/engine/physics/cloth/ecs/ClothHold.d.ts +91 -0
  165. package/src/engine/physics/cloth/ecs/ClothHold.d.ts.map +1 -0
  166. package/src/engine/physics/cloth/ecs/ClothHold.js +103 -0
  167. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +254 -48
  168. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  169. package/src/engine/physics/cloth/ecs/ClothInstance.js +277 -47
  170. package/src/engine/physics/cloth/ecs/ClothPin.d.ts +73 -0
  171. package/src/engine/physics/cloth/ecs/ClothPin.d.ts.map +1 -0
  172. package/src/engine/physics/cloth/ecs/ClothPin.js +92 -0
  173. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts +36 -0
  174. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts.map +1 -0
  175. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.js +61 -0
  176. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +23 -17
  177. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
  178. package/src/engine/physics/cloth/ecs/ClothRig.js +29 -27
  179. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +12 -14
  180. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  181. package/src/engine/physics/cloth/ecs/ClothSystem.js +20 -15
  182. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +57 -36
  183. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  184. package/src/engine/physics/cloth/ecs/ClothWorld.js +754 -207
  185. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +12 -13
  186. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
  187. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +20 -14
  188. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +63 -11
  189. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  190. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +297 -101
  191. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +9 -7
  192. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  193. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +12 -10
  194. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +3 -3
  195. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
  196. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +60 -120
  197. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +37 -0
  198. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -0
  199. package/src/engine/physics/cloth/ecs/cloth_geodesic.js +135 -0
  200. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts +97 -0
  201. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -0
  202. package/src/engine/physics/cloth/ecs/cloth_holds.js +583 -0
  203. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +2 -2
  204. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
  205. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +168 -51
  206. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +17 -22
  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 +55 -117
  209. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -6
  210. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  211. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +51 -42
  212. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +5 -0
  213. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  214. package/src/engine/physics/cloth/ecs/cloth_write_back.js +62 -50
  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 +65 -58
  217. package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts.map +1 -1
  218. package/src/engine/physics/cloth/playground/cloth_playground_build.js +2 -3
  219. package/src/engine/physics/cloth/playground/collide_main.js +3 -29
  220. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
  221. package/src/engine/physics/cloth/playground/garment_build.js +17 -5
  222. package/src/engine/physics/cloth/playground/garment_main.js +5 -20
  223. package/src/engine/physics/cloth/playground/main.js +6 -48
  224. package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -1
  225. package/src/engine/physics/cloth/playground/rig_build.js +302 -296
  226. package/src/engine/physics/cloth/playground/rig_main.js +947 -955
  227. package/src/engine/physics/cloth/playground/wind_main.js +8 -7
  228. package/src/engine/physics/cloth/solver/ClothState.d.ts +45 -7
  229. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  230. package/src/engine/physics/cloth/solver/ClothState.js +79 -83
  231. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts +10 -8
  232. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts.map +1 -1
  233. package/src/engine/physics/cloth/solver/cloth_color_particles.js +30 -102
  234. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +6 -1
  235. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  236. package/src/engine/physics/cloth/solver/cloth_contact_find.js +9 -3
  237. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts +114 -0
  238. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -0
  239. package/src/engine/physics/cloth/solver/cloth_hold_line.js +350 -0
  240. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts +21 -0
  241. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts.map +1 -0
  242. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.js +45 -0
  243. package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts +32 -0
  244. package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts.map +1 -0
  245. package/src/engine/physics/cloth/solver/cloth_particle_coupling.js +133 -0
  246. package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts +16 -0
  247. package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts.map +1 -0
  248. package/src/engine/physics/cloth/solver/cloth_particle_of_source.js +19 -0
  249. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +6 -2
  250. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  251. package/src/engine/physics/cloth/solver/cloth_self_find.js +19 -68
  252. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
  253. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +30 -65
  254. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +24 -12
  255. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  256. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +24 -12
  257. package/src/engine/physics/cloth/solver/cloth_step.d.ts +16 -0
  258. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  259. package/src/engine/physics/cloth/solver/cloth_step.js +189 -48
  260. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +1 -0
  261. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  262. package/src/engine/physics/cloth/solver/cloth_step_instance.js +12 -6
  263. package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts +21 -0
  264. package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts.map +1 -0
  265. package/src/engine/physics/cloth/solver/cloth_stretch_residual.js +54 -0
  266. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts +15 -0
  267. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts.map +1 -1
  268. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.js +28 -0
  269. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts +30 -0
  270. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts.map +1 -0
  271. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.js +56 -0
  272. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
  273. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +3 -17
  274. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +1 -1
  275. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -1
  276. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +353 -346
  277. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +7 -5
  278. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
  279. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +7 -5
  280. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +2 -1
  281. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
  282. package/src/engine/physics/cloth/wind/ClothFluidWind.js +7 -25
  283. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +12 -10
  284. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
  285. package/src/engine/physics/cloth/wind/cloth_sample_air.js +60 -82
  286. package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -1
  287. package/src/engine/physics/ecs/ContactProbeSystem.js +2 -18
  288. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  289. package/src/engine/physics/ecs/PhysicsSystem.js +9 -50
  290. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  291. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts +24 -0
  292. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts.map +1 -0
  293. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.js +42 -0
  294. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts +25 -0
  295. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts.map +1 -0
  296. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.js +40 -0
  297. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -1
  298. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +40 -90
  299. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
  300. package/src/engine/physics/narrowphase/capsule_contacts.js +3 -5
  301. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -1
  302. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +2 -14
  303. package/src/engine/physics/narrowphase/hull_sphere_contact.d.ts.map +1 -1
  304. package/src/engine/physics/narrowphase/hull_sphere_contact.js +2 -5
  305. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  306. package/src/engine/physics/narrowphase/narrowphase_step.js +13 -32
  307. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
  308. package/src/engine/physics/narrowphase/sphere_box_contact.js +2 -5
  309. package/src/engine/simulation/Ticker.d.ts +13 -0
  310. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  311. package/src/engine/simulation/Ticker.js +43 -8
  312. package/src/format/texture/basis/transcode/etc1s_to_astc.d.ts.map +1 -1
  313. package/src/format/texture/basis/transcode/etc1s_to_astc.js +2 -1
  314. package/src/shade/RENDERER_CONTRACT.md +8 -2
  315. package/src/shade/playground/image_decode_bench/main.js +2 -1
  316. package/src/shade/playground/mesh_row_ceiling/main.js +2 -1
  317. package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.d.ts.map +1 -1
  318. package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.js +2 -1
  319. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  320. package/src/shade/playground/skinned_blas_refit/main.js +11 -19
  321. package/src/shade/playground/skinned_blas_refit/place_character.d.ts +6 -3
  322. package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
  323. package/src/shade/playground/skinned_blas_refit/place_character.js +90 -90
  324. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  325. package/src/shade/playground/skinned_mesh_soup/main.js +502 -509
  326. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
  327. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +2 -1
  328. package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -1
  329. package/src/shade/playground/ssr_variance/statistics.js +2 -1
  330. package/src/shade/playground/texture_encode/README.md +129 -109
  331. package/src/shade/playground/texture_encode/main.d.ts.map +1 -1
  332. package/src/shade/playground/texture_encode/main.js +1431 -1430
  333. package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -1
  334. package/src/shade/playground/volumetrics_froxel/measure.js +2 -1
  335. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +45 -14
  336. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  337. package/src/shade/renderer/animation/GPUAnimationManager.js +316 -64
  338. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +5 -0
  339. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  340. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -1
  341. package/src/shade/renderer/buffer/table/gpu_database_check_links.d.ts.map +1 -1
  342. package/src/shade/renderer/buffer/table/gpu_database_check_links.js +2 -1
  343. package/src/shade/renderer/geometry/BoxGeometry.d.ts +1 -11
  344. package/src/shade/renderer/geometry/BoxGeometry.d.ts.map +1 -1
  345. package/src/shade/renderer/geometry/BoxGeometry.js +6 -13
  346. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts +19 -0
  347. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts.map +1 -0
  348. package/src/shade/renderer/geometry/CapsuleGeometry.js +24 -0
  349. package/src/shade/renderer/geometry/ConeGeometry.d.ts +20 -0
  350. package/src/shade/renderer/geometry/ConeGeometry.d.ts.map +1 -0
  351. package/src/shade/renderer/geometry/ConeGeometry.js +33 -0
  352. package/src/shade/renderer/geometry/CylinderGeometry.d.ts +21 -0
  353. package/src/shade/renderer/geometry/CylinderGeometry.d.ts.map +1 -0
  354. package/src/shade/renderer/geometry/CylinderGeometry.js +35 -0
  355. package/src/shade/renderer/geometry/PlaneGeometry.d.ts +17 -0
  356. package/src/shade/renderer/geometry/PlaneGeometry.d.ts.map +1 -0
  357. package/src/shade/renderer/geometry/PlaneGeometry.js +22 -0
  358. package/src/shade/renderer/geometry/TorusGeometry.d.ts +18 -0
  359. package/src/shade/renderer/geometry/TorusGeometry.d.ts.map +1 -0
  360. package/src/shade/renderer/geometry/TorusGeometry.js +23 -0
  361. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts +21 -0
  362. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts.map +1 -0
  363. package/src/shade/renderer/geometry/UVSphereGeometry.js +34 -0
  364. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts +19 -0
  365. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts.map +1 -0
  366. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.js +205 -0
  367. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts +21 -0
  368. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts.map +1 -0
  369. package/src/shade/renderer/geometry/primitives/make_cone_geometry.js +36 -0
  370. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts +1 -1
  371. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts.map +1 -1
  372. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +44 -9
  373. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts +20 -0
  374. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts.map +1 -0
  375. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.js +190 -0
  376. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -1
  377. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +3 -2
  378. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -1
  379. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +2 -1
  380. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -1
  381. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +2 -1
  382. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -1
  383. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +2 -1
  384. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -1
  385. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +3 -2
  386. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -1
  387. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.js +2 -1
  388. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
  389. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +2 -1
  390. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  391. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +3 -2
  392. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  393. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +7 -2
  394. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +26 -8
  395. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  396. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +56 -39
  397. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts +7 -0
  398. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts.map +1 -1
  399. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js +46 -4
  400. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.d.ts.map +1 -1
  401. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.js +4 -2
  402. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +2 -2
  403. package/src/shade/renderer/gpu_primitive/sort/defs.js +79 -79
  404. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +1 -1
  405. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  406. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +7 -3
  407. package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
  408. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -3
  409. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
  410. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +200 -194
  411. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  412. package/src/shade/renderer/particles/graph_particles.js +6 -2
  413. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -1
  414. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +3 -2
  415. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
  416. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +334 -329
  417. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  418. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +7 -2
  419. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  420. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +16 -4
  421. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +2444 -2345
  422. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.d.ts.map +1 -1
  423. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.js +312 -310
  424. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts +3 -3
  425. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts.map +1 -1
  426. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.js +383 -375
  427. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.d.ts.map +1 -1
  428. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.js +349 -346
  429. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts +58 -0
  430. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts.map +1 -0
  431. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.js +536 -0
  432. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts +21 -7
  433. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts.map +1 -1
  434. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js +291 -327
  435. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts +25 -0
  436. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts.map +1 -0
  437. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.js +99 -0
  438. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts +5 -3
  439. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts.map +1 -1
  440. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.js +47 -71
  441. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts +10 -0
  442. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts.map +1 -0
  443. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.js +50 -0
  444. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts +4 -5
  445. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts.map +1 -1
  446. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.js +7 -8
  447. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  448. package/src/shade/renderer/water/chunk_water_transport.js +7 -5
  449. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  450. package/src/shade/renderer/water/medium/GPUWaterBodies.js +8 -2
  451. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +3 -2
  452. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  453. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +3 -2
  454. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  455. package/src/shade/renderer/water/shader_water.js +3 -1
  456. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
  457. package/src/shade/renderer/water/surface/GPUWaterSurface.js +3 -1
  458. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
  459. package/src/shade/renderer/water/surface/graph_water_tessellation.js +11 -4
  460. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
  461. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +37 -20
  462. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  463. package/src/shade/wgsl/validate_wgsl_source.js +74 -3
  464. package/src/engine/graphics3/register_instance_animation.d.ts +0 -114
  465. package/src/engine/graphics3/register_instance_animation.d.ts.map +0 -1
  466. package/src/engine/graphics3/register_instance_animation.js +0 -201
@@ -1,212 +1,220 @@
1
- import { assert } from "../../../../core/assert.js";
2
- import { combine_hash } from "../../../../core/collection/array/combine_hash.js";
3
- import { computeHashFloat } from "../../../../core/primitives/numbers/computeHashFloat.js";
4
- import { ClothDynamics } from "./ClothDynamics.js";
5
- import { ClothFlags } from "./ClothFlags.js";
6
-
7
- /**
8
- * # The thing that simulates
9
- *
10
- * Put it on an entity and that entity's transform subtree becomes a simulated
11
- * chain: a rope, a chain, a hanging sign, a mooring line, a multi-strand rig.
12
- *
13
- * ```js
14
- * rope_top.add(Cloth.from(ClothDynamics.ROPE));
15
- * ```
16
- *
17
- * **The anchor is the entity the component is on**, and nothing names anything.
18
- * The particle set is that entity's own transform subtree, walked through
19
- * `TransformAttachmentSystem#findChildrenOf` — the parent-to-children index the
20
- * engine already maintains. Put `Cloth` on the top link of a rope and you get
21
- * the rope; put it on a node with several chains under it and you get all of
22
- * them in **one coupled solve**, which is what makes self-collision between
23
- * them work when it arrives.
24
- *
25
- * Two rules keep the walk unambiguous:
26
- *
27
- * - **A nested `Cloth` claims its own subtree.** The walk stops when it meets
28
- * another `Cloth`, so independent hanging parts of one prop partition
29
- * naturally. The two solves are ordered by hierarchy depth, so the outer one
30
- * has written the inner one's anchor before the inner one reads it.
31
- * - **{@link ClothExclude}** prunes a subtree from the walk, for the rig with a
32
- * non-simulated attachment point in the middle of a chain.
33
- *
34
- * From M3 a `ClothRig` alongside this component redirects the particle set to a
35
- * skinned model instance's joints instead (§11.2). The solver is identical
36
- * either way; only seeding and write-back differ, which is why there is no mode
37
- * enum here — component presence does the job an enum would otherwise do badly.
38
- *
39
- * ## What has to be true of the subtree
40
- *
41
- * Every simulated entity needs a `TransformAttachment` naming its parent and a
42
- * `Transform64`; that is what "is in the transform subtree" means, and it is
43
- * the ordinary way anything is parented. The subtree is walked **once**, when
44
- * the cloth first steps. Adding or removing links afterwards needs an explicit
45
- * re-seed, which is the same contract `TransformAttachment#parent` already
46
- * carries: remove the component and add it back.
47
- *
48
- * @author Alex Goldring
49
- * @copyright Company Named Limited (c) 2026
50
- */
51
- export class Cloth {
52
-
53
- /**
54
- * How it behaves. Assign a frozen library entry directly and it is shared,
55
- * immutable and free; `.clone()` it and you own a copy to edit. Writing a
56
- * field on an owned copy takes effect on the next step — the system
57
- * compares what it last saw and re-parameterises the rows when it differs,
58
- * so `cloth.dynamics.slack = 0.2` works live.
59
- * @type {ClothDynamics}
60
- */
61
- dynamics = new ClothDynamics();
62
-
63
- /**
64
- * `0` is the fully animated pose, `1` the fully simulated one.
65
- *
66
- * A lerp applied at write-back rather than a solver parameter, so it is
67
- * free and always safe. It is the escape hatch for cinematics, for LOD, and
68
- * for "turn it off for this one shot"; from M5 the culling pass drives it
69
- * to blend a cloth back in without a pop.
70
- * @type {number}
71
- */
72
- blend = 1;
73
-
74
- /**
75
- * Collision layer this cloth belongs to, `RigidBody` semantics. Read from
76
- * M2, when there is something to filter.
77
- * @type {number}
78
- */
79
- layer = 1;
80
-
81
- /**
82
- * Which `ClothCollider` layers this cloth collides against. Read from M2.
83
- * @type {number}
84
- */
85
- mask = 0xFFFFFFFF;
86
-
87
- /**
88
- * @see ClothFlags
89
- * @type {number}
90
- */
91
- flags = ClothFlags.None;
92
-
93
- /**
94
- * @param {number|ClothFlags} flag
95
- * @returns {boolean}
96
- */
97
- getFlag(flag) {
98
- return (this.flags & flag) === flag;
99
- }
100
-
101
- /**
102
- * @param {ClothDynamics} [dynamics] assigned by reference — pass a library
103
- * entry to share it, `.clone()` first to own it
104
- * @param {object} [spec]
105
- * @param {number} [spec.blend]
106
- * @param {number} [spec.layer]
107
- * @param {number} [spec.mask]
108
- * @param {number} [spec.flags]
109
- * @returns {Cloth}
110
- */
111
- static from(dynamics = undefined, spec = {}) {
112
- const r = new Cloth();
113
-
114
- if (dynamics !== undefined) {
115
- assert.ok(dynamics.isClothDynamics === true, 'dynamics must be a ClothDynamics');
116
-
117
- r.dynamics = dynamics;
118
- }
119
-
120
- const {
121
- blend = r.blend,
122
- layer = r.layer,
123
- mask = r.mask,
124
- flags = r.flags
125
- } = spec;
126
-
127
- assert.isNumber(blend, 'blend');
128
- assert.isNonNegativeInteger(layer, 'layer');
129
- assert.isNonNegativeInteger(mask, 'mask');
130
- assert.isNonNegativeInteger(flags, 'flags');
131
-
132
- r.blend = blend;
133
- r.layer = layer;
134
- r.mask = mask;
135
- r.flags = flags;
136
-
137
- return r;
138
- }
139
-
140
- /**
141
- * @param {Cloth} other
142
- * @returns {boolean}
143
- */
144
- equals(other) {
145
- if (other === this) {
146
- return true;
147
- }
148
-
149
- if (other === null || other === undefined || other.isCloth !== true) {
150
- return false;
151
- }
152
-
153
- return this.dynamics.equals(other.dynamics)
154
- && this.blend === other.blend
155
- && this.layer === other.layer
156
- && this.mask === other.mask
157
- && this.flags === other.flags;
158
- }
159
-
160
- /**
161
- * @returns {number}
162
- */
163
- hash() {
164
- return combine_hash(
165
- this.dynamics.hash(),
166
- computeHashFloat(this.blend),
167
- this.layer,
168
- this.mask,
169
- this.flags
170
- );
171
- }
172
-
173
- toJSON() {
174
- return {
175
- dynamics: this.dynamics.toJSON(),
176
- blend: this.blend,
177
- layer: this.layer,
178
- mask: this.mask,
179
- flags: this.flags
180
- };
181
- }
182
-
183
- /**
184
- * @param {object} json
185
- */
186
- fromJSON({ dynamics, blend = 1, layer = 1, mask = 0xFFFFFFFF, flags = ClothFlags.None }) {
187
- // Deserialising into a shared frozen library entry would be a
188
- // cross-instance write, so a loaded cloth always owns its dynamics.
189
- this.dynamics = new ClothDynamics();
190
-
191
- if (dynamics !== undefined) {
192
- this.dynamics.fromJSON(dynamics);
193
- }
194
-
195
- this.blend = blend;
196
- this.layer = layer;
197
- this.mask = mask;
198
- this.flags = flags;
199
- }
200
-
201
- toString() {
202
- return `Cloth${JSON.stringify(this.toJSON())}`;
203
- }
204
- }
205
-
206
- /**
207
- * @readonly
208
- * @type {boolean}
209
- */
210
- Cloth.prototype.isCloth = true;
211
-
212
- Cloth.typeName = "Cloth";
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { combine_hash } from "../../../../core/collection/array/combine_hash.js";
3
+ import { computeHashFloat } from "../../../../core/primitives/numbers/computeHashFloat.js";
4
+ import { ClothDynamics } from "./ClothDynamics.js";
5
+ import { ClothFlags } from "./ClothFlags.js";
6
+
7
+ /**
8
+ * # The thing that simulates
9
+ *
10
+ * Put it on an entity and that entity's transform subtree becomes a simulated
11
+ * chain: a rope, a chain, a hanging sign, a mooring line, a multi-strand rig.
12
+ *
13
+ * ```js
14
+ * rope_top.add(Cloth.from(ClothDynamics.ROPE));
15
+ * rope_top.add(ClothPin.from({ cloth: rope_top, particles: [0] }));
16
+ * ```
17
+ *
18
+ * **The entity the component is on is the cloth's frame**, and nothing names
19
+ * anything. The particle set is that entity and its transform subtree, walked
20
+ * through `TransformAttachmentSystem#findChildrenOf` — the parent-to-children
21
+ * index the engine already maintains — with the entity itself as particle 0.
22
+ * Put `Cloth` on the top link of a rope and you get the rope; put it on a node
23
+ * with several chains under it and you get all of them in **one coupled
24
+ * solve**, which is what makes self-collision between them work.
25
+ *
26
+ * **What holds it is a separate question**, answered by {@link ClothPin}s: any
27
+ * number of them, on any entities, holding any particles, added and removed
28
+ * while it runs. The rope above is held at its top by its own entity; a rope
29
+ * bridge is that plus a post holding its last link; a rope nothing holds falls.
30
+ * The frame is only what the cloth is simulated in and what §7 P7's inertia is
31
+ * measured against — the entity the cloth rides, which cloth reads and never
32
+ * writes.
33
+ *
34
+ * Two rules keep the walk unambiguous:
35
+ *
36
+ * - **A nested `Cloth` claims its own subtree.** The walk stops when it meets
37
+ * another `Cloth`, so independent hanging parts of one prop partition
38
+ * naturally, each read one fixed step after the cloth above it wrote it.
39
+ * - **{@link ClothExclude}** prunes a subtree from the walk, for the rig with a
40
+ * non-simulated attachment point in the middle of a chain.
41
+ *
42
+ * From M3 a `ClothRig` alongside this component redirects the particle set to a
43
+ * skinned model instance's joints instead (§11.2). The solver is identical
44
+ * either way; only seeding and write-back differ, which is why there is no mode
45
+ * enum here — component presence does the job an enum would otherwise do badly.
46
+ *
47
+ * ## What has to be true of the subtree
48
+ *
49
+ * Every simulated entity needs a `TransformAttachment` naming its parent and a
50
+ * `Transform64`; that is what "is in the transform subtree" means, and it is
51
+ * the ordinary way anything is parented. The subtree is walked **once**, when
52
+ * the cloth first steps. Adding or removing links afterwards needs an explicit
53
+ * re-seed, which is the same contract `TransformAttachment#parent` already
54
+ * carries: remove the component and add it back.
55
+ *
56
+ * @author Alex Goldring
57
+ * @copyright Company Named Limited (c) 2026
58
+ */
59
+ export class Cloth {
60
+
61
+ /**
62
+ * How it behaves. Assign a frozen library entry directly and it is shared,
63
+ * immutable and free; `.clone()` it and you own a copy to edit. Writing a
64
+ * field on an owned copy takes effect on the next step — the system
65
+ * compares what it last saw and re-parameterises the rows when it differs,
66
+ * so `cloth.dynamics.slack = 0.2` works live.
67
+ * @type {ClothDynamics}
68
+ */
69
+ dynamics = new ClothDynamics();
70
+
71
+ /**
72
+ * `0` is the fully animated pose, `1` the fully simulated one.
73
+ *
74
+ * A lerp applied at write-back rather than a solver parameter, so it is
75
+ * free and always safe. It is the escape hatch for cinematics, for LOD, and
76
+ * for "turn it off for this one shot"; from M5 the culling pass drives it
77
+ * to blend a cloth back in without a pop.
78
+ * @type {number}
79
+ */
80
+ blend = 1;
81
+
82
+ /**
83
+ * Collision layer this cloth belongs to, `RigidBody` semantics. Read from
84
+ * M2, when there is something to filter.
85
+ * @type {number}
86
+ */
87
+ layer = 1;
88
+
89
+ /**
90
+ * Which `ClothCollider` layers this cloth collides against. Read from M2.
91
+ * @type {number}
92
+ */
93
+ mask = 0xFFFFFFFF;
94
+
95
+ /**
96
+ * @see ClothFlags
97
+ * @type {number}
98
+ */
99
+ flags = ClothFlags.None;
100
+
101
+ /**
102
+ * @param {number|ClothFlags} flag
103
+ * @returns {boolean}
104
+ */
105
+ getFlag(flag) {
106
+ return (this.flags & flag) === flag;
107
+ }
108
+
109
+ /**
110
+ * @param {ClothDynamics} [dynamics] assigned by reference — pass a library
111
+ * entry to share it, `.clone()` first to own it
112
+ * @param {object} [spec]
113
+ * @param {number} [spec.blend]
114
+ * @param {number} [spec.layer]
115
+ * @param {number} [spec.mask]
116
+ * @param {number} [spec.flags]
117
+ * @returns {Cloth}
118
+ */
119
+ static from(dynamics = undefined, spec = {}) {
120
+ const r = new Cloth();
121
+
122
+ if (dynamics !== undefined) {
123
+ assert.ok(dynamics.isClothDynamics === true, 'dynamics must be a ClothDynamics');
124
+
125
+ r.dynamics = dynamics;
126
+ }
127
+
128
+ const {
129
+ blend = r.blend,
130
+ layer = r.layer,
131
+ mask = r.mask,
132
+ flags = r.flags
133
+ } = spec;
134
+
135
+ assert.isNumber(blend, 'blend');
136
+ assert.isNonNegativeInteger(layer, 'layer');
137
+ assert.isNonNegativeInteger(mask, 'mask');
138
+ assert.isNonNegativeInteger(flags, 'flags');
139
+
140
+ r.blend = blend;
141
+ r.layer = layer;
142
+ r.mask = mask;
143
+ r.flags = flags;
144
+
145
+ return r;
146
+ }
147
+
148
+ /**
149
+ * @param {Cloth} other
150
+ * @returns {boolean}
151
+ */
152
+ equals(other) {
153
+ if (other === this) {
154
+ return true;
155
+ }
156
+
157
+ if (other === null || other === undefined || other.isCloth !== true) {
158
+ return false;
159
+ }
160
+
161
+ return this.dynamics.equals(other.dynamics)
162
+ && this.blend === other.blend
163
+ && this.layer === other.layer
164
+ && this.mask === other.mask
165
+ && this.flags === other.flags;
166
+ }
167
+
168
+ /**
169
+ * @returns {number}
170
+ */
171
+ hash() {
172
+ return combine_hash(
173
+ this.dynamics.hash(),
174
+ computeHashFloat(this.blend),
175
+ this.layer,
176
+ this.mask,
177
+ this.flags
178
+ );
179
+ }
180
+
181
+ toJSON() {
182
+ return {
183
+ dynamics: this.dynamics.toJSON(),
184
+ blend: this.blend,
185
+ layer: this.layer,
186
+ mask: this.mask,
187
+ flags: this.flags
188
+ };
189
+ }
190
+
191
+ /**
192
+ * @param {object} json
193
+ */
194
+ fromJSON({ dynamics, blend = 1, layer = 1, mask = 0xFFFFFFFF, flags = ClothFlags.None }) {
195
+ // Deserialising into a shared frozen library entry would be a
196
+ // cross-instance write, so a loaded cloth always owns its dynamics.
197
+ this.dynamics = new ClothDynamics();
198
+
199
+ if (dynamics !== undefined) {
200
+ this.dynamics.fromJSON(dynamics);
201
+ }
202
+
203
+ this.blend = blend;
204
+ this.layer = layer;
205
+ this.mask = mask;
206
+ this.flags = flags;
207
+ }
208
+
209
+ toString() {
210
+ return `Cloth${JSON.stringify(this.toJSON())}`;
211
+ }
212
+ }
213
+
214
+ /**
215
+ * @readonly
216
+ * @type {boolean}
217
+ */
218
+ Cloth.prototype.isCloth = true;
219
+
220
+ Cloth.typeName = "Cloth";
@@ -4,6 +4,5 @@
4
4
  export type ClothColliderFlags = number;
5
5
  export namespace ClothColliderFlags {
6
6
  let None: number;
7
- let Static: number;
8
7
  }
9
8
  //# sourceMappingURL=ClothColliderFlags.d.ts.map
@@ -8,26 +8,13 @@
8
8
  * @copyright Company Named Limited (c) 2026
9
9
  */
10
10
  export const ClothColliderFlags = {
11
- None: 0,
11
+ None: 0
12
12
 
13
- /**
14
- * The collider never moves, so it is placed once and never swept.
15
- *
16
- * §8.2's swept collision interpolates each collider's pose between the
17
- * previous step's and this one's, and rolling one pose into the other and
18
- * refitting the swept bounds is the per-collider, per-step cost of that. A
19
- * ground plane, a wall, a rock pays it for nothing, and a large static
20
- * collider pays the most because its bounds are the biggest thing the
21
- * broadphase tests against.
22
- *
23
- * Set this and the pose is written once, at link, into **both** slots, so
24
- * the sweep degenerates to the pose it already had. Move the entity anyway
25
- * and the cloth will not notice: that is the trade, and it is why this is
26
- * an author's assertion rather than something derived from a pose that
27
- * happens not to have changed yet. An explicit TRANSFORM64_EVENT_PLACED
28
- * (including PhysicsSystem.setPose) does re-place a static proxy.
29
- */
30
- Static: 1
13
+ // Bit 0 was `Static`: "this collider never moves, so place it once and
14
+ // never sweep it". It is retired rather than reused, because saves carry
15
+ // it. The index skips the refit of a collider whose pose did not change,
16
+ // which is the saving the flag bought, observed rather than promised — and
17
+ // a "static" collider that moves anyway is swept like any other.
31
18
  };
32
19
 
33
20
  Object.freeze(ClothColliderFlags);
@@ -100,8 +100,7 @@ export class ClothColliderSystem extends System<any> {
100
100
  */
101
101
  refreshSurface(entity: number): void;
102
102
  /**
103
- * Reset motion history at an explicitly published placement, including
104
- * static proxies. The next refresh can still sweep any subsequent motion.
103
+ * Reset motion history at an explicitly published placement. The next refresh can still sweep any subsequent motion.
105
104
  * @param {number} handle
106
105
  * @param {Transform64} transform
107
106
  * @private
@@ -1 +1 @@
1
- {"version":3,"file":"ClothColliderSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/ClothColliderSystem.js"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH;;IAEI,8EAAsD;IAEtD,wKAIE;IAEF;;OAEG;IACH,OAFU,kBAAkB,CAEK;IAEjC;;;;;;OAMG;IACH,kBAAsB;IAEtB;;;;;;;;OAQG;IACH,iBAAc;IAEd;;;;;OAKG;IACH,qBALW,aAAa,YACb,QAAQ,aACR,WAAW,UACX,MAAM,QAoChB;IAED;;;;;OAKG;IACH,uBALW,aAAa,YACb,QAAQ,aACR,WAAW,UACX,MAAM,QAqBhB;IAED;;;;;;OAMG;IACH,WAFa,IAAI,CAkChB;IAED;;;;;;;;OAQG;IACH,uBAHW,MAAM,GACJ,IAAI,CAyBhB;IAED;;;;;;OAMG;IACH,gBAWC;IAED;;;OAGG;IACH,iBAHW,MAAM,GACJ,MAAM,CAIlB;CACJ;uBArQsB,wBAAwB;4BAMxC,uCAAuC;yBACrB,uBAAuB;8BAElB,oBAAoB;4CAVN,uDAAuD;mCAShE,mCAAmC"}
1
+ {"version":3,"file":"ClothColliderSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/ClothColliderSystem.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH;;IAEI,8EAAsD;IAEtD,wKAIE;IAEF;;OAEG;IACH,OAFU,kBAAkB,CAEK;IAEjC;;;;;;OAMG;IACH,kBAAsB;IAEtB;;;;;;;;OAQG;IACH,iBAAc;IAEd;;;;;OAKG;IACH,qBALW,aAAa,YACb,QAAQ,aACR,WAAW,UACX,MAAM,QAoChB;IAED;;;;;OAKG;IACH,uBALW,aAAa,YACb,QAAQ,aACR,WAAW,UACX,MAAM,QAqBhB;IAED;;;;;;OAMG;IACH,WAFa,IAAI,CA2BhB;IAED;;;;;;;;OAQG;IACH,uBAHW,MAAM,GACJ,IAAI,CAyBhB;IAED;;;;;OAKG;IACH,gBAWC;IAED;;;OAGG;IACH,iBAHW,MAAM,GACJ,MAAM,CAIlB;CACJ;uBA5PsB,wBAAwB;4BAMxC,uCAAuC;yBACrB,uBAAuB;8BAElB,oBAAoB;4CAVN,uDAAuD;mCAShE,mCAAmC"}
@@ -10,7 +10,6 @@ import {
10
10
  import { Collider } from "../../ecs/Collider.js";
11
11
  import { ClothColliderIndex } from "../collider/ClothColliderIndex.js";
12
12
  import { ClothCollider } from "./ClothCollider.js";
13
- import { ClothColliderFlags } from "./ClothColliderFlags.js";
14
13
 
15
14
  /**
16
15
  * # The index's owner
@@ -176,15 +175,8 @@ export class ClothColliderSystem extends System {
176
175
  for (let i = 0; i < linked.length; i++) {
177
176
  const entry = linked[i];
178
177
 
179
- const cloth_collider = entry.collider;
180
-
181
- if ((cloth_collider.flags & ClothColliderFlags.Static) !== 0) {
182
- // Placed once at link and never swept. `advance` has just made
183
- // its previous pose equal to its current one, which is exactly
184
- // the state a static collider wants and costs nothing to leave.
185
- continue;
186
- }
187
-
178
+ // A collider that has not moved since the last step is a pose equal
179
+ // to the one the index holds, which it does not refit.
188
180
  const transform = entry.transform;
189
181
 
190
182
  index.setPose(
@@ -235,8 +227,7 @@ export class ClothColliderSystem extends System {
235
227
  }
236
228
 
237
229
  /**
238
- * Reset motion history at an explicitly published placement, including
239
- * static proxies. The next refresh can still sweep any subsequent motion.
230
+ * Reset motion history at an explicitly published placement. The next refresh can still sweep any subsequent motion.
240
231
  * @param {number} handle
241
232
  * @param {Transform64} transform
242
233
  * @private
@@ -29,6 +29,12 @@ export const ClothDynamicsFlags = {
29
29
  * all and the row makes it marginally *worse*. `CLOTH_SILK`, `CLOTH_COTTON`
30
30
  * and `CLOTH_HAIR` set it; nothing else does. `MEASUREMENTS.md` §33.
31
31
  *
32
+ * Those figures are at the stiffness M4 shipped. At today's
33
+ * `CLOTH_SELF_RATIO`, the row removes 63% to 71% of the folding sheet's
34
+ * crossings, and in exchange a cloth resting on itself (a pile, a drape
35
+ * whose edges fold under, a skirt after a twirl) comes to rest instead of
36
+ * jittering for ever. `MEASUREMENTS.md` §65.
37
+ *
32
38
  * What it buys is **fewer crossings while the cloth moves**, not a cleaner
33
39
  * cloth at rest: a sheet that settles takes its tangles out with it either
34
40
  * way. And it is one tier of two — `MEASUREMENTS.md` §32 measures the limit
@@ -0,0 +1,91 @@
1
+ /**
2
+ * # One {@link ClothPin}, as the cloth sees it
3
+ *
4
+ * The pin is the author's statement — this entity holds these particles of that
5
+ * cloth. This is what the statement turns into: where each held particle sits
6
+ * relative to its holder, and where the holder is this step. {@link ClothWorld}
7
+ * keeps one per pin for as long as the pin exists, **outside** the seeded
8
+ * instance, because the offsets are the hold's and not the `ClothState`'s: a
9
+ * re-seed builds a new state and must not move what is being held.
10
+ *
11
+ * A struct: {@link ClothWorld} and `cloth_holds.js` are its behaviour.
12
+ *
13
+ * @author Alex Goldring
14
+ * @copyright Company Named Limited (c) 2026
15
+ */
16
+ export class ClothHold {
17
+ /**
18
+ * The entity carrying the {@link ClothPin}.
19
+ * @type {number}
20
+ */
21
+ holder: number;
22
+ /**
23
+ * @type {ClothPin|null}
24
+ */
25
+ pin: ClothPin | null;
26
+ /**
27
+ * Each held particle relative to the holder, in the holder's own frame, 3 per
28
+ * entry of the pin's particle list. Taken once, when the hold begins.
29
+ * @type {Float64Array}
30
+ */
31
+ offset: Float64Array;
32
+ /**
33
+ * Whether {@link offset} has been taken. Until it has, the hold holds
34
+ * nothing: its holder has not been found yet, or its cloth has not seeded.
35
+ * @type {boolean}
36
+ */
37
+ captured: boolean;
38
+ /**
39
+ * The holder's rotation in the cloth's frame when the hold began, `[x, y, z, w]`
40
+ * — what the animated pose measures the holder's turn from.
41
+ * @type {Float64Array}
42
+ */
43
+ rotation_at_hold: Float64Array;
44
+ /**
45
+ * The holder's pose in the cloth's frame this step, `[tx, ty, tz, qx, qy, qz, qw]`.
46
+ * @type {Float64Array}
47
+ */
48
+ pose: Float64Array;
49
+ /**
50
+ * {@link pose} as of the previous step — what the teleport test measures a
51
+ * jump against.
52
+ * @type {Float64Array}
53
+ */
54
+ pose_previous: Float64Array;
55
+ /**
56
+ * The holder's world pose this step, and the previous step's — what the
57
+ * wake test compares, because a holder that has not moved is a world that
58
+ * has not changed whatever the frame did.
59
+ * @type {Float64Array}
60
+ */
61
+ world: Float64Array;
62
+ /**
63
+ * @type {Float64Array}
64
+ */
65
+ world_previous: Float64Array;
66
+ /**
67
+ * Whether {@link pose} and {@link world} hold this step's answer. A holder
68
+ * whose hierarchy is not complete yet has none, and its particles stay where
69
+ * the last answer put them.
70
+ * @type {boolean}
71
+ */
72
+ valid: boolean;
73
+ /**
74
+ * Whether {@link pose_previous} and {@link world_previous} mean anything.
75
+ * @type {boolean}
76
+ */
77
+ has_previous: boolean;
78
+ /**
79
+ * Whether the cloth refused this hold — a holder that the cloth itself
80
+ * moves, or a particle it does not have — in which case it holds nothing.
81
+ * @type {boolean}
82
+ */
83
+ refused: boolean;
84
+ /**
85
+ * Whether the refusal has been said. Once: a hold that does not fit will not
86
+ * start fitting, and a warning a step is a log nobody reads.
87
+ * @type {boolean}
88
+ */
89
+ reported: boolean;
90
+ }
91
+ //# sourceMappingURL=ClothHold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClothHold.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/ClothHold.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH;IAEI;;;OAGG;IACH,QAFU,MAAM,CAEJ;IAEZ;;OAEG;IACH,KAFU,WAAS,IAAI,CAEZ;IAEX;;;;OAIG;IACH,QAFU,YAAY,CAEO;IAE7B;;;;OAIG;IACH,UAFU,OAAO,CAEA;IAEjB;;;;OAIG;IACH,kBAFU,YAAY,CAE4B;IAElD;;;OAGG;IACH,MAFU,YAAY,CAEyB;IAE/C;;;;OAIG;IACH,eAFU,YAAY,CAEkC;IAExD;;;;;OAKG;IACH,OAFU,YAAY,CAE0B;IAEhD;;OAEG;IACH,gBAFU,YAAY,CAEmC;IAEzD;;;;;OAKG;IACH,OAFU,OAAO,CAEH;IAEd;;;OAGG;IACH,cAFU,OAAO,CAEI;IAErB;;;;OAIG;IACH,SAFU,OAAO,CAED;IAEhB;;;;OAIG;IACH,UAFU,OAAO,CAEA;CACpB"}