@woosh/meep-engine 3.44.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 (233) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/collection/array/array_sort_insertion_ascending.d.ts +19 -0
  4. package/src/core/collection/array/array_sort_insertion_ascending.d.ts.map +1 -0
  5. package/src/core/collection/array/array_sort_insertion_ascending.js +31 -0
  6. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts +27 -0
  7. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts.map +1 -0
  8. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.js +39 -0
  9. package/src/core/geom/3d/aabb/aabb3_from_v3_array.d.ts.map +1 -1
  10. package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +4 -1
  11. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts +2 -2
  12. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -1
  13. package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +1 -1
  14. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts +21 -0
  15. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts.map +1 -0
  16. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.js +36 -0
  17. package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts +25 -0
  18. package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts.map +1 -0
  19. package/src/core/geom/3d/pose/pose3_apply_point_array.js +40 -0
  20. package/src/core/geom/3d/pose/pose3_compose_array.d.ts +28 -0
  21. package/src/core/geom/3d/pose/pose3_compose_array.d.ts.map +1 -0
  22. package/src/core/geom/3d/pose/pose3_compose_array.js +41 -0
  23. package/src/core/geom/3d/pose/pose3_to_local_array.d.ts +29 -0
  24. package/src/core/geom/3d/pose/pose3_to_local_array.d.ts.map +1 -0
  25. package/src/core/geom/3d/pose/pose3_to_local_array.js +42 -0
  26. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts +28 -0
  27. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts.map +1 -0
  28. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.js +66 -0
  29. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts +22 -0
  30. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts.map +1 -0
  31. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.js +30 -0
  32. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts +23 -0
  33. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts.map +1 -0
  34. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.js +31 -0
  35. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts +26 -0
  36. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts.map +1 -0
  37. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.js +46 -0
  38. package/src/core/geom/vec3/v3_distance_array.d.ts +11 -0
  39. package/src/core/geom/vec3/v3_distance_array.d.ts.map +1 -0
  40. package/src/core/geom/vec3/v3_distance_array.js +19 -0
  41. package/src/core/geom/vec3/v3_normalize_array_checked.d.ts +23 -0
  42. package/src/core/geom/vec3/v3_normalize_array_checked.d.ts.map +1 -0
  43. package/src/core/geom/vec3/v3_normalize_array_checked.js +49 -0
  44. package/src/core/geom/vec3/v3_reject_array.d.ts +15 -0
  45. package/src/core/geom/vec3/v3_reject_array.d.ts.map +1 -0
  46. package/src/core/geom/vec3/v3_reject_array.js +32 -0
  47. package/src/core/graph/csr/csr_build_incidence.d.ts +26 -0
  48. package/src/core/graph/csr/csr_build_incidence.d.ts.map +1 -0
  49. package/src/core/graph/csr/csr_build_incidence.js +71 -0
  50. package/src/core/graph/csr/csr_graph_color_greedy.d.ts +25 -0
  51. package/src/core/graph/csr/csr_graph_color_greedy.d.ts.map +1 -0
  52. package/src/core/graph/csr/csr_graph_color_greedy.js +83 -0
  53. package/src/core/graph/csr/csr_graph_validate_coloring.d.ts +15 -0
  54. package/src/core/graph/csr/csr_graph_validate_coloring.d.ts.map +1 -0
  55. package/src/core/graph/csr/csr_graph_validate_coloring.js +33 -0
  56. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts +26 -0
  57. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts.map +1 -0
  58. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.js +71 -0
  59. package/src/core/math/max2_exact.d.ts +15 -0
  60. package/src/core/math/max2_exact.d.ts.map +1 -0
  61. package/src/core/math/max2_exact.js +30 -0
  62. package/src/core/math/min2_exact.d.ts +20 -0
  63. package/src/core/math/min2_exact.d.ts.map +1 -0
  64. package/src/core/math/min2_exact.js +35 -0
  65. package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -1
  66. package/src/engine/ecs/ik/IKGoalSystem.js +3 -19
  67. package/src/engine/ecs/parent/parent_entity_model_of.d.ts +17 -0
  68. package/src/engine/ecs/parent/parent_entity_model_of.d.ts.map +1 -0
  69. package/src/engine/ecs/parent/parent_entity_model_of.js +26 -0
  70. package/src/engine/ecs/transform/t64_read_pose_array.d.ts +15 -0
  71. package/src/engine/ecs/transform/t64_read_pose_array.d.ts.map +1 -0
  72. package/src/engine/ecs/transform/t64_read_pose_array.js +24 -0
  73. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts +2 -0
  74. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts.map +1 -1
  75. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.js +10 -21
  76. package/src/engine/graphics3/AnimationGraphSystem.d.ts +5 -0
  77. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
  78. package/src/engine/graphics3/AnimationGraphSystem.js +48 -2
  79. package/src/engine/graphics3/AnimationSystem.d.ts +5 -0
  80. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
  81. package/src/engine/graphics3/AnimationSystem.js +47 -2
  82. package/src/engine/graphics3/register_clips.d.ts +29 -0
  83. package/src/engine/graphics3/register_clips.d.ts.map +1 -1
  84. package/src/engine/graphics3/register_clips.js +52 -0
  85. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +9 -0
  86. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -1
  87. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +3 -1
  88. package/src/engine/physics/cloth/PLAN.md +10 -8
  89. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +22 -0
  90. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -1
  91. package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +51 -19
  92. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  93. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +16 -2
  94. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -1
  95. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +19 -24
  96. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +7 -0
  97. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
  98. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +85 -67
  99. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -1
  100. package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +19 -101
  101. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +2 -5
  102. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -1
  103. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +7 -15
  104. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -1
  105. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +16 -61
  106. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +0 -1
  107. package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +6 -19
  108. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +1 -2
  109. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
  110. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +3 -12
  111. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  112. package/src/engine/physics/cloth/ecs/ClothWorld.js +40 -130
  113. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  114. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +17 -58
  115. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  116. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +3 -3
  117. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
  118. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +44 -104
  119. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -1
  120. package/src/engine/physics/cloth/ecs/cloth_geodesic.js +6 -13
  121. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -1
  122. package/src/engine/physics/cloth/ecs/cloth_holds.js +15 -40
  123. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
  124. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +45 -79
  125. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  126. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +7 -27
  127. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  128. package/src/engine/physics/cloth/ecs/cloth_write_back.js +30 -62
  129. package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts.map +1 -1
  130. package/src/engine/physics/cloth/playground/cloth_playground_build.js +2 -3
  131. package/src/engine/physics/cloth/playground/collide_main.js +2 -28
  132. package/src/engine/physics/cloth/playground/garment_main.js +4 -19
  133. package/src/engine/physics/cloth/playground/main.js +6 -48
  134. package/src/engine/physics/cloth/playground/rig_main.js +947 -955
  135. package/src/engine/physics/cloth/playground/wind_main.js +8 -7
  136. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  137. package/src/engine/physics/cloth/solver/ClothState.js +16 -76
  138. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts +10 -8
  139. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts.map +1 -1
  140. package/src/engine/physics/cloth/solver/cloth_color_particles.js +30 -102
  141. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  142. package/src/engine/physics/cloth/solver/cloth_contact_find.js +3 -2
  143. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -1
  144. package/src/engine/physics/cloth/solver/cloth_hold_line.js +2 -14
  145. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts +21 -0
  146. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts.map +1 -0
  147. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.js +45 -0
  148. package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts +32 -0
  149. package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts.map +1 -0
  150. package/src/engine/physics/cloth/solver/cloth_particle_coupling.js +133 -0
  151. package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts +16 -0
  152. package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts.map +1 -0
  153. package/src/engine/physics/cloth/solver/cloth_particle_of_source.js +19 -0
  154. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  155. package/src/engine/physics/cloth/solver/cloth_self_find.js +6 -55
  156. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
  157. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +30 -65
  158. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  159. package/src/engine/physics/cloth/solver/cloth_step.js +6 -28
  160. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  161. package/src/engine/physics/cloth/solver/cloth_step_instance.js +2 -3
  162. package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts +21 -0
  163. package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts.map +1 -0
  164. package/src/engine/physics/cloth/solver/cloth_stretch_residual.js +54 -0
  165. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts +15 -0
  166. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts.map +1 -1
  167. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.js +28 -0
  168. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts +30 -0
  169. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts.map +1 -0
  170. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.js +56 -0
  171. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
  172. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +3 -17
  173. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +2 -1
  174. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
  175. package/src/engine/physics/cloth/wind/ClothFluidWind.js +7 -25
  176. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +3 -1
  177. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
  178. package/src/engine/physics/cloth/wind/cloth_sample_air.js +40 -62
  179. package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -1
  180. package/src/engine/physics/ecs/ContactProbeSystem.js +2 -18
  181. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  182. package/src/engine/physics/ecs/PhysicsSystem.js +9 -50
  183. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts +24 -0
  184. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts.map +1 -0
  185. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.js +42 -0
  186. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts +25 -0
  187. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts.map +1 -0
  188. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.js +40 -0
  189. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -1
  190. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +40 -90
  191. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
  192. package/src/engine/physics/narrowphase/capsule_contacts.js +3 -5
  193. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -1
  194. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +2 -14
  195. package/src/engine/physics/narrowphase/hull_sphere_contact.d.ts.map +1 -1
  196. package/src/engine/physics/narrowphase/hull_sphere_contact.js +2 -5
  197. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  198. package/src/engine/physics/narrowphase/narrowphase_step.js +13 -32
  199. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
  200. package/src/engine/physics/narrowphase/sphere_box_contact.js +2 -5
  201. package/src/format/texture/basis/transcode/etc1s_to_astc.d.ts.map +1 -1
  202. package/src/format/texture/basis/transcode/etc1s_to_astc.js +2 -1
  203. package/src/shade/playground/image_decode_bench/main.js +2 -1
  204. package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.d.ts.map +1 -1
  205. package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.js +2 -1
  206. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
  207. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +2 -1
  208. package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -1
  209. package/src/shade/playground/ssr_variance/statistics.js +2 -1
  210. package/src/shade/playground/texture_encode/main.d.ts.map +1 -1
  211. package/src/shade/playground/texture_encode/main.js +2 -1
  212. package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -1
  213. package/src/shade/playground/volumetrics_froxel/measure.js +2 -1
  214. package/src/shade/renderer/buffer/table/gpu_database_check_links.d.ts.map +1 -1
  215. package/src/shade/renderer/buffer/table/gpu_database_check_links.js +2 -1
  216. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -1
  217. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +3 -2
  218. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -1
  219. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +2 -1
  220. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -1
  221. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +2 -1
  222. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -1
  223. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +2 -1
  224. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -1
  225. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +3 -2
  226. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -1
  227. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.js +2 -1
  228. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
  229. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +2 -1
  230. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  231. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +3 -2
  232. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -1
  233. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +3 -2
