@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,3 +1,5 @@
1
+ import { clamp01 } from "../../../../core/math/clamp01.js";
2
+
1
3
  /**
2
4
  * # Normalised coordinates → row parameters
3
5
  *
@@ -129,9 +131,10 @@ export const CLOTH_VELOCITY_CORRECTION_MARGIN = 4;
129
131
  export const CLOTH_DAMPING_RATE = 20;
130
132
 
131
133
  /**
132
- * How far a cloth's anchor may carry it in one fixed step, as a multiple of the
134
+ * How far a cloth's frame may carry it in one fixed step, as a multiple of the
133
135
  * cloth's own reach. Motion above this is felt as though it were exactly this,
134
- * which is what "anchor speed limit" means in §7 P7.
136
+ * which is what "anchor speed limit" means in §7 P7 — the frame being what the
137
+ * cloth rides.
135
138
  *
136
139
  * Expressing it as a fraction of reach rather than in metres per second is what
137
140
  * makes it work for a 3 cm pendant and a 30 m mooring line at the same time: a
@@ -142,10 +145,10 @@ export const CLOTH_DAMPING_RATE = 20;
142
145
  * badly-keyed cut does exceed.
143
146
  * @type {number}
144
147
  */
145
- export const CLOTH_ANCHOR_TRAVEL_REACH = 0.5;
148
+ export const CLOTH_FRAME_TRAVEL_REACH = 0.5;
146
149
 
147
150
  /**
148
- * How far a cloth's anchor may rotate in one fixed step, radians. Rotation
151
+ * How far a cloth's frame may rotate in one fixed step, radians. Rotation
149
152
  * above this is felt as though it were exactly this.
150
153
  *
151
154
  * Unlike the travel limit this has no length scale to hang off — an angle is
@@ -153,11 +156,12 @@ export const CLOTH_ANCHOR_TRAVEL_REACH = 0.5;
153
156
  * about 1,700 degrees a second, which is a spin rather than a turn.
154
157
  * @type {number}
155
158
  */
156
- export const CLOTH_ANCHOR_ROTATION_LIMIT = 0.5;
159
+ export const CLOTH_FRAME_ROTATION_LIMIT = 0.5;
157
160
 
158
161
  /**
159
- * Anchor displacement in one fixed step, as a multiple of the cloth's reach,
160
- * above which the motion is a **teleport** rather than locomotion (§7 P6).
162
+ * Displacement of the frame, or of a holder in the frame, in one fixed step, as
163
+ * a multiple of the cloth's reach, above which the motion is a **teleport**
164
+ * rather than locomotion (§7 P6).
161
165
  *
162
166
  * Four reaches in one step is 240 reaches a second: for a 1 m rope that is
163
167
  * 240 m/s, well past anything the world moves at and well short of the values a
@@ -267,9 +271,7 @@ export const CLOTH_SLEEP_STEPS = 30;
267
271
  * @returns {number} strain, `L_max = L₀·(1 + ε)`
268
272
  */
269
273
  export function cloth_strain_allowance(stretch) {
270
- const t = stretch < 0 ? 0 : (stretch > 1 ? 1 : stretch);
271
-
272
- return CLOTH_STRAIN_MAX * Math.pow(CLOTH_STRAIN_MIN / CLOTH_STRAIN_MAX, t);
274
+ return CLOTH_STRAIN_MAX * Math.pow(CLOTH_STRAIN_MIN / CLOTH_STRAIN_MAX, clamp01(stretch));
273
275
  }
274
276
 
