@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
@@ -0,0 +1,583 @@
1
+ import { array_range_equal_strict } from "../../../../core/collection/array/array_range_equal_strict.js";
2
+ import { pose3_apply_inverse_point_array } from "../../../../core/geom/3d/pose/pose3_apply_inverse_point_array.js";
3
+ import { pose3_apply_point_array } from "../../../../core/geom/3d/pose/pose3_apply_point_array.js";
4
+ import { quat3_multiply_array } from "../../../../core/geom/3d/quaternion/quat3_multiply.js";
5
+ import {
6
+ quat3_multiply_conjugate_right_array
7
+ } from "../../../../core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.js";
8
+ import { clamp01 } from "../../../../core/math/clamp01.js";
9
+ import { CLOTH_PARTICLE_MASS, CLOTH_SLACK_REACH } from "./cloth_build_rows.js";
10
+ import { cloth_geodesic_field } from "./cloth_geodesic.js";
11
+
12
+ /**
13
+ * # What holding a particle does to a cloth
14
+ *
15
+ * A {@link ClothPin} holds particles, and that one fact decides four things the
16
+ * rows depend on. This module is where they are decided, once per change in
17
+ * what is held ({@link cloth_apply_holds}) and once per step
18
+ * ({@link cloth_hold_step}):
19
+ *
20
+ * - **Who is kinematic.** A held particle has inverse mass zero and follows its
21
+ * holder: the solver carries it through the step towards
22
+ * `ClothState#kinematic_target`.
23
+ * - **What each free particle hangs from.** Its nearest held particle, along the
24
+ * fabric — one multi-source Dijkstra over the stretch edges, every held
25
+ * particle a source, so a path never runs through one held particle to reach
26
+ * another. Nothing held in reach means nothing to hang from.
27
+ * - **The tether and the slack**, §6's two leash rows, both measured from that
28
+ * particle (`ClothState#leash_source`), so that they follow it through the step
29
+ * rather than lag a step behind it. One tether per particle, to the nearest
30
+ * hold only: two hard tethers to two holders pulled apart are two bounds no
31
+ * position satisfies, and the fabric between them already says everything a
32
+ * second tether could.
33
+ * - **The animated pose**, which is the rest pose hung from that particle and
34
+ * turned by its holder — see `ClothInstance#animated_position`.
35
+ *
36
+ * A particle nothing held reaches gets a tether and a slack row of radius
37
+ * `Infinity`, which say nothing, and a cloth nothing holds is all such
38
+ * particles: there is no case here for it.
39
+ *
40
+ * ## The tether never pulls
41
+ *
42
+ * A hold that begins mid-run — a hand closing on a falling ribbon — begins
43
+ * wherever the fabric is, and a free configuration is routinely further from
44
+ * the new hold than the geodesic, because the fabric stretches and the tether
45
+ * only binds when something pulls. A tether switched on at its full tightness
46
+ * would snap the cloth onto the hold inside one step. So a tether's radius
47
+ * starts at the larger of `d_geo` and where the particle is, and each step comes
48
+ * down to wherever the particle has since come to, never below `d_geo`: it
49
+ * stops a particle going further than it has been since the hold began, and
50
+ * it never drags one in. A cloth seeded at rest is inside `d_geo` everywhere,
51
+ * so its tethers are `d_geo` from the first step, which is what they always
52
+ * were — and only a tether that began loose is looked at again, so a cloth
53
+ * whose holds have not changed pays nothing for it.
54
+ *
55
+ * @author Alex Goldring
56
+ * @copyright Company Named Limited (c) 2026
57
+ */
58
+
59
+ /**
60
+ * Take a hold's offsets: each of its particles relative to the holder, in the
61
+ * holder's own frame, from where the particle is now.
62
+ *
63
+ * Done in world terms, because the particles are in the frame they were last
64
+ * stepped in and the holder is where it is this step; the two meet in the
65
+ * world. The holder's turn is then measured from its pose in this step's frame,
66
+ * {@link ClothHold#pose}, so a hold begins unturned.
67
+ *
68
+ * @param {ClothInstance} instance
69
+ * @param {ClothHold} hold with {@link ClothHold#world} and {@link ClothHold#pose}
70
+ * this step's
71
+ * @param {Float64Array} frame_translation the frame the particle positions are in
72
+ * @param {Float64Array} frame_rotation
73
+ * @returns {void}
74
+ */
75
+ export function cloth_capture_hold(instance, hold, frame_translation, frame_rotation) {
76
+ const particles = hold.pin.particles;
77
+ const count = particles.length;
78
+
79
+ const state = instance.state;
80
+ const position = state.position;
81
+ const particle_of_node = instance.particle_of_node;
82
+ const node_count = instance.node_count;
83
+
84
+ const offset = new Float64Array(count * 3);
85
+
86
+ const world = hold.world;
87
+
88
+ for (let k = 0; k < count; k++) {
89
+ const node = particles[k];
90
+
91
+ if (node < 0 || node >= node_count) {
92
+ continue;
93
+ }
94
+
95
+ const p = particle_of_node[node] * 3;
96
+
97
+ // the particle in the world
98
+ pose3_apply_point_array(SCRATCH, 0, frame_translation, 0, frame_rotation, 0, position, p);
99
+
100
+ // relative to the holder, in its frame
101
+ pose3_apply_inverse_point_array(offset, k * 3, world, 0, world, 3, SCRATCH, 0);
102
+ }
103
+
104
+ hold.offset = offset;
105
+
106
+ const pose = hold.pose;
107
+
108
+ hold.rotation_at_hold[0] = pose[3];
109
+ hold.rotation_at_hold[1] = pose[4];
110
+ hold.rotation_at_hold[2] = pose[5];
111
+ hold.rotation_at_hold[3] = pose[6];
112
+
113
+ hold.captured = true;
114
+ }
115
+
116
+ /**
117
+ * Re-derive everything that depends on what is held: who is kinematic, what
118
+ * each free particle hangs from, the leash rows, and `reach`.
119
+ *
120
+ * Called once a seed and once per change in the set of holds — never per step.
121
+ * Writes into the instance's existing `ClothState`; nothing is re-built, so a
122
+ * worker that holds the buffer sees it on the next step without a second
123
+ * registration.
124
+ *
125
+ * @param {ClothInstance} instance
126
+ * @returns {void}
127
+ */
128
+ export function cloth_apply_holds(instance) {
129
+ const node_count = instance.node_count;
130
+
131
+ const state = instance.state;
132
+ const particle_of_node = instance.particle_of_node;
133
+
134
+ const node_hold = instance.node_hold;
135
+ const node_hold_slot = instance.node_hold_slot;
136
+
137
+ node_hold.fill(-1);
138
+ node_hold_slot.fill(-1);
139
+
140
+ const holds = instance.holds;
141
+
142
+ const sources = [];
143
+
144
+ // In holder order, so a particle two pins name goes to the lower holder,
145
+ // every time — `ClothWorld` sorts them and says so once.
146
+ for (let h = 0; h < holds.length; h++) {
147
+ const hold = holds[h];
148
+
149
+ if (!hold.captured) {
150
+ continue;
151
+ }
152
+
153
+ const particles = hold.pin.particles;
154
+
155
+ for (let k = 0; k < particles.length; k++) {
156
+ const node = particles[k];
157
+
158
+ if (node < 0 || node >= node_count || node_hold[node] !== -1) {
159
+ continue;
160
+ }
161
+
162
+ node_hold[node] = h;
163
+ node_hold_slot[node] = k;
164
+
165
+ sources.push(node);
166
+ }
167
+ }
168
+
169
+ const mass_inverse = state.mass_inverse;
170
+
171
+ for (let node = 0; node < node_count; node++) {
172
+ mass_inverse[particle_of_node[node]] = node_hold[node] === -1 ? 1 / CLOTH_PARTICLE_MASS : 0;
173
+ }
174
+
175
+ const distance = SCRATCH_DISTANCE.length >= node_count ? SCRATCH_DISTANCE : (SCRATCH_DISTANCE = new Float64Array(node_count));
176
+
177
+ const nearest = instance.tether_source;
178
+
179
+ cloth_geodesic_field(
180
+ distance, nearest,
181
+ node_count, instance.edge, instance.edge_length, instance.edge_incidence,
182
+ sources, sources.length,
183
+ null
184
+ );
185
+
186
+ const geodesic = instance.geodesic;
187
+
188
+ let reach = 0;
189
+
190
+ const rest = instance.rest_position;
191
+
192
+ for (let node = 0; node < node_count; node++) {
193
+ const d = distance[node];
194
+
195
+ geodesic[node] = d;
196
+
197
+ // what this node hangs from: its hold, or — nothing reaching it — the frame
198
+ const hang = d < Infinity
199
+ ? d
200
+ : Math.hypot(rest[node * 3], rest[node * 3 + 1], rest[node * 3 + 2]);
201
+
202
+ if (hang > reach) {
203
+ reach = hang;
204
+ }
205
+ }
206
+
207
+ instance.reach = reach;
208
+
209
+ // The one length a cloth with no rows carries.
210
+ if (!(instance.shortest_row < Infinity)) {
211
+ instance.shortest_row = reach;
212
+ }
213
+
214
+ const slack_scale = CLOTH_SLACK_REACH * clamp01(instance.cloth.dynamics.slack);
215
+
216
+ const position = state.position;
217
+
218
+ const leash_source = state.leash_source;
219
+ const leash_offset = state.leash_offset;
220
+ const leash_radius = state.leash_radius;
221
+ const leash_lambda = state.leash_lambda;
222
+
223
+ const loose = instance.tether_loose;
224
+
225
+ loose.fill(0);
226
+
227
+ let loose_count = 0;
228
+
229
+ for (let node = 0; node < node_count; node++) {
230
+ const tether = instance.tether_row[node];
231
+ const slack = instance.slack_row[node];
232
+
233
+ const source = node_hold[node] === -1 ? nearest[node] : -1;
234
+
235
+ const d = geodesic[node];
236
+
237
+ // A multiplier describes a force towards whatever the row was measured
238
+ // from, and that may have just changed.
239
+ leash_lambda[tether] = 0;
240
+
241
+ if (slack >= 0) {
242
+ leash_lambda[slack] = 0;
243
+ }
244
+
245
+ if (source < 0) {
246
+ leash_source[tether] = -1;
247
+ leash_radius[tether] = Infinity;
248
+
249
+ if (slack >= 0) {
250
+ leash_source[slack] = -1;
251
+ leash_radius[slack] = Infinity;
252
+ }
253
+
254
+ continue;
255
+ }
256
+
257
+ const p = particle_of_node[node] * 3;
258
+ const q = particle_of_node[source] * 3;
259
+
260
+ leash_source[tether] = particle_of_node[source];
261
+ leash_offset[tether * 3] = 0;
262
+ leash_offset[tether * 3 + 1] = 0;
263
+ leash_offset[tether * 3 + 2] = 0;
264
+
265
+ // §7 P2's bound, from wherever the particle is if that is further — see
266
+ // the module docblock.
267
+ const current = Math.hypot(
268
+ position[p] - position[q],
269
+ position[p + 1] - position[q + 1],
270
+ position[p + 2] - position[q + 2]
271
+ );
272
+
273
+ if (current > d) {
274
+ leash_radius[tether] = current;
275
+
276
+ loose[node] = 1;
277
+ loose_count++;
278
+ } else {
279
+ leash_radius[tether] = d;
280
+ }
281
+
282
+ if (slack >= 0) {
283
+ leash_source[slack] = particle_of_node[source];
284
+ leash_radius[slack] = slack_scale * d;
285
+ }
286
+ }
287
+
288
+ instance.tether_loose_count = loose_count;
289
+
290
+ // everything the per-step pass derives is stale now
291
+ instance.holds_dirty = true;
292
+
293
+ if (instance.hold_turn.length < holds.length * 4) {
294
+ instance.hold_turn = new Float64Array(holds.length * 4);
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Everything a hold changes per step: where each held particle is to be, the
300
+ * animated pose hung from them, the leash centres and the tethers' ratchet.
301
+ *
302
+ * Reads each hold's {@link ClothHold#pose} — the holder in this step's frame —
303
+ * and the particle positions as the frame carry left them.
304
+ *
305
+ * **Nothing is recomputed that cannot have changed.** Every quantity here
306
+ * except the ratchet is a function of the holds' poses in the frame, and a
307
+ * holder riding the frame — a rope's own top, a cape's shoulder in a cape riding
308
+ * that shoulder — has the same pose in it every step however the frame moves.
309
+ * So when no hold has moved in the frame since the last step, and nothing has
310
+ * rewritten the particles since ({@link ClothInstance#holds_dirty}), the
311
+ * targets, the animated pose and the leash offsets are left as they are: the
312
+ * question is a fact the step already has, not a kind of cloth.
313
+ *
314
+ * @param {ClothInstance} instance
315
+ * @returns {void}
316
+ */
317
+ export function cloth_hold_step(instance) {
318
+ if (!instance.holds_dirty && holds_still(instance.holds)) {
319
+ // Every held particle arrived on its target at the end of the last step
320
+ // and nothing has moved it since, so none travels this one.
321
+ instance.kinematic_travel = 0;
322
+
323
+ cloth_tether_ratchet(instance);
324
+
325
+ return;
326
+ }
327
+
328
+ instance.holds_dirty = false;
329
+
330
+ const node_count = instance.node_count;
331
+
332
+ const state = instance.state;
333
+ const position = state.position;
334
+ const particle_of_node = instance.particle_of_node;
335
+
336
+ const holds = instance.holds;
337
+ const node_hold = instance.node_hold;
338
+ const node_hold_slot = instance.node_hold_slot;
339
+
340
+ const turn = instance.hold_turn;
341
+
342
+ // Each holder's turn since its hold began, once per hold.
343
+ for (let h = 0; h < holds.length; h++) {
344
+ const hold = holds[h];
345
+ const at = hold.rotation_at_hold;
346
+ const pose = hold.pose;
347
+
348
+ quat3_multiply_conjugate_right_array(turn, h * 4, pose, 3, at, 0);
349
+ }
350
+
351
+ const target = instance.held_target;
352
+ const kinematic = state.kinematic_target;
353
+
354
+ let travel = 0;
355
+
356
+ for (let node = 0; node < node_count; node++) {
357
+ const h = node_hold[node];
358
+
359
+ if (h === -1) {
360
+ continue;
361
+ }
362
+
363
+ const hold = holds[h];
364
+ const pose = hold.pose;
365
+
366
+ const n = node * 3;
367
+
368
+ pose3_apply_point_array(target, n, pose, 0, pose, 3, hold.offset, node_hold_slot[node] * 3);
369
+
370
+ const p = particle_of_node[node] * 3;
371
+
372
+ kinematic[p] = target[n];
373
+ kinematic[p + 1] = target[n + 1];
374
+ kinematic[p + 2] = target[n + 2];
375
+
376
+ const moved = Math.hypot(target[n] - position[p], target[n + 1] - position[p + 1], target[n + 2] - position[p + 2]);
377
+
378
+ if (moved > travel) {
379
+ travel = moved;
380
+ }
381
+ }
382
+
383
+ instance.kinematic_travel = travel;
384
+
385
+ const rest = instance.rest_position;
386
+ const rest_rotation = instance.rest_rotation;
387
+
388
+ const animated = instance.animated_position;
389
+ const animated_rotation = instance.animated_rotation;
390
+
391
+ const source = instance.tether_source;
392
+
393
+ for (let node = 0; node < node_count; node++) {
394
+ const n = node * 3;
395
+ const r = node * 4;
396
+
397
+ const h = node_hold[node];
398
+
399
+ if (h !== -1) {
400
+ animated[n] = target[n];
401
+ animated[n + 1] = target[n + 1];
402
+ animated[n + 2] = target[n + 2];
403
+
404
+ quat3_multiply_array(animated_rotation, r, turn, h * 4, rest_rotation, r);
405
+
406
+ continue;
407
+ }
408
+
409
+ const s = source[node];
410
+
411
+ if (s === -1) {
412
+ animated[n] = rest[n];
413
+ animated[n + 1] = rest[n + 1];
414
+ animated[n + 2] = rest[n + 2];
415
+
416
+ animated_rotation[r] = rest_rotation[r];
417
+ animated_rotation[r + 1] = rest_rotation[r + 1];
418
+ animated_rotation[r + 2] = rest_rotation[r + 2];
419
+ animated_rotation[r + 3] = rest_rotation[r + 3];
420
+
421
+ continue;
422
+ }
423
+
424
+ // hung from its nearest held node, turned with that node's holder
425
+ const t = node_hold[s] * 4;
426
+
427
+ const m = s * 3;
428
+
429
+ SCRATCH[0] = rest[n] - rest[m];
430
+ SCRATCH[1] = rest[n + 1] - rest[m + 1];
431
+ SCRATCH[2] = rest[n + 2] - rest[m + 2];
432
+
433
+ pose3_apply_point_array(animated, n, target, m, turn, t, SCRATCH, 0);
434
+
435
+ quat3_multiply_array(animated_rotation, r, turn, t, rest_rotation, r);
436
+ }
437
+
438
+ const leash_target = state.leash_target;
439
+ const leash_offset = state.leash_offset;
440
+
441
+ for (let node = 0; node < node_count; node++) {
442
+ const tether = instance.tether_row[node];
443
+ const slack = instance.slack_row[node];
444
+
445
+ const n = node * 3;
446
+
447
+ const s = node_hold[node] === -1 ? source[node] : -1;
448
+
449
+ if (s === -1) {
450
+ // Unbounded rows, measured from somewhere finite.
451
+ leash_target[tether * 3] = animated[n];
452
+ leash_target[tether * 3 + 1] = animated[n + 1];
453
+ leash_target[tether * 3 + 2] = animated[n + 2];
454
+
455
+ if (slack >= 0) {
456
+ leash_target[slack * 3] = animated[n];
457
+ leash_target[slack * 3 + 1] = animated[n + 1];
458
+ leash_target[slack * 3 + 2] = animated[n + 2];
459
+ }
460
+
461
+ continue;
462
+ }
463
+
464
+ const m = s * 3;
465
+
466
+ if (slack >= 0) {
467
+ leash_offset[slack * 3] = animated[n] - target[m];
468
+ leash_offset[slack * 3 + 1] = animated[n + 1] - target[m + 1];
469
+ leash_offset[slack * 3 + 2] = animated[n + 2] - target[m + 2];
470
+ }
471
+ }
472
+
473
+ cloth_tether_ratchet(instance);
474
+ }
475
+
476
+ /**
477
+ * Whether every hold is where it was in the frame a step ago.
478
+ *
479
+ * @param {ClothHold[]} holds
480
+ * @returns {boolean}
481
+ * @private
482
+ */
483
+ function holds_still(holds) {
484
+ for (let h = 0; h < holds.length; h++) {
485
+ const hold = holds[h];
486
+
487
+ if (!hold.has_previous) {
488
+ return false;
489
+ }
490
+
491
+ if (!array_range_equal_strict(hold.pose, 0, hold.pose_previous, 0, 7)) {
492
+ return false;
493
+ }
494
+ }
495
+
496
+ return true;
497
+ }
498
+
499
+ /**
500
+ * Bring every tether that began loose down to wherever its particle has come
501
+ * to, never below `d_geo` and never up — see the module docblock. A cloth with
502
+ * none loose pays for the test and nothing else.
503
+ *
504
+ * @param {ClothInstance} instance
505
+ * @private
506
+ */
507
+ function cloth_tether_ratchet(instance) {
508
+ if (instance.tether_loose_count === 0) {
509
+ return;
510
+ }
511
+
512
+ const node_count = instance.node_count;
513
+
514
+ const state = instance.state;
515
+ const position = state.position;
516
+ const leash_radius = state.leash_radius;
517
+
518
+ const particle_of_node = instance.particle_of_node;
519
+ const node_hold = instance.node_hold;
520
+ const source = instance.tether_source;
521
+ const geodesic = instance.geodesic;
522
+ const loose = instance.tether_loose;
523
+
524
+ for (let node = 0; node < node_count; node++) {
525
+ if (loose[node] === 0) {
526
+ continue;
527
+ }
528
+
529
+ const s = node_hold[node] === -1 ? source[node] : -1;
530
+
531
+ if (s === -1) {
532
+ // held since, or cut off from every hold: nothing to bring in
533
+ loose[node] = 0;
534
+
535
+ instance.tether_loose_count--;
536
+
537
+ continue;
538
+ }
539
+
540
+ const tether = instance.tether_row[node];
541
+
542
+ // The ratchet: down to wherever the particle has come to, never below
543
+ // d_geo, never up.
544
+ const p = particle_of_node[node] * 3;
545
+ const q = particle_of_node[s] * 3;
546
+
547
+ const current = Math.hypot(
548
+ position[p] - position[q],
549
+ position[p + 1] - position[q + 1],
550
+ position[p + 2] - position[q + 2]
551
+ );
552
+
553
+ const d = geodesic[node];
554
+
555
+ const radius = leash_radius[tether];
556
+
557
+ const tightened = current < radius ? current : radius;
558
+
559
+ if (tightened > d) {
560
+ leash_radius[tether] = tightened;
561
+ } else {
562
+ leash_radius[tether] = d;
563
+
564
+ loose[node] = 0;
565
+
566
+ instance.tether_loose_count--;
567
+ }
568
+ }
569
+ }
570
+
571
+ /**
572
+ * @type {Float64Array}
573
+ * @private
574
+ */
575
+ const SCRATCH = new Float64Array(3);
576
+
577
+
578
+ /**
579
+ * The geodesic field's distances, in double, grown to the largest cloth seen.
580
+ * @type {Float64Array}
581
+ * @private
582
+ */
583
+ let SCRATCH_DISTANCE = new Float64Array(0);
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Both are in the **cloth's own frame**: the position is the particle lerped
5
5
  * towards its animated one by `Cloth#blend`, and the rotation is the swing
6
- * composed onto the animated orientation. Node 0 — the anchor — is the origin of
7
- * that frame, so its rotation is the identity rather than anything read off it.
6
+ * composed onto the animated orientation. A root of the seeder's tree has no
7
+ * link above it and takes its children's swing alone.
8
8
  *
9
9
  * @param {ClothInstance} instance
10
10
  * @returns {void}
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_reconstruct_pose.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js"],"names":[],"mappings":"AA6DA;;;;;;;;;;GAUG;AACH,iEAFa,IAAI,CA+DhB"}
1
+ {"version":3,"file":"cloth_reconstruct_pose.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js"],"names":[],"mappings":"AAyFA;;;;;;;;;;GAUG;AACH,iEAFa,IAAI,CAmEhB"}