@woosh/meep-engine 3.43.0 → 3.44.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/editor/prototypeEditorShell.d.ts.map +1 -1
- package/editor/prototypeEditorShell.js +4 -2
- package/package.json +1 -1
- 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/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/graphics3/AnimationGraphSystem.d.ts +23 -13
- package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationGraphSystem.js +61 -64
- package/src/engine/graphics3/AnimationSystem.d.ts +24 -15
- package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationSystem.js +67 -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 +64 -0
- package/src/engine/graphics3/register_clips.d.ts.map +1 -0
- package/src/engine/graphics3/register_clips.js +114 -0
- package/src/engine/physics/cloth/MEASUREMENTS.md +795 -0
- package/src/engine/physics/cloth/PLAN.md +339 -9
- 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 +22 -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 +75 -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 +357 -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 +280 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +1 -1
- 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/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 +816 -179
- 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 +321 -84
- 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 +9 -7
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +3 -3
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +30 -30
- 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 +142 -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 +608 -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 +160 -9
- 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 +44 -15
- 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 +60 -16
- 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/collide_main.js +1 -1
- 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 +1 -1
- 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/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 +63 -7
- 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 +7 -2
- 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 +362 -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 +13 -13
- 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 +183 -20
- 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 +10 -3
- 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/cloth_sample_air.d.ts +9 -9
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/cloth_sample_air.js +26 -26
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- 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/shade/RENDERER_CONTRACT.md +8 -2
- package/src/shade/playground/mesh_row_ceiling/main.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/texture_encode/README.md +129 -109
- package/src/shade/playground/texture_encode/main.js +1430 -1430
- 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/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/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/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
|
@@ -2,6 +2,8 @@ import { ClothState } from "../solver/ClothState.js";
|
|
|
2
2
|
import { ClothDynamicsFlags } from "./ClothDynamicsFlags.js";
|
|
3
3
|
import { cloth_self_closest_free_pair, cloth_self_exclusions } from "../solver/cloth_self_find.js";
|
|
4
4
|
import { cloth_bend_ratio, cloth_strain_allowance } from "./cloth_dynamics_map.js";
|
|
5
|
+
import { cloth_edge_incidence } from "./cloth_geodesic.js";
|
|
6
|
+
import { cloth_bend_stencil_weights } from "../solver/constraint/cloth_bend_row.js";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* # The rows, and everything that is a number rather than a walk
|
|
@@ -12,12 +14,19 @@ import { cloth_bend_ratio, cloth_strain_allowance } from "./cloth_dynamics_map.j
|
|
|
12
14
|
* proxy's baked joint list — and what they do identically is everything after
|
|
13
15
|
* that, because a row does not care what a node was made of.
|
|
14
16
|
*
|
|
15
|
-
* So the split is: a seeder produces
|
|
16
|
-
* {@link
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* So the split is: a seeder produces the particles' rest pose and the **graph**
|
|
18
|
+
* joining them — {@link ClothInstance#edge}, {@link ClothInstance#skip},
|
|
19
|
+
* {@link ClothInstance#hinge} — and {@link cloth_build_rows} turns those into
|
|
20
|
+
* geodesics, fabric rows, strain-limit rows, bending rows, leashes and the
|
|
21
|
+
* `ClothState` itself. M3 moved this out of `cloth_seed_subtree.js` unchanged
|
|
22
|
+
* rather than writing a second copy for the rig path, which is the whole reason
|
|
23
|
+
* §11 could say "the solver is identical either way; only seeding and
|
|
24
|
+
* write-back differ" and mean it.
|
|
25
|
+
*
|
|
26
|
+
* The rows are built from a graph rather than from a parent array because a row
|
|
27
|
+
* is a pair or a quad and has no use for a parent. A tree hands over its parent
|
|
28
|
+
* links and its skip pairs ({@link cloth_tree_graph}); a mesh would hand over
|
|
29
|
+
* its edges and hinges; the rows below are the same code either way.
|
|
21
30
|
*
|
|
22
31
|
* @author Alex Goldring
|
|
23
32
|
* @copyright Company Named Limited (c) 2026
|
|
@@ -36,9 +45,10 @@ export const CLOTH_PARTICLE_MASS = 0.02;
|
|
|
36
45
|
* Slack radius at `ClothDynamics#slack = 1`, as a multiple of `d_geo`.
|
|
37
46
|
*
|
|
38
47
|
* It is **2**, and that is a derivation rather than a taste. The tether row
|
|
39
|
-
* already holds every particle within `d_geo` of the
|
|
40
|
-
* position it is leashed to is itself within `d_geo` of
|
|
41
|
-
* never longer than the arc it subtends
|
|
48
|
+
* already holds every particle within `d_geo` of the held particle it hangs
|
|
49
|
+
* from, and the animated position it is leashed to is itself within `d_geo` of
|
|
50
|
+
* that particle — a chord is never longer than the arc it subtends, and the
|
|
51
|
+
* animated pose is the rest pose hung from it (`ClothInstance#animated_position`). By the triangle inequality the two can
|
|
42
52
|
* therefore never be more than `2·d_geo` apart, so a slack radius of `2·d_geo`
|
|
43
53
|
* is **provably inactive** and `slack = 1` means exactly "no leash" with no
|
|
44
54
|
* sentinel value and no discontinuity to code around.
|
|
@@ -64,30 +74,189 @@ export function cloth_build_children(instance) {
|
|
|
64
74
|
|
|
65
75
|
const offset = new Int32Array(node_count + 1);
|
|
66
76
|
|
|
67
|
-
for (let node =
|
|
68
|
-
|
|
77
|
+
for (let node = 0; node < node_count; node++) {
|
|
78
|
+
if (parent[node] >= 0) {
|
|
79
|
+
offset[parent[node] + 1]++;
|
|
80
|
+
}
|
|
69
81
|
}
|
|
70
82
|
|
|
71
83
|
for (let node = 0; node < node_count; node++) {
|
|
72
84
|
offset[node + 1] += offset[node];
|
|
73
85
|
}
|
|
74
86
|
|
|
75
|
-
const child = new Int32Array(node_count
|
|
87
|
+
const child = new Int32Array(offset[node_count]);
|
|
76
88
|
const cursor = offset.slice(0, node_count);
|
|
77
89
|
|
|
78
|
-
for (let node =
|
|
79
|
-
|
|
90
|
+
for (let node = 0; node < node_count; node++) {
|
|
91
|
+
if (parent[node] >= 0) {
|
|
92
|
+
child[cursor[parent[node]]++] = node;
|
|
93
|
+
}
|
|
80
94
|
}
|
|
81
95
|
|
|
82
96
|
instance.node_child_offset = offset;
|
|
83
97
|
instance.node_child = child;
|
|
84
98
|
}
|
|
85
99
|
|
|
100
|
+
/**
|
|
101
|
+
* The particle graph of a tree: a fabric edge from every node to its parent,
|
|
102
|
+
* and a skip pair from every node to its grandparent.
|
|
103
|
+
*
|
|
104
|
+
* The skip pair is a chain's bending model (`cloth_seed_subtree.js` carries the
|
|
105
|
+
* argument), and it is part of the graph rather than something the row builder
|
|
106
|
+
* derives from a parent array, so that the row builder never needs one.
|
|
107
|
+
*
|
|
108
|
+
* @param {ClothInstance} instance with {@link ClothInstance#node_parent} set
|
|
109
|
+
* @returns {void}
|
|
110
|
+
*/
|
|
111
|
+
export function cloth_tree_graph(instance) {
|
|
112
|
+
const node_count = instance.node_count;
|
|
113
|
+
const parent = instance.node_parent;
|
|
114
|
+
|
|
115
|
+
const edge = [];
|
|
116
|
+
const skip = [];
|
|
117
|
+
|
|
118
|
+
for (let node = 0; node < node_count; node++) {
|
|
119
|
+
const p = parent[node];
|
|
120
|
+
|
|
121
|
+
if (p < 0) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
edge.push(p, node);
|
|
126
|
+
|
|
127
|
+
const grandparent = parent[p];
|
|
128
|
+
|
|
129
|
+
if (grandparent >= 0) {
|
|
130
|
+
skip.push(grandparent, node);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
instance.edge = Int32Array.from(edge);
|
|
135
|
+
instance.skip = Int32Array.from(skip);
|
|
136
|
+
instance.hinge = new Int32Array(0);
|
|
137
|
+
instance.triangle = new Int32Array(0);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The triangles around each node, CSR, and one neighbour per node to measure a
|
|
142
|
+
* tangent by — what `cloth_reconstruct_pose` turns a sheet's joints with. A
|
|
143
|
+
* cloth with no triangles gets none.
|
|
144
|
+
*
|
|
145
|
+
* @param {ClothInstance} instance with {@link ClothInstance#triangle} and
|
|
146
|
+
* {@link ClothInstance#edge} set
|
|
147
|
+
* @returns {void}
|
|
148
|
+
*/
|
|
149
|
+
export function cloth_build_surface(instance) {
|
|
150
|
+
const node_count = instance.node_count;
|
|
151
|
+
const triangle = instance.triangle;
|
|
152
|
+
|
|
153
|
+
const triangle_count = triangle.length / 3;
|
|
154
|
+
|
|
155
|
+
if (triangle_count === 0) {
|
|
156
|
+
instance.surface_offset = null;
|
|
157
|
+
instance.surface_triangle = null;
|
|
158
|
+
instance.surface_neighbour = null;
|
|
159
|
+
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const offset = new Int32Array(node_count + 1);
|
|
164
|
+
|
|
165
|
+
for (let i = 0; i < triangle_count * 3; i++) {
|
|
166
|
+
offset[triangle[i] + 1]++;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
for (let node = 0; node < node_count; node++) {
|
|
170
|
+
offset[node + 1] += offset[node];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const surface = new Int32Array(triangle_count * 3);
|
|
174
|
+
const cursor = offset.slice(0, node_count);
|
|
175
|
+
|
|
176
|
+
for (let t = 0; t < triangle_count; t++) {
|
|
177
|
+
for (let k = 0; k < 3; k++) {
|
|
178
|
+
const node = triangle[t * 3 + k];
|
|
179
|
+
|
|
180
|
+
surface[cursor[node]++] = t;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// the first edge each node has: fixed for the life of the seed, which is all
|
|
185
|
+
// a reference direction has to be
|
|
186
|
+
const neighbour = new Int32Array(node_count).fill(-1);
|
|
187
|
+
|
|
188
|
+
const edge = instance.edge;
|
|
189
|
+
|
|
190
|
+
for (let e = 0; e < edge.length; e += 2) {
|
|
191
|
+
const a = edge[e];
|
|
192
|
+
const b = edge[e + 1];
|
|
193
|
+
|
|
194
|
+
if (neighbour[a] === -1) {
|
|
195
|
+
neighbour[a] = b;
|
|
196
|
+
}
|
|
86
197
|
|
|
198
|
+
if (neighbour[b] === -1) {
|
|
199
|
+
neighbour[b] = a;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
instance.surface_offset = offset;
|
|
204
|
+
instance.surface_triangle = surface;
|
|
205
|
+
instance.surface_neighbour = neighbour;
|
|
206
|
+
}
|
|
87
207
|
|
|
88
208
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
209
|
+
* How much a hinge resists, as a stiffness, for a fabric's `bend` ratio.
|
|
210
|
+
*
|
|
211
|
+
* The same rule the skip row follows: a ratio of the row's own effective
|
|
212
|
+
* inertia over the fixed step squared. A hinge's gradient on particle `k` is
|
|
213
|
+
* `w_k` along each axis, so its effective inertia is `1 / Σ (w_k² / m_k)` —
|
|
214
|
+
* `m / Σ w_k²` with one mass — and a hinge across a sliver, whose cotangents are
|
|
215
|
+
* large, is softer per unit `C` for exactly the reason its `C` is larger. A
|
|
216
|
+
* stiffness in newtons per metre, which is what Bergou's `6·modulus/A` is,
|
|
217
|
+
* would leave M0's dissipative band wherever the triangles are thin.
|
|
218
|
+
*
|
|
219
|
+
* @param {Float32Array} weight 4 per hinge
|
|
220
|
+
* @param {number} hinge
|
|
221
|
+
* @returns {number} the hinge's effective inertia, kg
|
|
222
|
+
*/
|
|
223
|
+
export function cloth_hinge_inertia(weight, hinge) {
|
|
224
|
+
let sum = 0;
|
|
225
|
+
|
|
226
|
+
for (let k = 0; k < 4; k++) {
|
|
227
|
+
const w = weight[hinge * 4 + k];
|
|
228
|
+
|
|
229
|
+
sum += w * w;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return sum > 0 ? CLOTH_PARTICLE_MASS / sum : 0;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Distance between two nodes of the rest pose.
|
|
237
|
+
* @param {Float32Array} rest
|
|
238
|
+
* @param {number} a
|
|
239
|
+
* @param {number} b
|
|
240
|
+
* @returns {number}
|
|
241
|
+
* @private
|
|
242
|
+
*/
|
|
243
|
+
function rest_distance(rest, a, b) {
|
|
244
|
+
return Math.hypot(
|
|
245
|
+
rest[b * 3] - rest[a * 3],
|
|
246
|
+
rest[b * 3 + 1] - rest[a * 3 + 1],
|
|
247
|
+
rest[b * 3 + 2] - rest[a * 3 + 2]
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Rows and the `ClothState` itself, from a seeded rest pose and the graph over
|
|
253
|
+
* it.
|
|
254
|
+
*
|
|
255
|
+
* **Nothing is held here.** Every particle is built free, with a tether row and
|
|
256
|
+
* — when the fabric is leashed at all — a slack row of radius `Infinity`, which
|
|
257
|
+
* say nothing until `cloth_apply_holds` points them at what the particle hangs
|
|
258
|
+
* from. The shape of the leash table is fixed by the particle count, so holding
|
|
259
|
+
* and letting go rewrite numbers in it rather than building it again.
|
|
91
260
|
*
|
|
92
261
|
* @param {ClothInstance} instance
|
|
93
262
|
* @param {number} dt
|
|
@@ -96,22 +265,22 @@ export function cloth_build_children(instance) {
|
|
|
96
265
|
export function cloth_build_rows(instance, dt) {
|
|
97
266
|
const node_count = instance.node_count;
|
|
98
267
|
|
|
99
|
-
const
|
|
100
|
-
const rest = instance.animated_position;
|
|
268
|
+
const rest = instance.rest_position;
|
|
101
269
|
|
|
102
|
-
const
|
|
270
|
+
const edge = instance.edge;
|
|
271
|
+
const skip = instance.skip;
|
|
272
|
+
const hinge = instance.hinge;
|
|
103
273
|
|
|
104
|
-
const
|
|
274
|
+
const edge_count = edge.length >> 1;
|
|
275
|
+
const skip_count = skip.length >> 1;
|
|
276
|
+
const hinge_count = hinge.length >> 2;
|
|
105
277
|
|
|
106
|
-
const
|
|
278
|
+
const dynamics = instance.cloth.dynamics;
|
|
107
279
|
|
|
108
|
-
const
|
|
280
|
+
const strain_limited = (dynamics.flags & ClothDynamicsFlags.StrainLimit) !== 0;
|
|
109
281
|
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
for (let node = 1; node < node_count; node++) {
|
|
113
|
-
mass_inverse[node] = 1 / CLOTH_PARTICLE_MASS;
|
|
114
|
-
}
|
|
282
|
+
// Free, every one: what is held is the holds' business.
|
|
283
|
+
const mass_inverse = new Float32Array(node_count).fill(1 / CLOTH_PARTICLE_MASS);
|
|
115
284
|
|
|
116
285
|
const stretch_particle = [];
|
|
117
286
|
const stretch_rest = [];
|
|
@@ -119,47 +288,35 @@ export function cloth_build_rows(instance, dt) {
|
|
|
119
288
|
const stretch_force_min = [];
|
|
120
289
|
const stretch_force_max = [];
|
|
121
290
|
|
|
122
|
-
const
|
|
123
|
-
const strain_row = new Int32Array(node_count).fill(-1);
|
|
124
|
-
const skip_row = new Int32Array(node_count).fill(-1);
|
|
125
|
-
|
|
126
|
-
const strain = cloth_strain_allowance(dynamics.stretch);
|
|
127
|
-
|
|
128
|
-
// A skip row spans two links and both of its ends are free, so its
|
|
129
|
-
// effective inertia along the constraint is half a particle's.
|
|
130
|
-
const bend_stiffness = cloth_bend_ratio(dynamics.bend)
|
|
131
|
-
* (CLOTH_PARTICLE_MASS * 0.5) / (dt * dt);
|
|
291
|
+
const edge_length = new Float64Array(edge_count);
|
|
132
292
|
|
|
133
|
-
|
|
293
|
+
const edge_row = new Int32Array(edge_count).fill(-1);
|
|
294
|
+
const strain_row = new Int32Array(edge_count).fill(-1);
|
|
295
|
+
const skip_row = new Int32Array(skip_count).fill(-1);
|
|
134
296
|
|
|
135
|
-
|
|
136
|
-
const p = parent[node];
|
|
297
|
+
const strain = cloth_strain_allowance(dynamics.stretch);
|
|
137
298
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
rest[node * 3 + 2] - rest[p * 3 + 2]
|
|
142
|
-
);
|
|
299
|
+
for (let e = 0; e < edge_count; e++) {
|
|
300
|
+
const a = edge[e * 2];
|
|
301
|
+
const b = edge[e * 2 + 1];
|
|
143
302
|
|
|
144
|
-
|
|
303
|
+
const length = rest_distance(rest, a, b);
|
|
145
304
|
|
|
146
|
-
|
|
147
|
-
reach = geodesic[node];
|
|
148
|
-
}
|
|
305
|
+
edge_length[e] = length;
|
|
149
306
|
|
|
150
|
-
|
|
307
|
+
edge_row[e] = stretch_rest.length;
|
|
151
308
|
|
|
152
309
|
// Hard, bilateral: the fabric row. It is hard because a *penalty* stiff
|
|
153
310
|
// enough to be fabric adds energy rather than dissipating it — see
|
|
154
311
|
// `cloth_dynamics_map.js`, and `MEASUREMENTS.md` §6 for the +6.8 J.
|
|
155
|
-
stretch_particle.push(
|
|
312
|
+
stretch_particle.push(a, b);
|
|
156
313
|
stretch_rest.push(length);
|
|
157
314
|
stretch_stiffness.push(Infinity);
|
|
158
315
|
stretch_force_min.push(-Infinity);
|
|
159
316
|
stretch_force_max.push(Infinity);
|
|
160
317
|
|
|
161
318
|
if (strain_limited) {
|
|
162
|
-
strain_row[
|
|
319
|
+
strain_row[e] = stretch_rest.length;
|
|
163
320
|
|
|
164
321
|
// Hard, one-sided: §6's strain limit, and note the clamp. A row
|
|
165
322
|
// that bounds a distance from ABOVE may only apply force that
|
|
@@ -167,56 +324,89 @@ export function cloth_build_rows(instance, dt) {
|
|
|
167
324
|
// `[0, +∞)`. §6's table has this row at `(−∞, 0]`, which is the
|
|
168
325
|
// force that pushes the two ends apart; `cloth_leash_row.js`
|
|
169
326
|
// carries the derivation and a spec that shows it directly.
|
|
170
|
-
stretch_particle.push(
|
|
327
|
+
stretch_particle.push(a, b);
|
|
171
328
|
stretch_rest.push(length * (1 + strain));
|
|
172
329
|
stretch_stiffness.push(Infinity);
|
|
173
330
|
stretch_force_min.push(0);
|
|
174
331
|
stretch_force_max.push(Infinity);
|
|
175
332
|
}
|
|
333
|
+
}
|
|
176
334
|
|
|
177
|
-
|
|
335
|
+
// A skip row spans two links and both of its ends are free, so its
|
|
336
|
+
// effective inertia along the constraint is half a particle's.
|
|
337
|
+
const bend_stiffness = cloth_bend_ratio(dynamics.bend)
|
|
338
|
+
* (CLOTH_PARTICLE_MASS * 0.5) / (dt * dt);
|
|
178
339
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
rest[node * 3 + 2] - rest[grandparent * 3 + 2]
|
|
184
|
-
);
|
|
340
|
+
if (bend_stiffness > 0) {
|
|
341
|
+
for (let s = 0; s < skip_count; s++) {
|
|
342
|
+
const a = skip[s * 2];
|
|
343
|
+
const b = skip[s * 2 + 1];
|
|
185
344
|
|
|
186
|
-
skip_row[
|
|
345
|
+
skip_row[s] = stretch_rest.length;
|
|
187
346
|
|
|
188
347
|
// Soft, bilateral: the bending model. Its rest length is read from
|
|
189
348
|
// the authored pose, so a chain authored with a curve holds it.
|
|
190
|
-
stretch_particle.push(
|
|
191
|
-
stretch_rest.push(
|
|
349
|
+
stretch_particle.push(a, b);
|
|
350
|
+
stretch_rest.push(rest_distance(rest, a, b));
|
|
192
351
|
stretch_stiffness.push(bend_stiffness);
|
|
193
352
|
stretch_force_min.push(-Infinity);
|
|
194
353
|
stretch_force_max.push(Infinity);
|
|
195
354
|
}
|
|
196
355
|
}
|
|
197
356
|
|
|
357
|
+
// A surface bends through its hinges: §6's quadratic stencil, its weights
|
|
358
|
+
// read from the rest pose, its stiffness a ratio of its own inertia.
|
|
359
|
+
const bend_ratio = cloth_bend_ratio(dynamics.bend);
|
|
360
|
+
|
|
361
|
+
const hinge_built = bend_ratio > 0 ? hinge_count : 0;
|
|
362
|
+
|
|
363
|
+
const bend_weight = new Float32Array(hinge_built * 4);
|
|
364
|
+
const hinge_stiffness = new Float32Array(hinge_built);
|
|
365
|
+
const hinge_inertia = new Float32Array(hinge_built);
|
|
366
|
+
|
|
367
|
+
for (let h = 0; h < hinge_built; h++) {
|
|
368
|
+
cloth_bend_stencil_weights(
|
|
369
|
+
bend_weight, h * 4, rest,
|
|
370
|
+
hinge[h * 4], hinge[h * 4 + 1], hinge[h * 4 + 2], hinge[h * 4 + 3]
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
hinge_inertia[h] = cloth_hinge_inertia(bend_weight, h);
|
|
374
|
+
hinge_stiffness[h] = bend_ratio * hinge_inertia[h] / (dt * dt);
|
|
375
|
+
}
|
|
376
|
+
|
|
198
377
|
const leash_particle = [];
|
|
199
378
|
const leash_radius = [];
|
|
200
379
|
|
|
201
380
|
const slack_row = new Int32Array(node_count).fill(-1);
|
|
202
381
|
const tether_row = new Int32Array(node_count).fill(-1);
|
|
203
382
|
|
|
204
|
-
const
|
|
383
|
+
const leashed = clamp01(dynamics.slack) < 1;
|
|
205
384
|
|
|
206
|
-
for (let node =
|
|
385
|
+
for (let node = 0; node < node_count; node++) {
|
|
207
386
|
// Tether first: §7 P2's long-range attachment, and the row that makes a
|
|
208
387
|
// low iteration budget viable at all, because being hard it is enforced
|
|
209
388
|
// almost exactly in one iteration however deep the chain is.
|
|
210
389
|
tether_row[node] = leash_radius.length;
|
|
211
390
|
|
|
212
391
|
leash_particle.push(node);
|
|
213
|
-
leash_radius.push(
|
|
392
|
+
leash_radius.push(Infinity);
|
|
214
393
|
|
|
215
|
-
if (
|
|
394
|
+
if (leashed) {
|
|
216
395
|
slack_row[node] = leash_radius.length;
|
|
217
396
|
|
|
218
397
|
leash_particle.push(node);
|
|
219
|
-
leash_radius.push(
|
|
398
|
+
leash_radius.push(Infinity);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Until the holds say otherwise, everything hangs from the frame.
|
|
403
|
+
let reach = 0;
|
|
404
|
+
|
|
405
|
+
for (let node = 0; node < node_count; node++) {
|
|
406
|
+
const r = Math.hypot(rest[node * 3], rest[node * 3 + 1], rest[node * 3 + 2]);
|
|
407
|
+
|
|
408
|
+
if (r > reach) {
|
|
409
|
+
reach = r;
|
|
220
410
|
}
|
|
221
411
|
}
|
|
222
412
|
|
|
@@ -232,9 +422,13 @@ export function cloth_build_rows(instance, dt) {
|
|
|
232
422
|
// authority to speak of and its reach is the only length it carries.
|
|
233
423
|
instance.shortest_row = shortest_row < Infinity ? shortest_row : reach;
|
|
234
424
|
|
|
235
|
-
instance.geodesic =
|
|
425
|
+
instance.geodesic = new Float32Array(node_count).fill(Infinity);
|
|
426
|
+
instance.tether_source = new Int32Array(node_count).fill(-1);
|
|
427
|
+
instance.edge_length = edge_length;
|
|
428
|
+
instance.edge_incidence = cloth_edge_incidence(node_count, edge);
|
|
429
|
+
instance.hinge_inertia = hinge_inertia;
|
|
236
430
|
instance.reach = reach;
|
|
237
|
-
instance.
|
|
431
|
+
instance.edge_row = edge_row;
|
|
238
432
|
instance.strain_row = strain_row;
|
|
239
433
|
instance.skip_row = skip_row;
|
|
240
434
|
instance.slack_row = slack_row;
|
|
@@ -248,6 +442,9 @@ export function cloth_build_rows(instance, dt) {
|
|
|
248
442
|
stretch_stiffness: Float32Array.from(stretch_stiffness),
|
|
249
443
|
stretch_force_min: Float32Array.from(stretch_force_min),
|
|
250
444
|
stretch_force_max: Float32Array.from(stretch_force_max),
|
|
445
|
+
bend_particle: hinge.subarray(0, hinge_built * 4),
|
|
446
|
+
bend_weight,
|
|
447
|
+
bend_stiffness: hinge_stiffness,
|
|
251
448
|
leash_particle: Int32Array.from(leash_particle),
|
|
252
449
|
leash_radius: Float32Array.from(leash_radius),
|
|
253
450
|
shared: instance.shared_state
|
|
@@ -278,6 +475,17 @@ export function cloth_build_rows(instance, dt) {
|
|
|
278
475
|
instance.particle_of_node = particle_of_node;
|
|
279
476
|
instance.blended_position = new Float64Array(node_count * 3);
|
|
280
477
|
instance.blended_rotation = new Float64Array(node_count * 4);
|
|
478
|
+
|
|
479
|
+
instance.node_hold = new Int32Array(node_count).fill(-1);
|
|
480
|
+
instance.tether_loose = new Uint8Array(node_count);
|
|
481
|
+
instance.tether_loose_count = 0;
|
|
482
|
+
instance.node_hold_slot = new Int32Array(node_count).fill(-1);
|
|
483
|
+
instance.held_target = new Float64Array(node_count * 3);
|
|
484
|
+
|
|
485
|
+
// Nothing held yet, so the animated pose is the rest pose.
|
|
486
|
+
instance.animated_position = Float64Array.from(rest);
|
|
487
|
+
instance.animated_rotation = Float64Array.from(instance.rest_rotation);
|
|
488
|
+
|
|
281
489
|
instance.state = state;
|
|
282
490
|
instance.seeded = true;
|
|
283
491
|
}
|
|
@@ -313,32 +521,61 @@ export function cloth_reparameterise(instance, dt) {
|
|
|
313
521
|
|
|
314
522
|
const state = instance.state;
|
|
315
523
|
|
|
316
|
-
const node_count = instance.node_count;
|
|
317
|
-
|
|
318
524
|
const strain = cloth_strain_allowance(dynamics.stretch);
|
|
319
525
|
|
|
526
|
+
const edge_row = instance.edge_row;
|
|
527
|
+
const strain_row = instance.strain_row;
|
|
528
|
+
|
|
529
|
+
for (let e = 0; e < strain_row.length; e++) {
|
|
530
|
+
const strain_limit = strain_row[e];
|
|
531
|
+
|
|
532
|
+
if (strain_limit >= 0) {
|
|
533
|
+
state.stretch_rest[strain_limit] = state.stretch_rest[edge_row[e]] * (1 + strain);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
320
537
|
const bend_stiffness = cloth_bend_ratio(dynamics.bend)
|
|
321
538
|
* (CLOTH_PARTICLE_MASS * 0.5) / (dt * dt);
|
|
322
539
|
|
|
540
|
+
const skip_row = instance.skip_row;
|
|
541
|
+
|
|
542
|
+
for (let s = 0; s < skip_row.length; s++) {
|
|
543
|
+
const row = skip_row[s];
|
|
544
|
+
|
|
545
|
+
if (row >= 0) {
|
|
546
|
+
state.stretch_stiffness[row] = bend_stiffness;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// A hinge is bend row `h`, in the order they were built.
|
|
551
|
+
const bend_ratio = cloth_bend_ratio(dynamics.bend);
|
|
552
|
+
const hinge_inertia = instance.hinge_inertia;
|
|
553
|
+
|
|
554
|
+
for (let h = 0; h < state.bend_count; h++) {
|
|
555
|
+
const stiffness = bend_ratio * hinge_inertia[h] / (dt * dt);
|
|
556
|
+
|
|
557
|
+
state.bend_stiffness[h] = stiffness;
|
|
558
|
+
state.bend_penalty[h] = stiffness;
|
|
559
|
+
}
|
|
560
|
+
|
|
323
561
|
const slack_scale = CLOTH_SLACK_REACH * clamp01(dynamics.slack);
|
|
324
562
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const skip = instance.skip_row[node];
|
|
563
|
+
const node_count = instance.node_count;
|
|
564
|
+
|
|
565
|
+
for (let node = 0; node < node_count; node++) {
|
|
329
566
|
const slack = instance.slack_row[node];
|
|
330
567
|
|
|
331
|
-
if (
|
|
332
|
-
|
|
568
|
+
if (slack < 0) {
|
|
569
|
+
continue;
|
|
333
570
|
}
|
|
334
571
|
|
|
335
|
-
|
|
336
|
-
state.stretch_stiffness[skip] = bend_stiffness;
|
|
337
|
-
}
|
|
572
|
+
const d = instance.geodesic[node];
|
|
338
573
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
574
|
+
// A free particle something holds; anything else has no bound to scale,
|
|
575
|
+
// and `0 · Infinity` would be a NaN where `Infinity` is meant.
|
|
576
|
+
state.leash_radius[slack] = d < Infinity && instance.node_hold[node] === -1
|
|
577
|
+
? slack_scale * d
|
|
578
|
+
: Infinity;
|
|
342
579
|
}
|
|
343
580
|
|
|
344
581
|
instance.dynamics_seen.copy(dynamics);
|
|
@@ -195,9 +195,10 @@ export const CLOTH_VELOCITY_CORRECTION_MARGIN: number;
|
|
|
195
195
|
*/
|
|
196
196
|
export const CLOTH_DAMPING_RATE: number;
|
|
197
197
|
/**
|
|
198
|
-
* How far a cloth's
|
|
198
|
+
* How far a cloth's frame may carry it in one fixed step, as a multiple of the
|
|
199
199
|
* cloth's own reach. Motion above this is felt as though it were exactly this,
|
|
200
|
-
* which is what "anchor speed limit" means in §7 P7
|
|
200
|
+
* which is what "anchor speed limit" means in §7 P7 — the frame being what the
|
|
201
|
+
* cloth rides.
|
|
201
202
|
*
|
|
202
203
|
* Expressing it as a fraction of reach rather than in metres per second is what
|
|
203
204
|
* makes it work for a 3 cm pendant and a 30 m mooring line at the same time: a
|
|
@@ -208,9 +209,9 @@ export const CLOTH_DAMPING_RATE: number;
|
|
|
208
209
|
* badly-keyed cut does exceed.
|
|
209
210
|
* @type {number}
|
|
210
211
|
*/
|
|
211
|
-
export const
|
|
212
|
+
export const CLOTH_FRAME_TRAVEL_REACH: number;
|
|
212
213
|
/**
|
|
213
|
-
* How far a cloth's
|
|
214
|
+
* How far a cloth's frame may rotate in one fixed step, radians. Rotation
|
|
214
215
|
* above this is felt as though it were exactly this.
|
|
215
216
|
*
|
|
216
217
|
* Unlike the travel limit this has no length scale to hang off — an angle is
|
|
@@ -218,10 +219,11 @@ export const CLOTH_ANCHOR_TRAVEL_REACH: number;
|
|
|
218
219
|
* about 1,700 degrees a second, which is a spin rather than a turn.
|
|
219
220
|
* @type {number}
|
|
220
221
|
*/
|
|
221
|
-
export const
|
|
222
|
+
export const CLOTH_FRAME_ROTATION_LIMIT: number;
|
|
222
223
|
/**
|
|
223
|
-
*
|
|
224
|
-
* above which the motion is a **teleport**
|
|
224
|
+
* Displacement of the frame, or of a holder in the frame, in one fixed step, as
|
|
225
|
+
* a multiple of the cloth's reach, above which the motion is a **teleport**
|
|
226
|
+
* rather than locomotion (§7 P6).
|
|
225
227
|
*
|
|
226
228
|
* Four reaches in one step is 240 reaches a second: for a 1 m rope that is
|
|
227
229
|
* 240 m/s, well past anything the world moves at and well short of the values a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloth_dynamics_map.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_dynamics_map.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloth_dynamics_map.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_dynamics_map.js"],"names":[],"mappings":"AAqQA;;;;;;;;GAQG;AACH,gDAHW,MAAM,GACJ,MAAM,CAMlB;AAED;;;;;;;;GAQG;AACH,uCAHW,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;;;;;GAWG;AACH,mDAPW,MAAM,YAEN,MAAM,cACN,MAAM,MACN,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,0CAJW,MAAM,MACN,MAAM,GACJ,MAAM,CAYlB;AAED;;;;;;;;GAQG;AACH,kDAJW,MAAM,MACN,MAAM,GACJ,MAAM,CAQlB;AA/WD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH;;;;;GAKG;AACH,+BAFU,MAAM,CAEqB;AAErC;;;;;GAKG;AACH,+BAFU,MAAM,CAEqB;AAErC;;;;;;;;;;;GAWG;AACH,mCAFU,MAAM,CAEsB;AAEtC;;;;;GAKG;AACH,mCAFU,MAAM,CAEyB;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,+CAFU,MAAM,CAEkC;AAElD;;;;;;;;GAQG;AACH,iCAFU,MAAM,CAEqB;AAErC;;;;;;;;;;;;;;GAcG;AACH,uCAFU,MAAM,CAE4B;AAE5C;;;;;;;;GAQG;AACH,yCAFU,MAAM,CAE8B;AAE9C;;;;;;;;;GASG;AACH,mCAFU,MAAM,CAEsB;AAEtC;;;;;;;;GAQG;AACH,mCAFU,MAAM,CAEsB;AAEtC;;;;;;;GAOG;AACH,oCAFU,MAAM,CAEwB;AAExC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,kCAFU,MAAM,CAEsB;AAEtC;;;;;;;GAOG;AACH,sCAFU,MAAM,CAE4B;AAE5C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,6CAFU,MAAM,CAEmC;AAEnD;;;;;GAKG;AACH,gCAFU,MAAM,CAEoB"}
|
|
@@ -129,9 +129,10 @@ export const CLOTH_VELOCITY_CORRECTION_MARGIN = 4;
|
|
|
129
129
|
export const CLOTH_DAMPING_RATE = 20;
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
|
-
* How far a cloth's
|
|
132
|
+
* How far a cloth's frame may carry it in one fixed step, as a multiple of the
|
|
133
133
|
* cloth's own reach. Motion above this is felt as though it were exactly this,
|
|
134
|
-
* which is what "anchor speed limit" means in §7 P7
|
|
134
|
+
* which is what "anchor speed limit" means in §7 P7 — the frame being what the
|
|
135
|
+
* cloth rides.
|
|
135
136
|
*
|
|
136
137
|
* Expressing it as a fraction of reach rather than in metres per second is what
|
|
137
138
|
* makes it work for a 3 cm pendant and a 30 m mooring line at the same time: a
|
|
@@ -142,10 +143,10 @@ export const CLOTH_DAMPING_RATE = 20;
|
|
|
142
143
|
* badly-keyed cut does exceed.
|
|
143
144
|
* @type {number}
|
|
144
145
|
*/
|
|
145
|
-
export const
|
|
146
|
+
export const CLOTH_FRAME_TRAVEL_REACH = 0.5;
|
|
146
147
|
|
|
147
148
|
/**
|
|
148
|
-
* How far a cloth's
|
|
149
|
+
* How far a cloth's frame may rotate in one fixed step, radians. Rotation
|
|
149
150
|
* above this is felt as though it were exactly this.
|
|
150
151
|
*
|
|
151
152
|
* Unlike the travel limit this has no length scale to hang off — an angle is
|
|
@@ -153,11 +154,12 @@ export const CLOTH_ANCHOR_TRAVEL_REACH = 0.5;
|
|
|
153
154
|
* about 1,700 degrees a second, which is a spin rather than a turn.
|
|
154
155
|
* @type {number}
|
|
155
156
|
*/
|
|
156
|
-
export const
|
|
157
|
+
export const CLOTH_FRAME_ROTATION_LIMIT = 0.5;
|
|
157
158
|
|
|
158
159
|
/**
|
|
159
|
-
*
|
|
160
|
-
* above which the motion is a **teleport**
|
|
160
|
+
* Displacement of the frame, or of a holder in the frame, in one fixed step, as
|
|
161
|
+
* a multiple of the cloth's reach, above which the motion is a **teleport**
|
|
162
|
+
* rather than locomotion (§7 P6).
|
|
161
163
|
*
|
|
162
164
|
* Four reaches in one step is 240 reaches a second: for a 1 m rope that is
|
|
163
165
|
* 240 m/s, well past anything the world moves at and well short of the values a
|