275
277
  /**
@@ -8,17 +8,17 @@
8
8
  * step, the colliders that could touch it are queried out of the index and
9
9
  * rewritten into its frame.
10
10
  *
11
- * ## Both poses go into the *current* anchor frame
11
+ * ## Both poses go into the cloth's *current* frame
12
12
  *
13
13
  * A record carries where the collider was and where it is. Both are converted
14
- * using the anchor's pose **now**, not each with the anchor pose of its own
14
+ * using the frame's pose **now**, not each with the frame pose of its own
15
15
  * step, so what the sweep interpolates is the collider's motion *relative to
16
16
  * the cloth's frame*. That is the motion the particles actually see: the frame
17
17
  * change has already been applied to them by `move_local_frame`, scaled by
18
18
  * `ClothDynamics#inertia`, before the step begins.
19
19
  *
20
20
  * The alternative — converting each pose in its own frame — would make a
21
- * collider appear to move whenever the anchor did, so a character running past
21
+ * collider appear to move whenever the frame did, so a character running past
22
22
  * a static wall would sweep the wall through their own cape.
23
23
  *
24
24
  * ## The query box
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_gather_colliders.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_gather_colliders.js"],"names":[],"mappings":"AAuCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qFAHW,MAAM,GACJ,MAAM,CAsBlB;AAyJD;;;;;;GAMG;AACH,kGAHW,MAAM,GACJ,MAAM,CAmBlB;AAwFD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,2FAFa,OAAO,CAkBnB;AAED;;;;;;;;GAQG;AACH,yEAHW,MAAM,GACJ,IAAI,CAgBhB"}
1
+ {"version":3,"file":"cloth_gather_colliders.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_gather_colliders.js"],"names":[],"mappings":"AAiCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qFAHW,MAAM,GACJ,MAAM,CAsBlB;AA2HD;;;;;;GAMG;AACH,kGAHW,MAAM,GACJ,MAAM,CAmBlB;AA2ED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,2FAFa,OAAO,CAkBnB;AAED;;;;;;;;GAQG;AACH,yEAHW,MAAM,GACJ,IAAI,CAgBhB"}
@@ -1,6 +1,6 @@
1
- import { quat3_multiply_array } from "../../../../core/geom/3d/quaternion/quat3_multiply.js";
2
- import { v3_quaternion_apply_array } from "../../../../core/geom/vec3/v3_quaternion_apply.js";
3
- import { v3_quaternion_apply_inverse_array } from "../../../../core/geom/vec3/v3_quaternion_apply_inverse.js";
1
+ import { aabb3_from_v3_array } from "../../../../core/geom/3d/aabb/aabb3_from_v3_array.js";
2
+ import { aabb3_transform_oriented_array } from "../../../../core/geom/3d/aabb/aabb3_transform_oriented.js";
3
+ import { pose3_to_local_array } from "../../../../core/geom/3d/pose/pose3_to_local_array.js";
4
4
  import {
5
5
  CCR_AABB_MAX_X,
6
6
  CCR_AABB_MAX_Y,
@@ -16,17 +16,11 @@ import {
16
16
  CCR_PARAM_1,
17
17
  CCR_PARAM_2,
18
18
  CCR_PARAM_3,
19
- CCR_PREV_QW,
20
19
  CCR_PREV_QX,
21
- CCR_PREV_QY,
22
- CCR_PREV_QZ,
23
20
  CCR_PREV_TX,
24
21
  CCR_PREV_TY,
25
22
  CCR_PREV_TZ,
26
- CCR_QW,
27
23
  CCR_QX,
28
- CCR_QY,
29
- CCR_QZ,
30
24
  CCR_STRIDE,
31
25
  CCR_TX,
32
26
  CCR_TY,
@@ -47,17 +41,17 @@ import { CLOTH_COLLIDER_SLOTS } from "../solver/cloth_solver_constants.js";
47
41
  * step, the colliders that could touch it are queried out of the index and
48
42
  * rewritten into its frame.
49
43
  *
50
- * ## Both poses go into the *current* anchor frame
44
+ * ## Both poses go into the cloth's *current* frame
51
45
  *
52
46
  * A record carries where the collider was and where it is. Both are converted
53
- * using the anchor's pose **now**, not each with the anchor pose of its own
47
+ * using the frame's pose **now**, not each with the frame pose of its own
54
48
  * step, so what the sweep interpolates is the collider's motion *relative to
55
49
  * the cloth's frame*. That is the motion the particles actually see: the frame
56
50
  * change has already been applied to them by `move_local_frame`, scaled by
57
51
  * `ClothDynamics#inertia`, before the step begins.
58
52
  *
59
53
  * The alternative — converting each pose in its own frame — would make a
60
- * collider appear to move whenever the anchor did, so a character running past
54
+ * collider appear to move whenever the frame did, so a character running past
61
55
  * a static wall would sweep the wall through their own cape.
62
56
  *
63
57
  * ## The query box
@@ -167,46 +161,33 @@ function query_colliders(instance, index, reach) {
167
161
  const particle_count = state.particle_count;
168
162
  const position = state.position;
169
163
 
170
- let min_x = Infinity;
171
- let min_y = Infinity;
172
- let min_z = Infinity;
173
- let max_x = -Infinity;
174
- let max_y = -Infinity;
175
- let max_z = -Infinity;
176
-
177
- for (let i = 0; i < particle_count; i++) {
178
- const p = i * 3;
179
-
180
- const x = position[p];
181
- const y = position[p + 1];
182
- const z = position[p + 2];
183
-
184
- if (x < min_x) { min_x = x; }
185
- if (y < min_y) { min_y = y; }
186
- if (z < min_z) { min_z = z; }
187
- if (x > max_x) { max_x = x; }
188
- if (y > max_y) { max_y = y; }
189
- if (z > max_z) { max_z = z; }
190
- }
191
-
192
164
  if (particle_count === 0) {
193
165
  return 0;
194
166
  }
195
167
 
196
- // The anchor pose the particles were carried into this step, not the live
168
+ aabb3_from_v3_array(LOCAL_BOX, position, particle_count * 3);
169
+
170
+ let min_x = LOCAL_BOX[0];
171
+ let min_y = LOCAL_BOX[1];
172
+ let min_z = LOCAL_BOX[2];
173
+ let max_x = LOCAL_BOX[3];
174
+ let max_y = LOCAL_BOX[4];
175
+ let max_z = LOCAL_BOX[5];
176
+
177
+ // The frame pose the particles were carried into this step, not the live
197
178
  // component — those are the same value by the time this runs, and the
198
179
  // cached pair is the one `move_local_frame` used.
199
- const anchor_x = instance.anchor_translation[0];
200
- const anchor_y = instance.anchor_translation[1];
201
- const anchor_z = instance.anchor_translation[2];
180
+ const frame_x = instance.frame_translation[0];
181
+ const frame_y = instance.frame_translation[1];
182
+ const frame_z = instance.frame_translation[2];
202
183
 
203
- const anchor_rotation = instance.anchor_rotation;
184
+ const frame_rotation = instance.frame_rotation;
204
185
 
205
186
  const contact_reach = reach + state.contact_radius * (1 + CLOTH_CONTACT_MARGIN);
206
187
  const local_scale = Math.max(Math.abs(min_x), Math.abs(max_x))
207
188
  + Math.max(Math.abs(min_y), Math.abs(max_y))
208
189
  + Math.max(Math.abs(min_z), Math.abs(max_z)) + contact_reach;
209
- const world_scale = local_scale + Math.abs(anchor_x) + Math.abs(anchor_y) + Math.abs(anchor_z);
190
+ const world_scale = local_scale + Math.abs(frame_x) + Math.abs(frame_y) + Math.abs(frame_z);
210
191
  const margin = contact_reach + cloth_contact_rounding(local_scale, world_scale);
211
192
 
212
193
  min_x -= margin;
@@ -216,46 +197,29 @@ function query_colliders(instance, index, reach) {
216
197
  max_y += margin;
217
198
  max_z += margin;
218
199
 
219
- // The local box's eight corners, in world. A rotated box is not a box, so
220
- // the world query volume is the bounds of the rotated one rather than the
221
- // rotation of the bounds.
222
- let world_min_x = Infinity;
223
- let world_min_y = Infinity;
224
- let world_min_z = Infinity;
225
- let world_max_x = -Infinity;
226
- let world_max_y = -Infinity;
227
- let world_max_z = -Infinity;
228
-
229
- for (let corner = 0; corner < 8; corner++) {
230
- // The corner and the rotation go in as arrays: handed over as seven numbers, each was boxed
231
- // wherever the call was not inlined, eight times a cloth a step.
232
- CORNER[0] = (corner & 1) === 0 ? min_x : max_x;
233
- CORNER[1] = (corner & 2) === 0 ? min_y : max_y;
234
- CORNER[2] = (corner & 4) === 0 ? min_z : max_z;
235
-
236
- v3_quaternion_apply_array(CORNER, 0, CORNER, 0, anchor_rotation, 0);
237
-
238
- const x = CORNER[0] + anchor_x;
239
- const y = CORNER[1] + anchor_y;
240
- const z = CORNER[2] + anchor_z;
241
-
242
- if (x < world_min_x) { world_min_x = x; }
243
- if (y < world_min_y) { world_min_y = y; }
244
- if (z < world_min_z) { world_min_z = z; }
245
- if (x > world_max_x) { world_max_x = x; }
246
- if (y > world_max_y) { world_max_y = y; }
247
- if (z > world_max_z) { world_max_z = z; }
248
- }
200
+ LOCAL_BOX[0] = min_x;
201
+ LOCAL_BOX[1] = min_y;
202
+ LOCAL_BOX[2] = min_z;
203
+ LOCAL_BOX[3] = max_x;
204
+ LOCAL_BOX[4] = max_y;
205
+ LOCAL_BOX[5] = max_z;
206
+
207
+ // The frame pose as the seven contiguous numbers the transform reads,
208
+ // translation then rotation; the instance keeps the two apart.
209
+ FRAME_POSE[0] = frame_x;
210
+ FRAME_POSE[1] = frame_y;
211
+ FRAME_POSE[2] = frame_z;
212
+ FRAME_POSE[3] = frame_rotation[0];
213
+ FRAME_POSE[4] = frame_rotation[1];
214
+ FRAME_POSE[5] = frame_rotation[2];
215
+ FRAME_POSE[6] = frame_rotation[3];
216
+
217
+ // A rotated box is not a box, so the world query volume is the bounds of
218
+ // the rotated one rather than the rotation of the bounds.
219
+ aabb3_transform_oriented_array(QUERY_BOX, 0, LOCAL_BOX, 0, FRAME_POSE, 0);
249
220
 
250
221
  const cloth = instance.cloth;
251
222
 
252
- QUERY_BOX[0] = world_min_x;
253
- QUERY_BOX[1] = world_min_y;
254
- QUERY_BOX[2] = world_min_z;
255
- QUERY_BOX[3] = world_max_x;
256
- QUERY_BOX[4] = world_max_y;
257
- QUERY_BOX[5] = world_max_z;
258
-
259
223
  const candidates = index.queryArray(HANDLES, QUERY_BOX, 0, cloth.layer, cloth.mask, true);
260
224
 
261
225
  // A half-space has no bounded world-space conversion allowance, so the
@@ -339,8 +303,8 @@ export function cloth_gather_colliders(instance, index, reach) {
339
303
  * @private
340
304
  */
