@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.
- package/build/bundle-worker-terrain.js +1 -1
- package/editor/prototypeEditorShell.d.ts.map +1 -1
- package/editor/prototypeEditorShell.js +4 -2
- package/package.json +1 -1
- package/src/core/collection/array/array_sort_insertion_ascending.d.ts +19 -0
- package/src/core/collection/array/array_sort_insertion_ascending.d.ts.map +1 -0
- package/src/core/collection/array/array_sort_insertion_ascending.js +31 -0
- package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts +27 -0
- package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts.map +1 -0
- package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.js +39 -0
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +4 -1
- package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts +2 -2
- package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +1 -1
- package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts +21 -0
- package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts.map +1 -0
- package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.js +36 -0
- package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts +25 -0
- package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts.map +1 -0
- package/src/core/geom/3d/pose/pose3_apply_point_array.js +40 -0
- package/src/core/geom/3d/pose/pose3_compose_array.d.ts +28 -0
- package/src/core/geom/3d/pose/pose3_compose_array.d.ts.map +1 -0
- package/src/core/geom/3d/pose/pose3_compose_array.js +41 -0
- package/src/core/geom/3d/pose/pose3_to_local_array.d.ts +29 -0
- package/src/core/geom/3d/pose/pose3_to_local_array.d.ts.map +1 -0
- package/src/core/geom/3d/pose/pose3_to_local_array.js +42 -0
- package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts +28 -0
- package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.js +66 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts +22 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.js +30 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts +23 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.js +31 -0
- package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts +26 -0
- package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts.map +1 -0
- package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.js +46 -0
- package/src/core/geom/vec3/v3_distance_array.d.ts +11 -0
- package/src/core/geom/vec3/v3_distance_array.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_distance_array.js +19 -0
- package/src/core/geom/vec3/v3_normalize_array_checked.d.ts +23 -0
- package/src/core/geom/vec3/v3_normalize_array_checked.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_normalize_array_checked.js +49 -0
- package/src/core/geom/vec3/v3_reject_array.d.ts +15 -0
- package/src/core/geom/vec3/v3_reject_array.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_reject_array.js +32 -0
- package/src/core/graph/csr/csr_build_incidence.d.ts +26 -0
- package/src/core/graph/csr/csr_build_incidence.d.ts.map +1 -0
- package/src/core/graph/csr/csr_build_incidence.js +71 -0
- package/src/core/graph/csr/csr_graph_color_greedy.d.ts +25 -0
- package/src/core/graph/csr/csr_graph_color_greedy.d.ts.map +1 -0
- package/src/core/graph/csr/csr_graph_color_greedy.js +83 -0
- package/src/core/graph/csr/csr_graph_validate_coloring.d.ts +15 -0
- package/src/core/graph/csr/csr_graph_validate_coloring.d.ts.map +1 -0
- package/src/core/graph/csr/csr_graph_validate_coloring.js +33 -0
- package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts +26 -0
- package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts.map +1 -0
- package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.js +71 -0
- package/src/core/math/max2_exact.d.ts +15 -0
- package/src/core/math/max2_exact.d.ts.map +1 -0
- package/src/core/math/max2_exact.js +30 -0
- package/src/core/math/min2_exact.d.ts +20 -0
- package/src/core/math/min2_exact.d.ts.map +1 -0
- package/src/core/math/min2_exact.js +35 -0
- package/src/engine/Clock.d.ts +15 -0
- package/src/engine/Clock.d.ts.map +1 -1
- package/src/engine/Clock.js +29 -5
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +11 -19
- package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -1
- package/src/engine/ecs/ik/IKGoalSystem.js +3 -19
- package/src/engine/ecs/parent/parent_entity_model_of.d.ts +17 -0
- package/src/engine/ecs/parent/parent_entity_model_of.d.ts.map +1 -0
- package/src/engine/ecs/parent/parent_entity_model_of.js +26 -0
- package/src/engine/ecs/transform/t64_read_pose_array.d.ts +15 -0
- package/src/engine/ecs/transform/t64_read_pose_array.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_read_pose_array.js +24 -0
- package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts +57 -0
- package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts.map +1 -0
- package/src/engine/graphics/ecs/mesh-v2/MeshSkin.js +84 -0
- package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts +2 -0
- package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts.map +1 -1
- package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.js +10 -21
- package/src/engine/graphics3/AnimationGraphSystem.d.ts +28 -13
- package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationGraphSystem.js +107 -64
- package/src/engine/graphics3/AnimationSystem.d.ts +29 -15
- package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationSystem.js +112 -61
- package/src/engine/graphics3/MeshSkinSystem.d.ts +56 -0
- package/src/engine/graphics3/MeshSkinSystem.d.ts.map +1 -0
- package/src/engine/graphics3/MeshSkinSystem.js +317 -0
- package/src/engine/graphics3/MeshSystem.d.ts +15 -35
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem.js +21 -298
- package/src/engine/graphics3/RowChains.d.ts +76 -0
- package/src/engine/graphics3/RowChains.d.ts.map +1 -0
- package/src/engine/graphics3/RowChains.js +347 -0
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -0
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem.js +329 -309
- package/src/engine/graphics3/animation/AnimationClips.d.ts +56 -0
- package/src/engine/graphics3/animation/AnimationClips.d.ts.map +1 -0
- package/src/engine/graphics3/animation/AnimationClips.js +79 -0
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts +13 -14
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
- package/src/engine/graphics3/animation/ClipListPlayer.js +262 -263
- package/src/engine/graphics3/animation/write_clip_playback.d.ts +3 -3
- package/src/engine/graphics3/animation/write_clip_playback.js +4 -4
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +5 -0
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
- package/src/engine/graphics3/pose/query_entity_node_world_pose.js +80 -75
- package/src/engine/graphics3/prefab/PrefabInstance.d.ts +4 -24
- package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/PrefabInstance.js +60 -80
- package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +16 -3
- package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/prefab_instantiate.js +49 -12
- package/src/engine/graphics3/prefab/prefab_place.d.ts +31 -17
- package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/prefab_place.js +175 -130
- package/src/engine/graphics3/register_clips.d.ts +93 -0
- package/src/engine/graphics3/register_clips.d.ts.map +1 -0
- package/src/engine/graphics3/register_clips.js +166 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +9 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -1
- package/src/engine/physics/broadphase/compute_fat_world_aabb.js +3 -1
- package/src/engine/physics/cloth/MEASUREMENTS.md +795 -0
- package/src/engine/physics/cloth/PLAN.md +349 -17
- package/src/engine/physics/cloth/build/ClothProxy.d.ts +113 -61
- package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -1
- package/src/engine/physics/cloth/build/ClothProxy.js +142 -77
- package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +44 -0
- package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +107 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +43 -30
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +371 -284
- package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts +62 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +275 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +7 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/ClothColliderIndex.js +85 -67
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +19 -101
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +2 -5
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_pack.js +7 -15
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +17 -62
- package/src/engine/physics/cloth/ecs/Cloth.d.ts +17 -9
- package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/Cloth.js +220 -212
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +0 -1
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +6 -19
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +1 -2
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +3 -12
- package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +6 -0
- package/src/engine/physics/cloth/ecs/ClothHold.d.ts +91 -0
- package/src/engine/physics/cloth/ecs/ClothHold.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothHold.js +103 -0
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +254 -48
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +277 -47
- package/src/engine/physics/cloth/ecs/ClothPin.d.ts +73 -0
- package/src/engine/physics/cloth/ecs/ClothPin.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothPin.js +92 -0
- package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts +36 -0
- package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.js +61 -0
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts +23 -17
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothRig.js +29 -27
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +12 -14
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +20 -15
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +57 -36
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +754 -207
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +12 -13
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +20 -14
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +63 -11
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_build_rows.js +297 -101
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +9 -7
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +12 -10
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +3 -3
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +60 -120
- package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +37 -0
- package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_geodesic.js +135 -0
- package/src/engine/physics/cloth/ecs/cloth_holds.d.ts +97 -0
- package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_holds.js +583 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +2 -2
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +168 -51
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +17 -22
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +55 -117
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -6
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +51 -42
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +5 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back.js +62 -50
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +65 -58
- package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts.map +1 -1
- package/src/engine/physics/cloth/playground/cloth_playground_build.js +2 -3
- package/src/engine/physics/cloth/playground/collide_main.js +3 -29
- package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
- package/src/engine/physics/cloth/playground/garment_build.js +17 -5
- package/src/engine/physics/cloth/playground/garment_main.js +5 -20
- package/src/engine/physics/cloth/playground/main.js +6 -48
- package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -1
- package/src/engine/physics/cloth/playground/rig_build.js +302 -296
- package/src/engine/physics/cloth/playground/rig_main.js +947 -955
- package/src/engine/physics/cloth/playground/wind_main.js +8 -7
- package/src/engine/physics/cloth/solver/ClothState.d.ts +45 -7
- package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/ClothState.js +79 -83
- package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts +10 -8
- package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_color_particles.js +30 -102
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +6 -1
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_contact_find.js +9 -3
- package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts +114 -0
- package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_hold_line.js +350 -0
- package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts +21 -0
- package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_kinetic_energy.js +45 -0
- package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts +32 -0
- package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_particle_coupling.js +133 -0
- package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts +16 -0
- package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_particle_of_source.js +19 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +6 -2
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_self_find.js +19 -68
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +30 -65
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +24 -12
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solver_constants.js +24 -12
- package/src/engine/physics/cloth/solver/cloth_step.d.ts +16 -0
- package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_step.js +189 -48
- package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +1 -0
- package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_step_instance.js +12 -6
- package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts +21 -0
- package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_stretch_residual.js +54 -0
- package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts +15 -0
- package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.js +28 -0
- package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts +30 -0
- package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.js +56 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +3 -17
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +353 -346
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +7 -5
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +7 -5
- package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +2 -1
- package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/ClothFluidWind.js +7 -25
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +12 -10
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/cloth_sample_air.js +60 -82
- package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/ContactProbeSystem.js +2 -18
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +9 -50
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts +24 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.js +42 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts +25 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.js +40 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -1
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +40 -90
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/capsule_contacts.js +3 -5
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +2 -14
- package/src/engine/physics/narrowphase/hull_sphere_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/hull_sphere_contact.js +2 -5
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/narrowphase_step.js +13 -32
- package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/sphere_box_contact.js +2 -5
- package/src/engine/simulation/Ticker.d.ts +13 -0
- package/src/engine/simulation/Ticker.d.ts.map +1 -1
- package/src/engine/simulation/Ticker.js +43 -8
- package/src/format/texture/basis/transcode/etc1s_to_astc.d.ts.map +1 -1
- package/src/format/texture/basis/transcode/etc1s_to_astc.js +2 -1
- package/src/shade/RENDERER_CONTRACT.md +8 -2
- package/src/shade/playground/image_decode_bench/main.js +2 -1
- package/src/shade/playground/mesh_row_ceiling/main.js +2 -1
- package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.js +2 -1
- package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/main.js +11 -19
- package/src/shade/playground/skinned_blas_refit/place_character.d.ts +6 -3
- package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/place_character.js +90 -90
- package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_mesh_soup/main.js +502 -509
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +2 -1
- package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -1
- package/src/shade/playground/ssr_variance/statistics.js +2 -1
- package/src/shade/playground/texture_encode/README.md +129 -109
- package/src/shade/playground/texture_encode/main.d.ts.map +1 -1
- package/src/shade/playground/texture_encode/main.js +1431 -1430
- package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -1
- package/src/shade/playground/volumetrics_froxel/measure.js +2 -1
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +45 -14
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +316 -64
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +5 -0
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -1
- package/src/shade/renderer/buffer/table/gpu_database_check_links.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/gpu_database_check_links.js +2 -1
- package/src/shade/renderer/geometry/BoxGeometry.d.ts +1 -11
- package/src/shade/renderer/geometry/BoxGeometry.d.ts.map +1 -1
- package/src/shade/renderer/geometry/BoxGeometry.js +6 -13
- package/src/shade/renderer/geometry/CapsuleGeometry.d.ts +19 -0
- package/src/shade/renderer/geometry/CapsuleGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/CapsuleGeometry.js +24 -0
- package/src/shade/renderer/geometry/ConeGeometry.d.ts +20 -0
- package/src/shade/renderer/geometry/ConeGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/ConeGeometry.js +33 -0
- package/src/shade/renderer/geometry/CylinderGeometry.d.ts +21 -0
- package/src/shade/renderer/geometry/CylinderGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/CylinderGeometry.js +35 -0
- package/src/shade/renderer/geometry/PlaneGeometry.d.ts +17 -0
- package/src/shade/renderer/geometry/PlaneGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/PlaneGeometry.js +22 -0
- package/src/shade/renderer/geometry/TorusGeometry.d.ts +18 -0
- package/src/shade/renderer/geometry/TorusGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/TorusGeometry.js +23 -0
- package/src/shade/renderer/geometry/UVSphereGeometry.d.ts +21 -0
- package/src/shade/renderer/geometry/UVSphereGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/UVSphereGeometry.js +34 -0
- package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts +19 -0
- package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/primitives/make_capsule_geometry.js +205 -0
- package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts +21 -0
- package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/primitives/make_cone_geometry.js +36 -0
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts +1 -1
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts.map +1 -1
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +44 -9
- package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts +20 -0
- package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.js +190 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +3 -2
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +2 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +2 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +2 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +3 -2
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.js +2 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +2 -1
- package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +3 -2
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +7 -2
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +26 -8
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +56 -39
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts +7 -0
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js +46 -4
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.js +4 -2
- package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +2 -2
- package/src/shade/renderer/gpu_primitive/sort/defs.js +79 -79
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +1 -1
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +7 -3
- package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -3
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +200 -194
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +6 -2
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +3 -2
- package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
- package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +334 -329
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +7 -2
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +16 -4
- package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +2444 -2345
- package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.js +312 -310
- package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts +3 -3
- package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.js +383 -375
- package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.js +349 -346
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts +58 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts.map +1 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.js +536 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts +21 -7
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js +291 -327
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts +25 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts.map +1 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.js +99 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts +5 -3
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.js +47 -71
- package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts +10 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts.map +1 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.js +50 -0
- package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts +4 -5
- package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.js +7 -8
- package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
- package/src/shade/renderer/water/chunk_water_transport.js +7 -5
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
- package/src/shade/renderer/water/medium/GPUWaterBodies.js +8 -2
- package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +3 -2
- package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
- package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +3 -2
- package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water.js +3 -1
- package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/GPUWaterSurface.js +3 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.js +11 -4
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +37 -20
- package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
- package/src/shade/wgsl/validate_wgsl_source.js +74 -3
- package/src/engine/graphics3/register_instance_animation.d.ts +0 -114
- package/src/engine/graphics3/register_instance_animation.d.ts.map +0 -1
- package/src/engine/graphics3/register_instance_animation.js +0 -201
|
@@ -1,346 +1,353 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CVA_F_X,
|
|
3
|
-
CVA_F_Y,
|
|
4
|
-
CVA_F_Z,
|
|
5
|
-
CVA_H_XX,
|
|
6
|
-
CVA_H_XY,
|
|
7
|
-
CVA_H_XZ,
|
|
8
|
-
CVA_H_YY,
|
|
9
|
-
CVA_H_YZ,
|
|
10
|
-
CVA_H_ZZ,
|
|
11
|
-
CVA_TRUST
|
|
12
|
-
} from "../cloth_vertex_accumulator.js";
|
|
13
|
-
import { CLOTH_STRETCH_EPSILON } from "./cloth_stretch_row.js";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* # Leash — the distance-to-a-point row
|
|
17
|
-
*
|
|
18
|
-
* C(x) = ‖x_i − s‖ − r
|
|
19
|
-
* ∂C/∂x_i = (x_i − s)/‖x_i − s‖ = n
|
|
20
|
-
*
|
|
21
|
-
* **This is both of §6's leash rows.** The slack row and the tether row have
|
|
22
|
-
* the same `C`, the same clamp and the same stiffness; they differ only in
|
|
23
|
-
* where `s` and `r` come from:
|
|
24
|
-
*
|
|
25
|
-
* | | `s` | `r` |
|
|
26
|
-
* |---|---|---|
|
|
27
|
-
* | slack | the particle's **animated position** | `slack · d_geo,i` |
|
|
28
|
-
* | tether (LRA) | the **
|
|
29
|
-
*
|
|
30
|
-
* So they are one module, parameterised by mode, exactly as
|
|
31
|
-
* `physics/constraint/solve_constraints.js` does for its 6-DOF joints at the
|
|
32
|
-
* velocity level, and exactly as `cloth_stretch_row.js` covers both the fabric
|
|
33
|
-
* row and its strain limit. A cape wants both, because they ask different
|
|
34
|
-
* questions: slack asks how loosely the cloth is leashed to the animation, the
|
|
35
|
-
* tether asks how far the fabric may extend from where it hangs (§6).
|
|
36
|
-
*
|
|
37
|
-
* §3.4's pin falls out too, with no third row and no branch: a particle whose
|
|
38
|
-
* `d_geo` is zero has a slack radius of zero, and `‖x_i − s‖ ≤ 0` under this
|
|
39
|
-
* clamp *is* a weld.
|
|
40
|
-
*
|
|
41
|
-
* ## The row is hard, and one-sided, structurally
|
|
42
|
-
*
|
|
43
|
-
* Neither a stiffness nor a pair of clamps is stored, because neither varies.
|
|
44
|
-
* A leash is `hard` in §6's table — its penalty lives in the measured band and
|
|
45
|
-
* its multiplier carries the load — and it is a *bound* rather than a spring,
|
|
46
|
-
* so it may only pull inwards. That is why this is the row that survives a low
|
|
47
|
-
* iteration budget: it is enforced almost exactly in one iteration, which is
|
|
48
|
-
* what §7 P2 means by long-range attachments making low iteration counts
|
|
49
|
-
* viable.
|
|
50
|
-
*
|
|
51
|
-
* ## Which way the clamp goes, and why §6's table has it backwards
|
|
52
|
-
*
|
|
53
|
-
* The solver applies `f -= fc·g`, so a **positive** `fc` on a distance row
|
|
54
|
-
* pulls the two ends together — that is what `cloth_stretch_row.js` means when
|
|
55
|
-
* it adds geometric stiffness for a row "in tension" at `fc > 0`. A row that
|
|
56
|
-
* bounds a distance from *above* must therefore be allowed positive force and
|
|
57
|
-
* no negative force: `f_min = 0, f_max = +∞`.
|
|
58
|
-
*
|
|
59
|
-
* §6's table gives slack, tether and strain limit `(−∞, 0]` instead, which
|
|
60
|
-
* under this convention is the force that pushes them apart — it would drive
|
|
61
|
-
* the particle *away* from its leash centre and the row would never bind.
|
|
62
|
-
* `cloth_leash_row.spec.js` demonstrates the correct sign directly; the
|
|
63
|
-
* table's own collision and self-collision rows are consistent with it once
|
|
64
|
-
* you notice that a collision row writes `C` with the opposite sense. The
|
|
65
|
-
* precise rule, which the table's "push-only / pull-only" gloss elides, is:
|
|
66
|
-
* `[0, +∞)` admits only forces that **reduce** `C`, and `(−∞, 0]` only forces
|
|
67
|
-
* that **increase** it.
|
|
68
|
-
*
|
|
69
|
-
* ## Coincident with the target
|
|
70
|
-
*
|
|
71
|
-
* `‖x − s‖` is not differentiable at zero. Below {@link CLOTH_STRETCH_EPSILON}
|
|
72
|
-
* the row is skipped, which is the standard guard and is also exactly when it
|
|
73
|
-
* has nothing to do — a particle sitting on its own leash centre is where the
|
|
74
|
-
* row was trying to put it.
|
|
75
|
-
*
|
|
76
|
-
* @author Alex Goldring
|
|
77
|
-
* @copyright Company Named Limited (c) 2026
|
|
78
|
-
*/
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Evaluate one leash row's constraint value and its gradient.
|
|
82
|
-
*
|
|
83
|
-
* This is the definition the accumulation loop below inlines, and the one the
|
|
84
|
-
* finite-difference spec checks — there is no second copy of the arithmetic.
|
|
85
|
-
*
|
|
86
|
-
* @param {Float64Array|number[]} gradient out, `∂C/∂x`
|
|
87
|
-
* @param {number} gradient_offset
|
|
88
|
-
* @param {ClothState} state
|
|
89
|
-
* @param {number} row
|
|
90
|
-
* @returns {number} `C`
|
|
91
|
-
*/
|
|
92
|
-
export function cloth_leash_evaluate(gradient, gradient_offset, state, row) {
|
|
93
|
-
const self = state.leash_particle[row] * 3;
|
|
94
|
-
const target = row * 3;
|
|
95
|
-
|
|
96
|
-
const position = state.position;
|
|
97
|
-
const leash_target = state.leash_target;
|
|
98
|
-
|
|
99
|
-
const dx = position[self] - leash_target[target];
|
|
100
|
-
const dy = position[self + 1] - leash_target[target + 1];
|
|
101
|
-
const dz = position[self + 2] - leash_target[target + 2];
|
|
102
|
-
|
|
103
|
-
const length = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
104
|
-
|
|
105
|
-
if (length < CLOTH_STRETCH_EPSILON) {
|
|
106
|
-
gradient[gradient_offset] = 0;
|
|
107
|
-
gradient[gradient_offset + 1] = 0;
|
|
108
|
-
gradient[gradient_offset + 2] = 0;
|
|
109
|
-
|
|
110
|
-
return length - state.leash_radius[row];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const inverse = 1 / length;
|
|
114
|
-
|
|
115
|
-
gradient[gradient_offset] = dx * inverse;
|
|
116
|
-
gradient[gradient_offset + 1] = dy * inverse;
|
|
117
|
-
gradient[gradient_offset + 2] = dz * inverse;
|
|
118
|
-
|
|
119
|
-
return length - state.leash_radius[row];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Add every leash row touching `particle` into the vertex accumulator.
|
|
124
|
-
*
|
|
125
|
-
* @param {Float64Array} accumulator
|
|
126
|
-
* @param {ClothState} state
|
|
127
|
-
* @param {number} particle
|
|
128
|
-
*/
|
|
129
|
-
export function cloth_leash_accumulate(accumulator, state, particle) {
|
|
130
|
-
const offset = state.leash_adjacency_offset;
|
|
131
|
-
|
|
132
|
-
const start = offset[particle];
|
|
133
|
-
const end = offset[particle + 1];
|
|
134
|
-
|
|
135
|
-
if (start === end) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const adjacency = state.leash_adjacency;
|
|
140
|
-
const radius = state.leash_radius;
|
|
141
|
-
const lambda = state.leash_lambda;
|
|
142
|
-
const penalty = state.leash_penalty;
|
|
143
|
-
const leash_target = state.leash_target;
|
|
144
|
-
const position = state.position;
|
|
145
|
-
|
|
146
|
-
const self = particle * 3;
|
|
147
|
-
|
|
148
|
-
const x = position[self];
|
|
149
|
-
const y = position[self + 1];
|
|
150
|
-
const z = position[self + 2];
|
|
151
|
-
|
|
152
|
-
let f_x = accumulator[CVA_F_X];
|
|
153
|
-
let f_y = accumulator[CVA_F_Y];
|
|
154
|
-
let f_z = accumulator[CVA_F_Z];
|
|
155
|
-
|
|
156
|
-
let h_xx = accumulator[CVA_H_XX];
|
|
157
|
-
let h_yy = accumulator[CVA_H_YY];
|
|
158
|
-
let h_zz = accumulator[CVA_H_ZZ];
|
|
159
|
-
let h_xy = accumulator[CVA_H_XY];
|
|
160
|
-
let h_xz = accumulator[CVA_H_XZ];
|
|
161
|
-
let h_yz = accumulator[CVA_H_YZ];
|
|
162
|
-
|
|
163
|
-
let trust = accumulator[CVA_TRUST];
|
|
164
|
-
|
|
165
|
-
for (let i = start; i < end; i++) {
|
|
166
|
-
const row = adjacency[i];
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
accumulator[
|
|
233
|
-
accumulator[
|
|
234
|
-
accumulator[
|
|
235
|
-
|
|
236
|
-
accumulator[
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
1
|
+
import {
|
|
2
|
+
CVA_F_X,
|
|
3
|
+
CVA_F_Y,
|
|
4
|
+
CVA_F_Z,
|
|
5
|
+
CVA_H_XX,
|
|
6
|
+
CVA_H_XY,
|
|
7
|
+
CVA_H_XZ,
|
|
8
|
+
CVA_H_YY,
|
|
9
|
+
CVA_H_YZ,
|
|
10
|
+
CVA_H_ZZ,
|
|
11
|
+
CVA_TRUST
|
|
12
|
+
} from "../cloth_vertex_accumulator.js";
|
|
13
|
+
import { CLOTH_STRETCH_EPSILON } from "./cloth_stretch_row.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* # Leash — the distance-to-a-point row
|
|
17
|
+
*
|
|
18
|
+
* C(x) = ‖x_i − s‖ − r
|
|
19
|
+
* ∂C/∂x_i = (x_i − s)/‖x_i − s‖ = n
|
|
20
|
+
*
|
|
21
|
+
* **This is both of §6's leash rows.** The slack row and the tether row have
|
|
22
|
+
* the same `C`, the same clamp and the same stiffness; they differ only in
|
|
23
|
+
* where `s` and `r` come from:
|
|
24
|
+
*
|
|
25
|
+
* | | `s` | `r` |
|
|
26
|
+
* |---|---|---|
|
|
27
|
+
* | slack | the particle's **animated position** | `slack · d_geo,i` |
|
|
28
|
+
* | tether (LRA) | the nearest **held particle's** position | `d_geo,i` |
|
|
29
|
+
*
|
|
30
|
+
* So they are one module, parameterised by mode, exactly as
|
|
31
|
+
* `physics/constraint/solve_constraints.js` does for its 6-DOF joints at the
|
|
32
|
+
* velocity level, and exactly as `cloth_stretch_row.js` covers both the fabric
|
|
33
|
+
* row and its strain limit. A cape wants both, because they ask different
|
|
34
|
+
* questions: slack asks how loosely the cloth is leashed to the animation, the
|
|
35
|
+
* tether asks how far the fabric may extend from where it hangs (§6).
|
|
36
|
+
*
|
|
37
|
+
* §3.4's pin falls out too, with no third row and no branch: a particle whose
|
|
38
|
+
* `d_geo` is zero has a slack radius of zero, and `‖x_i − s‖ ≤ 0` under this
|
|
39
|
+
* clamp *is* a weld.
|
|
40
|
+
*
|
|
41
|
+
* ## The row is hard, and one-sided, structurally
|
|
42
|
+
*
|
|
43
|
+
* Neither a stiffness nor a pair of clamps is stored, because neither varies.
|
|
44
|
+
* A leash is `hard` in §6's table — its penalty lives in the measured band and
|
|
45
|
+
* its multiplier carries the load — and it is a *bound* rather than a spring,
|
|
46
|
+
* so it may only pull inwards. That is why this is the row that survives a low
|
|
47
|
+
* iteration budget: it is enforced almost exactly in one iteration, which is
|
|
48
|
+
* what §7 P2 means by long-range attachments making low iteration counts
|
|
49
|
+
* viable.
|
|
50
|
+
*
|
|
51
|
+
* ## Which way the clamp goes, and why §6's table has it backwards
|
|
52
|
+
*
|
|
53
|
+
* The solver applies `f -= fc·g`, so a **positive** `fc` on a distance row
|
|
54
|
+
* pulls the two ends together — that is what `cloth_stretch_row.js` means when
|
|
55
|
+
* it adds geometric stiffness for a row "in tension" at `fc > 0`. A row that
|
|
56
|
+
* bounds a distance from *above* must therefore be allowed positive force and
|
|
57
|
+
* no negative force: `f_min = 0, f_max = +∞`.
|
|
58
|
+
*
|
|
59
|
+
* §6's table gives slack, tether and strain limit `(−∞, 0]` instead, which
|
|
60
|
+
* under this convention is the force that pushes them apart — it would drive
|
|
61
|
+
* the particle *away* from its leash centre and the row would never bind.
|
|
62
|
+
* `cloth_leash_row.spec.js` demonstrates the correct sign directly; the
|
|
63
|
+
* table's own collision and self-collision rows are consistent with it once
|
|
64
|
+
* you notice that a collision row writes `C` with the opposite sense. The
|
|
65
|
+
* precise rule, which the table's "push-only / pull-only" gloss elides, is:
|
|
66
|
+
* `[0, +∞)` admits only forces that **reduce** `C`, and `(−∞, 0]` only forces
|
|
67
|
+
* that **increase** it.
|
|
68
|
+
*
|
|
69
|
+
* ## Coincident with the target
|
|
70
|
+
*
|
|
71
|
+
* `‖x − s‖` is not differentiable at zero. Below {@link CLOTH_STRETCH_EPSILON}
|
|
72
|
+
* the row is skipped, which is the standard guard and is also exactly when it
|
|
73
|
+
* has nothing to do — a particle sitting on its own leash centre is where the
|
|
74
|
+
* row was trying to put it.
|
|
75
|
+
*
|
|
76
|
+
* @author Alex Goldring
|
|
77
|
+
* @copyright Company Named Limited (c) 2026
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Evaluate one leash row's constraint value and its gradient.
|
|
82
|
+
*
|
|
83
|
+
* This is the definition the accumulation loop below inlines, and the one the
|
|
84
|
+
* finite-difference spec checks — there is no second copy of the arithmetic.
|
|
85
|
+
*
|
|
86
|
+
* @param {Float64Array|number[]} gradient out, `∂C/∂x`
|
|
87
|
+
* @param {number} gradient_offset
|
|
88
|
+
* @param {ClothState} state
|
|
89
|
+
* @param {number} row
|
|
90
|
+
* @returns {number} `C`
|
|
91
|
+
*/
|
|
92
|
+
export function cloth_leash_evaluate(gradient, gradient_offset, state, row) {
|
|
93
|
+
const self = state.leash_particle[row] * 3;
|
|
94
|
+
const target = row * 3;
|
|
95
|
+
|
|
96
|
+
const position = state.position;
|
|
97
|
+
const leash_target = state.leash_target;
|
|
98
|
+
|
|
99
|
+
const dx = position[self] - leash_target[target];
|
|
100
|
+
const dy = position[self + 1] - leash_target[target + 1];
|
|
101
|
+
const dz = position[self + 2] - leash_target[target + 2];
|
|
102
|
+
|
|
103
|
+
const length = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
104
|
+
|
|
105
|
+
if (length < CLOTH_STRETCH_EPSILON) {
|
|
106
|
+
gradient[gradient_offset] = 0;
|
|
107
|
+
gradient[gradient_offset + 1] = 0;
|
|
108
|
+
gradient[gradient_offset + 2] = 0;
|
|
109
|
+
|
|
110
|
+
return length - state.leash_radius[row];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const inverse = 1 / length;
|
|
114
|
+
|
|
115
|
+
gradient[gradient_offset] = dx * inverse;
|
|
116
|
+
gradient[gradient_offset + 1] = dy * inverse;
|
|
117
|
+
gradient[gradient_offset + 2] = dz * inverse;
|
|
118
|
+
|
|
119
|
+
return length - state.leash_radius[row];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Add every leash row touching `particle` into the vertex accumulator.
|
|
124
|
+
*
|
|
125
|
+
* @param {Float64Array} accumulator
|
|
126
|
+
* @param {ClothState} state
|
|
127
|
+
* @param {number} particle
|
|
128
|
+
*/
|
|
129
|
+
export function cloth_leash_accumulate(accumulator, state, particle) {
|
|
130
|
+
const offset = state.leash_adjacency_offset;
|
|
131
|
+
|
|
132
|
+
const start = offset[particle];
|
|
133
|
+
const end = offset[particle + 1];
|
|
134
|
+
|
|
135
|
+
if (start === end) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const adjacency = state.leash_adjacency;
|
|
140
|
+
const radius = state.leash_radius;
|
|
141
|
+
const lambda = state.leash_lambda;
|
|
142
|
+
const penalty = state.leash_penalty;
|
|
143
|
+
const leash_target = state.leash_target;
|
|
144
|
+
const position = state.position;
|
|
145
|
+
|
|
146
|
+
const self = particle * 3;
|
|
147
|
+
|
|
148
|
+
const x = position[self];
|
|
149
|
+
const y = position[self + 1];
|
|
150
|
+
const z = position[self + 2];
|
|
151
|
+
|
|
152
|
+
let f_x = accumulator[CVA_F_X];
|
|
153
|
+
let f_y = accumulator[CVA_F_Y];
|
|
154
|
+
let f_z = accumulator[CVA_F_Z];
|
|
155
|
+
|
|
156
|
+
let h_xx = accumulator[CVA_H_XX];
|
|
157
|
+
let h_yy = accumulator[CVA_H_YY];
|
|
158
|
+
let h_zz = accumulator[CVA_H_ZZ];
|
|
159
|
+
let h_xy = accumulator[CVA_H_XY];
|
|
160
|
+
let h_xz = accumulator[CVA_H_XZ];
|
|
161
|
+
let h_yz = accumulator[CVA_H_YZ];
|
|
162
|
+
|
|
163
|
+
let trust = accumulator[CVA_TRUST];
|
|
164
|
+
|
|
165
|
+
for (let i = start; i < end; i++) {
|
|
166
|
+
const row = adjacency[i];
|
|
167
|
+
|
|
168
|
+
if (radius[row] === Infinity) {
|
|
169
|
+
// A row with no bound — a particle nothing holds — has nothing to
|
|
170
|
+
// say, and asked first it costs nothing and cannot meet a zero
|
|
171
|
+
// penalty times an infinite violation.
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const target = row * 3;
|
|
176
|
+
|
|
177
|
+
const dx = x - leash_target[target];
|
|
178
|
+
const dy = y - leash_target[target + 1];
|
|
179
|
+
const dz = z - leash_target[target + 2];
|
|
180
|
+
|
|
181
|
+
const length_squared = dx * dx + dy * dy + dz * dz;
|
|
182
|
+
|
|
183
|
+
if (length_squared < CLOTH_STRETCH_EPSILON * CLOTH_STRETCH_EPSILON) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const k = penalty[row];
|
|
188
|
+
|
|
189
|
+
const length = Math.sqrt(length_squared);
|
|
190
|
+
|
|
191
|
+
const unclamped = k * (length - radius[row]) + lambda[row];
|
|
192
|
+
|
|
193
|
+
if (unclamped <= 0) {
|
|
194
|
+
// Inside the leash and carrying no accumulated force: the row is
|
|
195
|
+
// clamped out, contributes neither force nor curvature, and — this
|
|
196
|
+
// is the part that matters — must not narrow the trust region
|
|
197
|
+
// either. A particle resting near its own leash centre would
|
|
198
|
+
// otherwise cap every step at its distance from that centre and
|
|
199
|
+
// freeze for reasons that have nothing to do with the rows doing
|
|
200
|
+
// the work.
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const inverse = 1 / length;
|
|
205
|
+
|
|
206
|
+
if (length < trust) {
|
|
207
|
+
trust = length;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const g_x = dx * inverse;
|
|
211
|
+
const g_y = dy * inverse;
|
|
212
|
+
const g_z = dz * inverse;
|
|
213
|
+
|
|
214
|
+
f_x -= unclamped * g_x;
|
|
215
|
+
f_y -= unclamped * g_y;
|
|
216
|
+
f_z -= unclamped * g_z;
|
|
217
|
+
|
|
218
|
+
// Geometric stiffness, positive part only. The row is in tension
|
|
219
|
+
// whenever it is active at all — that is what the clamp above means —
|
|
220
|
+
// so the `(fc/L)·(I − ggᵀ)` term is positive semidefinite here without
|
|
221
|
+
// a second test. `MEASUREMENTS.md` §5.1 for what dropping it costs.
|
|
222
|
+
const s = unclamped * inverse;
|
|
223
|
+
|
|
224
|
+
h_xx += s * (1 - g_x * g_x) + k * g_x * g_x;
|
|
225
|
+
h_yy += s * (1 - g_y * g_y) + k * g_y * g_y;
|
|
226
|
+
h_zz += s * (1 - g_z * g_z) + k * g_z * g_z;
|
|
227
|
+
h_xy += (k - s) * g_x * g_y;
|
|
228
|
+
h_xz += (k - s) * g_x * g_z;
|
|
229
|
+
h_yz += (k - s) * g_y * g_z;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
accumulator[CVA_F_X] = f_x;
|
|
233
|
+
accumulator[CVA_F_Y] = f_y;
|
|
234
|
+
accumulator[CVA_F_Z] = f_z;
|
|
235
|
+
|
|
236
|
+
accumulator[CVA_H_XX] = h_xx;
|
|
237
|
+
accumulator[CVA_H_YY] = h_yy;
|
|
238
|
+
accumulator[CVA_H_ZZ] = h_zz;
|
|
239
|
+
accumulator[CVA_H_XY] = h_xy;
|
|
240
|
+
accumulator[CVA_H_XZ] = h_xz;
|
|
241
|
+
accumulator[CVA_H_YZ] = h_yz;
|
|
242
|
+
|
|
243
|
+
accumulator[CVA_TRUST] = trust;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Warm start every leash row for a substep: regularise the carried multiplier
|
|
248
|
+
* and put the penalty in the band. §5.2.
|
|
249
|
+
*
|
|
250
|
+
* Every leash row is hard, so — unlike the stretch table — there is no soft
|
|
251
|
+
* branch here. The row's inertial scale is the particle's own `m/h²`, because
|
|
252
|
+
* a leash has one end that can move.
|
|
253
|
+
*
|
|
254
|
+
* @param {ClothState} state
|
|
255
|
+
* @param {number} alpha multiplier regularisation, `[0, 1]`
|
|
256
|
+
* @param {number} gamma dual decay, `[0, 1)`
|
|
257
|
+
* @param {number} k_min_ratio penalty floor, as a multiple of `m/h²`
|
|
258
|
+
* @param {number} k_max_ratio penalty ceiling, as a multiple of `m/h²`
|
|
259
|
+
* @param {number} inverse_h_squared
|
|
260
|
+
*/
|
|
261
|
+
export function cloth_leash_warm_start(state, alpha, gamma, k_min_ratio, k_max_ratio, inverse_h_squared) {
|
|
262
|
+
const count = state.leash_count;
|
|
263
|
+
|
|
264
|
+
const row_particle = state.leash_particle;
|
|
265
|
+
const mass_inverse = state.mass_inverse;
|
|
266
|
+
const lambda = state.leash_lambda;
|
|
267
|
+
const penalty = state.leash_penalty;
|
|
268
|
+
|
|
269
|
+
const decay = alpha * gamma;
|
|
270
|
+
|
|
271
|
+
for (let row = 0; row < count; row++) {
|
|
272
|
+
const compliance = mass_inverse[row_particle[row]];
|
|
273
|
+
|
|
274
|
+
if (compliance === 0) {
|
|
275
|
+
// A pinned particle cannot move, so the row has nothing to enforce
|
|
276
|
+
// and the band it would be clamped into is unbounded. Zeroed rather
|
|
277
|
+
// than left holding `Infinity` in live state.
|
|
278
|
+
penalty[row] = 0;
|
|
279
|
+
lambda[row] = 0;
|
|
280
|
+
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const scale = inverse_h_squared / compliance;
|
|
285
|
+
|
|
286
|
+
const lo = k_min_ratio * scale;
|
|
287
|
+
const hi = k_max_ratio * scale;
|
|
288
|
+
|
|
289
|
+
lambda[row] *= decay;
|
|
290
|
+
|
|
291
|
+
let k = penalty[row] * gamma;
|
|
292
|
+
|
|
293
|
+
if (k < lo) {
|
|
294
|
+
k = lo;
|
|
295
|
+
} else if (k > hi) {
|
|
296
|
+
k = hi;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
penalty[row] = k;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Dual update for every leash row: absorb this iteration's violation into the
|
|
305
|
+
* multiplier and ramp the penalty. §5.2.
|
|
306
|
+
*
|
|
307
|
+
* @param {ClothState} state
|
|
308
|
+
* @param {number} beta penalty ramp
|
|
309
|
+
* @param {number} k_max_ratio
|
|
310
|
+
* @param {number} inverse_h_squared
|
|
311
|
+
*/
|
|
312
|
+
export function cloth_leash_dual_update(state, beta, k_max_ratio, inverse_h_squared) {
|
|
313
|
+
const count = state.leash_count;
|
|
314
|
+
|
|
315
|
+
const row_particle = state.leash_particle;
|
|
316
|
+
const mass_inverse = state.mass_inverse;
|
|
317
|
+
const position = state.position;
|
|
318
|
+
const leash_target = state.leash_target;
|
|
319
|
+
const radius = state.leash_radius;
|
|
320
|
+
const lambda = state.leash_lambda;
|
|
321
|
+
const penalty = state.leash_penalty;
|
|
322
|
+
|
|
323
|
+
for (let row = 0; row < count; row++) {
|
|
324
|
+
const particle = row_particle[row];
|
|
325
|
+
|
|
326
|
+
const compliance = mass_inverse[particle];
|
|
327
|
+
|
|
328
|
+
if (compliance === 0 || radius[row] === Infinity) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const k_max = k_max_ratio * inverse_h_squared / compliance;
|
|
333
|
+
|
|
334
|
+
const self = particle * 3;
|
|
335
|
+
const target = row * 3;
|
|
336
|
+
|
|
337
|
+
const dx = position[self] - leash_target[target];
|
|
338
|
+
const dy = position[self + 1] - leash_target[target + 1];
|
|
339
|
+
const dz = position[self + 2] - leash_target[target + 2];
|
|
340
|
+
|
|
341
|
+
const c = Math.sqrt(dx * dx + dy * dy + dz * dz) - radius[row];
|
|
342
|
+
|
|
343
|
+
const k = penalty[row];
|
|
344
|
+
|
|
345
|
+
const next = k * c + lambda[row];
|
|
346
|
+
|
|
347
|
+
lambda[row] = next > 0 ? next : 0;
|
|
348
|
+
|
|
349
|
+
const ramped = k + beta * Math.abs(c);
|
|
350
|
+
|
|
351
|
+
penalty[row] = ramped < k_max ? ramped : k_max;
|
|
352
|
+
}
|
|
353
|
+
}
|