@woosh/meep-engine 3.22.0 → 3.23.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/package.json +1 -1
- package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts +118 -0
- package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts.map +1 -0
- package/src/core/geom/3d/hash-grid/PointHashGrid3.js +283 -0
- package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/BoxShape3D.js +6 -17
- package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/CapsuleShape3D.js +3 -14
- package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/CylinderShape3D.js +3 -21
- package/src/core/geom/3d/shape/PlaneShape3D.d.ts +105 -0
- package/src/core/geom/3d/shape/PlaneShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/PlaneShape3D.js +251 -0
- package/src/core/geom/3d/shape/SphereShape3D.js +3 -3
- package/src/core/geom/3d/shape/json/shape_to_type.d.ts.map +1 -1
- package/src/core/geom/3d/shape/json/shape_to_type.js +3 -0
- package/src/core/geom/3d/shape/json/type_adapters.d.ts +14 -0
- package/src/core/geom/3d/shape/json/type_adapters.d.ts.map +1 -1
- package/src/core/geom/3d/shape/json/type_adapters.js +15 -0
- package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts +51 -0
- package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_box.js +113 -0
- package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts +46 -0
- package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_capsule.js +82 -0
- package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts +60 -0
- package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_cylinder.js +126 -0
- package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts +50 -0
- package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.js +53 -0
- package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts +52 -0
- package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_plane.js +61 -0
- package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts +41 -0
- package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_sphere.js +71 -0
- package/src/core/process/ConcurrencyGate.d.ts +103 -0
- package/src/core/process/ConcurrencyGate.d.ts.map +1 -0
- package/src/core/process/ConcurrencyGate.js +207 -0
- package/src/engine/asset/AssetManager.d.ts +10 -0
- package/src/engine/asset/AssetManager.d.ts.map +1 -1
- package/src/engine/asset/AssetManager.js +10 -0
- package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +30 -13
- package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts +26 -0
- package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts.map +1 -0
- package/src/engine/graphics3/pose/collect_entity_playbacks.js +40 -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 +74 -101
- package/src/engine/physics/cloth/MEASUREMENTS.md +1287 -4
- package/src/engine/physics/cloth/PLAN.md +1967 -1581
- package/src/engine/physics/cloth/build/ClothProxy.d.ts +147 -0
- package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/ClothProxy.js +207 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +70 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +256 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +176 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.js +435 -0
- package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts +12 -0
- package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/ClothColliderKind.js +38 -0
- package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts +120 -0
- package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/ClothColliderRecord.js +137 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts +25 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +190 -0
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +44 -0
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/cloth_collider_pack.js +173 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +94 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +275 -0
- package/src/engine/physics/cloth/ecs/ClothCollider.d.ts +126 -0
- package/src/engine/physics/cloth/ecs/ClothCollider.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothCollider.js +199 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +9 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +32 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +114 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +243 -0
- package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +66 -57
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +109 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +479 -363
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts +95 -0
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothRig.js +140 -0
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +30 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +1021 -773
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +90 -0
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_build_rows.js +374 -0
- package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts +32 -3
- package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_library.js +283 -254
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +59 -0
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +328 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +13 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +288 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +58 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +199 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +8 -63
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +317 -645
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +61 -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 +212 -449
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +49 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +115 -0
- package/src/engine/physics/cloth/playground/README.md +155 -1
- package/src/engine/physics/cloth/playground/collide.html +178 -0
- package/src/engine/physics/cloth/playground/collide_build.d.ts +95 -0
- package/src/engine/physics/cloth/playground/collide_build.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/collide_build.js +315 -0
- package/src/engine/physics/cloth/playground/collide_main.d.ts +2 -0
- package/src/engine/physics/cloth/playground/collide_main.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/collide_main.js +720 -0
- package/src/engine/physics/cloth/playground/garment.html +182 -0
- package/src/engine/physics/cloth/playground/garment_build.d.ts +78 -0
- package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/garment_build.js +359 -0
- package/src/engine/physics/cloth/playground/garment_main.d.ts +2 -0
- package/src/engine/physics/cloth/playground/garment_main.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/garment_main.js +633 -0
- package/src/engine/physics/cloth/solver/ClothState.d.ts +208 -5
- package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/ClothState.js +302 -8
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +87 -0
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_contact_find.js +343 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +112 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.js +448 -0
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts +4 -1
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +16 -1
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +112 -5
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solver_constants.js +117 -6
- package/src/engine/physics/cloth/solver/cloth_step.d.ts +40 -9
- package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_step.js +122 -10
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +95 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +285 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +129 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +501 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +75 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +202 -0
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/playground/vgeo_viewer/README.md +18 -0
- package/src/shade/playground/vgeo_viewer/main.js +87 -50
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabase.js +191 -62
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +94 -2
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +414 -2
- package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts +14 -0
- package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.js +13 -0
- package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts +17 -0
- package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.js +116 -0
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +9 -4
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +843 -734
- package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts +12 -0
- package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js +13 -0
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +17 -0
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +185 -30
- package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +17 -0
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +141 -24
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +204 -64
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +110 -10
- package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +19 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +19 -6
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +26 -7
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +173 -14
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +458 -51
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +49 -13
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +52 -14
- package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.js +19 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts +27 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.js +48 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.js +60 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +8 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +32 -2
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +258 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +723 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +49 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +50 -0
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts +3 -0
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +121 -21
- package/src/shade/renderer/texture/virtual/README.md +6 -4
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +7 -0
- package/src/shade/renderer/texture/virtual/source/VTSourceTiled.d.ts +3 -3
- package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +3 -3
- package/src/engine/ecs/system/SystemExecutionPhase.d.ts +0 -9
- package/src/engine/ecs/system/SystemExecutionPhase.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/NOTES.md +0 -128
- package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts +0 -6
- package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.js +0 -5
- package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts +0 -49
- package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.js +0 -264
- package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts +0 -44
- package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VirtualTextureUsage.js +0 -228
- package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts +0 -3
- package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.js +0 -73
- package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts +0 -14
- package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.js +0 -85
- package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts +0 -12
- package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/debug/UsageDebugView.js +0 -63
- package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts +0 -12
- package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.js +0 -243
- package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts +0 -30
- package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.js +0 -39
- package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts +0 -9
- package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/compose_finger_print.js +0 -24
- package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts +0 -9
- package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/compose_tile_address.js +0 -26
- package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts +0 -11
- package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.js +0 -12
- package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts +0 -7
- package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.js +0 -16
- package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts +0 -7
- package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.js +0 -35
|
@@ -49,10 +49,26 @@
|
|
|
49
49
|
* for **transient** rows — a contact that should arrive soft and stiffen rather
|
|
50
50
|
* than shock the mesh on its first frame — and M0 has none.
|
|
51
51
|
*
|
|
52
|
-
* **`β`
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
52
|
+
* **`β` is M2's, and it is 1e3 rather than M0's 1e5 placeholder.** M0 could not
|
|
53
|
+
* choose it: above about 1e4 every M0 scenario gave an identical answer, and
|
|
54
|
+
* with the band collapsed it had no effect at all. M2's contacts are the first
|
|
55
|
+
* transient rows in the system and the ramp is finally live. Measured on a
|
|
56
|
+
* 400-particle sheet landing on the ground, both ends of the range are worse
|
|
57
|
+
* than the middle: **no ramp at all** leaves a fast arrival's penalty at the
|
|
58
|
+
* floor and the multiplier alone to carry it, which settles at 1.95 J of
|
|
59
|
+
* residual kinetic energy against 0.12 J at 1e3; a **fast** ramp reaches the
|
|
60
|
+
* ceiling on violations of a millimetre and gives up most of what the low floor
|
|
61
|
+
* bought, settling three orders of magnitude worse on a gentle landing
|
|
62
|
+
* (6.4e-5 J against 3.2e-8 J). `MEASUREMENTS.md` §17.
|
|
63
|
+
*
|
|
64
|
+
* The scale-dependence the paragraph above warns of is real and is stated
|
|
65
|
+
* rather than removed: `β` has units of N/m², so it is a stiffness *per metre
|
|
66
|
+
* of violation*, and 1e3 against a ceiling of `8·(m/h²)` means the ramp is
|
|
67
|
+
* inert for a millimetre of penetration and reaches the ceiling within a step
|
|
68
|
+
* for a decimetre of it. That shape — gentle where the contact is grazing,
|
|
69
|
+
* immediate where it is a real interpenetration — is what the measurement
|
|
70
|
+
* picked, and a ratio-valued `β` that removed the dependence would have to
|
|
71
|
+
* choose the reference length that shape is built out of.
|
|
56
72
|
*
|
|
57
73
|
* @author Alex Goldring
|
|
58
74
|
* @copyright Company Named Limited (c) 2026
|
|
@@ -65,10 +81,11 @@
|
|
|
65
81
|
export const CLOTH_ALPHA = 0.25;
|
|
66
82
|
|
|
67
83
|
/**
|
|
68
|
-
* Penalty ramp
|
|
84
|
+
* Penalty ramp, N/m². See the module docblock — measured at M2, against the
|
|
85
|
+
* first transient rows the system has.
|
|
69
86
|
* @type {number}
|
|
70
87
|
*/
|
|
71
|
-
export const CLOTH_BETA =
|
|
88
|
+
export const CLOTH_BETA = 1e3;
|
|
72
89
|
|
|
73
90
|
/**
|
|
74
91
|
* Dual decay, `[0, 1)`.
|
|
@@ -88,6 +105,100 @@ export const CLOTH_K_MIN_RATIO = 8;
|
|
|
88
105
|
*/
|
|
89
106
|
export const CLOTH_K_MAX_RATIO = 8;
|
|
90
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Penalty floor for a **contact** row, as a multiple of the row's `m/h²`.
|
|
110
|
+
*
|
|
111
|
+
* Separate from {@link CLOTH_K_MIN_RATIO}, which is pinned to the ceiling,
|
|
112
|
+
* because a contact is the one row kind that *arrives*: a persistent row has
|
|
113
|
+
* been converging since the cloth was seeded and wants the stiffest penalty the
|
|
114
|
+
* step is stable at, and a contact that starts there shocks the mesh on its
|
|
115
|
+
* first frame.
|
|
116
|
+
*
|
|
117
|
+
* **A thirty-second of the ceiling**, measured. The floor is what decides how
|
|
118
|
+
* hard a new contact hits, and the measurement is unambiguous about the
|
|
119
|
+
* direction: on a sheet landing at 3 m/s, the peak contact force falls from
|
|
120
|
+
* 18.9 N at the ceiling to 0.16 N at an eighth of it and the settled kinetic
|
|
121
|
+
* energy falls by six orders of magnitude, while the penetration *improves*
|
|
122
|
+
* from 1.6 cm to 1.1 cm. Below about an eighth the numbers stop moving — every
|
|
123
|
+
* floor from ×1/8 down to ×1/128 gives the same penetration to three figures —
|
|
124
|
+
* so the value is a margin decision the same way `α·γ` was, and ×1/32 sits in
|
|
125
|
+
* the middle of the flat region with two decades of ramp above it.
|
|
126
|
+
*
|
|
127
|
+
* The reason the floor matters so little to the *residual* is the augmented
|
|
128
|
+
* Lagrangian working as designed: the multiplier carries the load and the
|
|
129
|
+
* penalty only has to be large enough to generate one. See MEASUREMENTS §17.
|
|
130
|
+
* @type {number}
|
|
131
|
+
*/
|
|
132
|
+
export const CLOTH_CONTACT_K_MIN_RATIO = 0.25;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Penalty stiffness for a **self-collision** row, as a multiple of the row's
|
|
136
|
+
* own `m_eff/h²`.
|
|
137
|
+
*
|
|
138
|
+
* It is a plain penalty rather than a hard row because the load it carries is
|
|
139
|
+
* cloth against cloth. `MEASUREMENTS.md` §18 measured why a *collider* contact
|
|
140
|
+
* cannot be soft — 376 N for a sheet arriving at 8 m/s against the 4.6 N a soft
|
|
141
|
+
* row inside M0's dissipative band can deliver — and a self-collision row never
|
|
142
|
+
* sees anything of the kind: what it holds apart weighs grams and is moving at
|
|
143
|
+
* the speed cloth moves relative to itself.
|
|
144
|
+
*
|
|
145
|
+
* **Eight, and the dissipative band is not the reason.** Eight is where M0's
|
|
146
|
+
* band tops out and it would be natural to read this as the same ceiling, but
|
|
147
|
+
* `MEASUREMENTS.md` §32 swept the ratio from 1 to 64 and found no energy growth
|
|
148
|
+
* anywhere: the band was measured on rows that are *on every step*, and a
|
|
149
|
+
* one-sided row that vanishes the instant it is satisfied has no standing spring
|
|
150
|
+
* to pump. What picks eight is the crossing count — it is the joint minimum of
|
|
151
|
+
* the mean, and a stiffer row makes the *worst* case steadily worse by throwing
|
|
152
|
+
* a particle hard enough to put the sheet through itself elsewhere.
|
|
153
|
+
*
|
|
154
|
+
* The consequence is a row with no multiplier, no warm start and no identity
|
|
155
|
+
* across steps, which is what makes rebuilding the pair list from scratch every
|
|
156
|
+
* step affordable. `MEASUREMENTS.md` §33.
|
|
157
|
+
* @type {number}
|
|
158
|
+
*/
|
|
159
|
+
export const CLOTH_SELF_RATIO = 8;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Smallest radius a self-collision row is written at, as a multiple of the
|
|
163
|
+
* cloth's shortest row — so the row's **diameter** is one particle spacing.
|
|
164
|
+
*
|
|
165
|
+
* `ClothState#self_radius` carries why the radius is a property of the proxy
|
|
166
|
+
* rather than of the fabric, and `MEASUREMENTS.md` §31 is the sweep: at the
|
|
167
|
+
* fabric's own thickness the row removes 21% of a folding sheet's
|
|
168
|
+
* self-intersections and here it removes 82%.
|
|
169
|
+
* @type {number}
|
|
170
|
+
*/
|
|
171
|
+
export const CLOTH_SELF_RADIUS_MIN_RATIO = 0.5;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Largest radius a self-collision row is written at, as a fraction of the
|
|
175
|
+
* closest two particles get **with no row between them** in the bind pose —
|
|
176
|
+
* `ClothInstance#closest_free_pair`. Two fifths of it, so the row's diameter is
|
|
177
|
+
* four fifths of the nearest thing it could touch and a cloth at rest is never
|
|
178
|
+
* in contact with itself.
|
|
179
|
+
*
|
|
180
|
+
* **A ceiling is needed because the floor is not always reachable.** A thick
|
|
181
|
+
* fabric on a coarse proxy takes its thickness rather than
|
|
182
|
+
* {@link CLOTH_SELF_RADIUS_MIN_RATIO}, and a diameter that reaches the nearest
|
|
183
|
+
* ungoverned pair puts a cloth that is not folded at all in permanent contact
|
|
184
|
+
* with itself — leather, 20 mm thick on a 20 mm proxy, found 1,398 pairs a step
|
|
185
|
+
* across 576 particles standing still. `MEASUREMENTS.md` §36.
|
|
186
|
+
*
|
|
187
|
+
* **And it is measured rather than derived, because a garment is not a sheet.**
|
|
188
|
+
* On a triangulated sheet the closest ungoverned pair is exactly two hops, so
|
|
189
|
+
* this comes out at four fifths of the shortest row and the analytic answer
|
|
190
|
+
* would have done — checked at two spacings, to the precision the proxy's
|
|
191
|
+
* Float32 positions carry. A rigged
|
|
192
|
+
* garment's proxy is *strips* with nothing joining one to the next, so every
|
|
193
|
+
* pair across the gap is ungoverned at whatever distance the artist put the
|
|
194
|
+
* joints, which the shortest row knows nothing about: the playground's cape has
|
|
195
|
+
* 8 cm links and 8.5 cm gaps, half what a sheet would imply. Derived from the
|
|
196
|
+
* link length the ceiling left that cape with three pairs permanently in
|
|
197
|
+
* contact at rest; measured, it has none. `MEASUREMENTS.md` §37.
|
|
198
|
+
* @type {number}
|
|
199
|
+
*/
|
|
200
|
+
export const CLOTH_SELF_RADIUS_MAX_RATIO = 0.4;
|
|
201
|
+
|
|
91
202
|
/**
|
|
92
203
|
* The five constants as one frozen object, which is what {@link cloth_step}
|
|
93
204
|
* takes. A sweep passes its own; nothing else should.
|
|
@@ -15,10 +15,29 @@
|
|
|
15
15
|
* k ← min(k + β·|C|, min(k_max, stiffness))
|
|
16
16
|
* integrate v = (x − x_prev)/h
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* an accumulate and a dual update, and this
|
|
20
|
-
* them. A new row kind is a new module and
|
|
21
|
-
* what they have in common.
|
|
18
|
+
* Six row kinds — stretch, bend, leash, backstop, contact and self-collision —
|
|
19
|
+
* each contribute a warm start, an accumulate and a dual update, and this
|
|
20
|
+
* function knows nothing else about them. A new row kind is a new module and
|
|
21
|
+
* three more calls; §6 is the whole of what they have in common.
|
|
22
|
+
*
|
|
23
|
+
* Self-collision is the one that does not fit that shape, and §5.4 is why: it is
|
|
24
|
+
* a **pair**, so it is accumulated into a per-particle scratch once per
|
|
25
|
+
* iteration and read by the vertex updates rather than visited from them. It has
|
|
26
|
+
* no warm start and no dual update because it is a plain penalty
|
|
27
|
+
* (`cloth_self_row.js`).
|
|
28
|
+
*
|
|
29
|
+
* ## The colliders move within the step
|
|
30
|
+
*
|
|
31
|
+
* §8.2's swept collision is one call per substep: the packed collider table is
|
|
32
|
+
* re-posed at the substep's fraction of the way from the previous step's pose to
|
|
33
|
+
* this one's, and every contact row then evaluates against where the collider
|
|
34
|
+
* *is at that moment* rather than where it ended up. The contact **set** is
|
|
35
|
+
* fixed for the step (`cloth_contact_find.js` and its speculative margin); only
|
|
36
|
+
* the poses move.
|
|
37
|
+
*
|
|
38
|
+
* The fraction is the end of each substep rather than its start — with one
|
|
39
|
+
* substep that is the collider's final pose, which is the one a particle must
|
|
40
|
+
* not be inside when the step is over.
|
|
22
41
|
*
|
|
23
42
|
* ## What each piece is for
|
|
24
43
|
*
|
|
@@ -50,9 +69,17 @@
|
|
|
50
69
|
*
|
|
51
70
|
* ## What is deliberately not here
|
|
52
71
|
*
|
|
53
|
-
* *Chebyshev acceleration* (§5.2)
|
|
54
|
-
* not being in contact
|
|
55
|
-
*
|
|
72
|
+
* *Chebyshev acceleration* (§5.2), which M2 built, measured and removed. It is
|
|
73
|
+
* gated on a particle not being in contact, so M2 was the first milestone that
|
|
74
|
+
* could evaluate it at all — and it lost on every axis: on a sheet landing at
|
|
75
|
+
* 3 m/s it left the penetration inside the run-to-run spread and made the
|
|
76
|
+
* settled kinetic energy 1.5× worse; on a hanging cape it traded a third off the
|
|
77
|
+
* penetration for ten times the residual energy; and past `ρ = 0.9` it
|
|
78
|
+
* diverges, with `ρ = 0.99` reaching a non-positive-definite Hessian inside a
|
|
79
|
+
* second. A mechanism that costs 2–5%, does not help, and detonates at the top
|
|
80
|
+
* of its own parameter range is worse than its absence. `MEASUREMENTS.md` §21
|
|
81
|
+
* carries the grid, so a future attempt starts from the numbers rather than
|
|
82
|
+
* from the idea.
|
|
56
83
|
*
|
|
57
84
|
* *The velocity clamp* named in §7 P1 is derived from `ClothDynamics#thickness`
|
|
58
85
|
* and belongs with the component that carries it — `ClothSystem` applies it
|
|
@@ -79,13 +106,17 @@
|
|
|
79
106
|
* @param {number} acceleration_z
|
|
80
107
|
* @param {number} substeps
|
|
81
108
|
* @param {number} iterations descent iterations per substep
|
|
82
|
-
* @param {
|
|
109
|
+
* @param {Float32Array|Float64Array|null} [collider_table] packed colliders in the
|
|
110
|
+
* cloth's own frame, with their contact rows already found
|
|
111
|
+
* @param {number} [collider_count]
|
|
112
|
+
* @param {{alpha: number, beta: number, gamma: number, k_min_ratio: number, k_max_ratio: number, self_ratio?: number}} [tuning]
|
|
83
113
|
*/
|
|
84
|
-
export function cloth_step(state: ClothState, dt: number, acceleration_x: number, acceleration_y: number, acceleration_z: number, substeps: number, iterations: number, tuning?: {
|
|
114
|
+
export function cloth_step(state: ClothState, dt: number, acceleration_x: number, acceleration_y: number, acceleration_z: number, substeps: number, iterations: number, collider_table?: Float32Array | Float64Array | null, collider_count?: number, tuning?: {
|
|
85
115
|
alpha: number;
|
|
86
116
|
beta: number;
|
|
87
117
|
gamma: number;
|
|
88
118
|
k_min_ratio: number;
|
|
89
119
|
k_max_ratio: number;
|
|
120
|
+
self_ratio?: number;
|
|
90
121
|
}): void;
|
|
91
122
|
//# sourceMappingURL=cloth_step.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloth_step.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_step.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloth_step.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_step.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiGG;AAEH;;;;;;;;;;;;;;GAcG;AACH,kDAXW,MAAM,kBACN,MAAM,kBACN,MAAM,kBACN,MAAM,YACN,MAAM,cACN,MAAM,mBACN,YAAY,GAAC,YAAY,GAAC,IAAI,mBAE9B,MAAM,WACN;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAC,QA2FrH"}
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { cloth_collider_pose_at } from "../collider/cloth_collider_sdf.js";
|
|
2
3
|
import { cloth_solve_vertex } from "./cloth_solve_vertex.js";
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
CLOTH_CONTACT_K_MIN_RATIO,
|
|
6
|
+
CLOTH_SELF_RATIO,
|
|
7
|
+
CLOTH_SOLVER_TUNING
|
|
8
|
+
} from "./cloth_solver_constants.js";
|
|
9
|
+
import {
|
|
10
|
+
cloth_backstop_dual_update,
|
|
11
|
+
cloth_backstop_warm_start
|
|
12
|
+
} from "./constraint/cloth_backstop_row.js";
|
|
4
13
|
import {
|
|
5
14
|
cloth_bend_dual_update,
|
|
6
15
|
cloth_bend_warm_start
|
|
7
16
|
} from "./constraint/cloth_bend_row.js";
|
|
17
|
+
import {
|
|
18
|
+
cloth_contact_dual_update,
|
|
19
|
+
cloth_contact_warm_start
|
|
20
|
+
} from "./constraint/cloth_contact_row.js";
|
|
21
|
+
import { cloth_self_accumulate_scratch } from "./constraint/cloth_self_row.js";
|
|
8
22
|
import {
|
|
9
23
|
cloth_leash_dual_update,
|
|
10
24
|
cloth_leash_warm_start
|
|
@@ -32,10 +46,29 @@ import { find_non_finite_cloth_state } from "./find_non_finite_cloth_state.js";
|
|
|
32
46
|
* k ← min(k + β·|C|, min(k_max, stiffness))
|
|
33
47
|
* integrate v = (x − x_prev)/h
|
|
34
48
|
*
|
|
35
|
-
*
|
|
36
|
-
* an accumulate and a dual update, and this
|
|
37
|
-
* them. A new row kind is a new module and
|
|
38
|
-
* what they have in common.
|
|
49
|
+
* Six row kinds — stretch, bend, leash, backstop, contact and self-collision —
|
|
50
|
+
* each contribute a warm start, an accumulate and a dual update, and this
|
|
51
|
+
* function knows nothing else about them. A new row kind is a new module and
|
|
52
|
+
* three more calls; §6 is the whole of what they have in common.
|
|
53
|
+
*
|
|
54
|
+
* Self-collision is the one that does not fit that shape, and §5.4 is why: it is
|
|
55
|
+
* a **pair**, so it is accumulated into a per-particle scratch once per
|
|
56
|
+
* iteration and read by the vertex updates rather than visited from them. It has
|
|
57
|
+
* no warm start and no dual update because it is a plain penalty
|
|
58
|
+
* (`cloth_self_row.js`).
|
|
59
|
+
*
|
|
60
|
+
* ## The colliders move within the step
|
|
61
|
+
*
|
|
62
|
+
* §8.2's swept collision is one call per substep: the packed collider table is
|
|
63
|
+
* re-posed at the substep's fraction of the way from the previous step's pose to
|
|
64
|
+
* this one's, and every contact row then evaluates against where the collider
|
|
65
|
+
* *is at that moment* rather than where it ended up. The contact **set** is
|
|
66
|
+
* fixed for the step (`cloth_contact_find.js` and its speculative margin); only
|
|
67
|
+
* the poses move.
|
|
68
|
+
*
|
|
69
|
+
* The fraction is the end of each substep rather than its start — with one
|
|
70
|
+
* substep that is the collider's final pose, which is the one a particle must
|
|
71
|
+
* not be inside when the step is over.
|
|
39
72
|
*
|
|
40
73
|
* ## What each piece is for
|
|
41
74
|
*
|
|
@@ -67,9 +100,17 @@ import { find_non_finite_cloth_state } from "./find_non_finite_cloth_state.js";
|
|
|
67
100
|
*
|
|
68
101
|
* ## What is deliberately not here
|
|
69
102
|
*
|
|
70
|
-
* *Chebyshev acceleration* (§5.2)
|
|
71
|
-
* not being in contact
|
|
72
|
-
*
|
|
103
|
+
* *Chebyshev acceleration* (§5.2), which M2 built, measured and removed. It is
|
|
104
|
+
* gated on a particle not being in contact, so M2 was the first milestone that
|
|
105
|
+
* could evaluate it at all — and it lost on every axis: on a sheet landing at
|
|
106
|
+
* 3 m/s it left the penetration inside the run-to-run spread and made the
|
|
107
|
+
* settled kinetic energy 1.5× worse; on a hanging cape it traded a third off the
|
|
108
|
+
* penetration for ten times the residual energy; and past `ρ = 0.9` it
|
|
109
|
+
* diverges, with `ρ = 0.99` reaching a non-positive-definite Hessian inside a
|
|
110
|
+
* second. A mechanism that costs 2–5%, does not help, and detonates at the top
|
|
111
|
+
* of its own parameter range is worse than its absence. `MEASUREMENTS.md` §21
|
|
112
|
+
* carries the grid, so a future attempt starts from the numbers rather than
|
|
113
|
+
* from the idea.
|
|
73
114
|
*
|
|
74
115
|
* *The velocity clamp* named in §7 P1 is derived from `ClothDynamics#thickness`
|
|
75
116
|
* and belongs with the component that carries it — `ClothSystem` applies it
|
|
@@ -97,7 +138,10 @@ import { find_non_finite_cloth_state } from "./find_non_finite_cloth_state.js";
|
|
|
97
138
|
* @param {number} acceleration_z
|
|
98
139
|
* @param {number} substeps
|
|
99
140
|
* @param {number} iterations descent iterations per substep
|
|
100
|
-
* @param {
|
|
141
|
+
* @param {Float32Array|Float64Array|null} [collider_table] packed colliders in the
|
|
142
|
+
* cloth's own frame, with their contact rows already found
|
|
143
|
+
* @param {number} [collider_count]
|
|
144
|
+
* @param {{alpha: number, beta: number, gamma: number, k_min_ratio: number, k_max_ratio: number, self_ratio?: number}} [tuning]
|
|
101
145
|
*/
|
|
102
146
|
export function cloth_step(
|
|
103
147
|
state,
|
|
@@ -105,6 +149,8 @@ export function cloth_step(
|
|
|
105
149
|
acceleration_x, acceleration_y, acceleration_z,
|
|
106
150
|
substeps,
|
|
107
151
|
iterations,
|
|
152
|
+
collider_table = null,
|
|
153
|
+
collider_count = 0,
|
|
108
154
|
tuning = CLOTH_SOLVER_TUNING
|
|
109
155
|
) {
|
|
110
156
|
assert.isPositiveInteger(substeps, 'substeps');
|
|
@@ -120,28 +166,63 @@ export function cloth_step(
|
|
|
120
166
|
const inverse_h = 1 / h;
|
|
121
167
|
const inverse_h_squared = inverse_h * inverse_h;
|
|
122
168
|
|
|
169
|
+
// Both ends of a self-collision pair are free, so the row's effective
|
|
170
|
+
// inertia along the constraint is half a particle's — the same reasoning the
|
|
171
|
+
// stretch table uses for an interior row. `CLOTH_SELF_RATIO` is a multiple
|
|
172
|
+
// of that.
|
|
173
|
+
//
|
|
174
|
+
// Behind the pair count, because `max_inverse_mass` is a scan over every
|
|
175
|
+
// particle and a cloth with the flag clear should not pay for a feature it
|
|
176
|
+
// does not have.
|
|
177
|
+
const self_stiffness = state.self_count > 0 && state.particle_count > 0
|
|
178
|
+
? (tuning.self_ratio ?? CLOTH_SELF_RATIO) * inverse_h_squared * 0.5 / max_inverse_mass(state)
|
|
179
|
+
: 0;
|
|
180
|
+
|
|
123
181
|
const colour_count = state.colour_count;
|
|
124
182
|
const colour_offset = state.colour_offset;
|
|
125
183
|
|
|
184
|
+
const contacts = collider_table !== null && collider_count > 0 ? collider_table : null;
|
|
185
|
+
|
|
126
186
|
for (let substep = 0; substep < substeps; substep++) {
|
|
127
187
|
cloth_predict(state, h, acceleration_x, acceleration_y, acceleration_z);
|
|
128
188
|
|
|
189
|
+
if (contacts !== null) {
|
|
190
|
+
cloth_collider_pose_at(contacts, collider_count, (substep + 1) / substeps);
|
|
191
|
+
}
|
|
192
|
+
|
|
129
193
|
cloth_stretch_warm_start(state, alpha, gamma, k_min_ratio, k_max_ratio, inverse_h_squared);
|
|
130
194
|
cloth_bend_warm_start(state, alpha, gamma, k_min_ratio, k_max_ratio, inverse_h_squared);
|
|
131
195
|
cloth_leash_warm_start(state, alpha, gamma, k_min_ratio, k_max_ratio, inverse_h_squared);
|
|
196
|
+
cloth_backstop_warm_start(state, alpha, gamma, k_min_ratio, k_max_ratio, inverse_h_squared);
|
|
197
|
+
|
|
198
|
+
if (contacts !== null) {
|
|
199
|
+
cloth_contact_warm_start(
|
|
200
|
+
state, alpha, gamma,
|
|
201
|
+
CLOTH_CONTACT_K_MIN_RATIO, k_max_ratio, inverse_h_squared
|
|
202
|
+
);
|
|
203
|
+
}
|
|
132
204
|
|
|
133
205
|
for (let iteration = 0; iteration < iterations; iteration++) {
|
|
206
|
+
if (state.self_count > 0) {
|
|
207
|
+
cloth_self_accumulate_scratch(state, self_stiffness);
|
|
208
|
+
}
|
|
209
|
+
|
|
134
210
|
for (let colour = 0; colour < colour_count; colour++) {
|
|
135
211
|
const end = colour_offset[colour + 1];
|
|
136
212
|
|
|
137
213
|
for (let particle = colour_offset[colour]; particle < end; particle++) {
|
|
138
|
-
cloth_solve_vertex(state, particle, inverse_h_squared);
|
|
214
|
+
cloth_solve_vertex(state, particle, inverse_h_squared, contacts);
|
|
139
215
|
}
|
|
140
216
|
}
|
|
141
217
|
|
|
142
218
|
cloth_stretch_dual_update(state, beta, k_max_ratio, inverse_h_squared);
|
|
143
219
|
cloth_bend_dual_update(state, beta, k_max_ratio, inverse_h_squared);
|
|
144
220
|
cloth_leash_dual_update(state, beta, k_max_ratio, inverse_h_squared);
|
|
221
|
+
cloth_backstop_dual_update(state, beta, k_max_ratio, inverse_h_squared);
|
|
222
|
+
|
|
223
|
+
if (contacts !== null) {
|
|
224
|
+
cloth_contact_dual_update(state, contacts, beta, k_max_ratio, inverse_h_squared);
|
|
225
|
+
}
|
|
145
226
|
}
|
|
146
227
|
|
|
147
228
|
cloth_integrate(state, inverse_h, acceleration_x, acceleration_y, acceleration_z);
|
|
@@ -153,6 +234,37 @@ export function cloth_step(
|
|
|
153
234
|
);
|
|
154
235
|
}
|
|
155
236
|
|
|
237
|
+
/**
|
|
238
|
+
* The largest inverse mass in the cloth — the lightest particle, which is the
|
|
239
|
+
* one a shared penalty has to be safe for.
|
|
240
|
+
*
|
|
241
|
+
* A self-collision pair's stiffness is one number for the whole cloth rather
|
|
242
|
+
* than one per pair, because every pair has the same two free ends and cloth's
|
|
243
|
+
* particles are uniform (`cloth_build_rows.js` says why a mass is arbitrary
|
|
244
|
+
* here). This is what makes that true even for a state a caller built by hand
|
|
245
|
+
* with mixed masses: the band is measured against the *lightest* particle, so no
|
|
246
|
+
* pair is above it.
|
|
247
|
+
*
|
|
248
|
+
* @param {ClothState} state
|
|
249
|
+
* @returns {number}
|
|
250
|
+
* @private
|
|
251
|
+
*/
|
|
252
|
+
function max_inverse_mass(state) {
|
|
253
|
+
const mass_inverse = state.mass_inverse;
|
|
254
|
+
|
|
255
|
+
let worst = 0;
|
|
256
|
+
|
|
257
|
+
for (let i = 0; i < state.particle_count; i++) {
|
|
258
|
+
if (mass_inverse[i] > worst) {
|
|
259
|
+
worst = mass_inverse[i];
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Every particle pinned: nothing can move, so the stiffness is unused and
|
|
264
|
+
// any finite value is as good as another.
|
|
265
|
+
return worst > 0 ? worst : 1;
|
|
266
|
+
}
|
|
267
|
+
|
|
156
268
|
/**
|
|
157
269
|
* Predict: record where the substep started, build the inertial target every
|
|
158
270
|
* vertex update pulls towards, and seed the descent.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # Backstop — the half-space row
|
|
3
|
+
*
|
|
4
|
+
* C(x) = r_b − (x_i − b_i)·n_i
|
|
5
|
+
* ∂C/∂x_i = −n_i
|
|
6
|
+
*
|
|
7
|
+
* §6's row, verbatim: a particle is held at least `r_b` along its own normal
|
|
8
|
+
* from a point `b` just inside the body. `[0, +∞)` admits only forces that
|
|
9
|
+
* *reduce* `C`, which for this `C` means increasing `(x − b)·n` — pushing the
|
|
10
|
+
* particle out along its normal, which is what "never inside the body" means.
|
|
11
|
+
*
|
|
12
|
+
* ## What it is for, and why it is not a collider
|
|
13
|
+
*
|
|
14
|
+
* A cape's collider set approximates a torso with a handful of capsules, and
|
|
15
|
+
* between them is a gap the cloth can settle into. A backstop closes that gap
|
|
16
|
+
* without adding geometry: the plane is anchored to the particle's own
|
|
17
|
+
* *animated* position and its own surface normal, both of which the garment
|
|
18
|
+
* already knows, so it is a bound the mesh carries with it rather than a shape
|
|
19
|
+
* somebody has to author. Chaos Cloth ships the same thing under the same name
|
|
20
|
+
* and for the same reason (§15), and §7 P3 leans on it as one of the three
|
|
21
|
+
* layers that stop a garment tunnelling through a character.
|
|
22
|
+
*
|
|
23
|
+
* It is deliberately **not** a substitute for collision. A backstop is a plane
|
|
24
|
+
* per particle: it knows which way is out and nothing about what is actually
|
|
25
|
+
* there, so it cannot resolve a limb crossing the garment. The two rows answer
|
|
26
|
+
* different halves and a cape wants both.
|
|
27
|
+
*
|
|
28
|
+
* ## Where the plane comes from
|
|
29
|
+
*
|
|
30
|
+
* The caller writes it, per step, into {@link ClothState#backstop_plane} — the
|
|
31
|
+
* same contract {@link ClothState#leash_target} carries, and for the same
|
|
32
|
+
* reason: `b` and `n` are anchored to the animated pose, which moves, and are
|
|
33
|
+
* not properties of the rest shape.
|
|
34
|
+
*
|
|
35
|
+
* **M2 builds the row and does not author it.** The natural source is the
|
|
36
|
+
* garment's own skinned surface — `b` a short way inside along the vertex
|
|
37
|
+
* normal, `r_b` that distance again — and a skinned garment is M3. M2's entity
|
|
38
|
+
* path has a chain rather than a surface, so it has no normal to offer: a rope
|
|
39
|
+
* has no inside. So the row ships with storage, a spec and a playground demo
|
|
40
|
+
* driving it directly, and `cloth_proxy_build` is what will fill it.
|
|
41
|
+
*
|
|
42
|
+
* ## No trust region, and no geometric stiffness
|
|
43
|
+
*
|
|
44
|
+
* `C` is **linear** in `x`, so its second derivative is exactly zero — there is
|
|
45
|
+
* no geometric term to keep or drop — and its gradient is a constant unit
|
|
46
|
+
* vector, so there is no distance beyond which the linearisation stops
|
|
47
|
+
* describing it. A backstop is the one row in the system whose model is not a
|
|
48
|
+
* model.
|
|
49
|
+
*
|
|
50
|
+
* @author Alex Goldring
|
|
51
|
+
* @copyright Company Named Limited (c) 2026
|
|
52
|
+
*/
|
|
53
|
+
/**
|
|
54
|
+
* Evaluate one backstop row's constraint value and its gradient.
|
|
55
|
+
*
|
|
56
|
+
* The definition the accumulation below inlines, and the one the
|
|
57
|
+
* finite-difference spec checks — there is no second copy of the arithmetic.
|
|
58
|
+
*
|
|
59
|
+
* @param {Float64Array|number[]} gradient out, `∂C/∂x`
|
|
60
|
+
* @param {number} gradient_offset
|
|
61
|
+
* @param {ClothState} state
|
|
62
|
+
* @param {number} row
|
|
63
|
+
* @returns {number} `C`
|
|
64
|
+
*/
|
|
65
|
+
export function cloth_backstop_evaluate(gradient: Float64Array | number[], gradient_offset: number, state: ClothState, row: number): number;
|
|
66
|
+
/**
|
|
67
|
+
* Add every backstop row touching `particle` into the vertex accumulator.
|
|
68
|
+
*
|
|
69
|
+
* @param {Float64Array} accumulator
|
|
70
|
+
* @param {ClothState} state
|
|
71
|
+
* @param {number} particle
|
|
72
|
+
*/
|
|
73
|
+
export function cloth_backstop_accumulate(accumulator: Float64Array, state: ClothState, particle: number): void;
|
|
74
|
+
/**
|
|
75
|
+
* Warm start every backstop row for a substep. Every one is hard, so — as with
|
|
76
|
+
* the leash table — there is no soft branch.
|
|
77
|
+
*
|
|
78
|
+
* @param {ClothState} state
|
|
79
|
+
* @param {number} alpha
|
|
80
|
+
* @param {number} gamma
|
|
81
|
+
* @param {number} k_min_ratio
|
|
82
|
+
* @param {number} k_max_ratio
|
|
83
|
+
* @param {number} inverse_h_squared
|
|
84
|
+
*/
|
|
85
|
+
export function cloth_backstop_warm_start(state: ClothState, alpha: number, gamma: number, k_min_ratio: number, k_max_ratio: number, inverse_h_squared: number): void;
|
|
86
|
+
/**
|
|
87
|
+
* Dual update for every backstop row.
|
|
88
|
+
*
|
|
89
|
+
* @param {ClothState} state
|
|
90
|
+
* @param {number} beta
|
|
91
|
+
* @param {number} k_max_ratio
|
|
92
|
+
* @param {number} inverse_h_squared
|
|
93
|
+
*/
|
|
94
|
+
export function cloth_backstop_dual_update(state: ClothState, beta: number, k_max_ratio: number, inverse_h_squared: number): void;
|
|
95
|
+
//# sourceMappingURL=cloth_backstop_row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloth_backstop_row.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH;;;;;;;;;;;GAWG;AACH,kDANW,YAAY,GAAC,MAAM,EAAE,mBACrB,MAAM,0BAEN,MAAM,GACJ,MAAM,CAuBlB;AAED;;;;;;GAMG;AACH,uDAJW,YAAY,+BAEZ,MAAM,QA8EhB;AAED;;;;;;;;;;GAUG;AACH,oEANW,MAAM,SACN,MAAM,eACN,MAAM,eACN,MAAM,qBACN,MAAM,QAuChB;AAED;;;;;;;GAOG;AACH,oEAJW,MAAM,eACN,MAAM,qBACN,MAAM,QA2ChB"}
|