@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
|
@@ -42,10 +42,30 @@
|
|
|
42
42
|
* row, which have the same `C` and differ only in where their centre and
|
|
43
43
|
* radius come from (`cloth_leash_row.js`). §6's strain-limit row needed no new
|
|
44
44
|
* storage at all — it is a stretch row with a longer rest length and a
|
|
45
|
-
* one-sided clamp, which the stretch table already carries.
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
45
|
+
* one-sided clamp, which the stretch table already carries. M2 adds the
|
|
46
|
+
* **backstop**, which is a leash against a plane rather than a point.
|
|
47
|
+
*
|
|
48
|
+
* ## Contacts are transient, and they live here anyway
|
|
49
|
+
*
|
|
50
|
+
* §5.4 says contact rows "never enter this structure" and are kept in a
|
|
51
|
+
* per-particle scratch applied Jacobi-style. Half of that is right and half of
|
|
52
|
+
* it is a solution to a problem a *collider* contact does not have.
|
|
53
|
+
*
|
|
54
|
+
* A contact against a collider is **unary** — one particle against a surface
|
|
55
|
+
* that is fixed for the substep — so it couples no two particles, so there is
|
|
56
|
+
* no Gauss-Seidel/Jacobi distinction to make and nothing to keep out of the
|
|
57
|
+
* colouring. It accumulates in the vertex update exactly like a leash row, in
|
|
58
|
+
* colour order, deterministically. What M4's particle-particle rows need is a
|
|
59
|
+
* different question and §9 is where it is answered.
|
|
60
|
+
*
|
|
61
|
+
* What *is* true is that a contact comes and goes, so it cannot be a CSR table
|
|
62
|
+
* sized at build time. It is instead a fixed **{@link CLOTH_CONTACT_SLOTS}
|
|
63
|
+
* slots per particle**, allocated once inside this buffer and rebuilt each
|
|
64
|
+
* step: an occupied slot names a collider, an empty one holds `-1`. That keeps
|
|
65
|
+
* §12's one-allocation property, bounds the worst case — a particle inside
|
|
66
|
+
* thirty colliders gets rows against the four nearest, which is the four that
|
|
67
|
+
* matter — and makes the accumulation a counted loop over adjacent slots
|
|
68
|
+
* rather than an indirection.
|
|
49
69
|
*
|
|
50
70
|
* A leash row is **unary** — one particle against a point — which has two
|
|
51
71
|
* pleasant consequences. It adds no edge to the particle graph, so the
|
|
@@ -82,9 +102,12 @@ export class ClothState {
|
|
|
82
102
|
* @param {Int32Array|number[]} [description.leash_particle] the particle each leash row holds
|
|
83
103
|
* @param {Float32Array|number[]} [description.leash_radius] leash radius per row; its length is
|
|
84
104
|
* the row count, and the leash centres are written per step rather than here
|
|
105
|
+
* @param {Int32Array|number[]} [description.backstop_particle] the particle each backstop row holds
|
|
106
|
+
* @param {Float32Array|number[]} [description.backstop_radius] backstop radius per row; the planes
|
|
107
|
+
* themselves are written per step rather than here
|
|
85
108
|
* @returns {ClothState}
|
|
86
109
|
*/
|
|
87
|
-
static from({ position, mass_inverse, stretch_particle, stretch_rest, stretch_stiffness, stretch_force_min, stretch_force_max, bend_particle, bend_weight, bend_stiffness, leash_particle, leash_radius }: {
|
|
110
|
+
static from({ position, mass_inverse, stretch_particle, stretch_rest, stretch_stiffness, stretch_force_min, stretch_force_max, bend_particle, bend_weight, bend_stiffness, leash_particle, leash_radius, backstop_particle, backstop_radius }: {
|
|
88
111
|
position: Float32Array | number[];
|
|
89
112
|
mass_inverse: Float32Array | number[];
|
|
90
113
|
stretch_particle?: Int32Array | number[];
|
|
@@ -97,6 +120,8 @@ export class ClothState {
|
|
|
97
120
|
bend_stiffness?: Float32Array | number[];
|
|
98
121
|
leash_particle?: Int32Array | number[];
|
|
99
122
|
leash_radius?: Float32Array | number[];
|
|
123
|
+
backstop_particle?: Int32Array | number[];
|
|
124
|
+
backstop_radius?: Float32Array | number[];
|
|
100
125
|
}): ClothState;
|
|
101
126
|
/**
|
|
102
127
|
* The single allocation every view below is cut from.
|
|
@@ -319,5 +344,183 @@ export class ClothState {
|
|
|
319
344
|
* @type {Int32Array}
|
|
320
345
|
*/
|
|
321
346
|
leash_adjacency: Int32Array;
|
|
347
|
+
/**
|
|
348
|
+
* @type {number}
|
|
349
|
+
*/
|
|
350
|
+
backstop_count: number;
|
|
351
|
+
/**
|
|
352
|
+
* Particle each backstop row holds, one per row.
|
|
353
|
+
* @type {Int32Array}
|
|
354
|
+
*/
|
|
355
|
+
backstop_particle: Int32Array;
|
|
356
|
+
/**
|
|
357
|
+
* The backstop plane per row: origin `b` then unit normal `n`, 6 per row,
|
|
358
|
+
* in the cloth's own local frame.
|
|
359
|
+
*
|
|
360
|
+
* **Written per step by the caller, not baked**, for the same reason
|
|
361
|
+
* {@link leash_target} is: a backstop is anchored to the *animated* pose —
|
|
362
|
+
* a point just inside the body with the surface normal there — and neither
|
|
363
|
+
* is a property of the rest shape. §6's row is
|
|
364
|
+
* `C = r_b − (x_i − b_i)·n_i`, so the row holds the particle at least
|
|
365
|
+
* {@link backstop_radius} out along its own normal from that point, which
|
|
366
|
+
* is what "never inside the body" means when the body is a shape the cloth
|
|
367
|
+
* does not have a collider for.
|
|
368
|
+
* @type {Float32Array}
|
|
369
|
+
*/
|
|
370
|
+
backstop_plane: Float32Array;
|
|
371
|
+
/**
|
|
372
|
+
* Backstop radius, one per row.
|
|
373
|
+
* @type {Float32Array}
|
|
374
|
+
*/
|
|
375
|
+
backstop_radius: Float32Array;
|
|
376
|
+
/**
|
|
377
|
+
* Augmented-Lagrangian multiplier, one per backstop row. Hard, like a leash.
|
|
378
|
+
* @type {Float32Array}
|
|
379
|
+
*/
|
|
380
|
+
backstop_lambda: Float32Array;
|
|
381
|
+
/**
|
|
382
|
+
* Penalty stiffness `k_c`, one per backstop row.
|
|
383
|
+
* @type {Float32Array}
|
|
384
|
+
*/
|
|
385
|
+
backstop_penalty: Float32Array;
|
|
386
|
+
/**
|
|
387
|
+
* CSR offsets into {@link backstop_adjacency}, `particle_count + 1` entries.
|
|
388
|
+
* @type {Int32Array}
|
|
389
|
+
*/
|
|
390
|
+
backstop_adjacency_offset: Int32Array;
|
|
391
|
+
/**
|
|
392
|
+
* Row indices — unary, like a leash.
|
|
393
|
+
* @type {Int32Array}
|
|
394
|
+
*/
|
|
395
|
+
backstop_adjacency: Int32Array;
|
|
396
|
+
/**
|
|
397
|
+
* Particle radius, metres — `ClothDynamics#thickness`, written by the
|
|
398
|
+
* caller before each step.
|
|
399
|
+
*
|
|
400
|
+
* A scalar rather than the per-particle array §12's table names, because
|
|
401
|
+
* nothing produces a proxy whose particles differ in size: a garment's
|
|
402
|
+
* thickness is a property of its fabric. A per-particle radius is what a
|
|
403
|
+
* decimated proxy with a strongly varying edge length would want, and the
|
|
404
|
+
* shape of that change is one array and one indexed read.
|
|
405
|
+
*
|
|
406
|
+
* It sits outside the buffer because it is a *parameter* rather than state
|
|
407
|
+
* — the same class of thing as `substeps`, which §12 sends across the
|
|
408
|
+
* worker boundary through the command region and not through the shared
|
|
409
|
+
* region.
|
|
410
|
+
* @type {number}
|
|
411
|
+
*/
|
|
412
|
+
contact_radius: number;
|
|
413
|
+
/**
|
|
414
|
+
* Which collider each contact slot holds, `CLOTH_CONTACT_SLOTS` per
|
|
415
|
+
* particle. A **record index into the caller's packed collider table**, not
|
|
416
|
+
* a handle, and `-1` for an empty slot.
|
|
417
|
+
* @type {Int32Array}
|
|
418
|
+
*/
|
|
419
|
+
contact_collider: Int32Array;
|
|
420
|
+
/**
|
|
421
|
+
* The collider's stable identity for each occupied slot — its handle in the
|
|
422
|
+
* `ClothColliderIndex`, which unlike the record index survives the table
|
|
423
|
+
* being rebuilt from a different query. This is the key §12 warm-starts a
|
|
424
|
+
* transient row on, and a collider that leaves the index drops its slot and
|
|
425
|
+
* its contacts start cold, which is correct.
|
|
426
|
+
* @type {Int32Array}
|
|
427
|
+
*/
|
|
428
|
+
contact_key: Int32Array;
|
|
429
|
+
/**
|
|
430
|
+
* Normal-force multiplier per contact slot, carried across steps.
|
|
431
|
+
* @type {Float32Array}
|
|
432
|
+
*/
|
|
433
|
+
contact_lambda: Float32Array;
|
|
434
|
+
/**
|
|
435
|
+
* Normal-force penalty per contact slot.
|
|
436
|
+
* @type {Float32Array}
|
|
437
|
+
*/
|
|
438
|
+
contact_penalty: Float32Array;
|
|
439
|
+
/**
|
|
440
|
+
* Friction multiplier per contact slot — the magnitude of the tangential
|
|
441
|
+
* force, because §6's friction row measures the *magnitude* of the slip and
|
|
442
|
+
* a magnitude has no sign to be clamped either side of.
|
|
443
|
+
* @type {Float32Array}
|
|
444
|
+
*/
|
|
445
|
+
contact_friction_lambda: Float32Array;
|
|
446
|
+
/**
|
|
447
|
+
* Friction penalty per contact slot.
|
|
448
|
+
* @type {Float32Array}
|
|
449
|
+
*/
|
|
450
|
+
contact_friction_penalty: Float32Array;
|
|
451
|
+
/**
|
|
452
|
+
* The radius a self-collision row holds two particles apart at, metres —
|
|
453
|
+
* **not** {@link contact_radius}, and M4 got that wrong before it measured
|
|
454
|
+
* its way out.
|
|
455
|
+
*
|
|
456
|
+
* §6 writes the row as `‖x_i − x_j‖ − (r_i + r_j)` with the same `r` a
|
|
457
|
+
* collider contact uses, which is `ClothDynamics#thickness`. A garment's
|
|
458
|
+
* fabric is 4 to 20 mm thick and a proxy's particles are 2 to 8 cm apart, so
|
|
459
|
+
* two layers of a fold are almost never within a fabric thickness of each
|
|
460
|
+
* other — their particles would have to line up, and nothing makes them.
|
|
461
|
+
*
|
|
462
|
+
* The radius that works is the **proxy's own resolution**: half the shortest
|
|
463
|
+
* row, so the row's diameter is one particle spacing. The pairs this row
|
|
464
|
+
* acts on are by construction the ones no fabric row governs, and the
|
|
465
|
+
* nearest of those is two hops away — so a diameter of one hop is the
|
|
466
|
+
* largest that cannot contradict a stretch row. Measured on a folding sheet
|
|
467
|
+
* at 2 cm spacing and 6 mm thickness, with only the radius moved: at the
|
|
468
|
+
* fabric's own 6 mm the row removes **21%** of the sheet's
|
|
469
|
+
* self-intersections, and at half the shortest row **82%**.
|
|
470
|
+
* `MEASUREMENTS.md` §31.
|
|
471
|
+
* @type {number}
|
|
472
|
+
*/
|
|
473
|
+
self_radius: number;
|
|
474
|
+
/**
|
|
475
|
+
* Self-collision pairs, 2 per pair, rebuilt every step (§9).
|
|
476
|
+
*
|
|
477
|
+
* A **pair** rather than a slot per particle, which is the difference from
|
|
478
|
+
* the contact table above and follows from the row being binary: a pair is
|
|
479
|
+
* stored once, with `i < j`, and contributes to both of its particles when
|
|
480
|
+
* the Jacobi scratch is built. Storing it on each side would double the
|
|
481
|
+
* memory to save an addition.
|
|
482
|
+
*
|
|
483
|
+
* The region is sized at build time — `CLOTH_SELF_PAIRS_PER_PARTICLE` per
|
|
484
|
+
* particle — and `self_count` says how much of it is live. A garment that
|
|
485
|
+
* crumples past that keeps what it found first and drops the rest, which is
|
|
486
|
+
* bounded and visible rather than an allocation per frame.
|
|
487
|
+
* @type {Int32Array}
|
|
488
|
+
*/
|
|
489
|
+
self_pair: Int32Array;
|
|
490
|
+
/**
|
|
491
|
+
* Live pairs in {@link self_pair}.
|
|
492
|
+
* @type {number}
|
|
493
|
+
*/
|
|
494
|
+
self_count: number;
|
|
495
|
+
/**
|
|
496
|
+
* The Jacobi scratch's force, 3 per particle — every self-collision row
|
|
497
|
+
* touching that particle, summed once per iteration from the positions the
|
|
498
|
+
* previous iteration left.
|
|
499
|
+
*
|
|
500
|
+
* §5.4's per-particle scratch, and this is the row kind it was written for:
|
|
501
|
+
* a pair is what the colouring cannot pre-partition, so applying it inside
|
|
502
|
+
* the sweep would make the answer depend on the order the sweep was split
|
|
503
|
+
* in. `MEASUREMENTS.md` §18 has why a *collider* contact needs none of this.
|
|
504
|
+
* @type {Float32Array}
|
|
505
|
+
*/
|
|
506
|
+
self_force: Float32Array;
|
|
507
|
+
/**
|
|
508
|
+
* The Jacobi scratch's Hessian, 6 per particle — the symmetric 3×3 in the
|
|
509
|
+
* same order {@link cloth_vertex_accumulator} uses: xx, yy, zz, xy, xz, yz.
|
|
510
|
+
* @type {Float32Array}
|
|
511
|
+
*/
|
|
512
|
+
self_hessian: Float32Array;
|
|
513
|
+
/**
|
|
514
|
+
* Where the particle last stuck to the collider, 3 per contact slot, in the
|
|
515
|
+
* **collider's own local frame**.
|
|
516
|
+
*
|
|
517
|
+
* That frame rather than the cloth's is the whole of what makes a sliding
|
|
518
|
+
* collider drag cloth with it: the anchor is stored where the collider will
|
|
519
|
+
* always agree it is, and read back wherever the collider has moved to. In
|
|
520
|
+
* the cloth's frame it would be a point in space and the friction row would
|
|
521
|
+
* hold the cloth still while the body slid out from under it.
|
|
522
|
+
* @type {Float32Array}
|
|
523
|
+
*/
|
|
524
|
+
contact_anchor: Float32Array;
|
|
322
525
|
}
|
|
323
526
|
//# sourceMappingURL=ClothState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClothState.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/ClothState.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ClothState.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/ClothState.js"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { assert } from "../../../../core/assert.js";
|
|
2
2
|
import { cloth_color_order, cloth_color_particles } from "./cloth_color_particles.js";
|
|
3
|
+
import { CLOTH_SELF_PAIRS_PER_PARTICLE } from "./cloth_self_find.js";
|
|
4
|
+
import { CLOTH_CONTACT_SLOTS } from "./constraint/cloth_contact_row.js";
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* # ClothState — the whole simulated cloth, SoA, over one buffer
|
|
@@ -45,10 +47,30 @@ import { cloth_color_order, cloth_color_particles } from "./cloth_color_particle
|
|
|
45
47
|
* row, which have the same `C` and differ only in where their centre and
|
|
46
48
|
* radius come from (`cloth_leash_row.js`). §6's strain-limit row needed no new
|
|
47
49
|
* storage at all — it is a stretch row with a longer rest length and a
|
|
48
|
-
* one-sided clamp, which the stretch table already carries.
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
50
|
+
* one-sided clamp, which the stretch table already carries. M2 adds the
|
|
51
|
+
* **backstop**, which is a leash against a plane rather than a point.
|
|
52
|
+
*
|
|
53
|
+
* ## Contacts are transient, and they live here anyway
|
|
54
|
+
*
|
|
55
|
+
* §5.4 says contact rows "never enter this structure" and are kept in a
|
|
56
|
+
* per-particle scratch applied Jacobi-style. Half of that is right and half of
|
|
57
|
+
* it is a solution to a problem a *collider* contact does not have.
|
|
58
|
+
*
|
|
59
|
+
* A contact against a collider is **unary** — one particle against a surface
|
|
60
|
+
* that is fixed for the substep — so it couples no two particles, so there is
|
|
61
|
+
* no Gauss-Seidel/Jacobi distinction to make and nothing to keep out of the
|
|
62
|
+
* colouring. It accumulates in the vertex update exactly like a leash row, in
|
|
63
|
+
* colour order, deterministically. What M4's particle-particle rows need is a
|
|
64
|
+
* different question and §9 is where it is answered.
|
|
65
|
+
*
|
|
66
|
+
* What *is* true is that a contact comes and goes, so it cannot be a CSR table
|
|
67
|
+
* sized at build time. It is instead a fixed **{@link CLOTH_CONTACT_SLOTS}
|
|
68
|
+
* slots per particle**, allocated once inside this buffer and rebuilt each
|
|
69
|
+
* step: an occupied slot names a collider, an empty one holds `-1`. That keeps
|
|
70
|
+
* §12's one-allocation property, bounds the worst case — a particle inside
|
|
71
|
+
* thirty colliders gets rows against the four nearest, which is the four that
|
|
72
|
+
* matter — and makes the accumulation a counted loop over adjacent slots
|
|
73
|
+
* rather than an indirection.
|
|
52
74
|
*
|
|
53
75
|
* A leash row is **unary** — one particle against a point — which has two
|
|
54
76
|
* pleasant consequences. It adds no edge to the particle graph, so the
|
|
@@ -318,6 +340,205 @@ export class ClothState {
|
|
|
318
340
|
*/
|
|
319
341
|
leash_adjacency = null;
|
|
320
342
|
|
|
343
|
+
/**
|
|
344
|
+
* @type {number}
|
|
345
|
+
*/
|
|
346
|
+
backstop_count = 0;
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Particle each backstop row holds, one per row.
|
|
350
|
+
* @type {Int32Array}
|
|
351
|
+
*/
|
|
352
|
+
backstop_particle = null;
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* The backstop plane per row: origin `b` then unit normal `n`, 6 per row,
|
|
356
|
+
* in the cloth's own local frame.
|
|
357
|
+
*
|
|
358
|
+
* **Written per step by the caller, not baked**, for the same reason
|
|
359
|
+
* {@link leash_target} is: a backstop is anchored to the *animated* pose —
|
|
360
|
+
* a point just inside the body with the surface normal there — and neither
|
|
361
|
+
* is a property of the rest shape. §6's row is
|
|
362
|
+
* `C = r_b − (x_i − b_i)·n_i`, so the row holds the particle at least
|
|
363
|
+
* {@link backstop_radius} out along its own normal from that point, which
|
|
364
|
+
* is what "never inside the body" means when the body is a shape the cloth
|
|
365
|
+
* does not have a collider for.
|
|
366
|
+
* @type {Float32Array}
|
|
367
|
+
*/
|
|
368
|
+
backstop_plane = null;
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Backstop radius, one per row.
|
|
372
|
+
* @type {Float32Array}
|
|
373
|
+
*/
|
|
374
|
+
backstop_radius = null;
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Augmented-Lagrangian multiplier, one per backstop row. Hard, like a leash.
|
|
378
|
+
* @type {Float32Array}
|
|
379
|
+
*/
|
|
380
|
+
backstop_lambda = null;
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Penalty stiffness `k_c`, one per backstop row.
|
|
384
|
+
* @type {Float32Array}
|
|
385
|
+
*/
|
|
386
|
+
backstop_penalty = null;
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* CSR offsets into {@link backstop_adjacency}, `particle_count + 1` entries.
|
|
390
|
+
* @type {Int32Array}
|
|
391
|
+
*/
|
|
392
|
+
backstop_adjacency_offset = null;
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Row indices — unary, like a leash.
|
|
396
|
+
* @type {Int32Array}
|
|
397
|
+
*/
|
|
398
|
+
backstop_adjacency = null;
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Particle radius, metres — `ClothDynamics#thickness`, written by the
|
|
402
|
+
* caller before each step.
|
|
403
|
+
*
|
|
404
|
+
* A scalar rather than the per-particle array §12's table names, because
|
|
405
|
+
* nothing produces a proxy whose particles differ in size: a garment's
|
|
406
|
+
* thickness is a property of its fabric. A per-particle radius is what a
|
|
407
|
+
* decimated proxy with a strongly varying edge length would want, and the
|
|
408
|
+
* shape of that change is one array and one indexed read.
|
|
409
|
+
*
|
|
410
|
+
* It sits outside the buffer because it is a *parameter* rather than state
|
|
411
|
+
* — the same class of thing as `substeps`, which §12 sends across the
|
|
412
|
+
* worker boundary through the command region and not through the shared
|
|
413
|
+
* region.
|
|
414
|
+
* @type {number}
|
|
415
|
+
*/
|
|
416
|
+
contact_radius = 0;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Which collider each contact slot holds, `CLOTH_CONTACT_SLOTS` per
|
|
420
|
+
* particle. A **record index into the caller's packed collider table**, not
|
|
421
|
+
* a handle, and `-1` for an empty slot.
|
|
422
|
+
* @type {Int32Array}
|
|
423
|
+
*/
|
|
424
|
+
contact_collider = null;
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* The collider's stable identity for each occupied slot — its handle in the
|
|
428
|
+
* `ClothColliderIndex`, which unlike the record index survives the table
|
|
429
|
+
* being rebuilt from a different query. This is the key §12 warm-starts a
|
|
430
|
+
* transient row on, and a collider that leaves the index drops its slot and
|
|
431
|
+
* its contacts start cold, which is correct.
|
|
432
|
+
* @type {Int32Array}
|
|
433
|
+
*/
|
|
434
|
+
contact_key = null;
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Normal-force multiplier per contact slot, carried across steps.
|
|
438
|
+
* @type {Float32Array}
|
|
439
|
+
*/
|
|
440
|
+
contact_lambda = null;
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Normal-force penalty per contact slot.
|
|
444
|
+
* @type {Float32Array}
|
|
445
|
+
*/
|
|
446
|
+
contact_penalty = null;
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Friction multiplier per contact slot — the magnitude of the tangential
|
|
450
|
+
* force, because §6's friction row measures the *magnitude* of the slip and
|
|
451
|
+
* a magnitude has no sign to be clamped either side of.
|
|
452
|
+
* @type {Float32Array}
|
|
453
|
+
*/
|
|
454
|
+
contact_friction_lambda = null;
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Friction penalty per contact slot.
|
|
458
|
+
* @type {Float32Array}
|
|
459
|
+
*/
|
|
460
|
+
contact_friction_penalty = null;
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* The radius a self-collision row holds two particles apart at, metres —
|
|
464
|
+
* **not** {@link contact_radius}, and M4 got that wrong before it measured
|
|
465
|
+
* its way out.
|
|
466
|
+
*
|
|
467
|
+
* §6 writes the row as `‖x_i − x_j‖ − (r_i + r_j)` with the same `r` a
|
|
468
|
+
* collider contact uses, which is `ClothDynamics#thickness`. A garment's
|
|
469
|
+
* fabric is 4 to 20 mm thick and a proxy's particles are 2 to 8 cm apart, so
|
|
470
|
+
* two layers of a fold are almost never within a fabric thickness of each
|
|
471
|
+
* other — their particles would have to line up, and nothing makes them.
|
|
472
|
+
*
|
|
473
|
+
* The radius that works is the **proxy's own resolution**: half the shortest
|
|
474
|
+
* row, so the row's diameter is one particle spacing. The pairs this row
|
|
475
|
+
* acts on are by construction the ones no fabric row governs, and the
|
|
476
|
+
* nearest of those is two hops away — so a diameter of one hop is the
|
|
477
|
+
* largest that cannot contradict a stretch row. Measured on a folding sheet
|
|
478
|
+
* at 2 cm spacing and 6 mm thickness, with only the radius moved: at the
|
|
479
|
+
* fabric's own 6 mm the row removes **21%** of the sheet's
|
|
480
|
+
* self-intersections, and at half the shortest row **82%**.
|
|
481
|
+
* `MEASUREMENTS.md` §31.
|
|
482
|
+
* @type {number}
|
|
483
|
+
*/
|
|
484
|
+
self_radius = 0;
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Self-collision pairs, 2 per pair, rebuilt every step (§9).
|
|
488
|
+
*
|
|
489
|
+
* A **pair** rather than a slot per particle, which is the difference from
|
|
490
|
+
* the contact table above and follows from the row being binary: a pair is
|
|
491
|
+
* stored once, with `i < j`, and contributes to both of its particles when
|
|
492
|
+
* the Jacobi scratch is built. Storing it on each side would double the
|
|
493
|
+
* memory to save an addition.
|
|
494
|
+
*
|
|
495
|
+
* The region is sized at build time — `CLOTH_SELF_PAIRS_PER_PARTICLE` per
|
|
496
|
+
* particle — and `self_count` says how much of it is live. A garment that
|
|
497
|
+
* crumples past that keeps what it found first and drops the rest, which is
|
|
498
|
+
* bounded and visible rather than an allocation per frame.
|
|
499
|
+
* @type {Int32Array}
|
|
500
|
+
*/
|
|
501
|
+
self_pair = null;
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Live pairs in {@link self_pair}.
|
|
505
|
+
* @type {number}
|
|
506
|
+
*/
|
|
507
|
+
self_count = 0;
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* The Jacobi scratch's force, 3 per particle — every self-collision row
|
|
511
|
+
* touching that particle, summed once per iteration from the positions the
|
|
512
|
+
* previous iteration left.
|
|
513
|
+
*
|
|
514
|
+
* §5.4's per-particle scratch, and this is the row kind it was written for:
|
|
515
|
+
* a pair is what the colouring cannot pre-partition, so applying it inside
|
|
516
|
+
* the sweep would make the answer depend on the order the sweep was split
|
|
517
|
+
* in. `MEASUREMENTS.md` §18 has why a *collider* contact needs none of this.
|
|
518
|
+
* @type {Float32Array}
|
|
519
|
+
*/
|
|
520
|
+
self_force = null;
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* The Jacobi scratch's Hessian, 6 per particle — the symmetric 3×3 in the
|
|
524
|
+
* same order {@link cloth_vertex_accumulator} uses: xx, yy, zz, xy, xz, yz.
|
|
525
|
+
* @type {Float32Array}
|
|
526
|
+
*/
|
|
527
|
+
self_hessian = null;
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Where the particle last stuck to the collider, 3 per contact slot, in the
|
|
531
|
+
* **collider's own local frame**.
|
|
532
|
+
*
|
|
533
|
+
* That frame rather than the cloth's is the whole of what makes a sliding
|
|
534
|
+
* collider drag cloth with it: the anchor is stored where the collider will
|
|
535
|
+
* always agree it is, and read back wherever the collider has moved to. In
|
|
536
|
+
* the cloth's frame it would be a point in space and the friction row would
|
|
537
|
+
* hold the cloth still while the body slid out from under it.
|
|
538
|
+
* @type {Float32Array}
|
|
539
|
+
*/
|
|
540
|
+
contact_anchor = null;
|
|
541
|
+
|
|
321
542
|
/**
|
|
322
543
|
* Build a cloth from a rest configuration and its rows.
|
|
323
544
|
*
|
|
@@ -344,6 +565,9 @@ export class ClothState {
|
|
|
344
565
|
* @param {Int32Array|number[]} [description.leash_particle] the particle each leash row holds
|
|
345
566
|
* @param {Float32Array|number[]} [description.leash_radius] leash radius per row; its length is
|
|
346
567
|
* the row count, and the leash centres are written per step rather than here
|
|
568
|
+
* @param {Int32Array|number[]} [description.backstop_particle] the particle each backstop row holds
|
|
569
|
+
* @param {Float32Array|number[]} [description.backstop_radius] backstop radius per row; the planes
|
|
570
|
+
* themselves are written per step rather than here
|
|
347
571
|
* @returns {ClothState}
|
|
348
572
|
*/
|
|
349
573
|
static from({
|
|
@@ -358,12 +582,15 @@ export class ClothState {
|
|
|
358
582
|
bend_weight = EMPTY_FLOAT32,
|
|
359
583
|
bend_stiffness = EMPTY_FLOAT32,
|
|
360
584
|
leash_particle = EMPTY_INT32,
|
|
361
|
-
leash_radius = EMPTY_FLOAT32
|
|
585
|
+
leash_radius = EMPTY_FLOAT32,
|
|
586
|
+
backstop_particle = EMPTY_INT32,
|
|
587
|
+
backstop_radius = EMPTY_FLOAT32
|
|
362
588
|
}) {
|
|
363
589
|
const particle_count = mass_inverse.length;
|
|
364
590
|
const stretch_count = stretch_rest.length;
|
|
365
591
|
const bend_count = bend_stiffness.length;
|
|
366
592
|
const leash_count = leash_radius.length;
|
|
593
|
+
const backstop_count = backstop_radius.length;
|
|
367
594
|
|
|
368
595
|
assert.equal(position.length, particle_count * 3, 'position.length');
|
|
369
596
|
assert.equal(stretch_particle.length, stretch_count * 2, 'stretch_particle.length');
|
|
@@ -371,6 +598,7 @@ export class ClothState {
|
|
|
371
598
|
assert.equal(bend_particle.length, bend_count * 4, 'bend_particle.length');
|
|
372
599
|
assert.equal(bend_weight.length, bend_count * 4, 'bend_weight.length');
|
|
373
600
|
assert.equal(leash_particle.length, leash_count, 'leash_particle.length');
|
|
601
|
+
assert.equal(backstop_particle.length, backstop_count, 'backstop_particle.length');
|
|
374
602
|
|
|
375
603
|
const colors = cloth_color_particles(
|
|
376
604
|
particle_count,
|
|
@@ -389,7 +617,7 @@ export class ClothState {
|
|
|
389
617
|
|
|
390
618
|
const state = new ClothState();
|
|
391
619
|
|
|
392
|
-
allocate(state, particle_count, stretch_count, bend_count, leash_count, colour_count);
|
|
620
|
+
allocate(state, particle_count, stretch_count, bend_count, leash_count, backstop_count, colour_count);
|
|
393
621
|
|
|
394
622
|
state.colour_offset.set(colour_offset);
|
|
395
623
|
state.source_of_particle.set(order);
|
|
@@ -474,6 +702,31 @@ export class ClothState {
|
|
|
474
702
|
state.leash_particle, leash_count, particle_count
|
|
475
703
|
);
|
|
476
704
|
|
|
705
|
+
for (let row = 0; row < backstop_count; row++) {
|
|
706
|
+
const particle = particle_of_source[backstop_particle[row]];
|
|
707
|
+
|
|
708
|
+
state.backstop_particle[row] = particle;
|
|
709
|
+
state.backstop_radius[row] = backstop_radius[row];
|
|
710
|
+
|
|
711
|
+
// Seeded at the particle with an upward normal, where `C` is
|
|
712
|
+
// `radius` and the row is *violated* rather than inactive — so an
|
|
713
|
+
// unwritten backstop is visible as a row doing something, rather
|
|
714
|
+
// than as a plane through the origin that looks plausible. The
|
|
715
|
+
// caller writes the real plane before the first step.
|
|
716
|
+
state.backstop_plane[row * 6] = state.position[particle * 3];
|
|
717
|
+
state.backstop_plane[row * 6 + 1] = state.position[particle * 3 + 1];
|
|
718
|
+
state.backstop_plane[row * 6 + 2] = state.position[particle * 3 + 2];
|
|
719
|
+
state.backstop_plane[row * 6 + 4] = 1;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
build_unary_adjacency(
|
|
723
|
+
state.backstop_adjacency_offset, state.backstop_adjacency,
|
|
724
|
+
state.backstop_particle, backstop_count, particle_count
|
|
725
|
+
);
|
|
726
|
+
|
|
727
|
+
state.contact_collider.fill(-1);
|
|
728
|
+
state.contact_key.fill(-1);
|
|
729
|
+
|
|
477
730
|
return state;
|
|
478
731
|
}
|
|
479
732
|
}
|
|
@@ -503,7 +756,10 @@ const EMPTY_FLOAT32 = new Float32Array(0);
|
|
|
503
756
|
* @param {number} colour_count
|
|
504
757
|
* @private
|
|
505
758
|
*/
|
|
506
|
-
function allocate(state, particle_count, stretch_count, bend_count, leash_count, colour_count) {
|
|
759
|
+
function allocate(state, particle_count, stretch_count, bend_count, leash_count, backstop_count, colour_count) {
|
|
760
|
+
const contact_count = particle_count * CLOTH_CONTACT_SLOTS;
|
|
761
|
+
const self_capacity = particle_count * CLOTH_SELF_PAIRS_PER_PARTICLE;
|
|
762
|
+
|
|
507
763
|
const sizes = [
|
|
508
764
|
particle_count * 3, // position
|
|
509
765
|
particle_count * 3, // position_previous
|
|
@@ -535,7 +791,24 @@ function allocate(state, particle_count, stretch_count, bend_count, leash_count,
|
|
|
535
791
|
leash_count, // leash_lambda
|
|
536
792
|
leash_count, // leash_penalty
|
|
537
793
|
particle_count + 1, // leash_adjacency_offset
|
|
538
|
-
leash_count
|
|
794
|
+
leash_count, // leash_adjacency
|
|
795
|
+
backstop_count, // backstop_particle
|
|
796
|
+
backstop_count * 6, // backstop_plane
|
|
797
|
+
backstop_count, // backstop_radius
|
|
798
|
+
backstop_count, // backstop_lambda
|
|
799
|
+
backstop_count, // backstop_penalty
|
|
800
|
+
particle_count + 1, // backstop_adjacency_offset
|
|
801
|
+
backstop_count, // backstop_adjacency
|
|
802
|
+
contact_count, // contact_collider
|
|
803
|
+
contact_count, // contact_key
|
|
804
|
+
contact_count, // contact_lambda
|
|
805
|
+
contact_count, // contact_penalty
|
|
806
|
+
contact_count, // contact_friction_lambda
|
|
807
|
+
contact_count, // contact_friction_penalty
|
|
808
|
+
contact_count * 3, // contact_anchor
|
|
809
|
+
self_capacity * 2, // self_pair
|
|
810
|
+
particle_count * 3, // self_force
|
|
811
|
+
particle_count * 6 // self_hessian
|
|
539
812
|
];
|
|
540
813
|
|
|
541
814
|
let total = 0;
|
|
@@ -565,6 +838,7 @@ function allocate(state, particle_count, stretch_count, bend_count, leash_count,
|
|
|
565
838
|
state.stretch_count = stretch_count;
|
|
566
839
|
state.bend_count = bend_count;
|
|
567
840
|
state.leash_count = leash_count;
|
|
841
|
+
state.backstop_count = backstop_count;
|
|
568
842
|
state.colour_count = colour_count;
|
|
569
843
|
|
|
570
844
|
state.position = cut(Float32Array, particle_count * 3);
|
|
@@ -602,6 +876,26 @@ function allocate(state, particle_count, stretch_count, bend_count, leash_count,
|
|
|
602
876
|
state.leash_adjacency_offset = cut(Int32Array, particle_count + 1);
|
|
603
877
|
state.leash_adjacency = cut(Int32Array, leash_count);
|
|
604
878
|
|
|
879
|
+
state.backstop_particle = cut(Int32Array, backstop_count);
|
|
880
|
+
state.backstop_plane = cut(Float32Array, backstop_count * 6);
|
|
881
|
+
state.backstop_radius = cut(Float32Array, backstop_count);
|
|
882
|
+
state.backstop_lambda = cut(Float32Array, backstop_count);
|
|
883
|
+
state.backstop_penalty = cut(Float32Array, backstop_count);
|
|
884
|
+
state.backstop_adjacency_offset = cut(Int32Array, particle_count + 1);
|
|
885
|
+
state.backstop_adjacency = cut(Int32Array, backstop_count);
|
|
886
|
+
|
|
887
|
+
state.contact_collider = cut(Int32Array, contact_count);
|
|
888
|
+
state.contact_key = cut(Int32Array, contact_count);
|
|
889
|
+
state.contact_lambda = cut(Float32Array, contact_count);
|
|
890
|
+
state.contact_penalty = cut(Float32Array, contact_count);
|
|
891
|
+
state.contact_friction_lambda = cut(Float32Array, contact_count);
|
|
892
|
+
state.contact_friction_penalty = cut(Float32Array, contact_count);
|
|
893
|
+
state.contact_anchor = cut(Float32Array, contact_count * 3);
|
|
894
|
+
|
|
895
|
+
state.self_pair = cut(Int32Array, self_capacity * 2);
|
|
896
|
+
state.self_force = cut(Float32Array, particle_count * 3);
|
|
897
|
+
state.self_hessian = cut(Float32Array, particle_count * 6);
|
|
898
|
+
|
|
605
899
|
assert.equal(cursor, total, 'buffer cursor at end of allocation');
|
|
606
900
|
}
|
|
607
901
|
|