@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
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # Putting the answer back onto a skinned model's joints — §11.2
|
|
3
|
+
*
|
|
4
|
+
* The same reconstruction the entity path uses, written onto `Node3D`s instead
|
|
5
|
+
* of onto entities. **Cloth moves joints; it does not produce vertices** — the
|
|
6
|
+
* mapping from a simulated joint to a render vertex already exists in this
|
|
7
|
+
* engine and it is the skin, so the existing skinning pass does the rest,
|
|
8
|
+
* including bounds refresh and BLAS refit that a bespoke vertex-deformation
|
|
9
|
+
* path would have to reimplement.
|
|
10
|
+
*
|
|
11
|
+
* ## `transform_local` is the output, and `transform_global` is written too
|
|
12
|
+
*
|
|
13
|
+
* `transform_local` is a joint's own truth and the handle §11.2 names. It is
|
|
14
|
+
* also *passive*: a `Node3D` does not track its components, and nothing
|
|
15
|
+
* downstream sees a change until `updateMatrices` runs — which recurses into
|
|
16
|
+
* every descendant, so calling it on the anchor would recompose the whole
|
|
17
|
+
* character every fixed step to move a cape.
|
|
18
|
+
*
|
|
19
|
+
* So this pass composes the cloth subtree's `transform_global` itself, which
|
|
20
|
+
* costs nothing because the pose is already in hand, and bumps each joint's
|
|
21
|
+
* version through `needsUpdate` so the renderer uploads the row. Nothing above
|
|
22
|
+
* the anchor is touched and nothing below the garment is walked.
|
|
23
|
+
*
|
|
24
|
+
* `transform_global` is derived, so writing it is only ever a shortcut for the
|
|
25
|
+
* recomposition it saves — and it is a *correct* shortcut only because this
|
|
26
|
+
* pass has the anchor's world pose and the whole chain under it. Anything that
|
|
27
|
+
* moves the anchor without telling cloth invalidates it, which is the same
|
|
28
|
+
* contract every consumer of a derived transform already has.
|
|
29
|
+
*
|
|
30
|
+
* ## What is not here
|
|
31
|
+
*
|
|
32
|
+
* No announcement, and no pruned boundary. The entity path has both because its
|
|
33
|
+
* subtree is an entity hierarchy with other things hanging off it; a proxy's
|
|
34
|
+
* joint list is closed by construction, and a socket parented to a cape joint
|
|
35
|
+
* follows it through the ordinary node hierarchy.
|
|
36
|
+
*
|
|
37
|
+
* @author Alex Goldring
|
|
38
|
+
* @copyright Company Named Limited (c) 2026
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* Write one cloth's solved pose onto the joints it drives.
|
|
42
|
+
*
|
|
43
|
+
* @param {ClothInstance} instance
|
|
44
|
+
* @param {Transform64} anchor the anchor joint's **world** pose, evaluated by
|
|
45
|
+
* the caller — see `ClothSystem` for why it is not read off the node
|
|
46
|
+
* @returns {void}
|
|
47
|
+
*/
|
|
48
|
+
export function cloth_write_back_rig(instance: ClothInstance, anchor: Transform64): void;
|
|
49
|
+
//# sourceMappingURL=cloth_write_back_rig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloth_write_back_rig.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_write_back_rig.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH;;;;;;;GAOG;AACH,oFAFa,IAAI,CA2DhB"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { quat3_multiply } from "../../../../core/geom/3d/quaternion/quat3_multiply.js";
|
|
2
|
+
import { v3_quaternion_apply } from "../../../../core/geom/vec3/v3_quaternion_apply.js";
|
|
3
|
+
import {
|
|
4
|
+
TRANSFORM64_ROTATION_OFFSET,
|
|
5
|
+
TRANSFORM64_TRANSLATION_OFFSET
|
|
6
|
+
} from "../../../ecs/transform/Transform64.js";
|
|
7
|
+
import { cloth_reconstruct_pose } from "./cloth_reconstruct_pose.js";
|
|
8
|
+
import { cloth_write_local_pose } from "./cloth_write_back.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* # Putting the answer back onto a skinned model's joints — §11.2
|
|
12
|
+
*
|
|
13
|
+
* The same reconstruction the entity path uses, written onto `Node3D`s instead
|
|
14
|
+
* of onto entities. **Cloth moves joints; it does not produce vertices** — the
|
|
15
|
+
* mapping from a simulated joint to a render vertex already exists in this
|
|
16
|
+
* engine and it is the skin, so the existing skinning pass does the rest,
|
|
17
|
+
* including bounds refresh and BLAS refit that a bespoke vertex-deformation
|
|
18
|
+
* path would have to reimplement.
|
|
19
|
+
*
|
|
20
|
+
* ## `transform_local` is the output, and `transform_global` is written too
|
|
21
|
+
*
|
|
22
|
+
* `transform_local` is a joint's own truth and the handle §11.2 names. It is
|
|
23
|
+
* also *passive*: a `Node3D` does not track its components, and nothing
|
|
24
|
+
* downstream sees a change until `updateMatrices` runs — which recurses into
|
|
25
|
+
* every descendant, so calling it on the anchor would recompose the whole
|
|
26
|
+
* character every fixed step to move a cape.
|
|
27
|
+
*
|
|
28
|
+
* So this pass composes the cloth subtree's `transform_global` itself, which
|
|
29
|
+
* costs nothing because the pose is already in hand, and bumps each joint's
|
|
30
|
+
* version through `needsUpdate` so the renderer uploads the row. Nothing above
|
|
31
|
+
* the anchor is touched and nothing below the garment is walked.
|
|
32
|
+
*
|
|
33
|
+
* `transform_global` is derived, so writing it is only ever a shortcut for the
|
|
34
|
+
* recomposition it saves — and it is a *correct* shortcut only because this
|
|
35
|
+
* pass has the anchor's world pose and the whole chain under it. Anything that
|
|
36
|
+
* moves the anchor without telling cloth invalidates it, which is the same
|
|
37
|
+
* contract every consumer of a derived transform already has.
|
|
38
|
+
*
|
|
39
|
+
* ## What is not here
|
|
40
|
+
*
|
|
41
|
+
* No announcement, and no pruned boundary. The entity path has both because its
|
|
42
|
+
* subtree is an entity hierarchy with other things hanging off it; a proxy's
|
|
43
|
+
* joint list is closed by construction, and a socket parented to a cape joint
|
|
44
|
+
* follows it through the ordinary node hierarchy.
|
|
45
|
+
*
|
|
46
|
+
* @author Alex Goldring
|
|
47
|
+
* @copyright Company Named Limited (c) 2026
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Write one cloth's solved pose onto the joints it drives.
|
|
52
|
+
*
|
|
53
|
+
* @param {ClothInstance} instance
|
|
54
|
+
* @param {Transform64} anchor the anchor joint's **world** pose, evaluated by
|
|
55
|
+
* the caller — see `ClothSystem` for why it is not read off the node
|
|
56
|
+
* @returns {void}
|
|
57
|
+
*/
|
|
58
|
+
export function cloth_write_back_rig(instance, anchor) {
|
|
59
|
+
cloth_reconstruct_pose(instance);
|
|
60
|
+
|
|
61
|
+
const node_count = instance.node_count;
|
|
62
|
+
|
|
63
|
+
const blended = instance.blended_position;
|
|
64
|
+
const reconstructed = instance.blended_rotation;
|
|
65
|
+
|
|
66
|
+
const ax = anchor[TRANSFORM64_TRANSLATION_OFFSET];
|
|
67
|
+
const ay = anchor[TRANSFORM64_TRANSLATION_OFFSET + 1];
|
|
68
|
+
const az = anchor[TRANSFORM64_TRANSLATION_OFFSET + 2];
|
|
69
|
+
|
|
70
|
+
const aqx = anchor[TRANSFORM64_ROTATION_OFFSET];
|
|
71
|
+
const aqy = anchor[TRANSFORM64_ROTATION_OFFSET + 1];
|
|
72
|
+
const aqz = anchor[TRANSFORM64_ROTATION_OFFSET + 2];
|
|
73
|
+
const aqw = anchor[TRANSFORM64_ROTATION_OFFSET + 3];
|
|
74
|
+
|
|
75
|
+
const parent = instance.node_parent;
|
|
76
|
+
const node_joint = instance.node_joint;
|
|
77
|
+
|
|
78
|
+
for (let node = 1; node < node_count; node++) {
|
|
79
|
+
const joint = node_joint[node];
|
|
80
|
+
|
|
81
|
+
if (joint === undefined || joint === null) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
cloth_write_local_pose(joint.transform_local, instance, node, parent[node]);
|
|
86
|
+
|
|
87
|
+
const global = joint.transform_global;
|
|
88
|
+
|
|
89
|
+
const n = node * 3;
|
|
90
|
+
|
|
91
|
+
v3_quaternion_apply(
|
|
92
|
+
global, TRANSFORM64_TRANSLATION_OFFSET,
|
|
93
|
+
blended[n], blended[n + 1], blended[n + 2],
|
|
94
|
+
aqx, aqy, aqz, aqw
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
global[TRANSFORM64_TRANSLATION_OFFSET] += ax;
|
|
98
|
+
global[TRANSFORM64_TRANSLATION_OFFSET + 1] += ay;
|
|
99
|
+
global[TRANSFORM64_TRANSLATION_OFFSET + 2] += az;
|
|
100
|
+
|
|
101
|
+
quat3_multiply(
|
|
102
|
+
global, TRANSFORM64_ROTATION_OFFSET,
|
|
103
|
+
aqx, aqy, aqz, aqw,
|
|
104
|
+
reconstructed[node * 4], reconstructed[node * 4 + 1],
|
|
105
|
+
reconstructed[node * 4 + 2], reconstructed[node * 4 + 3]
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
global.updateMatrix();
|
|
109
|
+
|
|
110
|
+
// The version is what the renderer compares against to decide whether
|
|
111
|
+
// to upload the row, so a joint whose transform changed and whose
|
|
112
|
+
// version did not is a joint that moved nowhere.
|
|
113
|
+
joint.needsUpdate = true;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
npm run dev --workspace @woosh/meep-engine
|
|
5
5
|
```
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Four pages, one directory, one layer of the system each. (Vite takes the next
|
|
8
8
|
free port if 5173 is busy — the terminal says which.)
|
|
9
9
|
|
|
10
10
|
| | |
|
|
11
11
|
|---|---|
|
|
12
12
|
| [`index.html`](./index.html) | **the solver, M0.** `cloth_step` over a `ClothState`, no ECS at all. |
|
|
13
13
|
| [`rig.html`](./rig.html) | **the entity subtree, M1.** A real `EntityManager`, real entities, `ClothSystem` walking and writing back. |
|
|
14
|
+
| [`collide.html`](./collide.html) | **collision, M2.** The solver again, with a packed collider table in the argument list. |
|
|
15
|
+
| [`garment.html`](./garment.html) | **skinned garments, M3, and self-collision, M4.** A `Node3D` skeleton, a `Skin`, and a `Cloth` + `ClothRig` driving some of its joints. |
|
|
14
16
|
|
|
15
17
|
Both are at
|
|
16
18
|
`http://localhost:5173/src/engine/physics/cloth/playground/<page>`.
|
|
@@ -183,3 +185,155 @@ real: `rebuild` returns a promise, because `EntityManager#startup` does and an
|
|
|
183
185
|
entity created before it resolves is never linked; and `render` is separate from
|
|
184
186
|
`step_once`, because `requestAnimationFrame` does not fire in a hidden pane and
|
|
185
187
|
everything on the page hangs off it.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
# The collision page — `collide.html`
|
|
192
|
+
|
|
193
|
+
## What it is
|
|
194
|
+
|
|
195
|
+
The solver page again, with a **packed collider table** in `cloth_step`'s
|
|
196
|
+
argument list. There is no `EntityManager`, no `ClothColliderIndex` and no
|
|
197
|
+
`ClothColliderSystem`: `collide_build.js` hands the solver exactly what
|
|
198
|
+
`cloth_gather_colliders` would, already in the cloth's own frame, so what is on
|
|
199
|
+
screen is the layer M2's findings live in and nothing above it.
|
|
200
|
+
|
|
201
|
+
Two of those findings are things to *watch* rather than read.
|
|
202
|
+
|
|
203
|
+
**The sweep, which is not really about tunnelling.** Pick **a capsule swept
|
|
204
|
+
through** and press *end-of-step only*. The capsule stops being *noticed*: the
|
|
205
|
+
contact readout drops by four while the capsule visibly passes through the sheet.
|
|
206
|
+
Discovery evaluates the field at the end-of-step pose, so a collider that crossed
|
|
207
|
+
the cloth within the step is nowhere near it by then, and without the travel term
|
|
208
|
+
in the discovery reach no row is ever created for the swept poses to act through.
|
|
209
|
+
At 20 m/s in `MEASUREMENTS.md` §20 the difference is 95 rows a step against none.
|
|
210
|
+
|
|
211
|
+
**The penalty floor, which decides how hard a new contact hits.** Pick **the
|
|
212
|
+
ground**, drag `k_min ÷ k_max` to 1, and press *reset*: the cape slaps down.
|
|
213
|
+
Drag it back to 1/32 and it lands. Peak contact force across that range measured
|
|
214
|
+
18.9 N against 0.16 N, and the settled energy six orders of magnitude apart —
|
|
215
|
+
with the *penetration improving* at the low end, which is the augmented
|
|
216
|
+
Lagrangian working as designed. §17.
|
|
217
|
+
|
|
218
|
+
## The scenes
|
|
219
|
+
|
|
220
|
+
- **sphere under a cape** — the simplest thing a contact row can be right about.
|
|
221
|
+
- **every primitive** — sphere, capsule, box and cylinder side by side, each
|
|
222
|
+
protruding 25 mm through the sheet. Four different fields, one dispatch, and
|
|
223
|
+
the same free functions the shape classes now call.
|
|
224
|
+
- **the ground** — `PlaneShape3D`, which §14.3 asked for and did not exist.
|
|
225
|
+
- **a shoulder, animated** — three capsules as an arm, swinging. The swept pose,
|
|
226
|
+
in the configuration it was designed for.
|
|
227
|
+
- **a capsule swept through** — 3 m/s straight through the sheet. The sweep
|
|
228
|
+
toggle's scene.
|
|
229
|
+
- **a spinning bar** — a bar turning behind the cape and through its plane. It is
|
|
230
|
+
also the one scene that does not resolve: a rigid collider driven through cloth
|
|
231
|
+
that is pinned above it wraps rather than parts, and the 18 mm of resting
|
|
232
|
+
penetration is the row bounding a case it cannot prevent. That is authoring
|
|
233
|
+
rather than a solver gap, and it is here so it is visible rather than
|
|
234
|
+
surprising.
|
|
235
|
+
|
|
236
|
+
## The readout
|
|
237
|
+
|
|
238
|
+
- **contacts** — rows the discovery pass created this step. Zero while a collider
|
|
239
|
+
is visibly passing through the cloth is the finding above.
|
|
240
|
+
- **worst penetration** — the deepest any particle got, over the whole run.
|
|
241
|
+
- **resting penetration** — how deep anything is *now*. This is the number that
|
|
242
|
+
says whether a screenshot showing a sphere apparently poking through a cape is
|
|
243
|
+
a simulation problem or a drawing one — the collider outline is dashed and has
|
|
244
|
+
no depth test, so it is painted over the cloth whether it is in front or behind.
|
|
245
|
+
- **step** — milliseconds for `cloth_contact_find` plus `cloth_step`, window
|
|
246
|
+
minimum, against §17's 2 ms. Browser `performance.now()` is coarse and a hidden
|
|
247
|
+
pane throttles the page; `__fixtures__/cloth_m2_measure.mjs` under node is the
|
|
248
|
+
number that means something.
|
|
249
|
+
|
|
250
|
+
## Notes
|
|
251
|
+
|
|
252
|
+
`globalThis.cloth_collide_playground` exposes `{ control, camera, rebuild,
|
|
253
|
+
step_once, penetration, cloth, colliders, contacts }`. `requestAnimationFrame`
|
|
254
|
+
does not fire in a hidden pane, so a driver calls `step_once` itself.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
# The garment page — `garment.html`
|
|
259
|
+
|
|
260
|
+
## What it is
|
|
261
|
+
|
|
262
|
+
`rig.html` is a `Cloth` over an entity subtree; this is a `Cloth` + a `ClothRig`
|
|
263
|
+
over a skinned model's **joints**. Every point on screen is a
|
|
264
|
+
`Node3D.transform_global` — a joint of a `Skin`, not an entity — and it is where
|
|
265
|
+
it is because the solver wrote its `transform_local` and this page composed the
|
|
266
|
+
chain.
|
|
267
|
+
|
|
268
|
+
`ClothSystem#models` takes a stub rather than a `MeshSystem` for the reason the
|
|
269
|
+
field exists: a `MeshSystem` needs a graphics engine, a scene and a loader, and a
|
|
270
|
+
garment's joints are a `Node3D` tree that needs none of the three. The stub
|
|
271
|
+
answers exactly the one method the system calls.
|
|
272
|
+
|
|
273
|
+
## The garments
|
|
274
|
+
|
|
275
|
+
- **cape** — five strips of seven off the chest. The common case and the cheap
|
|
276
|
+
one: an artist made the joints and skinned the cape to them, so the proxy is
|
|
277
|
+
joint indices, the topology and the bind pose. No binding step, no generated
|
|
278
|
+
geometry.
|
|
279
|
+
- **coat tails** — three strips of nine in denim, which is the library entry that
|
|
280
|
+
spends its two levers on particles rather than iterations.
|
|
281
|
+
- **ponytail** — one chain of twelve off the neck. The rig path is the entity
|
|
282
|
+
path with `Node3D`s in it, and a single chain is where that is most obviously
|
|
283
|
+
true.
|
|
284
|
+
- **loincloth** — seven strips of five off the pelvis, and the one preset that
|
|
285
|
+
spends most of its time against the leg colliders.
|
|
286
|
+
|
|
287
|
+
## The motion drives the character, and only the character
|
|
288
|
+
|
|
289
|
+
The buttons write the **character's own bones**. The garment's joints are
|
|
290
|
+
cloth's, and the seed says so: it claims `TransformAuthority.CPU` on every one of
|
|
291
|
+
them, because a joint a clip drives is under GPU authority and its
|
|
292
|
+
`transform_local` is not read by anything. Two writers of one row is the race the
|
|
293
|
+
authority enum exists to prevent, and the claim is where a garment whose joints
|
|
294
|
+
are *also* keyed shows up as an authoring error.
|
|
295
|
+
|
|
296
|
+
**sprint** is §7 P7's own profile: a square wave in velocity, integrated. Written
|
|
297
|
+
as a position that resets it would be a nine-metre discontinuity, which is a
|
|
298
|
+
teleport wearing a sprint's clothes — and the cloth would be right to treat it as
|
|
299
|
+
one.
|
|
300
|
+
|
|
301
|
+
## The readout
|
|
302
|
+
|
|
303
|
+
- **worst |x−anchor| / d_geo** — §7 P2's rubber number. Green at rest and under
|
|
304
|
+
walking and turning; **sprint takes it past 1.1**, which is P2's own conditional
|
|
305
|
+
bound showing on a shape M1 did not measure. `MEASUREMENTS.md` §26 has both
|
|
306
|
+
paths side by side, and they agree to the digit — this is the geometry, not the
|
|
307
|
+
rig path.
|
|
308
|
+
- **contacts** — with **collide with the body** on. A cape clear of its own
|
|
309
|
+
torso reads zero here most of the time, which is what a garment that was
|
|
310
|
+
authored correctly looks like; see below.
|
|
311
|
+
- **self pairs** — M4's, with **collide with itself** on. Zero while the
|
|
312
|
+
garment hangs and climbing the moment a fold closes, which is the shape of
|
|
313
|
+
the whole tier: it is a broadphase over particles and it has nothing to do
|
|
314
|
+
until two of them are near. Three library entries set the flag — silk,
|
|
315
|
+
cotton and hair — and the button overrides whichever the fabric picker is
|
|
316
|
+
on, by cloning the frozen entry and moving one bit.
|
|
317
|
+
|
|
318
|
+
**The radius is the proxy's resolution, not the fabric's thickness**, and it
|
|
319
|
+
is the single thing most worth knowing about this tier. Silk is 4 mm thick
|
|
320
|
+
and this cape's particles are 8 cm apart; at 4 mm the two layers of a fold
|
|
321
|
+
are never in contact and the feature does nothing at all.
|
|
322
|
+
`MEASUREMENTS.md` §31 is the sweep, §36 is the clamp at the other end.
|
|
323
|
+
|
|
324
|
+
## The one thing worth knowing before authoring a garment
|
|
325
|
+
|
|
326
|
+
A garment authored **inside** its own body collider reads as a *tether* failure.
|
|
327
|
+
The contact row pushes it out, the tether pulls it back, the contact wins, and
|
|
328
|
+
the readout says the tether is failing by thirty per cent. It is not. §11.3
|
|
329
|
+
step 10 validates exactly this at build time — "the skinned bind pose is
|
|
330
|
+
collision-free against the character's `ClothCollider` set" — and M3 does not
|
|
331
|
+
build that check, so this page's geometry is right by hand. `MEASUREMENTS.md` §29
|
|
332
|
+
has the numbers, because it cost an hour to diagnose the first time.
|
|
333
|
+
|
|
334
|
+
## Notes
|
|
335
|
+
|
|
336
|
+
`globalThis.cloth_garment_playground` exposes `{ control, camera, ready, rebuild,
|
|
337
|
+
step_once, draw, scene }`. `rebuild` returns a promise, because
|
|
338
|
+
`EntityManager#startup` does and an entity created before it resolves is never
|
|
339
|
+
linked.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>meep — cloth collision (M2)</title>
|
|
6
|
+
<style>
|
|
7
|
+
:root {
|
|
8
|
+
color-scheme: dark;
|
|
9
|
+
--ink: #d6dae0;
|
|
10
|
+
--dim: #8b939f;
|
|
11
|
+
--line: #2b3038;
|
|
12
|
+
--panel: #14171c;
|
|
13
|
+
--warn: #e5b54a;
|
|
14
|
+
--bad: #e5533d;
|
|
15
|
+
--good: #5ad19a;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
html, body {
|
|
19
|
+
margin: 0;
|
|
20
|
+
height: 100%;
|
|
21
|
+
background: #0d0f12;
|
|
22
|
+
color: var(--ink);
|
|
23
|
+
font: 12px/1.5 ui-monospace, Consolas, monospace;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
body { display: flex; }
|
|
28
|
+
|
|
29
|
+
#stage { position: relative; flex: 1; min-width: 0; }
|
|
30
|
+
#view { display: block; width: 100%; height: 100%; cursor: grab; }
|
|
31
|
+
#view.grabbing { cursor: grabbing; }
|
|
32
|
+
|
|
33
|
+
#hint {
|
|
34
|
+
position: absolute; left: 14px; bottom: 12px;
|
|
35
|
+
color: var(--dim); pointer-events: none;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#readout {
|
|
39
|
+
position: absolute; left: 14px; top: 12px;
|
|
40
|
+
background: rgba(13, 15, 18, 0.82);
|
|
41
|
+
border: 1px solid var(--line);
|
|
42
|
+
padding: 8px 12px;
|
|
43
|
+
min-width: 260px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#readout table { border-collapse: collapse; width: 100%; }
|
|
47
|
+
#readout td { padding: 1px 0; white-space: nowrap; }
|
|
48
|
+
#readout td:last-child { text-align: right; padding-left: 18px; }
|
|
49
|
+
#readout td:first-child { color: var(--dim); }
|
|
50
|
+
|
|
51
|
+
#budget {
|
|
52
|
+
height: 4px; margin-top: 7px;
|
|
53
|
+
background: #22262d; position: relative; overflow: hidden;
|
|
54
|
+
}
|
|
55
|
+
#budget > i { display: block; height: 100%; background: var(--good); width: 0; }
|
|
56
|
+
#budget.over > i { background: var(--bad); }
|
|
57
|
+
|
|
58
|
+
aside {
|
|
59
|
+
width: 310px; flex: none; overflow-y: auto;
|
|
60
|
+
background: var(--panel); border-left: 1px solid var(--line);
|
|
61
|
+
padding: 12px 14px 40px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
aside h2 {
|
|
65
|
+
font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
|
|
66
|
+
color: var(--dim); margin: 18px 0 6px; font-weight: 600;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
aside h2:first-child { margin-top: 0; }
|
|
70
|
+
|
|
71
|
+
.blurb { color: var(--dim); margin: 0 0 8px; font-size: 11px; }
|
|
72
|
+
.blurb b { color: var(--ink); font-weight: 600; }
|
|
73
|
+
|
|
74
|
+
label { display: flex; align-items: center; gap: 8px; margin: 3px 0; }
|
|
75
|
+
label > span { flex: none; width: 96px; color: var(--dim); }
|
|
76
|
+
label > input[type=range] { flex: 1; min-width: 0; accent-color: #6b8afd; }
|
|
77
|
+
label > output { flex: none; width: 54px; text-align: right; }
|
|
78
|
+
|
|
79
|
+
select {
|
|
80
|
+
width: 100%; background: #1b1f26; color: var(--ink);
|
|
81
|
+
border: 1px solid var(--line); padding: 4px 6px; font: inherit;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.buttons { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
|
|
85
|
+
|
|
86
|
+
button {
|
|
87
|
+
background: #1b1f26; color: var(--ink); border: 1px solid var(--line);
|
|
88
|
+
padding: 4px 9px; font: inherit; cursor: pointer;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
button:hover { border-color: #47506045; background: #232833; }
|
|
92
|
+
button.on { background: #2b3546; border-color: #4a5b7d; color: #cfe0ff; }
|
|
93
|
+
|
|
94
|
+
.bad { color: var(--bad); }
|
|
95
|
+
.warn { color: var(--warn); }
|
|
96
|
+
.good { color: var(--good); }
|
|
97
|
+
</style>
|
|
98
|
+
</head>
|
|
99
|
+
<body>
|
|
100
|
+
<div id="stage">
|
|
101
|
+
<canvas id="view"></canvas>
|
|
102
|
+
|
|
103
|
+
<div id="readout">
|
|
104
|
+
<table>
|
|
105
|
+
<tr><td>step</td><td id="r_step">—</td></tr>
|
|
106
|
+
<tr><td>contacts</td><td id="r_contacts">—</td></tr>
|
|
107
|
+
<tr><td>worst penetration</td><td id="r_pen">—</td></tr>
|
|
108
|
+
<tr><td>resting penetration</td><td id="r_rest">—</td></tr>
|
|
109
|
+
<tr><td>kinetic energy</td><td id="r_energy">—</td></tr>
|
|
110
|
+
<tr><td>finite</td><td id="r_finite">—</td></tr>
|
|
111
|
+
</table>
|
|
112
|
+
<div id="budget"><i></i></div>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<div id="hint">drag to orbit · shift-drag to pan · wheel to zoom · the dashed collider outline has no depth test</div>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<aside>
|
|
119
|
+
<h2>Scene</h2>
|
|
120
|
+
<select id="scene"></select>
|
|
121
|
+
<p class="blurb" id="scene_blurb"></p>
|
|
122
|
+
|
|
123
|
+
<h2>Cloth</h2>
|
|
124
|
+
<label><span>particles</span><input id="size" type="range" min="8" max="34" step="1"><output id="size_out"></output></label>
|
|
125
|
+
<label><span>spacing</span><input id="spacing" type="range" min="0.01" max="0.08" step="0.002"><output id="spacing_out"></output></label>
|
|
126
|
+
<label><span>thickness</span><input id="thickness" type="range" min="0.001" max="0.05" step="0.001"><output id="thickness_out"></output></label>
|
|
127
|
+
<p class="blurb">
|
|
128
|
+
<b>thickness</b> is the contact offset: the row holds every particle that far off the surface,
|
|
129
|
+
and a row is created — inactive — from twice that out. It is <i>not</i> where the velocity
|
|
130
|
+
clamp comes from; §7 P1 measured that and it is the solver's own correction authority.
|
|
131
|
+
</p>
|
|
132
|
+
|
|
133
|
+
<h2>Surface</h2>
|
|
134
|
+
<label><span>friction</span><input id="friction" type="range" min="0" max="2" step="0.02"><output id="friction_out"></output></label>
|
|
135
|
+
<label><span>inflation</span><input id="inflation" type="range" min="0" max="0.06" step="0.002"><output id="inflation_out"></output></label>
|
|
136
|
+
<p class="blurb">
|
|
137
|
+
Friction is a row on the same contact, clamped at <b>μ·f<sub>n</sub></b> — the collision row's
|
|
138
|
+
own force this iteration. Its anchor lives in the <b>collider's</b> frame, which is what makes
|
|
139
|
+
a sliding surface drag cloth instead of a stationary point holding it still.
|
|
140
|
+
</p>
|
|
141
|
+
|
|
142
|
+
<h2>Budget</h2>
|
|
143
|
+
<label><span>substeps</span><input id="substeps" type="range" min="1" max="8" step="1"><output id="substeps_out"></output></label>
|
|
144
|
+
<label><span>iterations</span><input id="iterations" type="range" min="1" max="16" step="1"><output id="iterations_out"></output></label>
|
|
145
|
+
|
|
146
|
+
<h2>Contact band</h2>
|
|
147
|
+
<p class="blurb">
|
|
148
|
+
M0 could not choose these: the ramp only means something for a row that <b>arrives</b>, and a
|
|
149
|
+
contact is the first one in the system that does. Measured defaults are
|
|
150
|
+
k_min = k_max/32 and β = 1e3.
|
|
151
|
+
</p>
|
|
152
|
+
<label><span>k_min ÷ k_max</span><input id="k_floor" type="range" min="-7" max="0" step="0.25"><output id="k_floor_out"></output></label>
|
|
153
|
+
<label><span>β</span><input id="beta" type="range" min="0" max="7" step="0.25"><output id="beta_out"></output></label>
|
|
154
|
+
<div class="buttons"><button id="defaults">measured defaults</button></div>
|
|
155
|
+
|
|
156
|
+
<h2>Sweep</h2>
|
|
157
|
+
<div class="buttons">
|
|
158
|
+
<button id="sweep" class="on">swept (§8.2)</button>
|
|
159
|
+
<button id="unswept">end-of-step only</button>
|
|
160
|
+
</div>
|
|
161
|
+
<p class="blurb">
|
|
162
|
+
With the sweep off, a collider's previous pose is its current one: the substeps stop
|
|
163
|
+
interpolating <i>and</i> the discovery pass loses the travel margin. On the swept-capsule
|
|
164
|
+
scene that is the difference between a capsule the cloth notices and one it does not.
|
|
165
|
+
</p>
|
|
166
|
+
|
|
167
|
+
<h2>Run</h2>
|
|
168
|
+
<div class="buttons">
|
|
169
|
+
<button id="pause">pause</button>
|
|
170
|
+
<button id="single">step once</button>
|
|
171
|
+
<button id="reset">reset</button>
|
|
172
|
+
<button id="animate" class="on">animate colliders</button>
|
|
173
|
+
</div>
|
|
174
|
+
</aside>
|
|
175
|
+
|
|
176
|
+
<script type="module" src="./collide_main.js"></script>
|
|
177
|
+
</body>
|
|
178
|
+
</html>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {number} x
|
|
3
|
+
* @param {number} y
|
|
4
|
+
* @param {number} z
|
|
5
|
+
* @param {number} angle radians
|
|
6
|
+
* @returns {number[]} `[x, y, z, w]`
|
|
7
|
+
*/
|
|
8
|
+
export function axis_angle(x: number, y: number, z: number, angle: number): number[];
|
|
9
|
+
/**
|
|
10
|
+
* Move a record, carrying its current pose into its previous one — what a fixed
|
|
11
|
+
* step does to the index.
|
|
12
|
+
*
|
|
13
|
+
* @param {ColliderScene} built
|
|
14
|
+
* @param {number} record
|
|
15
|
+
* @param {number} x
|
|
16
|
+
* @param {number} y
|
|
17
|
+
* @param {number} z
|
|
18
|
+
*/
|
|
19
|
+
export function move(built: ColliderScene, record: number, x: number, y: number, z: number): void;
|
|
20
|
+
/**
|
|
21
|
+
* @param {ColliderScene} built
|
|
22
|
+
* @param {number} record
|
|
23
|
+
* @param {number} x
|
|
24
|
+
* @param {number} y
|
|
25
|
+
* @param {number} z
|
|
26
|
+
* @param {number[]} rotation
|
|
27
|
+
*/
|
|
28
|
+
export function turn(built: ColliderScene, record: number, x: number, y: number, z: number, rotation: number[]): void;
|
|
29
|
+
/**
|
|
30
|
+
* Freeze a record's previous pose onto its current one, so the sweep has nothing
|
|
31
|
+
* to interpolate. This is the "sweep off" switch, and it is exactly what the
|
|
32
|
+
* design would be without §8.2.
|
|
33
|
+
*
|
|
34
|
+
* @param {ColliderScene} built
|
|
35
|
+
* @param {number} record
|
|
36
|
+
*/
|
|
37
|
+
export function unsweep(built: ColliderScene, record: number): void;
|
|
38
|
+
/**
|
|
39
|
+
* # The collider scenes the M2 page collides against
|
|
40
|
+
*
|
|
41
|
+
* Packed tables built straight from shapes, already in the cloth's own frame —
|
|
42
|
+
* there is no `EntityManager` on this page, so `ClothColliderIndex` and
|
|
43
|
+
* `ClothColliderSystem` are not in the loop and everything below the gather is.
|
|
44
|
+
*
|
|
45
|
+
* Kept beside the page rather than in `__fixtures__` for the reason
|
|
46
|
+
* `cloth_playground_build.js` gives: `__fixtures__` is excluded from the
|
|
47
|
+
* published package and the playground is not, so importing across that line
|
|
48
|
+
* would ship a broken module.
|
|
49
|
+
*
|
|
50
|
+
* @author Alex Goldring
|
|
51
|
+
* @copyright Company Named Limited (c) 2026
|
|
52
|
+
*/
|
|
53
|
+
/**
|
|
54
|
+
* @typedef {object} ColliderScene
|
|
55
|
+
* @property {string} label
|
|
56
|
+
* @property {string} blurb what the scene is for
|
|
57
|
+
* @property {Float32Array} table packed records, cloth-local
|
|
58
|
+
* @property {Int32Array} keys
|
|
59
|
+
* @property {number} count
|
|
60
|
+
* @property {AbstractShape3D[]} shape the shape behind each record, for drawing
|
|
61
|
+
* @property {function(number, number): void} [animate] `(record, time) => void`
|
|
62
|
+
*/
|
|
63
|
+
/**
|
|
64
|
+
* Every scene, by name.
|
|
65
|
+
* @type {Readonly<Object<string, {label: string, blurb: string, build: function}>>}
|
|
66
|
+
*/
|
|
67
|
+
export const COLLIDER_SCENES: Readonly<{
|
|
68
|
+
[x: string]: {
|
|
69
|
+
label: string;
|
|
70
|
+
blurb: string;
|
|
71
|
+
build: Function;
|
|
72
|
+
};
|
|
73
|
+
}>;
|
|
74
|
+
export type ColliderScene = {
|
|
75
|
+
label: string;
|
|
76
|
+
/**
|
|
77
|
+
* what the scene is for
|
|
78
|
+
*/
|
|
79
|
+
blurb: string;
|
|
80
|
+
/**
|
|
81
|
+
* packed records, cloth-local
|
|
82
|
+
*/
|
|
83
|
+
table: Float32Array;
|
|
84
|
+
keys: Int32Array;
|
|
85
|
+
count: number;
|
|
86
|
+
/**
|
|
87
|
+
* the shape behind each record, for drawing
|
|
88
|
+
*/
|
|
89
|
+
shape: AbstractShape3D[];
|
|
90
|
+
/**
|
|
91
|
+
* `(record, time) => void`
|
|
92
|
+
*/
|
|
93
|
+
animate?: (arg0: number, arg1: number) => void;
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=collide_build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collide_build.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/playground/collide_build.js"],"names":[],"mappings":"AAsKA;;;;;;GAMG;AACH,8BANW,MAAM,KACN,MAAM,KACN,MAAM,SACN,MAAM,GACJ,MAAM,EAAE,CAOpB;AAyDD;;;;;;;;;GASG;AACH,4BANW,aAAa,UACb,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,QAchB;AAED;;;;;;;GAOG;AACH,4BAPW,aAAa,UACb,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,YACN,MAAM,EAAE,QAmBlB;AAED;;;;;;;GAOG;AACH,+BAHW,aAAa,UACb,MAAM,QAMhB;AA/QD;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AAEH;;;GAGG;AACH,8BAFU;QAAgB,MAAM,GAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,WAAU;KAAC;EAAE,CA4GhF;;WAvHW,MAAM;;;;WACN,MAAM;;;;WACN,YAAY;UACZ,UAAU;WACV,MAAM;;;;WACN,iBAAiB;;;;qBACR,MAAM,QAAE,MAAM,KAAG,IAAI"}
|