@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
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../../../graphics3/prefab/Prefab.js").Prefab} Prefab
|
|
3
|
+
* @typedef {import("../../../../shade/renderer/animation/Skin.js").Skin} Skin
|
|
4
|
+
* @typedef {import("./cloth_proxy_from_joints.js").ClothProxyBuildResult} ClothProxyBuildResult
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* # Building a proxy for a sheet: one joint per vertex, and the triangles between them
|
|
8
|
+
*
|
|
9
|
+
* A sheet — a flag, a banner, a curtain, a cloth dropped on a sphere — is a
|
|
10
|
+
* triangle mesh, and what drives its render mesh is a skin with **one joint per
|
|
11
|
+
* vertex**: each vertex weighted wholly to its own joint, every joint hanging
|
|
12
|
+
* straight off one root joint. That skin is ordinary; the engine draws it the way
|
|
13
|
+
* it draws any skinned model, and cloth moves its joints the way it moves a
|
|
14
|
+
* cape's. This builds the proxy for it — §11.3's steps 4, 6 and 10 over a mesh
|
|
15
|
+
* that is already welded and already a particle set:
|
|
16
|
+
*
|
|
17
|
+
* - **a hard stretch row per edge**, every edge of every triangle once;
|
|
18
|
+
* - **a hinge per interior edge** — the shared edge, then the wing opposite it in
|
|
19
|
+
* each triangle, which is `cloth_bend_row`'s stencil order. The stencil is built
|
|
20
|
+
* here rather than read through `bt_edge_read_diamond`, whose quad puts the
|
|
21
|
+
* shared edge in the middle;
|
|
22
|
+
* - the bind pose of every joint in the root joint's, and the root joint as the
|
|
23
|
+
* frame the sheet is simulated in.
|
|
24
|
+
*
|
|
25
|
+
* **Nothing is pinned.** Which vertices are held is the scene's business — a pole
|
|
26
|
+
* holding a flag's hoist, a hook holding a ribbon's top — and a `ClothPin` names
|
|
27
|
+
* them by particle, which is their position in `joint_names`.
|
|
28
|
+
*
|
|
29
|
+
* ## What is refused, and why at build
|
|
30
|
+
*
|
|
31
|
+
* §7 P8: a triangle with no area (no normal, no stencil), an edge three triangles
|
|
32
|
+
* share (no single hinge across it), joints that do not all hang from the same
|
|
33
|
+
* root, and a name the skin does not have. Each is an authoring mistake, and each
|
|
34
|
+
* comes back as a message naming it rather than as a sheet that misbehaves.
|
|
35
|
+
*
|
|
36
|
+
* ## The rest shape is assumed flat where it bends
|
|
37
|
+
*
|
|
38
|
+
* The hinge is §6's quadratic stencil, which annihilates a planar rest shape and
|
|
39
|
+
* every affine image of it and reads a curved rest as already bent (§18). A flag,
|
|
40
|
+
* a sheet and a circle skirt cut flat are what this serves; a tube is not.
|
|
41
|
+
*
|
|
42
|
+
* @author Alex Goldring
|
|
43
|
+
* @copyright Company Named Limited (c) 2026
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Build a proxy from the joints of a sheet's skin and the triangles over them.
|
|
47
|
+
*
|
|
48
|
+
* @param {Prefab} prefab the compiled model the joints are nodes of
|
|
49
|
+
* @param {Skin} skin one of the prefab's skins — joints as node indices
|
|
50
|
+
* @param {string[]} joint_names one joint per vertex; particle `i` is `joint_names[i]`
|
|
51
|
+
* @param {Int32Array|number[]} triangles indices into `joint_names`, 3 per triangle
|
|
52
|
+
* @param {object} [options]
|
|
53
|
+
* @param {string} [options.name]
|
|
54
|
+
* @returns {ClothProxyBuildResult}
|
|
55
|
+
*/
|
|
56
|
+
export function cloth_proxy_from_mesh(prefab: Prefab, skin: Skin, joint_names: string[], triangles: Int32Array | number[], { name }?: {
|
|
57
|
+
name?: string;
|
|
58
|
+
}): ClothProxyBuildResult;
|
|
59
|
+
export type Prefab = import("../../../graphics3/prefab/Prefab.js").Prefab;
|
|
60
|
+
export type Skin = import("../../../../shade/renderer/animation/Skin.js").Skin;
|
|
61
|
+
export type ClothProxyBuildResult = import("./cloth_proxy_from_joints.js").ClothProxyBuildResult;
|
|
62
|
+
//# sourceMappingURL=cloth_proxy_from_mesh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloth_proxy_from_mesh.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/build/cloth_proxy_from_mesh.js"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH;;;;;;;;;;GAUG;AACH,8CARW,MAAM,QACN,IAAI,eACJ,MAAM,EAAE,aACR,UAAU,GAAC,MAAM,EAAE;IAEF,IAAI,GAArB,MAAM;IACJ,qBAAqB,CA8MjC;qBApQY,OAAO,qCAAqC,EAAE,MAAM;mBACpD,OAAO,8CAA8C,EAAE,IAAI;oCAC3D,OAAO,8BAA8B,EAAE,qBAAqB"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { tri3_area } from "../../../../core/geom/3d/triangle/tri3_area.js";
|
|
2
|
+
import { ClothProxy } from "./ClothProxy.js";
|
|
3
|
+
import { cloth_bind_in_frame, cloth_bind_scaled_above } from "./cloth_bind_in_frame.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import("../../../graphics3/prefab/Prefab.js").Prefab} Prefab
|
|
7
|
+
* @typedef {import("../../../../shade/renderer/animation/Skin.js").Skin} Skin
|
|
8
|
+
* @typedef {import("./cloth_proxy_from_joints.js").ClothProxyBuildResult} ClothProxyBuildResult
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* # Building a proxy for a sheet: one joint per vertex, and the triangles between them
|
|
13
|
+
*
|
|
14
|
+
* A sheet — a flag, a banner, a curtain, a cloth dropped on a sphere — is a
|
|
15
|
+
* triangle mesh, and what drives its render mesh is a skin with **one joint per
|
|
16
|
+
* vertex**: each vertex weighted wholly to its own joint, every joint hanging
|
|
17
|
+
* straight off one root joint. That skin is ordinary; the engine draws it the way
|
|
18
|
+
* it draws any skinned model, and cloth moves its joints the way it moves a
|
|
19
|
+
* cape's. This builds the proxy for it — §11.3's steps 4, 6 and 10 over a mesh
|
|
20
|
+
* that is already welded and already a particle set:
|
|
21
|
+
*
|
|
22
|
+
* - **a hard stretch row per edge**, every edge of every triangle once;
|
|
23
|
+
* - **a hinge per interior edge** — the shared edge, then the wing opposite it in
|
|
24
|
+
* each triangle, which is `cloth_bend_row`'s stencil order. The stencil is built
|
|
25
|
+
* here rather than read through `bt_edge_read_diamond`, whose quad puts the
|
|
26
|
+
* shared edge in the middle;
|
|
27
|
+
* - the bind pose of every joint in the root joint's, and the root joint as the
|
|
28
|
+
* frame the sheet is simulated in.
|
|
29
|
+
*
|
|
30
|
+
* **Nothing is pinned.** Which vertices are held is the scene's business — a pole
|
|
31
|
+
* holding a flag's hoist, a hook holding a ribbon's top — and a `ClothPin` names
|
|
32
|
+
* them by particle, which is their position in `joint_names`.
|
|
33
|
+
*
|
|
34
|
+
* ## What is refused, and why at build
|
|
35
|
+
*
|
|
36
|
+
* §7 P8: a triangle with no area (no normal, no stencil), an edge three triangles
|
|
37
|
+
* share (no single hinge across it), joints that do not all hang from the same
|
|
38
|
+
* root, and a name the skin does not have. Each is an authoring mistake, and each
|
|
39
|
+
* comes back as a message naming it rather than as a sheet that misbehaves.
|
|
40
|
+
*
|
|
41
|
+
* ## The rest shape is assumed flat where it bends
|
|
42
|
+
*
|
|
43
|
+
* The hinge is §6's quadratic stencil, which annihilates a planar rest shape and
|
|
44
|
+
* every affine image of it and reads a curved rest as already bent (§18). A flag,
|
|
45
|
+
* a sheet and a circle skirt cut flat are what this serves; a tube is not.
|
|
46
|
+
*
|
|
47
|
+
* @author Alex Goldring
|
|
48
|
+
* @copyright Company Named Limited (c) 2026
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Build a proxy from the joints of a sheet's skin and the triangles over them.
|
|
53
|
+
*
|
|
54
|
+
* @param {Prefab} prefab the compiled model the joints are nodes of
|
|
55
|
+
* @param {Skin} skin one of the prefab's skins — joints as node indices
|
|
56
|
+
* @param {string[]} joint_names one joint per vertex; particle `i` is `joint_names[i]`
|
|
57
|
+
* @param {Int32Array|number[]} triangles indices into `joint_names`, 3 per triangle
|
|
58
|
+
* @param {object} [options]
|
|
59
|
+
* @param {string} [options.name]
|
|
60
|
+
* @returns {ClothProxyBuildResult}
|
|
61
|
+
*/
|
|
62
|
+
export function cloth_proxy_from_mesh(prefab, skin, joint_names, triangles, { name = "" } = {}) {
|
|
63
|
+
if (prefab === undefined || prefab === null || prefab.isPrefab !== true) {
|
|
64
|
+
return refuse(`${name}: no prefab`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (skin === undefined || skin === null) {
|
|
68
|
+
return refuse(`${name}: no skin`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const joints = skin.joints;
|
|
72
|
+
const parent_of = prefab.parent;
|
|
73
|
+
const name_of = prefab.name;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @type {Map<number, number>} node index → position in the skin's joints
|
|
77
|
+
*/
|
|
78
|
+
const index_of = new Map();
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @type {Map<string, number>}
|
|
82
|
+
*/
|
|
83
|
+
const by_name = new Map();
|
|
84
|
+
|
|
85
|
+
for (let i = 0; i < joints.length; i++) {
|
|
86
|
+
index_of.set(joints[i], i);
|
|
87
|
+
|
|
88
|
+
const joint_name = name_of[joints[i]];
|
|
89
|
+
|
|
90
|
+
if (joint_name !== "" && !by_name.has(joint_name)) {
|
|
91
|
+
by_name.set(joint_name, joints[i]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const particle_count = joint_names.length;
|
|
96
|
+
|
|
97
|
+
if (particle_count === 0) {
|
|
98
|
+
return refuse(`${name}: no joints`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const node = new Int32Array(particle_count);
|
|
102
|
+
|
|
103
|
+
const seen = new Set();
|
|
104
|
+
|
|
105
|
+
for (let i = 0; i < particle_count; i++) {
|
|
106
|
+
const found = by_name.get(joint_names[i]);
|
|
107
|
+
|
|
108
|
+
if (found === undefined) {
|
|
109
|
+
return refuse(`${name}: the skin has no joint named "${joint_names[i]}"`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (seen.has(found)) {
|
|
113
|
+
return refuse(`${name}: "${joint_names[i]}" is named twice`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
seen.add(found);
|
|
117
|
+
|
|
118
|
+
node[i] = found;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// One root for every vertex joint: the frame, and what the write-back
|
|
122
|
+
// expresses each joint against.
|
|
123
|
+
const frame_node = parent_of[node[0]];
|
|
124
|
+
|
|
125
|
+
for (let i = 1; i < particle_count; i++) {
|
|
126
|
+
if (parent_of[node[i]] !== frame_node) {
|
|
127
|
+
return refuse(
|
|
128
|
+
`${name}: "${joint_names[0]}" hangs from "${name_of[frame_node] ?? 'nothing'}" and "${joint_names[i]}"`
|
|
129
|
+
+ ` from "${name_of[parent_of[node[i]]] ?? 'nothing'}" — a sheet's joints hang from one root joint`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (frame_node < 0 || !index_of.has(frame_node)) {
|
|
135
|
+
return refuse(`${name}: the sheet's joints hang from "${name_of[frame_node] ?? 'nothing'}", which is not a joint of this skin`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const triangle_count = Math.floor(triangles.length / 3);
|
|
139
|
+
|
|
140
|
+
if (triangle_count * 3 !== triangles.length) {
|
|
141
|
+
return refuse(`${name}: ${triangles.length} triangle indices is not a whole number of triangles`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Every vertex joint hangs from the frame, so one walk up from any of them asks the lot.
|
|
145
|
+
const scaled = cloth_bind_scaled_above(prefab, node[0]);
|
|
146
|
+
|
|
147
|
+
if (scaled >= 0) {
|
|
148
|
+
const local = prefab.local[scaled];
|
|
149
|
+
|
|
150
|
+
return refuse(
|
|
151
|
+
`${name}: "${name_of[scaled]}", above "${name_of[node[0]]}", is scaled by (${local.scale_x}, ${local.scale_y}, ${local.scale_z}) at rest;`
|
|
152
|
+
+ ` cloth poses its joints rigidly, so it would simulate a different garment from the one drawn`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const pose = cloth_bind_in_frame(prefab, frame_node);
|
|
157
|
+
|
|
158
|
+
const rest_position = new Float32Array(particle_count * 3);
|
|
159
|
+
const rest_rotation = new Float32Array(particle_count * 4);
|
|
160
|
+
|
|
161
|
+
for (let i = 0; i < particle_count; i++) {
|
|
162
|
+
const p = pose(node[i]);
|
|
163
|
+
|
|
164
|
+
rest_position[i * 3] = p[0];
|
|
165
|
+
rest_position[i * 3 + 1] = p[1];
|
|
166
|
+
rest_position[i * 3 + 2] = p[2];
|
|
167
|
+
|
|
168
|
+
rest_rotation[i * 4] = p[3];
|
|
169
|
+
rest_rotation[i * 4 + 1] = p[4];
|
|
170
|
+
rest_rotation[i * 4 + 2] = p[5];
|
|
171
|
+
rest_rotation[i * 4 + 3] = p[6];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Every edge once, keyed by its two particles, with the wing opposite it in
|
|
176
|
+
* each triangle that has it.
|
|
177
|
+
* @type {Map<number, {a: number, b: number, wings: number[]}>}
|
|
178
|
+
*/
|
|
179
|
+
const edges = new Map();
|
|
180
|
+
|
|
181
|
+
for (let t = 0; t < triangle_count; t++) {
|
|
182
|
+
const i0 = triangles[t * 3];
|
|
183
|
+
const i1 = triangles[t * 3 + 1];
|
|
184
|
+
const i2 = triangles[t * 3 + 2];
|
|
185
|
+
|
|
186
|
+
for (const index of [i0, i1, i2]) {
|
|
187
|
+
if (!(index >= 0 && index < particle_count)) {
|
|
188
|
+
return refuse(`${name}: triangle ${t} names particle ${index} of ${particle_count}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (tri3_area(
|
|
193
|
+
rest_position[i0 * 3], rest_position[i0 * 3 + 1], rest_position[i0 * 3 + 2],
|
|
194
|
+
rest_position[i1 * 3], rest_position[i1 * 3 + 1], rest_position[i1 * 3 + 2],
|
|
195
|
+
rest_position[i2 * 3], rest_position[i2 * 3 + 1], rest_position[i2 * 3 + 2]
|
|
196
|
+
) <= 0) {
|
|
197
|
+
return refuse(
|
|
198
|
+
`${name}: triangle ${t} ("${joint_names[i0]}", "${joint_names[i1]}", "${joint_names[i2]}") has no area,`
|
|
199
|
+
+ ` so no normal and no hinge across it`
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const corners = [i0, i1, i2];
|
|
204
|
+
|
|
205
|
+
for (let k = 0; k < 3; k++) {
|
|
206
|
+
const a = corners[k];
|
|
207
|
+
const b = corners[(k + 1) % 3];
|
|
208
|
+
const wing = corners[(k + 2) % 3];
|
|
209
|
+
|
|
210
|
+
const lo = a < b ? a : b;
|
|
211
|
+
const hi = a < b ? b : a;
|
|
212
|
+
|
|
213
|
+
const key = lo * particle_count + hi;
|
|
214
|
+
|
|
215
|
+
let edge = edges.get(key);
|
|
216
|
+
|
|
217
|
+
if (edge === undefined) {
|
|
218
|
+
edge = { a: lo, b: hi, wings: [] };
|
|
219
|
+
|
|
220
|
+
edges.set(key, edge);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
edge.wings.push(wing);
|
|
224
|
+
|
|
225
|
+
if (edge.wings.length > 2) {
|
|
226
|
+
return refuse(
|
|
227
|
+
`${name}: the edge "${joint_names[lo]}"–"${joint_names[hi]}" is shared by more than two triangles,`
|
|
228
|
+
+ ` so there is no one hinge across it`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const edge = [];
|
|
235
|
+
const hinge = [];
|
|
236
|
+
|
|
237
|
+
for (const { a, b, wings } of edges.values()) {
|
|
238
|
+
edge.push(a, b);
|
|
239
|
+
|
|
240
|
+
if (wings.length === 2) {
|
|
241
|
+
hinge.push(a, b, wings[0], wings[1]);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const particle_name = joint_names.slice();
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
proxy: ClothProxy.from({
|
|
249
|
+
name,
|
|
250
|
+
joint: Array.from(node, n => index_of.get(n)),
|
|
251
|
+
output: new Uint8Array(particle_count).fill(1),
|
|
252
|
+
// every joint hangs straight off the frame
|
|
253
|
+
parent: new Int32Array(particle_count).fill(-1),
|
|
254
|
+
edge,
|
|
255
|
+
skip: [],
|
|
256
|
+
hinge,
|
|
257
|
+
triangle: Int32Array.from(triangles),
|
|
258
|
+
frame: index_of.get(frame_node),
|
|
259
|
+
rest_position,
|
|
260
|
+
rest_rotation,
|
|
261
|
+
particle_name
|
|
262
|
+
}),
|
|
263
|
+
groups: [],
|
|
264
|
+
error: ""
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @param {string} error
|
|
270
|
+
* @returns {ClothProxyBuildResult}
|
|
271
|
+
* @private
|
|
272
|
+
*/
|
|
273
|
+
function refuse(error) {
|
|
274
|
+
return { proxy: null, groups: [], error };
|
|
275
|
+
}
|
|
@@ -164,6 +164,13 @@ export class ClothColliderIndex {
|
|
|
164
164
|
* ignores it, so a distance in the shape's local frame is a distance in
|
|
165
165
|
* world space.
|
|
166
166
|
*
|
|
167
|
+
* A pose equal to the one the record already holds is not refit: its
|
|
168
|
+
* bounds were fit to exactly this pair of poses when either last changed —
|
|
169
|
+
* here, in {@link placePose}, or in {@link advance} — so the refit would
|
|
170
|
+
* write what is there. That is what a collider that never moves costs, and
|
|
171
|
+
* why nothing has to say it will not: 1.43 µs per collider per step
|
|
172
|
+
* refitting, 0.42 µs skipping, of which {@link advance} is 0.32.
|
|
173
|
+
*
|
|
167
174
|
* @param {number} handle
|
|
168
175
|
* @param {number} tx
|
|
169
176
|
* @param {number} ty
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClothColliderIndex.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/collider/ClothColliderIndex.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ClothColliderIndex.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/collider/ClothColliderIndex.js"],"names":[],"mappings":"AAkDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH;IAEI;;;;;;OAMG;IACH,OAFU,YAAY,CAEM;IAE5B;;;;;OAKG;IACH,MAFU,UAAU,CAEK;IAEzB;;;;OAIG;IACH,OAFU,MAAM,CAEN;IAEV;;;;;;OAMG;IACH,eAFU,MAAM,CAEE;IAElB;;;;;;OAMG;IACH,qBAFU,MAAM,CAEQ;IAoFxB;;;;;;;;;;;OAWG;IACH,sCAPW,MAAM,aACN,MAAM,SACN,MAAM,QACN,MAAM,UACN,MAAM,GACJ,MAAM,CA8DlB;IAED;;;;;;;OAOG;IACH,eAHW,MAAM,GACJ,IAAI,CAkChB;IAED;;;;OAIG;IACH,eAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;OAGG;IACH,mBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;OAIG;IACH,WAFa,IAAI,CA4ChB;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gBAVW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,IAAI,CAqBhB;IAsLD;;;;;;;;;;;;;;;OAeG;IACH,kBAVW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,IAAI,CAqBhB;IAED;;;;;;;;OAQG;IACH,mBALW,MAAM,YACN,MAAM,aACN,MAAM,GACJ,IAAI,CAoBhB;IAED;;;;;OAKG;IACH,kBALW,MAAM,SACN,MAAM,QACN,MAAM,GACJ,IAAI,CAWhB;IAED;;;OAGG;IACH,iBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,WAdW,MAAM,EAAE,SACR,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,SACN,MAAM,QACN,MAAM,YACN,OAAO,GAGL,MAAM,CAWlB;IAED;;;;;;;;;;;OAWG;IACH,gBARW,MAAM,EAAE,OACR,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,cAClC,MAAM,SACN,MAAM,QACN,MAAM,WACN,OAAO,GACL,MAAM,CA6DlB;;CAyGJ"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { assert } from "../../../../core/assert.js";
|
|
2
2
|
import { BVH, NULL_NODE } from "../../../../core/bvh2/bvh3/BVH.js";
|
|
3
|
+
import { number_compare_ascending } from "../../../../core/primitives/numbers/number_compare_ascending.js";
|
|
3
4
|
import {
|
|
4
5
|
bvh_query_user_data_intersects_aabb
|
|
5
6
|
} from "../../../../core/bvh2/bvh3/query/bvh_query_user_data_intersects_aabb.js";
|
|
7
|
+
import { array_copy } from "../../../../core/collection/array/array_copy.js";
|
|
8
|
+
import { array_range_equal_strict } from "../../../../core/collection/array/array_range_equal_strict.js";
|
|
9
|
+
import { array_remove_first } from "../../../../core/collection/array/array_remove_first.js";
|
|
10
|
+
import { array_sort_insertion_ascending } from "../../../../core/collection/array/array_sort_insertion_ascending.js";
|
|
11
|
+
import { aabb3_array_round_outward_f32 } from "../../../../core/geom/3d/aabb/aabb3_array_round_outward_f32.js";
|
|
12
|
+
import { FAT_LINEAR } from "../../broadphase/compute_fat_world_aabb.js";
|
|
6
13
|
import {
|
|
7
14
|
CCR_AABB_MAX_X,
|
|
8
15
|
CCR_AABB_MAX_Y,
|
|
@@ -341,11 +348,9 @@ export class ClothColliderIndex {
|
|
|
341
348
|
const node = this.#node[handle];
|
|
342
349
|
|
|
343
350
|
if (node === NULL_NODE) {
|
|
344
|
-
const
|
|
351
|
+
const planes = this.#planes;
|
|
345
352
|
|
|
346
|
-
|
|
347
|
-
this.#planes.splice(at, 1);
|
|
348
|
-
}
|
|
353
|
+
array_remove_first(planes, handle, 0, planes.length);
|
|
349
354
|
} else {
|
|
350
355
|
this.#bvh.remove_leaf(node);
|
|
351
356
|
this.#bvh.release_node(node);
|
|
@@ -419,22 +424,11 @@ export class ClothColliderIndex {
|
|
|
419
424
|
this.max_inflation = table[r + CCR_INFLATION];
|
|
420
425
|
}
|
|
421
426
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|| table[r + CCR_PREV_QX] !== table[r + CCR_QX]
|
|
426
|
-
|| table[r + CCR_PREV_QY] !== table[r + CCR_QY]
|
|
427
|
-
|| table[r + CCR_PREV_QZ] !== table[r + CCR_QZ]
|
|
428
|
-
|| table[r + CCR_PREV_QW] !== table[r + CCR_QW];
|
|
429
|
-
|
|
430
|
-
table[r + CCR_PREV_TX] = table[r + CCR_TX];
|
|
431
|
-
table[r + CCR_PREV_TY] = table[r + CCR_TY];
|
|
432
|
-
table[r + CCR_PREV_TZ] = table[r + CCR_TZ];
|
|
427
|
+
// A pose is seven contiguous slots, translation then rotation, in
|
|
428
|
+
// both the current and the previous half of the record.
|
|
429
|
+
const moved = !array_range_equal_strict(table, r + CCR_PREV_TX, table, r + CCR_TX, POSE_SLOTS);
|
|
433
430
|
|
|
434
|
-
table
|
|
435
|
-
table[r + CCR_PREV_QY] = table[r + CCR_QY];
|
|
436
|
-
table[r + CCR_PREV_QZ] = table[r + CCR_QZ];
|
|
437
|
-
table[r + CCR_PREV_QW] = table[r + CCR_QW];
|
|
431
|
+
array_copy(table, r + CCR_TX, table, r + CCR_PREV_TX, POSE_SLOTS);
|
|
438
432
|
|
|
439
433
|
if (moved) {
|
|
440
434
|
cloth_collider_refit_bounds(table, handle, CCR_STRIDE);
|
|
@@ -451,6 +445,13 @@ export class ClothColliderIndex {
|
|
|
451
445
|
* ignores it, so a distance in the shape's local frame is a distance in
|
|
452
446
|
* world space.
|
|
453
447
|
*
|
|
448
|
+
* A pose equal to the one the record already holds is not refit: its
|
|
449
|
+
* bounds were fit to exactly this pair of poses when either last changed —
|
|
450
|
+
* here, in {@link placePose}, or in {@link advance} — so the refit would
|
|
451
|
+
* write what is there. That is what a collider that never moves costs, and
|
|
452
|
+
* why nothing has to say it will not: 1.43 µs per collider per step
|
|
453
|
+
* refitting, 0.42 µs skipping, of which {@link advance} is 0.32.
|
|
454
|
+
*
|
|
454
455
|
* @param {number} handle
|
|
455
456
|
* @param {number} tx
|
|
456
457
|
* @param {number} ty
|
|
@@ -471,6 +472,35 @@ export class ClothColliderIndex {
|
|
|
471
472
|
|
|
472
473
|
const r = handle * CCR_STRIDE;
|
|
473
474
|
|
|
475
|
+
if (table[r + CCR_TX] === tx && table[r + CCR_TY] === ty && table[r + CCR_TZ] === tz
|
|
476
|
+
&& table[r + CCR_QX] === qx && table[r + CCR_QY] === qy
|
|
477
|
+
&& table[r + CCR_QZ] === qz && table[r + CCR_QW] === qw
|
|
478
|
+
// no leaf — never posed, or a plane, which is never in the tree — refits regardless
|
|
479
|
+
&& this.#node[handle] !== NULL_NODE) {
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
this.#pose(handle, tx, ty, tz, qx, qy, qz, qw);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Write the current pose and refit, unconditionally.
|
|
488
|
+
*
|
|
489
|
+
* @param {number} handle
|
|
490
|
+
* @param {number} tx
|
|
491
|
+
* @param {number} ty
|
|
492
|
+
* @param {number} tz
|
|
493
|
+
* @param {number} qx
|
|
494
|
+
* @param {number} qy
|
|
495
|
+
* @param {number} qz
|
|
496
|
+
* @param {number} qw
|
|
497
|
+
* @private
|
|
498
|
+
*/
|
|
499
|
+
#pose(handle, tx, ty, tz, qx, qy, qz, qw) {
|
|
500
|
+
const table = this.table;
|
|
501
|
+
|
|
502
|
+
const r = handle * CCR_STRIDE;
|
|
503
|
+
|
|
474
504
|
if (table[r + CCR_TX] !== tx || table[r + CCR_TY] !== ty || table[r + CCR_TZ] !== tz
|
|
475
505
|
|| table[r + CCR_QX] !== qx || table[r + CCR_QY] !== qy
|
|
476
506
|
|| table[r + CCR_QZ] !== qz || table[r + CCR_QW] !== qw) {
|
|
@@ -561,9 +591,15 @@ export class ClothColliderIndex {
|
|
|
561
591
|
if (lower < STORED_AABB[axis] || upper > STORED_AABB[axis + 3]) contained = false;
|
|
562
592
|
// A one-step outlier must not leave a scene-sized leaf behind once
|
|
563
593
|
// motion stops. Allow ordinary jitter to keep spending the slack.
|
|
594
|
+
// The yardstick is twice what a store would write now: the slack
|
|
595
|
+
// on both sides plus the outward rounding, which grows each side by
|
|
596
|
+
// under one float32 step of its magnitude. Without that term a leaf
|
|
597
|
+
// far enough out that a step outgrows the slack — past about four
|
|
598
|
+
// hundred kilometres — would read as oversized straight after being
|
|
599
|
+
// stored, and be re-homed every step.
|
|
564
600
|
if (STORED_AABB[axis + 3] - STORED_AABB[axis]
|
|
565
|
-
> 2 * (upper - lower + 2 *
|
|
566
|
-
+ (Math.abs(lower) + Math.abs(upper)) *
|
|
601
|
+
> 2 * (upper - lower + 2 * FAT_LINEAR
|
|
602
|
+
+ (Math.abs(lower) + Math.abs(upper) + 2 * FAT_LINEAR) * FLOAT32_STEP)) oversized = true;
|
|
567
603
|
}
|
|
568
604
|
|
|
569
605
|
if (contained && !oversized) {
|
|
@@ -589,18 +625,18 @@ export class ClothColliderIndex {
|
|
|
589
625
|
* Write a record's swept bounds plus its contact reach into {@link FAT_AABB}
|
|
590
626
|
* with the slack the refit skip spends, and store them on the leaf.
|
|
591
627
|
*
|
|
592
|
-
* The slack
|
|
593
|
-
* `Float64` world
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
* past
|
|
599
|
-
*
|
|
600
|
-
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
628
|
+
* The slack covers jitter; it does not cover the tree's `Float32` nodes
|
|
629
|
+
* holding a `Float64` world. {@link BVH#node_set_aabb} rounds each bound to
|
|
630
|
+
* the nearest `Float32`, and `Float32`'s step is a *proportion* of the
|
|
631
|
+
* magnitude — a millimetre at ten kilometres out, but **a whole metre at
|
|
632
|
+
* ten thousand**, which is well past any constant: measured, a leaf there
|
|
633
|
+
* fattened by 5 cm came back 45 cm inside its own record. A bound that
|
|
634
|
+
* rounds inward past its slack is a leaf smaller than the record it stands
|
|
635
|
+
* for, and that is a collider the tree stops answering with — silently,
|
|
636
|
+
* and only far from the origin, which is the worst shape a bug can have.
|
|
637
|
+
* So the fattened box is rounded outward to `Float32` before it is stored,
|
|
638
|
+
* which makes the store exact at every scale and leaves the constant to do
|
|
639
|
+
* only its own job.
|
|
604
640
|
*
|
|
605
641
|
* The exact test in {@link query} reads the `Float64` record, so the tree
|
|
606
642
|
* only ever has to avoid a false **negative**; being generous here costs a
|
|
@@ -618,10 +654,12 @@ export class ClothColliderIndex {
|
|
|
618
654
|
const lower = table[r + CCR_AABB_MIN_X + axis] - reach;
|
|
619
655
|
const upper = table[r + CCR_AABB_MAX_X + axis] + reach;
|
|
620
656
|
|
|
621
|
-
FAT_AABB[axis] = lower -
|
|
622
|
-
FAT_AABB[axis + 3] = upper +
|
|
657
|
+
FAT_AABB[axis] = lower - FAT_LINEAR;
|
|
658
|
+
FAT_AABB[axis + 3] = upper + FAT_LINEAR;
|
|
623
659
|
}
|
|
624
660
|
|
|
661
|
+
aabb3_array_round_outward_f32(FAT_AABB, 0, FAT_AABB, 0);
|
|
662
|
+
|
|
625
663
|
this.#bvh.node_set_aabb(node, FAT_AABB);
|
|
626
664
|
}
|
|
627
665
|
|
|
@@ -657,7 +695,9 @@ export class ClothColliderIndex {
|
|
|
657
695
|
this.table[r + CCR_PREV_QZ] = qz;
|
|
658
696
|
this.table[r + CCR_PREV_QW] = qw;
|
|
659
697
|
|
|
660
|
-
|
|
698
|
+
// Not {@link setPose}: the previous pose has just changed, so the
|
|
699
|
+
// bounds are stale even when the current one has not.
|
|
700
|
+
this.#pose(handle, tx, ty, tz, qx, qy, qz, qw);
|
|
661
701
|
}
|
|
662
702
|
|
|
663
703
|
/**
|
|
@@ -926,21 +966,19 @@ export class ClothColliderIndex {
|
|
|
926
966
|
}
|
|
927
967
|
|
|
928
968
|
/**
|
|
929
|
-
*
|
|
930
|
-
*
|
|
931
|
-
*
|
|
969
|
+
* One `Float32` step as a proportion of a value's magnitude, an upper bound
|
|
970
|
+
* for every normal `Float32`: 23 fraction bits, so a step is at most `2^-23`
|
|
971
|
+
* of the magnitude. The most an outward rounding can widen a bound by.
|
|
932
972
|
* @type {number}
|
|
933
973
|
*/
|
|
934
|
-
const
|
|
974
|
+
const FLOAT32_STEP = 2 ** -23;
|
|
935
975
|
|
|
936
976
|
/**
|
|
937
|
-
*
|
|
938
|
-
*
|
|
939
|
-
* rounding does. `Float32` carries 23 fraction bits, so one ulp is `2^-23` of
|
|
940
|
-
* the magnitude and two is the first multiple that is unconditionally outside.
|
|
977
|
+
* Slots in one pose, `[tx, ty, tz, qx, qy, qz, qw]`: {@link CCR_TX} to {@link CCR_QW}, and the same
|
|
978
|
+
* from {@link CCR_PREV_TX}.
|
|
941
979
|
* @type {number}
|
|
942
980
|
*/
|
|
943
|
-
const
|
|
981
|
+
const POSE_SLOTS = 7;
|
|
944
982
|
|
|
945
983
|
/**
|
|
946
984
|
* The box being queried, `[min_x, min_y, min_z, max_x, max_y, max_z]`: what the tree is walked with
|
|
@@ -972,23 +1010,12 @@ function sort_handles(handles) {
|
|
|
972
1010
|
const n = handles.length;
|
|
973
1011
|
|
|
974
1012
|
if (n > INSERTION_SORT_LIMIT) {
|
|
975
|
-
handles.sort(
|
|
1013
|
+
handles.sort(number_compare_ascending);
|
|
976
1014
|
|
|
977
1015
|
return;
|
|
978
1016
|
}
|
|
979
1017
|
|
|
980
|
-
|
|
981
|
-
const handle = handles[i];
|
|
982
|
-
|
|
983
|
-
let j = i - 1;
|
|
984
|
-
|
|
985
|
-
while (j >= 0 && handles[j] > handle) {
|
|
986
|
-
handles[j + 1] = handles[j];
|
|
987
|
-
j--;
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
handles[j + 1] = handle;
|
|
991
|
-
}
|
|
1018
|
+
array_sort_insertion_ascending(handles, 0, n);
|
|
992
1019
|
}
|
|
993
1020
|
|
|
994
1021
|
/**
|
|
@@ -1002,12 +1029,3 @@ const FAT_AABB = new Float64Array(6);
|
|
|
1002
1029
|
* @type {Float32Array}
|
|
1003
1030
|
*/
|
|
1004
1031
|
const STORED_AABB = new Float32Array(6);
|
|
1005
|
-
|
|
1006
|
-
/**
|
|
1007
|
-
* @param {number} a
|
|
1008
|
-
* @param {number} b
|
|
1009
|
-
* @returns {number}
|
|
1010
|
-
*/
|
|
1011
|
-
function ASCENDING(a, b) {
|
|
1012
|
-
return a - b;
|
|
1013
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloth_collider_bounds.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/collider/cloth_collider_bounds.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloth_collider_bounds.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/collider/cloth_collider_bounds.js"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,oDAJW,MAAM,eACN,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,mDALW,YAAY,GAAC,YAAY,UACzB,MAAM,UACN,MAAM,GACJ,IAAI,CA2BhB"}
|