@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,182 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>meep — skinned garments (M3)</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: 250px;
|
|
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
|
+
aside {
|
|
52
|
+
width: 310px; flex: none; overflow-y: auto;
|
|
53
|
+
background: var(--panel); border-left: 1px solid var(--line);
|
|
54
|
+
padding: 12px 14px 40px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
aside h2 {
|
|
58
|
+
font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
|
|
59
|
+
color: var(--dim); margin: 18px 0 6px; font-weight: 600;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
aside h2:first-child { margin-top: 0; }
|
|
63
|
+
|
|
64
|
+
.blurb { color: var(--dim); margin: 0 0 8px; font-size: 11px; }
|
|
65
|
+
.blurb b { color: var(--ink); font-weight: 600; }
|
|
66
|
+
|
|
67
|
+
label { display: flex; align-items: center; gap: 8px; margin: 3px 0; }
|
|
68
|
+
label > span { flex: none; width: 92px; color: var(--dim); }
|
|
69
|
+
label > input[type=range] { flex: 1; min-width: 0; accent-color: #6b8afd; }
|
|
70
|
+
label > output { flex: none; width: 54px; text-align: right; }
|
|
71
|
+
|
|
72
|
+
select {
|
|
73
|
+
width: 100%; background: #1b1f26; color: var(--ink);
|
|
74
|
+
border: 1px solid var(--line); padding: 4px 6px; font: inherit;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.buttons { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
|
|
78
|
+
|
|
79
|
+
button {
|
|
80
|
+
background: #1b1f26; color: var(--ink); border: 1px solid var(--line);
|
|
81
|
+
padding: 4px 9px; font: inherit; cursor: pointer;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
button:hover { border-color: #47506045; background: #232833; }
|
|
85
|
+
button.on { background: #2b3546; border-color: #4a5b7d; color: #cfe0ff; }
|
|
86
|
+
|
|
87
|
+
.bad { color: var(--bad); }
|
|
88
|
+
.good { color: var(--good); }
|
|
89
|
+
</style>
|
|
90
|
+
</head>
|
|
91
|
+
<body>
|
|
92
|
+
<div id="stage">
|
|
93
|
+
<canvas id="view"></canvas>
|
|
94
|
+
|
|
95
|
+
<div id="readout">
|
|
96
|
+
<table>
|
|
97
|
+
<tr><td>joints simulated</td><td id="r_joints">—</td></tr>
|
|
98
|
+
<tr><td>particles</td><td id="r_particles">—</td></tr>
|
|
99
|
+
<tr><td>rows s / leash</td><td id="r_rows">—</td></tr>
|
|
100
|
+
<tr><td>contacts</td><td id="r_contacts">—</td></tr>
|
|
101
|
+
<tr><td>self pairs</td><td id="r_self">—</td></tr>
|
|
102
|
+
<tr><td>worst |x−anchor| / d_geo</td><td id="r_reach">—</td></tr>
|
|
103
|
+
<tr><td>fixed step</td><td id="r_step">—</td></tr>
|
|
104
|
+
</table>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div id="hint">drag to orbit · shift-drag to pan · wheel to zoom</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<aside>
|
|
111
|
+
<h2>Garment</h2>
|
|
112
|
+
<select id="preset"></select>
|
|
113
|
+
<p class="blurb" id="preset_blurb"></p>
|
|
114
|
+
|
|
115
|
+
<label><span>links</span><input id="links" type="range" min="3" max="16" step="1"><output id="links_out"></output></label>
|
|
116
|
+
<label><span>spacing</span><input id="spacing" type="range" min="0.03" max="0.14" step="0.005"><output id="spacing_out"></output></label>
|
|
117
|
+
|
|
118
|
+
<h2>Fabric</h2>
|
|
119
|
+
<select id="dynamics"></select>
|
|
120
|
+
<p class="blurb">
|
|
121
|
+
The same library the entity path uses. <b>The solver is identical either way</b> — §11's claim,
|
|
122
|
+
and what makes it true is that seeding and write-back are the only two files that differ.
|
|
123
|
+
</p>
|
|
124
|
+
|
|
125
|
+
<h2>Motion</h2>
|
|
126
|
+
<div class="buttons">
|
|
127
|
+
<button id="motion_still" class="on">still</button>
|
|
128
|
+
<button id="motion_walk">walk</button>
|
|
129
|
+
<button id="motion_turn">turn</button>
|
|
130
|
+
<button id="motion_sprint">sprint</button>
|
|
131
|
+
</div>
|
|
132
|
+
<p class="blurb">
|
|
133
|
+
The motion drives the <b>character's own bones</b> and nothing else. The garment's joints are
|
|
134
|
+
cloth's, and the seed says so: it claims <b>TransformAuthority.CPU</b> on every one of them,
|
|
135
|
+
because a joint a clip drives is under GPU authority and its <code>transform_local</code> is
|
|
136
|
+
not read by anything. Two writers of one row is the race the authority enum exists to prevent.
|
|
137
|
+
</p>
|
|
138
|
+
|
|
139
|
+
<h2>Body</h2>
|
|
140
|
+
<div class="buttons">
|
|
141
|
+
<button id="collide" class="on">collide with the body</button>
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
<h2>Self-collision</h2>
|
|
145
|
+
<div class="buttons">
|
|
146
|
+
<button id="self_collision" class="on">collide with itself</button>
|
|
147
|
+
</div>
|
|
148
|
+
<p class="blurb">
|
|
149
|
+
§9's first tier: a hash grid over the particles, and a one-sided penalty on every pair
|
|
150
|
+
no row already governs. Watch <b>self pairs</b> on a cape in a sprint — it is zero while
|
|
151
|
+
the garment hangs and climbs the moment a fold closes. <b>The radius is the proxy's
|
|
152
|
+
resolution, not the fabric's thickness</b>: at 6 mm of silk on 8 cm particles the two
|
|
153
|
+
layers of a fold are never in contact at all, which is what MEASUREMENTS §31 measured
|
|
154
|
+
before the field existed.
|
|
155
|
+
</p>
|
|
156
|
+
|
|
157
|
+
<h2>Blend</h2>
|
|
158
|
+
<label><span>blend</span><input id="blend" type="range" min="0" max="1" step="0.01"><output id="blend_out"></output></label>
|
|
159
|
+
<p class="blurb">
|
|
160
|
+
At <b>0</b> the garment is exactly its baked bind pose, carried by the animated bone it hangs
|
|
161
|
+
from — which is what a proxy's rest data is for, and why a re-seed of a live garment does not
|
|
162
|
+
mistake the shape the solver left behind for the shape the artist authored.
|
|
163
|
+
</p>
|
|
164
|
+
|
|
165
|
+
<h2>View</h2>
|
|
166
|
+
<div class="buttons">
|
|
167
|
+
<button id="view_bind" class="on">bind pose</button>
|
|
168
|
+
<button id="view_frames">frames</button>
|
|
169
|
+
<button id="view_body" class="on">body</button>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<h2>Run</h2>
|
|
173
|
+
<div class="buttons">
|
|
174
|
+
<button id="pause">pause</button>
|
|
175
|
+
<button id="single">step once</button>
|
|
176
|
+
<button id="reset">reset</button>
|
|
177
|
+
</div>
|
|
178
|
+
</aside>
|
|
179
|
+
|
|
180
|
+
<script type="module" src="./garment_main.js"></script>
|
|
181
|
+
</body>
|
|
182
|
+
</html>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {object} options
|
|
3
|
+
* @returns {Promise<GarmentScene>}
|
|
4
|
+
*/
|
|
5
|
+
export function build_garment({ preset, dynamics, links, spacing, collide, self_collision }: object): Promise<GarmentScene>;
|
|
6
|
+
/**
|
|
7
|
+
* Put every body collider where its bone is. Called once a step, before the
|
|
8
|
+
* cloth, which is what a rig binding collision capsules to bones would do.
|
|
9
|
+
*
|
|
10
|
+
* @param {object} scene
|
|
11
|
+
* @returns {void}
|
|
12
|
+
*/
|
|
13
|
+
export function garment_sync_colliders(scene: object): void;
|
|
14
|
+
/**
|
|
15
|
+
* # A rigged character for the M3 page
|
|
16
|
+
*
|
|
17
|
+
* A `Node3D` skeleton with a `Skin` over it, a garment built out of some of its
|
|
18
|
+
* joints, and a real `ClothSystem` driving them — the §11.2 path with nothing
|
|
19
|
+
* standing in for it except the renderer, which a 2D canvas does not need.
|
|
20
|
+
*
|
|
21
|
+
* `ClothSystem#models` takes the stub below rather than a `MeshSystem` for the
|
|
22
|
+
* reason the field exists: a `MeshSystem` needs a graphics engine, a scene and a
|
|
23
|
+
* loader, and a garment's joints are a `Node3D` tree that needs none of the
|
|
24
|
+
* three. The stub answers exactly the one method the system calls.
|
|
25
|
+
*
|
|
26
|
+
* @author Alex Goldring
|
|
27
|
+
* @copyright Company Named Limited (c) 2026
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {object} GarmentScene
|
|
31
|
+
* @property {EntityComponentDataset} ecd
|
|
32
|
+
* @property {ClothSystem} cloth
|
|
33
|
+
* @property {ClothColliderSystem} colliders
|
|
34
|
+
* @property {number} entity
|
|
35
|
+
* @property {Node3D} root the character's own node — what the motion drives
|
|
36
|
+
* @property {Node3D} pelvis
|
|
37
|
+
* @property {Node3D[]} bone the character's bones, for drawing
|
|
38
|
+
* @property {Node3D[]} joint the garment's joints, for drawing
|
|
39
|
+
* @property {ClothProxy} proxy
|
|
40
|
+
* @property {number[][]} bind the garment's bind-pose world positions, for drawing
|
|
41
|
+
*/
|
|
42
|
+
export const GARMENT_PRESETS: {
|
|
43
|
+
id: string;
|
|
44
|
+
label: string;
|
|
45
|
+
blurb: string;
|
|
46
|
+
strips: number;
|
|
47
|
+
links: number;
|
|
48
|
+
dynamics: string;
|
|
49
|
+
}[];
|
|
50
|
+
export type GarmentScene = {
|
|
51
|
+
ecd: EntityComponentDataset;
|
|
52
|
+
cloth: ClothSystem;
|
|
53
|
+
colliders: ClothColliderSystem;
|
|
54
|
+
entity: number;
|
|
55
|
+
/**
|
|
56
|
+
* the character's own node — what the motion drives
|
|
57
|
+
*/
|
|
58
|
+
root: Node3D;
|
|
59
|
+
pelvis: Node3D;
|
|
60
|
+
/**
|
|
61
|
+
* the character's bones, for drawing
|
|
62
|
+
*/
|
|
63
|
+
bone: Node3D[];
|
|
64
|
+
/**
|
|
65
|
+
* the garment's joints, for drawing
|
|
66
|
+
*/
|
|
67
|
+
joint: Node3D[];
|
|
68
|
+
proxy: ClothProxy;
|
|
69
|
+
/**
|
|
70
|
+
* the garment's bind-pose world positions, for drawing
|
|
71
|
+
*/
|
|
72
|
+
bind: number[][];
|
|
73
|
+
};
|
|
74
|
+
import { EntityComponentDataset } from "../../../ecs/EntityComponentDataset.js";
|
|
75
|
+
import { ClothSystem } from "../ecs/ClothSystem.js";
|
|
76
|
+
import { ClothColliderSystem } from "../ecs/ClothColliderSystem.js";
|
|
77
|
+
import { Node3D } from "../../../../shade/renderer/scene/Node3D.js";
|
|
78
|
+
//# sourceMappingURL=garment_build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"garment_build.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/playground/garment_build.js"],"names":[],"mappings":"AA2FA;;;GAGG;AACH,6FAHW,MAAM,GACJ,QAAQ,YAAY,CAAC,CA4EjC;AA8JD;;;;;;GAMG;AACH,8CAHW,MAAM,GACJ,IAAI,CA0BhB;AAhVD;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;;GAYG;AAEH;;;;;;;IAqCE;;SAjDY,sBAAsB;WACtB,WAAW;eACX,mBAAmB;YACnB,MAAM;;;;UACN,MAAM;YACN,MAAM;;;;UACN,MAAM,EAAE;;;;WACR,MAAM,EAAE;;;;;UAER,MAAM,EAAE,EAAE;;uCA7Ce,wCAAwC;4BAcnD,uBAAuB;oCAHf,+BAA+B;uBAZ5C,4CAA4C"}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { CapsuleShape3D } from "../../../../core/geom/3d/shape/CapsuleShape3D.js";
|
|
2
|
+
import { SphereShape3D } from "../../../../core/geom/3d/shape/SphereShape3D.js";
|
|
3
|
+
import { Skin } from "../../../../shade/renderer/animation/Skin.js";
|
|
4
|
+
import { Node3D } from "../../../../shade/renderer/scene/Node3D.js";
|
|
5
|
+
import { EntityComponentDataset } from "../../../ecs/EntityComponentDataset.js";
|
|
6
|
+
import { EntityManager } from "../../../ecs/EntityManager.js";
|
|
7
|
+
import { TransformAttachment } from "../../../ecs/transform-attachment/TransformAttachment.js";
|
|
8
|
+
import {
|
|
9
|
+
TransformAttachmentSystem
|
|
10
|
+
} from "../../../ecs/transform-attachment/TransformAttachmentSystem.js";
|
|
11
|
+
import { Transform64 } from "../../../ecs/transform/Transform64.js";
|
|
12
|
+
import { Collider } from "../../ecs/Collider.js";
|
|
13
|
+
import { cloth_proxy_from_joints } from "../build/cloth_proxy_from_joints.js";
|
|
14
|
+
import { Cloth } from "../ecs/Cloth.js";
|
|
15
|
+
import { ClothCollider } from "../ecs/ClothCollider.js";
|
|
16
|
+
import { ClothColliderSystem } from "../ecs/ClothColliderSystem.js";
|
|
17
|
+
import { ClothFlags } from "../ecs/ClothFlags.js";
|
|
18
|
+
import { ClothRig } from "../ecs/ClothRig.js";
|
|
19
|
+
import { ClothSystem } from "../ecs/ClothSystem.js";
|
|
20
|
+
import { ClothDynamicsFlags } from "../ecs/ClothDynamicsFlags.js";
|
|
21
|
+
import { CLOTH_DYNAMICS_BY_NAME } from "../ecs/cloth_dynamics_library.js";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* # A rigged character for the M3 page
|
|
25
|
+
*
|
|
26
|
+
* A `Node3D` skeleton with a `Skin` over it, a garment built out of some of its
|
|
27
|
+
* joints, and a real `ClothSystem` driving them — the §11.2 path with nothing
|
|
28
|
+
* standing in for it except the renderer, which a 2D canvas does not need.
|
|
29
|
+
*
|
|
30
|
+
* `ClothSystem#models` takes the stub below rather than a `MeshSystem` for the
|
|
31
|
+
* reason the field exists: a `MeshSystem` needs a graphics engine, a scene and a
|
|
32
|
+
* loader, and a garment's joints are a `Node3D` tree that needs none of the
|
|
33
|
+
* three. The stub answers exactly the one method the system calls.
|
|
34
|
+
*
|
|
35
|
+
* @author Alex Goldring
|
|
36
|
+
* @copyright Company Named Limited (c) 2026
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @typedef {object} GarmentScene
|
|
41
|
+
* @property {EntityComponentDataset} ecd
|
|
42
|
+
* @property {ClothSystem} cloth
|
|
43
|
+
* @property {ClothColliderSystem} colliders
|
|
44
|
+
* @property {number} entity
|
|
45
|
+
* @property {Node3D} root the character's own node — what the motion drives
|
|
46
|
+
* @property {Node3D} pelvis
|
|
47
|
+
* @property {Node3D[]} bone the character's bones, for drawing
|
|
48
|
+
* @property {Node3D[]} joint the garment's joints, for drawing
|
|
49
|
+
* @property {ClothProxy} proxy
|
|
50
|
+
* @property {number[][]} bind the garment's bind-pose world positions, for drawing
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
export const GARMENT_PRESETS = [
|
|
54
|
+
{
|
|
55
|
+
id: 'cape',
|
|
56
|
+
label: 'cape — 5 strips × 7',
|
|
57
|
+
blurb: 'The common case, and the cheap one: an artist made the joints and skinned the cape '
|
|
58
|
+
+ 'to them, so the proxy is joint indices, the topology, and the bind pose. No binding '
|
|
59
|
+
+ 'step and no generated geometry.',
|
|
60
|
+
strips: 5,
|
|
61
|
+
links: 7,
|
|
62
|
+
dynamics: 'SILK'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'coat',
|
|
66
|
+
label: 'coat tails — 3 strips × 9',
|
|
67
|
+
blurb: 'Longer and heavier. Denim at 2×2, which is what the library spends its two levers on.',
|
|
68
|
+
strips: 3,
|
|
69
|
+
links: 9,
|
|
70
|
+
dynamics: 'DENIM'
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'ponytail',
|
|
74
|
+
label: 'ponytail — 1 × 12',
|
|
75
|
+
blurb: 'One chain, deep. The rig path is the entity path with Node3Ds in it, and a single '
|
|
76
|
+
+ 'chain is where that is most obviously true.',
|
|
77
|
+
strips: 1,
|
|
78
|
+
links: 12,
|
|
79
|
+
dynamics: 'HAIR'
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: 'loincloth',
|
|
83
|
+
label: 'loincloth — 7 strips × 5',
|
|
84
|
+
blurb: 'Wide and short, hanging from the hips rather than the shoulders — and the one preset '
|
|
85
|
+
+ 'that spends most of its time against the leg colliders.',
|
|
86
|
+
strips: 7,
|
|
87
|
+
links: 5,
|
|
88
|
+
dynamics: 'COTTON'
|
|
89
|
+
}
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {object} options
|
|
94
|
+
* @returns {Promise<GarmentScene>}
|
|
95
|
+
*/
|
|
96
|
+
export async function build_garment({ preset, dynamics, links, spacing, collide, self_collision }) {
|
|
97
|
+
const em = new EntityManager();
|
|
98
|
+
const ecd = new EntityComponentDataset();
|
|
99
|
+
|
|
100
|
+
ecd.setComponentTypeMap([Transform64, TransformAttachment, Cloth, ClothRig, Collider, ClothCollider]);
|
|
101
|
+
|
|
102
|
+
em.addSystem(new TransformAttachmentSystem());
|
|
103
|
+
|
|
104
|
+
const colliders = new ClothColliderSystem();
|
|
105
|
+
|
|
106
|
+
em.addSystem(colliders);
|
|
107
|
+
|
|
108
|
+
const cloth = new ClothSystem();
|
|
109
|
+
|
|
110
|
+
em.addSystem(cloth);
|
|
111
|
+
em.attachDataset(ecd);
|
|
112
|
+
|
|
113
|
+
await new Promise((resolve, reject) => em.startup(resolve, reject));
|
|
114
|
+
|
|
115
|
+
const entry = GARMENT_PRESETS.find(p => p.id === preset) ?? GARMENT_PRESETS[0];
|
|
116
|
+
|
|
117
|
+
const skeleton = build_skeleton(entry, links, spacing);
|
|
118
|
+
|
|
119
|
+
const { proxy, error } = cloth_proxy_from_joints(skeleton.skin, skeleton.garment_names, {
|
|
120
|
+
name: entry.label
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (proxy === null) {
|
|
124
|
+
throw new Error(error);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const entity = ecd.createEntity();
|
|
128
|
+
|
|
129
|
+
const transform = new Transform64();
|
|
130
|
+
|
|
131
|
+
transform.updateMatrix();
|
|
132
|
+
|
|
133
|
+
ecd.addComponentToEntity(entity, transform);
|
|
134
|
+
ecd.addComponentToEntity(entity, ClothRig.from(proxy));
|
|
135
|
+
|
|
136
|
+
// The library entry is frozen and shared, so a page that wants to switch
|
|
137
|
+
// one flag owns a copy — which is the whole of what `.clone()` is for.
|
|
138
|
+
const fabric = (CLOTH_DYNAMICS_BY_NAME[dynamics] ?? CLOTH_DYNAMICS_BY_NAME[entry.dynamics]).clone();
|
|
139
|
+
|
|
140
|
+
fabric.flags = self_collision
|
|
141
|
+
? fabric.flags | ClothDynamicsFlags.SelfCollision
|
|
142
|
+
: fabric.flags & ~ClothDynamicsFlags.SelfCollision;
|
|
143
|
+
|
|
144
|
+
ecd.addComponentToEntity(entity, Cloth.from(fabric, { flags: ClothFlags.NeverSleep }));
|
|
145
|
+
|
|
146
|
+
cloth.models = { instance_of: () => ({ skins: [skeleton.skin] }) };
|
|
147
|
+
|
|
148
|
+
if (collide) {
|
|
149
|
+
add_body_colliders(ecd, skeleton);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// One step so the seed runs and the bind pose is on the joints.
|
|
153
|
+
cloth.fixedUpdate(1 / 60);
|
|
154
|
+
|
|
155
|
+
const bind = skeleton.joint.map(node => [
|
|
156
|
+
node.transform_global.translation[0],
|
|
157
|
+
node.transform_global.translation[1],
|
|
158
|
+
node.transform_global.translation[2]
|
|
159
|
+
]);
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
ecd,
|
|
163
|
+
cloth,
|
|
164
|
+
colliders,
|
|
165
|
+
entity,
|
|
166
|
+
proxy,
|
|
167
|
+
bind,
|
|
168
|
+
...skeleton
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* A character: pelvis, spine, shoulders, two legs, and the garment's own strips
|
|
174
|
+
* hanging from whichever bone the preset says.
|
|
175
|
+
*
|
|
176
|
+
* @param {object} entry
|
|
177
|
+
* @param {number} links
|
|
178
|
+
* @param {number} spacing
|
|
179
|
+
* @returns {object}
|
|
180
|
+
* @private
|
|
181
|
+
*/
|
|
182
|
+
function build_skeleton(entry, links, spacing) {
|
|
183
|
+
/** @type {Node3D[]} */
|
|
184
|
+
const joints = [];
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @param {string} name
|
|
188
|
+
* @param {Node3D|null} parent
|
|
189
|
+
* @param {number[]} offset
|
|
190
|
+
* @returns {Node3D}
|
|
191
|
+
*/
|
|
192
|
+
const bone = (name, parent, offset) => {
|
|
193
|
+
const node = new Node3D();
|
|
194
|
+
|
|
195
|
+
node.name = name;
|
|
196
|
+
node.transform_local.setTranslation(offset[0], offset[1], offset[2]);
|
|
197
|
+
|
|
198
|
+
if (parent !== null) {
|
|
199
|
+
parent.addChild(node);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
joints.push(node);
|
|
203
|
+
|
|
204
|
+
return node;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const root = bone('root', null, [0, 0, 0]);
|
|
208
|
+
const pelvis = bone('pelvis', root, [0, 0.95, 0]);
|
|
209
|
+
const spine = bone('spine', pelvis, [0, 0.22, 0]);
|
|
210
|
+
const chest = bone('chest', spine, [0, 0.2, 0]);
|
|
211
|
+
const neck = bone('neck', chest, [0, 0.16, 0]);
|
|
212
|
+
|
|
213
|
+
bone('head', neck, [0, 0.12, 0]);
|
|
214
|
+
|
|
215
|
+
const left_leg = bone('leg_l', pelvis, [-0.1, -0.06, 0]);
|
|
216
|
+
const right_leg = bone('leg_r', pelvis, [0.1, -0.06, 0]);
|
|
217
|
+
|
|
218
|
+
bone('knee_l', left_leg, [0, -0.42, 0]);
|
|
219
|
+
bone('knee_r', right_leg, [0, -0.42, 0]);
|
|
220
|
+
|
|
221
|
+
const character = joints.slice();
|
|
222
|
+
|
|
223
|
+
// The garment hangs from the chest for a cape and from the pelvis for a
|
|
224
|
+
// loincloth, which is the difference between the two presets.
|
|
225
|
+
const from = entry.id === 'loincloth' ? pelvis : (entry.id === 'ponytail' ? neck : chest);
|
|
226
|
+
|
|
227
|
+
const garment_names = [];
|
|
228
|
+
const garment = [];
|
|
229
|
+
|
|
230
|
+
const strips = entry.strips;
|
|
231
|
+
|
|
232
|
+
for (let s = 0; s < strips; s++) {
|
|
233
|
+
const across = strips === 1 ? 0 : (s / (strips - 1) - 0.5) * 0.34;
|
|
234
|
+
|
|
235
|
+
let parent = from;
|
|
236
|
+
|
|
237
|
+
for (let i = 0; i < links; i++) {
|
|
238
|
+
const node = bone(
|
|
239
|
+
`garment_${s}_${i}`,
|
|
240
|
+
parent,
|
|
241
|
+
i === 0
|
|
242
|
+
// The first link carries the strip sideways and behind, so
|
|
243
|
+
// the garment starts as a fan rather than as a bundle.
|
|
244
|
+
// Clear of the body colliders, deliberately: §11.3 step 10
|
|
245
|
+
// validates that a garment's bind pose is collision-free
|
|
246
|
+
// against the character's collider set, and a garment that
|
|
247
|
+
// is not reads as a *tether* failure — the contact row
|
|
248
|
+
// pushes it out past its own reach and the readout says so.
|
|
249
|
+
// M3 does not build that validation, so the scene has to be
|
|
250
|
+
// right by hand.
|
|
251
|
+
? [across, -spacing * 0.4, entry.id === 'ponytail' ? -0.09 : -0.21]
|
|
252
|
+
: [0, -spacing, -spacing * 0.05]
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
garment_names.push(node.name);
|
|
256
|
+
garment.push(node);
|
|
257
|
+
|
|
258
|
+
parent = node;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
root.updateMatrices();
|
|
263
|
+
|
|
264
|
+
return {
|
|
265
|
+
root,
|
|
266
|
+
pelvis,
|
|
267
|
+
bone: character,
|
|
268
|
+
joint: garment,
|
|
269
|
+
garment_names,
|
|
270
|
+
skin: Skin.from({
|
|
271
|
+
joints,
|
|
272
|
+
inverse_bind_matrices: new Float32Array(joints.length * 16)
|
|
273
|
+
})
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Capsules on the character's own bones, opted into cloth the way any collider
|
|
279
|
+
* is: a `ClothCollider` beside an existing `(Collider, Transform64)`.
|
|
280
|
+
*
|
|
281
|
+
* They are entities rather than nodes because that is what a `ClothCollider`
|
|
282
|
+
* is — §3.5's "the `RigidBody`-analogue" — and because a character's collision
|
|
283
|
+
* capsules are authored as entities in a real scene too. The page keeps their
|
|
284
|
+
* transforms in step with the bones by hand, which is what a rig would do.
|
|
285
|
+
*
|
|
286
|
+
* @param {EntityComponentDataset} ecd
|
|
287
|
+
* @param {object} skeleton
|
|
288
|
+
* @private
|
|
289
|
+
*/
|
|
290
|
+
function add_body_colliders(ecd, skeleton) {
|
|
291
|
+
const by_name = new Map(skeleton.bone.map(node => [node.name, node]));
|
|
292
|
+
|
|
293
|
+
const parts = [
|
|
294
|
+
{ bone: 'spine', shape: CapsuleShape3D.from(0.13, 0.3), offset: [0, 0.1, 0] },
|
|
295
|
+
{ bone: 'pelvis', shape: SphereShape3D.from(0.13), offset: [0, 0, 0] },
|
|
296
|
+
{ bone: 'leg_l', shape: CapsuleShape3D.from(0.08, 0.34), offset: [0, -0.21, 0] },
|
|
297
|
+
{ bone: 'leg_r', shape: CapsuleShape3D.from(0.08, 0.34), offset: [0, -0.21, 0] }
|
|
298
|
+
];
|
|
299
|
+
|
|
300
|
+
skeleton.body = [];
|
|
301
|
+
|
|
302
|
+
for (const part of parts) {
|
|
303
|
+
const node = by_name.get(part.bone);
|
|
304
|
+
|
|
305
|
+
if (node === undefined) {
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const entity = ecd.createEntity();
|
|
310
|
+
|
|
311
|
+
const transform = new Transform64();
|
|
312
|
+
|
|
313
|
+
transform.updateMatrix();
|
|
314
|
+
|
|
315
|
+
const collider = new Collider();
|
|
316
|
+
|
|
317
|
+
collider.shape = part.shape;
|
|
318
|
+
collider.friction = 0.35;
|
|
319
|
+
|
|
320
|
+
ecd.addComponentToEntity(entity, transform);
|
|
321
|
+
ecd.addComponentToEntity(entity, collider);
|
|
322
|
+
ecd.addComponentToEntity(entity, ClothCollider.from({ inflation: 0.01 }));
|
|
323
|
+
|
|
324
|
+
skeleton.body.push({ entity, node, transform, offset: part.offset, shape: part.shape });
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Put every body collider where its bone is. Called once a step, before the
|
|
330
|
+
* cloth, which is what a rig binding collision capsules to bones would do.
|
|
331
|
+
*
|
|
332
|
+
* @param {object} scene
|
|
333
|
+
* @returns {void}
|
|
334
|
+
*/
|
|
335
|
+
export function garment_sync_colliders(scene) {
|
|
336
|
+
const body = scene.body;
|
|
337
|
+
|
|
338
|
+
if (body === undefined) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
for (const part of body) {
|
|
343
|
+
const node = part.node;
|
|
344
|
+
|
|
345
|
+
const t = node.transform_global;
|
|
346
|
+
|
|
347
|
+
part.transform.setTranslation(
|
|
348
|
+
t.translation[0] + part.offset[0],
|
|
349
|
+
t.translation[1] + part.offset[1],
|
|
350
|
+
t.translation[2] + part.offset[2]
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
part.transform.setRotation(
|
|
354
|
+
t.rotation[0], t.rotation[1], t.rotation[2], t.rotation[3]
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
part.transform.updateMatrix();
|
|
358
|
+
}
|
|
359
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"garment_main.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/playground/garment_main.js"],"names":[],"mappings":""}
|