341
305
  function localise_record(table, record, source, handle, instance) {
342
- const anchor_translation = instance.anchor_translation;
343
- const anchor_rotation = instance.anchor_rotation;
306
+ const frame_translation = instance.frame_translation;
307
+ const frame_rotation = instance.frame_rotation;
344
308
  const from = handle * CCR_STRIDE;
345
309
  const to = record * CCR_STRIDE;
346
310
 
@@ -356,13 +320,13 @@ function localise_record(table, record, source, handle, instance) {
356
320
  localise(
357
321
  table, to + CCR_TX, to + CCR_QX,
358
322
  source, from + CCR_TX, from + CCR_QX,
359
- anchor_translation, anchor_rotation
323
+ frame_translation, frame_rotation
360
324
  );
361
325
 
362
326
  localise(
363
327
  table, to + CCR_PREV_TX, to + CCR_PREV_QX,
364
328
  source, from + CCR_PREV_TX, from + CCR_PREV_QX,
365
- anchor_translation, anchor_rotation
329
+ frame_translation, frame_rotation
366
330
  );
367
331
 
368
332
  cloth_collider_refit_bounds(table, record, CCR_STRIDE);
@@ -382,36 +346,23 @@ function localise_record(table, record, source, handle, instance) {
382
346
  * @param {Float32Array|Float64Array} source the world pose's record table
383
347
  * @param {number} source_translation_slot `[x, y, z]`
384
348
  * @param {number} source_rotation_slot `[x, y, z, w]`
385
- * @param {Float64Array} anchor_translation `[x, y, z]`
386
- * @param {Float64Array} anchor_rotation `[x, y, z, w]`
349
+ * @param {Float64Array} frame_translation `[x, y, z]`
350
+ * @param {Float64Array} frame_rotation `[x, y, z, w]`
387
351
  * @private
388
352
  */
389
353
  function localise(
390
354
  table, translation_slot, rotation_slot,
391
355
  source, source_translation_slot, source_rotation_slot,
392
- anchor_translation, anchor_rotation
356
+ frame_translation, frame_rotation
393
357
  ) {
394
- LOCAL_TRANSLATION[0] = source[source_translation_slot] - anchor_translation[0];
395
- LOCAL_TRANSLATION[1] = source[source_translation_slot + 1] - anchor_translation[1];
396
- LOCAL_TRANSLATION[2] = source[source_translation_slot + 2] - anchor_translation[2];
397
-
398
- v3_quaternion_apply_inverse_array(LOCAL_TRANSLATION, 0, LOCAL_TRANSLATION, 0, anchor_rotation, 0);
399
-
400
- table[translation_slot] = LOCAL_TRANSLATION[0];
401
- table[translation_slot + 1] = LOCAL_TRANSLATION[1];
402
- table[translation_slot + 2] = LOCAL_TRANSLATION[2];
403
-
404
- ANCHOR_CONJUGATE[0] = -anchor_rotation[0];
405
- ANCHOR_CONJUGATE[1] = -anchor_rotation[1];
406
- ANCHOR_CONJUGATE[2] = -anchor_rotation[2];
407
- ANCHOR_CONJUGATE[3] = anchor_rotation[3];
408
-
409
- quat3_multiply_array(LOCAL_ROTATION, 0, ANCHOR_CONJUGATE, 0, source, source_rotation_slot);
410
-
411
- table[rotation_slot] = LOCAL_ROTATION[0];
412
- table[rotation_slot + 1] = LOCAL_ROTATION[1];
413
- table[rotation_slot + 2] = LOCAL_ROTATION[2];
414
- table[rotation_slot + 3] = LOCAL_ROTATION[3];
358
+ pose3_to_local_array(
359
+ table, translation_slot,
360
+ table, rotation_slot,
361
+ frame_translation, 0,
362
+ frame_rotation, 0,
363
+ source, source_translation_slot,
364
+ source, source_rotation_slot
365
+ );
415
366
  }
416
367
 
417
368
  /**
@@ -495,29 +446,18 @@ const HANDLES = [];
495
446
  const PLANE_RECORD = new Float32Array(CCR_STRIDE);
496
447
 
497
448
  /**
449
+ * The cloth's particle bounds, then the same fattened by the query margin, in its local frame.
498
450
  * @type {Float64Array}
499
451
  * @private
500
452
  */
501
- const CORNER = new Float64Array(3);
502
-
503
- /**
504
- * @type {Float64Array}
505
- * @private
506
- */
507
- const LOCAL_TRANSLATION = new Float64Array(3);
508
-
509
- /**
510
- * @type {Float64Array}
511
- * @private
512
- */
513
- const LOCAL_ROTATION = new Float64Array(4);
453
+ const LOCAL_BOX = new Float64Array(6);
514
454
 
515
455
  /**
516
- * The anchor's rotation conjugated, `[-x, -y, -z, w]`: {@link localise}'s left operand.
456
+ * The cloth's frame pose, `[px, py, pz, qx, qy, qz, qw]`, for {@link aabb3_transform_oriented_array}.
517
457
  * @type {Float64Array}
518
458
  * @private
519
459
  */
520
- const ANCHOR_CONJUGATE = new Float64Array(4);
460
+ const FRAME_POSE = new Float64Array(7);
521
461
 
522
462
  /**
523
463
  * The world box {@link query_colliders} asks the index about, `[min_x, min_y, min_z, max_x, max_y,
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Edges incident on each node, CSR, from an edge list.
3
+ *
4
+ * @param {number} node_count
5
+ * @param {Int32Array} edge node pairs, 2 per edge
6
+ * @returns {{offset: Int32Array, edge: Int32Array}} `edge[offset[n] .. offset[n + 1]]` are the
7
+ * edges touching `n`
8
+ */
9
+ export function cloth_edge_incidence(node_count: number, edge: Int32Array): {
10
+ offset: Int32Array;
11
+ edge: Int32Array;
12
+ };
13
+ /**
14
+ * Distance from every node to the nearest of a set of source nodes, along the
15
+ * edges, and which source that is.
16
+ *
17
+ * A node marked in `blocked` can be reached but is never passed through. That is
18
+ * Chaos Cloth's rule for its long-range attachments (`ClothTetherData.cpp`):
19
+ * a path from one island of held particles does not run through another, because
20
+ * the far side of another island is that island's business.
21
+ *
22
+ * @param {Float64Array} out_distance per node; `Infinity` where no source reaches
23
+ * @param {Int32Array} out_nearest per node, the source it is nearest; `−1` where none reaches
24
+ * @param {number} node_count
25
+ * @param {Int32Array} edge node pairs, 2 per edge
26
+ * @param {Float64Array} edge_length rest length per edge
27
+ * @param {{offset: Int32Array, edge: Int32Array}} incidence from {@link cloth_edge_incidence}
28
+ * @param {Int32Array|number[]} source
29
+ * @param {number} source_count
30
+ * @param {Uint8Array|null} blocked per node, non-zero for a node no path may pass through;
31
+ * `null` for none
32
+ */
33
+ export function cloth_geodesic_field(out_distance: Float64Array, out_nearest: Int32Array, node_count: number, edge: Int32Array, edge_length: Float64Array, incidence: {
34
+ offset: Int32Array;
35
+ edge: Int32Array;
36
+ }, source: Int32Array | number[], source_count: number, blocked: Uint8Array | null): void;
37
+ //# sourceMappingURL=cloth_geodesic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloth_geodesic.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_geodesic.js"],"names":[],"mappings":"AAuCA;;;;;;;GAOG;AACH,iDALW,MAAM,QACN,UAAU,GACR;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAC,CAiBlD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,mDAXW,YAAY,eACZ,UAAU,cACV,MAAM,QACN,UAAU,eACV,YAAY,aACZ;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAC,UACtC,UAAU,GAAC,MAAM,EAAE,gBACnB,MAAM,WACN,UAAU,GAAC,IAAI,QAsDzB"}
@@ -0,0 +1,135 @@
1
+ import { Uint32Heap } from "../../../../core/collection/heap/Uint32Heap.js";
2
+ import { csr_build_incidence } from "../../../../core/graph/csr/csr_build_incidence.js";
3
+
4
+ /**
5
+ * # How far each particle is from a set of particles, along the fabric
6
+ *
7
+ * The tether row (§6, §7 P2) bounds a particle's distance from a held one by
8
+ * the length of fabric between them, so it needs that length: the shortest path
9
+ * through the cloth's stretch edges, each weighted by its rest length. A chain
10
+ * has one path and the answer is a sum; a sheet has many and the answer is
11
+ * Dijkstra's.
12
+ *
13
+ * A path along edges is never shorter than the surface geodesic it follows, and
14
+ * that is never shorter than the straight line, so in the rest pose a tether
15
+ * built from it is never taut. That is the property the tether needs; how much
16
+ * longer a grid path is than the true geodesic is how much slack the bound
17
+ * carries, and it is the price of a bound that costs nothing at runtime.
18
+ *
19
+ * ## In double, and label-correcting
20
+ *
21
+ * The distances are accumulated in `Float64` from `Float64` edge lengths. The
22
+ * open set is a {@link Uint32Heap}, whose scores are `Float32`, so two
23
+ * candidates closer together than a single-precision step can pop in the wrong
24
+ * order; a node is therefore never closed, and a shorter path arriving after it
25
+ * popped is relaxed through again. The answer is the exact shortest path
26
+ * whatever the heap's rounding, and on the graphs this sees the extra pops are
27
+ * a handful.
28
+ *
29
+ * @author Alex Goldring
30
+ * @copyright Company Named Limited (c) 2026
31
+ */
32
+
33
+ /**
34
+ * The open set. Module-level: a search runs start to finish synchronously, and
35
+ * it runs when a cloth is seeded or its held set changes, never per step.
36
+ * @type {Uint32Heap}
37
+ */
38
+ const OPEN = new Uint32Heap();
39
+
40
+ /**
41
+ * Edges incident on each node, CSR, from an edge list.
42
+ *
43
+ * @param {number} node_count
44
+ * @param {Int32Array} edge node pairs, 2 per edge
45
+ * @returns {{offset: Int32Array, edge: Int32Array}} `edge[offset[n] .. offset[n + 1]]` are the
46
+ * edges touching `n`
47
+ */
48
+ export function cloth_edge_incidence(node_count, edge) {
49
+ const edge_count = edge.length >> 1;
50
+
51
+ const offset = new Int32Array(node_count + 1);
52
+ const incident = new Int32Array(edge_count * 2);
53
+
54
+ csr_build_incidence(offset, incident, edge, edge_count * 2, node_count);
55
+
56
+ // an endpoint's flat index `e·2 + k` to its edge `e`
57
+ for (let i = 0; i < edge_count * 2; i++) {
58
+ incident[i] >>= 1;
59
+ }
60
+
61
+ return { offset, edge: incident };
62
+ }
63
+
64
+ /**
65
+ * Distance from every node to the nearest of a set of source nodes, along the
66
+ * edges, and which source that is.
67
+ *
68
+ * A node marked in `blocked` can be reached but is never passed through. That is
69
+ * Chaos Cloth's rule for its long-range attachments (`ClothTetherData.cpp`):
70
+ * a path from one island of held particles does not run through another, because
71
+ * the far side of another island is that island's business.
72
+ *
73
+ * @param {Float64Array} out_distance per node; `Infinity` where no source reaches
74
+ * @param {Int32Array} out_nearest per node, the source it is nearest; `−1` where none reaches
75
+ * @param {number} node_count
76
+ * @param {Int32Array} edge node pairs, 2 per edge
77
+ * @param {Float64Array} edge_length rest length per edge
78
+ * @param {{offset: Int32Array, edge: Int32Array}} incidence from {@link cloth_edge_incidence}
79
+ * @param {Int32Array|number[]} source
80
+ * @param {number} source_count
81
+ * @param {Uint8Array|null} blocked per node, non-zero for a node no path may pass through;
82
+ * `null` for none
83
+ */
84
+ export function cloth_geodesic_field(
85
+ out_distance, out_nearest,
86
+ node_count, edge, edge_length, incidence,
87
+ source, source_count,
88
+ blocked
89
+ ) {
90
+ out_distance.fill(Infinity, 0, node_count);
91
+ out_nearest.fill(-1, 0, node_count);
92
+
93
+ OPEN.clear();
94
+
95
+ for (let i = 0; i < source_count; i++) {
96
+ const s = source[i];
97
+
98
+ out_distance[s] = 0;
99
+ out_nearest[s] = s;
100
+
101
+ OPEN.insert(s, 0);
102
+ }
103
+
104
+ const offset = incidence.offset;
105
+ const incident = incidence.edge;
106
+
107
+ while (!OPEN.is_empty()) {
108
+ const u = OPEN.pop_min();
109
+
110
+ const d = out_distance[u];
111
+
112
+ if (d > 0 && blocked !== null && blocked[u] !== 0) {
113
+ // Reached, and that is where the path stops.
114
+ continue;
115
+ }
116
+
117
+ const nearest = out_nearest[u];
118
+
119
+ for (let k = offset[u]; k < offset[u + 1]; k++) {
120
+ const e = incident[k];
121
+
122
+ const a = edge[e * 2];
123
+ const v = a === u ? edge[e * 2 + 1] : a;
124
+
125
+ const candidate = d + edge_length[e];
126
+
127
+ if (candidate < out_distance[v]) {
128
+ out_distance[v] = candidate;
129
+ out_nearest[v] = nearest;
130
+
131
+ OPEN.insert(v, candidate);
132
+ }
133
+ }
134
+ }
135
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * # What holding a particle does to a cloth
3
+ *
4
+ * A {@link ClothPin} holds particles, and that one fact decides four things the
5
+ * rows depend on. This module is where they are decided, once per change in
6
+ * what is held ({@link cloth_apply_holds}) and once per step
7
+ * ({@link cloth_hold_step}):
8
+ *
9
+ * - **Who is kinematic.** A held particle has inverse mass zero and follows its
10
+ * holder: the solver carries it through the step towards
11
+ * `ClothState#kinematic_target`.
12
+ * - **What each free particle hangs from.** Its nearest held particle, along the
13
+ * fabric — one multi-source Dijkstra over the stretch edges, every held
14
+ * particle a source, so a path never runs through one held particle to reach
15
+ * another. Nothing held in reach means nothing to hang from.
16
+ * - **The tether and the slack**, §6's two leash rows, both measured from that
17
+ * particle (`ClothState#leash_source`), so that they follow it through the step
18
+ * rather than lag a step behind it. One tether per particle, to the nearest
19
+ * hold only: two hard tethers to two holders pulled apart are two bounds no
20
+ * position satisfies, and the fabric between them already says everything a
21
+ * second tether could.
22
+ * - **The animated pose**, which is the rest pose hung from that particle and
23
+ * turned by its holder — see `ClothInstance#animated_position`.
24
+ *
25
+ * A particle nothing held reaches gets a tether and a slack row of radius
26
+ * `Infinity`, which say nothing, and a cloth nothing holds is all such
27
+ * particles: there is no case here for it.
28
+ *
29
+ * ## The tether never pulls
30
+ *
31
+ * A hold that begins mid-run — a hand closing on a falling ribbon — begins
32
+ * wherever the fabric is, and a free configuration is routinely further from
33
+ * the new hold than the geodesic, because the fabric stretches and the tether
34
+ * only binds when something pulls. A tether switched on at its full tightness
35
+ * would snap the cloth onto the hold inside one step. So a tether's radius
36
+ * starts at the larger of `d_geo` and where the particle is, and each step comes
37
+ * down to wherever the particle has since come to, never below `d_geo`: it
38
+ * stops a particle going further than it has been since the hold began, and
39
+ * it never drags one in. A cloth seeded at rest is inside `d_geo` everywhere,
40
+ * so its tethers are `d_geo` from the first step, which is what they always
41
+ * were — and only a tether that began loose is looked at again, so a cloth
42
+ * whose holds have not changed pays nothing for it.
43
+ *
44
+ * @author Alex Goldring
45
+ * @copyright Company Named Limited (c) 2026
46
+ */
47
+ /**
48
+ * Take a hold's offsets: each of its particles relative to the holder, in the
49
+ * holder's own frame, from where the particle is now.
50
+ *
51
+ * Done in world terms, because the particles are in the frame they were last
52
+ * stepped in and the holder is where it is this step; the two meet in the
53
+ * world. The holder's turn is then measured from its pose in this step's frame,
54
+ * {@link ClothHold#pose}, so a hold begins unturned.
55
+ *
56
+ * @param {ClothInstance} instance
57
+ * @param {ClothHold} hold with {@link ClothHold#world} and {@link ClothHold#pose}
58
+ * this step's
59
+ * @param {Float64Array} frame_translation the frame the particle positions are in
60
+ * @param {Float64Array} frame_rotation
61
+ * @returns {void}
62
+ */
63
+ export function cloth_capture_hold(instance: ClothInstance, hold: ClothHold, frame_translation: Float64Array, frame_rotation: Float64Array): void;
64
+ /**
65
+ * Re-derive everything that depends on what is held: who is kinematic, what
66
+ * each free particle hangs from, the leash rows, and `reach`.
67
+ *
68
+ * Called once a seed and once per change in the set of holds — never per step.
69
+ * Writes into the instance's existing `ClothState`; nothing is re-built, so a
70
+ * worker that holds the buffer sees it on the next step without a second
71
+ * registration.
72
+ *
73
+ * @param {ClothInstance} instance
74
+ * @returns {void}
75
+ */
76
+ export function cloth_apply_holds(instance: ClothInstance): void;
77
+ /**
78
+ * Everything a hold changes per step: where each held particle is to be, the
79
+ * animated pose hung from them, the leash centres and the tethers' ratchet.
80
+ *
81
+ * Reads each hold's {@link ClothHold#pose} — the holder in this step's frame —
82
+ * and the particle positions as the frame carry left them.
83
+ *
84
+ * **Nothing is recomputed that cannot have changed.** Every quantity here
85
+ * except the ratchet is a function of the holds' poses in the frame, and a
86
+ * holder riding the frame — a rope's own top, a cape's shoulder in a cape riding
87
+ * that shoulder — has the same pose in it every step however the frame moves.
88
+ * So when no hold has moved in the frame since the last step, and nothing has
89
+ * rewritten the particles since ({@link ClothInstance#holds_dirty}), the
90
+ * targets, the animated pose and the leash offsets are left as they are: the
91
+ * question is a fact the step already has, not a kind of cloth.
92
+ *
93
+ * @param {ClothInstance} instance
94
+ * @returns {void}
95
+ */
96
+ export function cloth_hold_step(instance: ClothInstance): void;
97
+ //# sourceMappingURL=cloth_holds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloth_holds.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_holds.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,gGAJW,YAAY,kBACZ,YAAY,GACV,IAAI,CAyChB;AAED;;;;;;;;;;;GAWG;AACH,4DAFa,IAAI,CA0KhB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,0DAFa,IAAI,CA+JhB"}