@@ -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,
@@ -167,32 +161,19 @@ 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
 
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
+
196
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.
@@ -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, frame_rotation, 0);
237
-
238
- const x = CORNER[0] + frame_x;
239
- const y = CORNER[1] + frame_y;
240
- const z = CORNER[2] + frame_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
@@ -391,27 +355,14 @@ function localise(
391
355
  source, source_translation_slot, source_rotation_slot,
392
356
  frame_translation, frame_rotation
393
357
  ) {
394
- LOCAL_TRANSLATION[0] = source[source_translation_slot] - frame_translation[0];
395
- LOCAL_TRANSLATION[1] = source[source_translation_slot + 1] - frame_translation[1];
396
- LOCAL_TRANSLATION[2] = source[source_translation_slot + 2] - frame_translation[2];
397
-
398
- v3_quaternion_apply_inverse_array(LOCAL_TRANSLATION, 0, LOCAL_TRANSLATION, 0, frame_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
- FRAME_CONJUGATE[0] = -frame_rotation[0];
405
- FRAME_CONJUGATE[1] = -frame_rotation[1];
406
- FRAME_CONJUGATE[2] = -frame_rotation[2];
407
- FRAME_CONJUGATE[3] = frame_rotation[3];
408
-
409
- quat3_multiply_array(LOCAL_ROTATION, 0, FRAME_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 FRAME_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,
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_geodesic.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_geodesic.js"],"names":[],"mappings":"AAsCA;;;;;;;GAOG;AACH,iDALW,MAAM,QACN,UAAU,GACR;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAC,CAyBlD;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"}
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"}
@@ -1,4 +1,5 @@
1
1
  import { Uint32Heap } from "../../../../core/collection/heap/Uint32Heap.js";
2
+ import { csr_build_incidence } from "../../../../core/graph/csr/csr_build_incidence.js";
2
3
 
3
4
  /**
4
5
  * # How far each particle is from a set of particles, along the fabric
@@ -48,21 +49,13 @@ export function cloth_edge_incidence(node_count, edge) {
48
49
  const edge_count = edge.length >> 1;
49
50
 
50
51
  const offset = new Int32Array(node_count + 1);
51
-
52
- for (let i = 0; i < edge_count * 2; i++) {
53
- offset[edge[i] + 1]++;
54
- }
55
-
56
- for (let n = 0; n < node_count; n++) {
57
- offset[n + 1] += offset[n];
58
- }
59
-
60
52
  const incident = new Int32Array(edge_count * 2);
61
- const cursor = offset.slice(0, node_count);
62
53
 
63
- for (let e = 0; e < edge_count; e++) {
64
- incident[cursor[edge[e * 2]]++] = e;
65
- incident[cursor[edge[e * 2 + 1]]++] = e;
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;
66
59
  }
67
60
 
68
61
  return { offset, edge: incident };
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_holds.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_holds.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,gGAJW,YAAY,kBACZ,YAAY,GACV,IAAI,CA6ChB;AAED;;;;;;;;;;;GAWG;AACH,4DAFa,IAAI,CA0KhB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,0DAFa,IAAI,CA2KhB"}
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"}
@@ -1,6 +1,11 @@
1
- import { quat3_multiply, 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 { 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";
4
9
  import { CLOTH_PARTICLE_MASS, CLOTH_SLACK_REACH } from "./cloth_build_rows.js";
5
10
  import { cloth_geodesic_field } from "./cloth_geodesic.js";
6
11
 
@@ -90,14 +95,10 @@ export function cloth_capture_hold(instance, hold, frame_translation, frame_rota
90
95
  const p = particle_of_node[node] * 3;
91
96
 
92
97
  // the particle in the world
93
- v3_quaternion_apply_array(SCRATCH, 0, position, p, frame_rotation, 0);
94
-
95
- SCRATCH[0] += frame_translation[0] - world[0];
96
- SCRATCH[1] += frame_translation[1] - world[1];
97
- SCRATCH[2] += frame_translation[2] - world[2];
98
+ pose3_apply_point_array(SCRATCH, 0, frame_translation, 0, frame_rotation, 0, position, p);
98
99
 
99
100
  // relative to the holder, in its frame
100
- v3_quaternion_apply_inverse_array(offset, k * 3, SCRATCH, 0, world, 3);
101
+ pose3_apply_inverse_point_array(offset, k * 3, world, 0, world, 3, SCRATCH, 0);
101
102
  }
102
103
 
103
104
  hold.offset = offset;
@@ -344,11 +345,7 @@ export function cloth_hold_step(instance) {
344
345
  const at = hold.rotation_at_hold;
345
346
  const pose = hold.pose;
346
347
 
347
- quat3_multiply(
348
- turn, h * 4,
349
- pose[3], pose[4], pose[5], pose[6],
350
- -at[0], -at[1], -at[2], at[3]
351
- );
348
+ quat3_multiply_conjugate_right_array(turn, h * 4, pose, 3, at, 0);
352
349
  }
353
350
 
354
351
  const target = instance.held_target;
@@ -368,11 +365,7 @@ export function cloth_hold_step(instance) {
368
365
 
369
366
  const n = node * 3;
370
367
 
371
- v3_quaternion_apply_array(target, n, hold.offset, node_hold_slot[node] * 3, pose, 3);
372
-
373
- target[n] += pose[0];
374
- target[n + 1] += pose[1];
375
- target[n + 2] += pose[2];
368
+ pose3_apply_point_array(target, n, pose, 0, pose, 3, hold.offset, node_hold_slot[node] * 3);
376
369
 
377
370
  const p = particle_of_node[node] * 3;
378
371
 
@@ -437,11 +430,7 @@ export function cloth_hold_step(instance) {
437
430
  SCRATCH[1] = rest[n + 1] - rest[m + 1];
438
431
  SCRATCH[2] = rest[n + 2] - rest[m + 2];
439
432
 
440
- v3_quaternion_apply_array(animated, n, SCRATCH, 0, turn, t);
441
-
442
- animated[n] += target[m];
443
- animated[n + 1] += target[m + 1];
444
- animated[n + 2] += target[m + 2];
433
+ pose3_apply_point_array(animated, n, target, m, turn, t, SCRATCH, 0);
445
434
 
446
435
  quat3_multiply_array(animated_rotation, r, turn, t, rest_rotation, r);
447
436
  }
@@ -499,13 +488,8 @@ function holds_still(holds) {
499
488
  return false;
500
489
  }
501
490
 
502
- const pose = hold.pose;
503
- const before = hold.pose_previous;
504
-
505
- for (let i = 0; i < 7; i++) {
506
- if (pose[i] !== before[i]) {
507
- return false;
508
- }
491
+ if (!array_range_equal_strict(hold.pose, 0, hold.pose_previous, 0, 7)) {
492
+ return false;
509
493
  }
510
494
  }
511
495
 
@@ -584,15 +568,6 @@ function cloth_tether_ratchet(instance) {
584
568
  }
585
569
  }
586
570
 
587
- /**
588
- * @param {number} v
589
- * @returns {number}
590
- * @private
591
- */
592
- function clamp01(v) {
593
- return v < 0 ? 0 : (v > 1 ? 1 : v);
594
- }
595
-
596
571
  /**
597
572
  * @type {Float64Array}
598
573
  * @private
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_reconstruct_pose.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js"],"names":[],"mappings":"AA6EA;;;;;;;;;;GAUG;AACH,iEAFa,IAAI,CAyEhB"}
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"}
@@ -1,7 +1,11 @@
1
1
  import { quat3_multiply_array } from "../../../../core/geom/3d/quaternion/quat3_multiply.js";
2
2
  import { quat3_nlerp_array } from "../../../../core/geom/3d/quaternion/quat3_nlerp.js";
3
3
  import { quat3_shortest_arc_array } from "../../../../core/geom/3d/quaternion/quat3_shortest_arc.js";
4
+ import { tri3_compute_normal_area_weighted_array } from "../../../../core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.js";
5
+ import { v3_normalize_array_checked } from "../../../../core/geom/vec3/v3_normalize_array_checked.js";
4
6
  import { v3_quaternion_apply_array } from "../../../../core/geom/vec3/v3_quaternion_apply.js";
7
+ import { v3_reject_array } from "../../../../core/geom/vec3/v3_reject_array.js";
8
+ import { clamp01 } from "../../../../core/math/clamp01.js";
5
9
 
6
10
  /**
7
11
  * # From particles to a pose — the half of the write-back that is arithmetic
@@ -75,6 +79,14 @@ const SWING_TWIST = 12;
75
79
  */
76
80
  const DIRECTION = new Float64Array(12);
77
81
 
82
+ /**
83
+ * Squared length below which a direction in {@link DIRECTION} is rounding
84
+ * rather than a direction, and is left as it was.
85
+ * @type {number}
86
+ * @private
87
+ */
88
+ const NO_DIRECTION_SQR = 1e-24;
89
+
78
90
  /**
79
91
  * Fill `blended_position` and `blended_rotation` from the solved particles.
80
92
  *
@@ -95,13 +107,7 @@ export function cloth_reconstruct_pose(instance) {
95
107
  const blended = instance.blended_position;
96
108
  const animated = instance.animated_position;
97
109
 
98
- let blend = instance.cloth.blend;
99
-
100
- if (blend < 0) {
101
- blend = 0;
102
- } else if (blend > 1) {
103
- blend = 1;
104
- }
110
+ const blend = clamp01(instance.cloth.blend);
105
111
 
106
112
  const position = state.position;
107
113
 
@@ -175,7 +181,9 @@ function surface_turn(instance, node, out) {
175
181
  surface_normal(DIRECTION, 0, instance, animated, node);
176
182
  surface_normal(DIRECTION, 3, instance, blended, node);
177
183
 
178
- const has_normal = unit(DIRECTION, 0) && unit(DIRECTION, 3);
184
+ const has_normal =
185
+ v3_normalize_array_checked(DIRECTION, 0, DIRECTION, 0, NO_DIRECTION_SQR) &&
186
+ v3_normalize_array_checked(DIRECTION, 3, DIRECTION, 3, NO_DIRECTION_SQR);
179
187
 
180
188
  // the swing: normal onto normal
181
189
  if (has_normal) {
@@ -203,11 +211,14 @@ function surface_turn(instance, node, out) {
203
211
  if (has_normal) {
204
212
  // both into the plane the normal leaves them, so the arc between them
205
213
  // turns about the normal and nothing else
206
- reject(DIRECTION, 6, DIRECTION, 3);
207
- reject(DIRECTION, 9, DIRECTION, 3);
214
+ v3_reject_array(DIRECTION, 6, DIRECTION, 6, DIRECTION, 3);
215
+ v3_reject_array(DIRECTION, 9, DIRECTION, 9, DIRECTION, 3);
208
216
  }
209
217
 
210
- if (!unit(DIRECTION, 6) || !unit(DIRECTION, 9)) {
218
+ if (
219
+ !v3_normalize_array_checked(DIRECTION, 6, DIRECTION, 6, NO_DIRECTION_SQR) ||
220
+ !v3_normalize_array_checked(DIRECTION, 9, DIRECTION, 9, NO_DIRECTION_SQR)
221
+ ) {
211
222
  return;
212
223
  }
213
224
 
@@ -217,6 +228,13 @@ function surface_turn(instance, node, out) {
217
228
  quat3_multiply_array(SWING, out, SWING, SWING_TWIST, SWING, out);
218
229
  }
219
230
 
231
+ /**
232
+ * One triangle's area-weighted normal, before it is summed.
233
+ * @type {Float64Array}
234
+ * @private
235
+ */
236
+ const FACE_NORMAL = new Float64Array(3);
237
+
220
238
  /**
221
239
  * The area-weighted normal of the triangles around a node, unnormalised, into
222
240
  * `out` at `offset`.
@@ -237,22 +255,17 @@ function surface_normal(out, offset, instance, position, node) {
237
255
  for (let k = instance.surface_offset[node]; k < instance.surface_offset[node + 1]; k++) {
238
256
  const t = surface[k] * 3;
239
257
 
240
- const a = triangle[t] * 3;
241
- const b = triangle[t + 1] * 3;
242
- const c = triangle[t + 2] * 3;
243
-
244
- const ux = position[b] - position[a];
245
- const uy = position[b + 1] - position[a + 1];
246
- const uz = position[b + 2] - position[a + 2];
247
-
248
- const vx = position[c] - position[a];
249
- const vy = position[c + 1] - position[a + 1];
250
- const vz = position[c + 2] - position[a + 2];
251
-
252
258
  // twice the area, along the normal: the weighting is the cross product's own length
253
- nx += uy * vz - uz * vy;
254
- ny += uz * vx - ux * vz;
255
- nz += ux * vy - uy * vx;
259
+ tri3_compute_normal_area_weighted_array(
260
+ FACE_NORMAL, 0,
261
+ position, triangle[t] * 3,
262
+ position, triangle[t + 1] * 3,
263
+ position, triangle[t + 2] * 3
264
+ );
265
+
266
+ nx += FACE_NORMAL[0];
267
+ ny += FACE_NORMAL[1];
268
+ nz += FACE_NORMAL[2];
256
269
  }
257
270
 
258
271
  out[offset] = nx;
@@ -260,24 +273,6 @@ function surface_normal(out, offset, instance, position, node) {
260
273
  out[offset + 2] = nz;
261
274
  }
262
275
 
263
- /**
264
- * Remove from the vector at `offset` its part along the unit vector at
265
- * `normal_offset`.
266
- *
267
- * @param {Float64Array} v
268
- * @param {number} offset
269
- * @param {Float64Array} n
270
- * @param {number} normal_offset
271
- * @private
272
- */
273
- function reject(v, offset, n, normal_offset) {
274
- const d = v[offset] * n[normal_offset] + v[offset + 1] * n[normal_offset + 1] + v[offset + 2] * n[normal_offset + 2];
275
-
276
- v[offset] -= d * n[normal_offset];
277
- v[offset + 1] -= d * n[normal_offset + 1];
278
- v[offset + 2] -= d * n[normal_offset + 2];
279
- }
280
-
281
276
  /**
282
277
  * @type {Float64Array}
283
278
  * @private
@@ -310,8 +305,8 @@ function link_swing(instance, from, to, out) {
310
305
  DIRECTION[4] = blended[b + 1] - blended[a + 1];
311
306
  DIRECTION[5] = blended[b + 2] - blended[a + 2];
312
307
 
313
- const has_animated = unit(DIRECTION, 0);
314
- const has_blended = unit(DIRECTION, 3);
308
+ const has_animated = v3_normalize_array_checked(DIRECTION, 0, DIRECTION, 0, NO_DIRECTION_SQR);
309
+ const has_blended = v3_normalize_array_checked(DIRECTION, 3, DIRECTION, 3, NO_DIRECTION_SQR);
315
310
 
316
311
  if (!has_animated || !has_blended) {
317
312
  identity(out);
@@ -363,7 +358,7 @@ function children_swing(instance, node, out) {
363
358
  DIRECTION[7] = animated[b + 1] - animated[a + 1];
364
359
  DIRECTION[8] = animated[b + 2] - animated[a + 2];
365
360
 
366
- if (unit(DIRECTION, 6)) {
361
+ if (v3_normalize_array_checked(DIRECTION, 6, DIRECTION, 6, NO_DIRECTION_SQR)) {
367
362
  anim_x += DIRECTION[6];
368
363
  anim_y += DIRECTION[7];
369
364
  anim_z += DIRECTION[8];
@@ -373,7 +368,7 @@ function children_swing(instance, node, out) {
373
368
  DIRECTION[10] = blended[b + 1] - blended[a + 1];
374
369
  DIRECTION[11] = blended[b + 2] - blended[a + 2];
375
370
 
376
- if (unit(DIRECTION, 9)) {
371
+ if (v3_normalize_array_checked(DIRECTION, 9, DIRECTION, 9, NO_DIRECTION_SQR)) {
377
372
  sim_x += DIRECTION[9];
378
373
  sim_y += DIRECTION[10];
379
374
  sim_z += DIRECTION[11];
@@ -388,8 +383,8 @@ function children_swing(instance, node, out) {
388
383
  DIRECTION[4] = sim_y;
389
384
  DIRECTION[5] = sim_z;
390
385
 
391
- const has_animated = unit(DIRECTION, 0);
392
- const has_blended = unit(DIRECTION, 3);
386
+ const has_animated = v3_normalize_array_checked(DIRECTION, 0, DIRECTION, 0, NO_DIRECTION_SQR);
387
+ const has_blended = v3_normalize_array_checked(DIRECTION, 3, DIRECTION, 3, NO_DIRECTION_SQR);
393
388
 
394
389
  if (!has_animated || !has_blended) {
395
390
  // Branches that cancel — a node with two children pointing opposite
@@ -405,35 +400,6 @@ function children_swing(instance, node, out) {
405
400
  return true;
406
401
  }
407
402
 
408
- /**
409
- * Normalise the vector at `offset` in place, reporting whether there was a direction to find; one
410
- * that was not is left as it was.
411
- *
412
- * @param {Float64Array} out
413
- * @param {number} offset
414
- * @returns {boolean}
415
- * @private
416
- */
417
- function unit(out, offset) {
418
- const x = out[offset];
419
- const y = out[offset + 1];
420
- const z = out[offset + 2];
421
-
422
- const length_squared = x * x + y * y + z * z;
423
-
424
- if (length_squared < 1e-24) {
425
- return false;
426
- }
427
-
428
- const inverse = 1 / Math.sqrt(length_squared);
429
-
430
- out[offset] = x * inverse;
431
- out[offset + 1] = y * inverse;
432
- out[offset + 2] = z * inverse;
433
-
434
- return true;
435
- }
436
-
437
403
  /**
438
404
  * @param {number} offset
439
405
  * @private
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_seed_subtree.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_seed_subtree.js"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH;;;;;;;;;GASG;AACH,6CAPW,aAAa,2EAGb,MAAM,GAEJ,IAAI,CAqHhB;AA8GD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,gDAJW,aAAa,gCAEX,IAAI,CAkChB;8BAhW6B,oBAAoB"}
1
+ {"version":3,"file":"cloth_seed_subtree.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_seed_subtree.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH;;;;;;;;;GASG;AACH,6CAPW,aAAa,2EAGb,MAAM,GAEJ,IAAI,CAqHhB;AAiGD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,gDAJW,aAAa,gCAEX,IAAI,CAkChB;8BAnV6B,oBAAoB"}
@@ -1,6 +1,5 @@
1
1
  import { assert } from "../../../../core/assert.js";
2
- import { quat3_multiply } from "../../../../core/geom/3d/quaternion/quat3_multiply.js";
3
- import { v3_quaternion_apply } from "../../../../core/geom/vec3/v3_quaternion_apply.js";
2
+ import { pose3_compose_array } from "../../../../core/geom/3d/pose/pose3_compose_array.js";
4
3
  import { GPUStateAuthorityFlags } from "../../../ecs/gpu/GPUStateAuthorityFlags.js";
5
4
  import { gpu_authority_assert_cpu } from "../../../ecs/gpu/gpu_authority_assert_cpu.js";
6
5
  import { TransformAttachment } from "../../../ecs/transform-attachment/TransformAttachment.js";
@@ -282,26 +281,13 @@ function read_rest_pose(instance, remembered) {
282
281
  // always already done, so one forward pass is the whole hierarchy.
283
282
  const p = parent[node];
284
283
 
285
- const pqx = rotation[p * 4];
286
- const pqy = rotation[p * 4 + 1];
287
- const pqz = rotation[p * 4 + 2];
288
- const pqw = rotation[p * 4 + 3];
289
-
290
- v3_quaternion_apply(
291
- COMPOSE, 0,
292
- local_position[node * 3], local_position[node * 3 + 1], local_position[node * 3 + 2],
293
- pqx, pqy, pqz, pqw
294
- );
295
-
296
- position[node * 3] = position[p * 3] + COMPOSE[0];
297
- position[node * 3 + 1] = position[p * 3 + 1] + COMPOSE[1];
298
- position[node * 3 + 2] = position[p * 3 + 2] + COMPOSE[2];
299
-
300
- quat3_multiply(
284
+ pose3_compose_array(
285
+ position, node * 3,
301
286
  rotation, node * 4,
302
- pqx, pqy, pqz, pqw,
303
- local_rotation[node * 4], local_rotation[node * 4 + 1],
304
- local_rotation[node * 4 + 2], local_rotation[node * 4 + 3]
287
+ position, p * 3,
288
+ rotation, p * 4,
289
+ local_position, node * 3,
290
+ local_rotation, node * 4
305
291
  );
306
292
  }
307
293
 
@@ -366,12 +352,6 @@ export function cloth_release_subtree(instance, ecd) {
366
352
  t64_announce_change(ecd, instance.node_entity[0]);
367
353
  }
368
354
 
369
- /**
370
- * @type {Float64Array}
371
- * @private
372
- */
373
- const COMPOSE = new Float64Array(3);
374
-
375
355
  /**
376
356
  * The authored pose a previous seeding captured, keyed by entity, so a re-seed
377
357
  * of a live cloth does not mistake the shape the solver left behind for the
@@ -1 +1 @@
1
- {"version":3,"file":"cloth_write_back.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_write_back.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH;;;;;;GAMG;AACH,wFAFa,IAAI,CAwDhB;AAyBD;;;;;;;;;;;;;;GAcG;AACH,0FAJW,MAAM,UACN,MAAM,GACJ,IAAI,CA6DhB"}
1
+ {"version":3,"file":"cloth_write_back.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_write_back.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH;;;;;;GAMG;AACH,wFAFa,IAAI,CAqDhB;AAyBD;;;;;;;;;;;;;;GAcG;AACH,0FAJW,MAAM,UACN,MAAM,GACJ,IAAI,CAiDhB"}