@woosh/meep-engine 3.24.0 → 3.26.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/shape/HeightMapShape3D.d.ts +59 -0
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/HeightMapShape3D.js +285 -0
- package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/PosedShape3D.js +57 -0
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/TransformedShape3D.js +102 -0
- package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnionShape3D.js +64 -0
- package/src/engine/graphics3/PickingSystem.d.ts +3 -3
- package/src/engine/graphics3/PickingSystem.d.ts.map +1 -1
- package/src/engine/graphics3/PickingSystem.js +52 -55
- package/src/engine/graphics3/shader_picking_gather.d.ts +40 -0
- package/src/engine/graphics3/shader_picking_gather.d.ts.map +1 -0
- package/src/engine/graphics3/shader_picking_gather.js +120 -0
- package/src/engine/physics/cloth/MEASUREMENTS.md +1632 -0
- package/src/engine/physics/cloth/PLAN.md +738 -95
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +84 -17
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/ClothColliderIndex.js +451 -42
- package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts +52 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.js +70 -0
- package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts +12 -3
- package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothDynamics.js +340 -331
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +101 -29
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +110 -31
- package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts +84 -0
- package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.js +141 -0
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +71 -81
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +135 -856
- package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts +48 -0
- package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothWorkerCore.js +107 -0
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +323 -0
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothWorld.js +1248 -0
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +192 -0
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +578 -0
- package/src/engine/physics/cloth/ecs/cloth.worker.d.ts +2 -0
- package/src/engine/physics/cloth/ecs/cloth.worker.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth.worker.js +12 -0
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_build_rows.js +2 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +85 -3
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +366 -271
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +95 -12
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +170 -27
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +19 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +249 -201
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +62 -1
- package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts +29 -0
- package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_worker_protocol.js +78 -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 +18 -10
- package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts +17 -0
- package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/makeClothWorker.js +18 -0
- package/src/engine/physics/cloth/playground/README.md +73 -2
- package/src/engine/physics/cloth/playground/collide_main.js +1 -1
- package/src/engine/physics/cloth/playground/wind.html +166 -0
- package/src/engine/physics/cloth/playground/wind_build.d.ts +81 -0
- package/src/engine/physics/cloth/playground/wind_build.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/wind_build.js +141 -0
- package/src/engine/physics/cloth/playground/wind_main.d.ts +2 -0
- package/src/engine/physics/cloth/playground/wind_main.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/wind_main.js +681 -0
- package/src/engine/physics/cloth/solver/ClothState.d.ts +134 -79
- package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/ClothState.js +273 -12
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +29 -8
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_contact_find.js +37 -9
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +45 -2
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solver_constants.js +46 -2
- package/src/engine/physics/cloth/solver/cloth_step.d.ts +21 -2
- package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_step.js +173 -4
- package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +40 -0
- package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_step_instance.js +284 -0
- package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts +107 -0
- package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_wind_accelerate.js +263 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +9 -2
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +9 -2
- package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +102 -0
- package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts.map +1 -0
- package/src/engine/physics/cloth/wind/AbstractClothWind.js +114 -0
- package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts +87 -0
- package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts.map +1 -0
- package/src/engine/physics/cloth/wind/ClothAmbientWind.js +185 -0
- package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +79 -0
- package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -0
- package/src/engine/physics/cloth/wind/ClothFluidWind.js +213 -0
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +106 -0
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -0
- package/src/engine/physics/cloth/wind/cloth_sample_air.js +297 -0
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/device/mock/texture_copy.d.ts.map +1 -1
- package/src/shade/device/mock/texture_copy.js +28 -0
- package/src/shade/playground/vgeo_runtime/README.md +94 -0
- package/src/shade/playground/vgeo_runtime/index.html +62 -0
- package/src/shade/playground/vgeo_runtime/main.d.ts +2 -0
- package/src/shade/playground/vgeo_runtime/main.d.ts.map +1 -0
- package/src/shade/playground/vgeo_runtime/main.js +399 -0
- package/src/shade/playground/vgeo_viewer/sample_asset.js +1 -1
- package/src/shade/renderer/camera/Camera.d.ts +14 -0
- package/src/shade/renderer/camera/Camera.d.ts.map +1 -1
- package/src/shade/renderer/camera/Camera.js +7 -1
- package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.js +16 -1
- package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/GPUGeometryManager.js +29 -9
- package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts +10 -0
- package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts.map +1 -1
- package/src/shade/renderer/geometry/GPUGeometryMetadata.js +13 -0
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +46 -18
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +70 -22
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +97 -19
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +12 -2
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +14 -3
- package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +2 -2
- package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +124 -6
- package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +22 -0
- package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.js +53 -0
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +8 -1
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +8 -1
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts +16 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.js +15 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts +54 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.js +53 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +13 -2
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +14 -2
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +100 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +113 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +5 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +108 -0
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +23 -0
- package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +40 -0
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +228 -0
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +932 -0
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +176 -0
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +425 -0
- package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +241 -0
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +574 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +120 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +674 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +287 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +976 -0
- package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +42 -0
- package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +96 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts +16 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.js +15 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts +19 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +83 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.js +8 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +19 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +160 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts +3 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +255 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts +3 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +80 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts +3 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +144 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts +3 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +530 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +39 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +54 -0
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts +41 -0
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.js +56 -0
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts +49 -0
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +328 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +10 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +51 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +13 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +12 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +99 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +8 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +7 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +27 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts +14 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.js +13 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts +7 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.js +35 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.js +8 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.js +14 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +7 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +36 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +10 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +9 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts +11 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.js +54 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.js +8 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts +11 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.js +10 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts +7 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.js +30 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.js +8 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts +13 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.js +12 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts +14 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.js +13 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +11 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +61 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +8 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts +13 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.js +12 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.js +8 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.js +19 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts +23 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +70 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +25 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +35 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +41 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +32 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +138 -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/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +9 -0
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +12 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +12 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +10 -0
- package/src/shade/renderer/scene/GPUSceneContext.d.ts +18 -0
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +647 -594
- package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
- package/src/shade/renderer/scene/rows/GPUSceneRows.js +22 -0
- package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts +35 -0
- package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.js +91 -0
- package/src/engine/graphics3/instantiate_scene_bundle.d.ts +0 -54
- package/src/engine/graphics3/instantiate_scene_bundle.d.ts.map +0 -1
- package/src/engine/graphics3/shade_node_to_entity_composition.d.ts +0 -39
- package/src/engine/graphics3/shade_node_to_entity_composition.d.ts.map +0 -1
- package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts +0 -35
- package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts.map +0 -1
- package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts +0 -96
- package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts.map +0 -1
- package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts +0 -20
- package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts.map +0 -1
- package/src/shade/renderer/animation/skin_bind_transform.d.ts +0 -25
- package/src/shade/renderer/animation/skin_bind_transform.d.ts.map +0 -1
- package/src/shade/renderer/animation/skin_frame_defect.d.ts +0 -34
- package/src/shade/renderer/animation/skin_frame_defect.d.ts.map +0 -1
- package/src/shade/renderer/animation/skin_joint_matrix.d.ts +0 -24
- package/src/shade/renderer/animation/skin_joint_matrix.d.ts.map +0 -1
- package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts +0 -70
- package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts.map +0 -1
- package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts +0 -96
- package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts.map +0 -1
- package/src/shade/renderer/scene/InstanceBatch.d.ts +0 -92
- package/src/shade/renderer/scene/InstanceBatch.d.ts.map +0 -1
- package/src/shade/renderer/scene/Mesh.d.ts +0 -55
- package/src/shade/renderer/scene/Mesh.d.ts.map +0 -1
- package/src/shade/renderer/scene/Node3D.d.ts +0 -159
- package/src/shade/renderer/scene/Node3D.d.ts.map +0 -1
- package/src/shade/renderer/scene/Node3DDirtyList.d.ts +0 -59
- package/src/shade/renderer/scene/Node3DDirtyList.d.ts.map +0 -1
- package/src/shade/renderer/scene/SceneNodeBinding.d.ts +0 -52
- package/src/shade/renderer/scene/SceneNodeBinding.d.ts.map +0 -1
- package/src/shade/renderer/scene/SkinnedMesh.d.ts +0 -27
- package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +0 -1
- package/src/shade/renderer/scene/TransformAuthority.d.ts +0 -19
- package/src/shade/renderer/scene/TransformAuthority.d.ts.map +0 -1
|
@@ -1,331 +1,340 @@
|
|
|
1
|
-
import { assert } from "../../../../core/assert.js";
|
|
2
|
-
import { combine_hash } from "../../../../core/collection/array/combine_hash.js";
|
|
3
|
-
import { computeHashFloat } from "../../../../core/primitives/numbers/computeHashFloat.js";
|
|
4
|
-
import { ClothDynamicsFlags } from "./ClothDynamicsFlags.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* # How a cloth behaves — the whole parameter set
|
|
8
|
-
*
|
|
9
|
-
* Ten fields, and the library in `cloth_dynamics_library.js` is a set of points
|
|
10
|
-
* in them that are known to be good. There is no second "advanced" block, no
|
|
11
|
-
* field that silently rewrites another, and no animation curve over depth: the
|
|
12
|
-
* per-particle profile that other cloth packages author with curves falls out
|
|
13
|
-
* of the baked geodesic distance instead (§3.4).
|
|
14
|
-
*
|
|
15
|
-
* ## The stiffnesses are normalised, and what they map to is measured
|
|
16
|
-
*
|
|
17
|
-
* `stretch` and `bend` are coordinates in `[0, 1]`, not moduli in N/m, and they
|
|
18
|
-
* are log-mapped internally so that `0.7` means something an author can predict
|
|
19
|
-
* and `0.9` is not four orders of magnitude away from it. `cloth_dynamics_map.js`
|
|
20
|
-
* is that mapping and carries the measurement behind each end of each range.
|
|
21
|
-
*
|
|
22
|
-
* Two of those mappings are M0 findings rather than taste:
|
|
23
|
-
*
|
|
24
|
-
* - **`stretch` does not map to a stiffness at all.** A stretch *penalty*
|
|
25
|
-
* stiffer than about `8·(m/h²)` makes the step add energy rather than
|
|
26
|
-
* dissipate it — measured at +6.8 J on a sheet whose entire gravitational
|
|
27
|
-
* potential is 1.2 J — and for a half-gram particle at 60 Hz × 2 substeps
|
|
28
|
-
* that boundary sits near 60 N/m, which is a rubber band rather than a
|
|
29
|
-
* fabric. So the stretch row is **hard** (§6), and `stretch` maps to the
|
|
30
|
-
* strain the fabric is allowed to carry before the strain-limit row stops it.
|
|
31
|
-
* `MEASUREMENTS.md` §6.
|
|
32
|
-
* - **`bend` maps to a ratio, not to a stiffness.** A bend row is soft, so it
|
|
33
|
-
* has to stay inside that same dissipative band, and the band is a multiple
|
|
34
|
-
* of the row's own `m/h²` rather than a number of newtons per metre —
|
|
35
|
-
* `MEASUREMENTS.md` §4 held a chain at a fixed ratio across five decades of
|
|
36
|
-
* particle mass and got the same answer every time. Expressing `bend` as a
|
|
37
|
-
* ratio of `m/dt²` therefore keeps the fabric's *look* invariant to how heavy
|
|
38
|
-
* the author made it and to how many substeps the budget allows.
|
|
39
|
-
*
|
|
40
|
-
* ## `damping` is load-bearing
|
|
41
|
-
*
|
|
42
|
-
* §7 P5's mechanism for jitter at rest is the multiplier decay `α·γ < 1`, and
|
|
43
|
-
* that reaches **hard** rows only, because a soft row has no multiplier to
|
|
44
|
-
* decay. M0 measured a soft cloth landing in a bounded limit cycle that 2,000
|
|
45
|
-
* further steps do not move. `damping` is what reaches it, which makes this
|
|
46
|
-
* field part of the correctness argument rather than a taste control. See
|
|
47
|
-
* `ClothSystem`'s settle pass.
|
|
48
|
-
*
|
|
49
|
-
* ## `substeps` and `iterations` are budget, and the library is sized to it
|
|
50
|
-
*
|
|
51
|
-
* They are here rather than on the system because a chain wants more of both
|
|
52
|
-
* than a bedsheet does, so they are part of what "chain" means. They are also
|
|
53
|
-
* the levers that bring a garment inside the measured frame budget: 1,024
|
|
54
|
-
* particles at 2×4 costs 3.48 ms against a 2 ms target, and halving either one
|
|
55
|
-
* lands inside (`MEASUREMENTS.md` §7). Every library entry states the particle
|
|
56
|
-
* count it is sized for and which lever it took.
|
|
57
|
-
*
|
|
58
|
-
* @author Alex Goldring
|
|
59
|
-
* @copyright Company Named Limited (c) 2026
|
|
60
|
-
*/
|
|
61
|
-
export class ClothDynamics {
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* How little the fabric extends, `[0, 1]`. `0` is a knit that gives a
|
|
65
|
-
* quarter of its length; `1` is a chain. Maps to the strain-limit row's
|
|
66
|
-
* allowance, not to a stiffness — see the class docblock.
|
|
67
|
-
* @type {number}
|
|
68
|
-
*/
|
|
69
|
-
stretch = 0.7;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* How strongly the fabric resists folding, `[0, 1]`. Maps to a bend row
|
|
73
|
-
* stiffness expressed as a ratio of the row's own `m/dt²`.
|
|
74
|
-
* @type {number}
|
|
75
|
-
*/
|
|
76
|
-
bend = 0.2;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Velocity retained per step, inverted: `0` is undamped, `1` is heavily
|
|
80
|
-
* damped. Load-bearing for §7 P5 on any cloth carrying soft rows.
|
|
81
|
-
* @type {number}
|
|
82
|
-
*/
|
|
83
|
-
damping = 0.15;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* How far the cloth may leave its animated pose, `[0, 1]`. Each particle's
|
|
87
|
-
* leash radius is `slack · d_geo,i` — its own baked geodesic distance to
|
|
88
|
-
* the fixed set — so a hem gets a long leash and a waistband a short one
|
|
89
|
-
* without anybody painting a profile (§3.4). At `0` every particle is
|
|
90
|
-
* welded to its animated position.
|
|
91
|
-
* @type {number}
|
|
92
|
-
*/
|
|
93
|
-
slack = 0.5;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Particle radius, metres. Collision offset and self-collision separation
|
|
97
|
-
* from M2 onwards; in M1 it is the length scale the velocity clamp of
|
|
98
|
-
* §7 P1 is derived from.
|
|
99
|
-
* @type {number}
|
|
100
|
-
*/
|
|
101
|
-
thickness = 0.02;
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* How much of the anchor's own world motion the cloth feels, `[0, 1]`.
|
|
105
|
-
* `1` is a cape that trails a sprinting character; `0` is a cloth welded
|
|
106
|
-
* into the anchor's frame, which feels no locomotion at all. §7 P7.
|
|
107
|
-
* @type {number}
|
|
108
|
-
*/
|
|
109
|
-
inertia = 1;
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Aerodynamic coupling to the air, `[0, 1]`. §10
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
* @param {
|
|
162
|
-
* @param {number} [spec.
|
|
163
|
-
* @
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
assert.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
this.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
r
|
|
230
|
-
|
|
231
|
-
r.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
this.
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
this.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { combine_hash } from "../../../../core/collection/array/combine_hash.js";
|
|
3
|
+
import { computeHashFloat } from "../../../../core/primitives/numbers/computeHashFloat.js";
|
|
4
|
+
import { ClothDynamicsFlags } from "./ClothDynamicsFlags.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* # How a cloth behaves — the whole parameter set
|
|
8
|
+
*
|
|
9
|
+
* Ten fields, and the library in `cloth_dynamics_library.js` is a set of points
|
|
10
|
+
* in them that are known to be good. There is no second "advanced" block, no
|
|
11
|
+
* field that silently rewrites another, and no animation curve over depth: the
|
|
12
|
+
* per-particle profile that other cloth packages author with curves falls out
|
|
13
|
+
* of the baked geodesic distance instead (§3.4).
|
|
14
|
+
*
|
|
15
|
+
* ## The stiffnesses are normalised, and what they map to is measured
|
|
16
|
+
*
|
|
17
|
+
* `stretch` and `bend` are coordinates in `[0, 1]`, not moduli in N/m, and they
|
|
18
|
+
* are log-mapped internally so that `0.7` means something an author can predict
|
|
19
|
+
* and `0.9` is not four orders of magnitude away from it. `cloth_dynamics_map.js`
|
|
20
|
+
* is that mapping and carries the measurement behind each end of each range.
|
|
21
|
+
*
|
|
22
|
+
* Two of those mappings are M0 findings rather than taste:
|
|
23
|
+
*
|
|
24
|
+
* - **`stretch` does not map to a stiffness at all.** A stretch *penalty*
|
|
25
|
+
* stiffer than about `8·(m/h²)` makes the step add energy rather than
|
|
26
|
+
* dissipate it — measured at +6.8 J on a sheet whose entire gravitational
|
|
27
|
+
* potential is 1.2 J — and for a half-gram particle at 60 Hz × 2 substeps
|
|
28
|
+
* that boundary sits near 60 N/m, which is a rubber band rather than a
|
|
29
|
+
* fabric. So the stretch row is **hard** (§6), and `stretch` maps to the
|
|
30
|
+
* strain the fabric is allowed to carry before the strain-limit row stops it.
|
|
31
|
+
* `MEASUREMENTS.md` §6.
|
|
32
|
+
* - **`bend` maps to a ratio, not to a stiffness.** A bend row is soft, so it
|
|
33
|
+
* has to stay inside that same dissipative band, and the band is a multiple
|
|
34
|
+
* of the row's own `m/h²` rather than a number of newtons per metre —
|
|
35
|
+
* `MEASUREMENTS.md` §4 held a chain at a fixed ratio across five decades of
|
|
36
|
+
* particle mass and got the same answer every time. Expressing `bend` as a
|
|
37
|
+
* ratio of `m/dt²` therefore keeps the fabric's *look* invariant to how heavy
|
|
38
|
+
* the author made it and to how many substeps the budget allows.
|
|
39
|
+
*
|
|
40
|
+
* ## `damping` is load-bearing
|
|
41
|
+
*
|
|
42
|
+
* §7 P5's mechanism for jitter at rest is the multiplier decay `α·γ < 1`, and
|
|
43
|
+
* that reaches **hard** rows only, because a soft row has no multiplier to
|
|
44
|
+
* decay. M0 measured a soft cloth landing in a bounded limit cycle that 2,000
|
|
45
|
+
* further steps do not move. `damping` is what reaches it, which makes this
|
|
46
|
+
* field part of the correctness argument rather than a taste control. See
|
|
47
|
+
* `ClothSystem`'s settle pass.
|
|
48
|
+
*
|
|
49
|
+
* ## `substeps` and `iterations` are budget, and the library is sized to it
|
|
50
|
+
*
|
|
51
|
+
* They are here rather than on the system because a chain wants more of both
|
|
52
|
+
* than a bedsheet does, so they are part of what "chain" means. They are also
|
|
53
|
+
* the levers that bring a garment inside the measured frame budget: 1,024
|
|
54
|
+
* particles at 2×4 costs 3.48 ms against a 2 ms target, and halving either one
|
|
55
|
+
* lands inside (`MEASUREMENTS.md` §7). Every library entry states the particle
|
|
56
|
+
* count it is sized for and which lever it took.
|
|
57
|
+
*
|
|
58
|
+
* @author Alex Goldring
|
|
59
|
+
* @copyright Company Named Limited (c) 2026
|
|
60
|
+
*/
|
|
61
|
+
export class ClothDynamics {
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* How little the fabric extends, `[0, 1]`. `0` is a knit that gives a
|
|
65
|
+
* quarter of its length; `1` is a chain. Maps to the strain-limit row's
|
|
66
|
+
* allowance, not to a stiffness — see the class docblock.
|
|
67
|
+
* @type {number}
|
|
68
|
+
*/
|
|
69
|
+
stretch = 0.7;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* How strongly the fabric resists folding, `[0, 1]`. Maps to a bend row
|
|
73
|
+
* stiffness expressed as a ratio of the row's own `m/dt²`.
|
|
74
|
+
* @type {number}
|
|
75
|
+
*/
|
|
76
|
+
bend = 0.2;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Velocity retained per step, inverted: `0` is undamped, `1` is heavily
|
|
80
|
+
* damped. Load-bearing for §7 P5 on any cloth carrying soft rows.
|
|
81
|
+
* @type {number}
|
|
82
|
+
*/
|
|
83
|
+
damping = 0.15;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* How far the cloth may leave its animated pose, `[0, 1]`. Each particle's
|
|
87
|
+
* leash radius is `slack · d_geo,i` — its own baked geodesic distance to
|
|
88
|
+
* the fixed set — so a hem gets a long leash and a waistband a short one
|
|
89
|
+
* without anybody painting a profile (§3.4). At `0` every particle is
|
|
90
|
+
* welded to its animated position.
|
|
91
|
+
* @type {number}
|
|
92
|
+
*/
|
|
93
|
+
slack = 0.5;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Particle radius, metres. Collision offset and self-collision separation
|
|
97
|
+
* from M2 onwards; in M1 it is the length scale the velocity clamp of
|
|
98
|
+
* §7 P1 is derived from.
|
|
99
|
+
* @type {number}
|
|
100
|
+
*/
|
|
101
|
+
thickness = 0.02;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* How much of the anchor's own world motion the cloth feels, `[0, 1]`.
|
|
105
|
+
* `1` is a cape that trails a sprinting character; `0` is a cloth welded
|
|
106
|
+
* into the anchor's frame, which feels no locomotion at all. §7 P7.
|
|
107
|
+
* @type {number}
|
|
108
|
+
*/
|
|
109
|
+
inertia = 1;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Aerodynamic coupling to the air, `[0, 1]`. §10.
|
|
113
|
+
*
|
|
114
|
+
* A **relaxation rate** toward whatever the air is doing, linearly mapped
|
|
115
|
+
* onto `[0, CLOTH_DRAG_RATE_MAX]` by `cloth_drag_response` — `0` is a cloth
|
|
116
|
+
* the air cannot reach and `1` is one with no aerodynamic memory at all,
|
|
117
|
+
* taking the air's velocity within a fixed step. The library reads silk at
|
|
118
|
+
* 0.45 (a 37 ms time constant) down to leather and chain at 0.05 (a third of
|
|
119
|
+
* a second).
|
|
120
|
+
*
|
|
121
|
+
* It only does anything where there is air: a `ClothWorld` with no wind
|
|
122
|
+
* source feels none, and what a cloth does in air that is *not* moving is
|
|
123
|
+
* `damping`'s job rather than this one.
|
|
124
|
+
* @type {number}
|
|
125
|
+
*/
|
|
126
|
+
drag = 0.1;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Solver substeps per fixed step. More substeps means less of implicit
|
|
130
|
+
* Euler's numerical damping and a livelier drape, and a proportionally
|
|
131
|
+
* larger frame cost.
|
|
132
|
+
* @type {number}
|
|
133
|
+
*/
|
|
134
|
+
substeps = 2;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Descent iterations per substep. More iterations converges further
|
|
138
|
+
* towards the same answer rather than changing which answer it is (§5.1).
|
|
139
|
+
* @type {number}
|
|
140
|
+
*/
|
|
141
|
+
iterations = 4;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @see ClothDynamicsFlags
|
|
145
|
+
* @type {number}
|
|
146
|
+
*/
|
|
147
|
+
flags = ClothDynamicsFlags.StrainLimit;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @param {number|ClothDynamicsFlags} flag
|
|
151
|
+
* @returns {boolean}
|
|
152
|
+
*/
|
|
153
|
+
getFlag(flag) {
|
|
154
|
+
return (this.flags & flag) === flag;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Build one from a partial specification; anything left out keeps the
|
|
159
|
+
* default above.
|
|
160
|
+
*
|
|
161
|
+
* @param {object} [spec]
|
|
162
|
+
* @param {number} [spec.stretch]
|
|
163
|
+
* @param {number} [spec.bend]
|
|
164
|
+
* @param {number} [spec.damping]
|
|
165
|
+
* @param {number} [spec.slack]
|
|
166
|
+
* @param {number} [spec.thickness]
|
|
167
|
+
* @param {number} [spec.inertia]
|
|
168
|
+
* @param {number} [spec.drag]
|
|
169
|
+
* @param {number} [spec.substeps]
|
|
170
|
+
* @param {number} [spec.iterations]
|
|
171
|
+
* @param {number} [spec.flags]
|
|
172
|
+
* @returns {ClothDynamics}
|
|
173
|
+
*/
|
|
174
|
+
static from(spec = {}) {
|
|
175
|
+
const r = new ClothDynamics();
|
|
176
|
+
|
|
177
|
+
r.#assign(spec);
|
|
178
|
+
|
|
179
|
+
return r;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* @param {object} spec
|
|
184
|
+
* @private
|
|
185
|
+
*/
|
|
186
|
+
#assign({
|
|
187
|
+
stretch = this.stretch,
|
|
188
|
+
bend = this.bend,
|
|
189
|
+
damping = this.damping,
|
|
190
|
+
slack = this.slack,
|
|
191
|
+
thickness = this.thickness,
|
|
192
|
+
inertia = this.inertia,
|
|
193
|
+
drag = this.drag,
|
|
194
|
+
substeps = this.substeps,
|
|
195
|
+
iterations = this.iterations,
|
|
196
|
+
flags = this.flags
|
|
197
|
+
}) {
|
|
198
|
+
assert.isNumber(stretch, 'stretch');
|
|
199
|
+
assert.isNumber(bend, 'bend');
|
|
200
|
+
assert.isNumber(damping, 'damping');
|
|
201
|
+
assert.isNumber(slack, 'slack');
|
|
202
|
+
assert.isNumber(thickness, 'thickness');
|
|
203
|
+
assert.isNumber(inertia, 'inertia');
|
|
204
|
+
assert.isNumber(drag, 'drag');
|
|
205
|
+
assert.isPositiveInteger(substeps, 'substeps');
|
|
206
|
+
assert.isPositiveInteger(iterations, 'iterations');
|
|
207
|
+
assert.isNonNegativeInteger(flags, 'flags');
|
|
208
|
+
|
|
209
|
+
this.stretch = stretch;
|
|
210
|
+
this.bend = bend;
|
|
211
|
+
this.damping = damping;
|
|
212
|
+
this.slack = slack;
|
|
213
|
+
this.thickness = thickness;
|
|
214
|
+
this.inertia = inertia;
|
|
215
|
+
this.drag = drag;
|
|
216
|
+
this.substeps = substeps;
|
|
217
|
+
this.iterations = iterations;
|
|
218
|
+
this.flags = flags;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* A mutable copy. This is how a library entry is edited: the entries are
|
|
223
|
+
* frozen and shared, and `clone` is the one step between "assign one" and
|
|
224
|
+
* "own one".
|
|
225
|
+
*
|
|
226
|
+
* @returns {ClothDynamics}
|
|
227
|
+
*/
|
|
228
|
+
clone() {
|
|
229
|
+
const r = new ClothDynamics();
|
|
230
|
+
|
|
231
|
+
r.stretch = this.stretch;
|
|
232
|
+
r.bend = this.bend;
|
|
233
|
+
r.damping = this.damping;
|
|
234
|
+
r.slack = this.slack;
|
|
235
|
+
r.thickness = this.thickness;
|
|
236
|
+
r.inertia = this.inertia;
|
|
237
|
+
r.drag = this.drag;
|
|
238
|
+
r.substeps = this.substeps;
|
|
239
|
+
r.iterations = this.iterations;
|
|
240
|
+
r.flags = this.flags;
|
|
241
|
+
|
|
242
|
+
return r;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @param {ClothDynamics} other
|
|
247
|
+
* @returns {boolean}
|
|
248
|
+
*/
|
|
249
|
+
copy(other) {
|
|
250
|
+
this.stretch = other.stretch;
|
|
251
|
+
this.bend = other.bend;
|
|
252
|
+
this.damping = other.damping;
|
|
253
|
+
this.slack = other.slack;
|
|
254
|
+
this.thickness = other.thickness;
|
|
255
|
+
this.inertia = other.inertia;
|
|
256
|
+
this.drag = other.drag;
|
|
257
|
+
this.substeps = other.substeps;
|
|
258
|
+
this.iterations = other.iterations;
|
|
259
|
+
this.flags = other.flags;
|
|
260
|
+
|
|
261
|
+
return this;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @param {ClothDynamics} other
|
|
266
|
+
* @returns {boolean}
|
|
267
|
+
*/
|
|
268
|
+
equals(other) {
|
|
269
|
+
if (other === this) {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (other === null || other === undefined || other.isClothDynamics !== true) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return this.stretch === other.stretch
|
|
278
|
+
&& this.bend === other.bend
|
|
279
|
+
&& this.damping === other.damping
|
|
280
|
+
&& this.slack === other.slack
|
|
281
|
+
&& this.thickness === other.thickness
|
|
282
|
+
&& this.inertia === other.inertia
|
|
283
|
+
&& this.drag === other.drag
|
|
284
|
+
&& this.substeps === other.substeps
|
|
285
|
+
&& this.iterations === other.iterations
|
|
286
|
+
&& this.flags === other.flags;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* @returns {number}
|
|
291
|
+
*/
|
|
292
|
+
hash() {
|
|
293
|
+
return combine_hash(
|
|
294
|
+
computeHashFloat(this.stretch),
|
|
295
|
+
computeHashFloat(this.bend),
|
|
296
|
+
computeHashFloat(this.damping),
|
|
297
|
+
computeHashFloat(this.slack),
|
|
298
|
+
computeHashFloat(this.thickness),
|
|
299
|
+
computeHashFloat(this.inertia),
|
|
300
|
+
computeHashFloat(this.drag),
|
|
301
|
+
this.substeps,
|
|
302
|
+
this.iterations,
|
|
303
|
+
this.flags
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
toJSON() {
|
|
308
|
+
return {
|
|
309
|
+
stretch: this.stretch,
|
|
310
|
+
bend: this.bend,
|
|
311
|
+
damping: this.damping,
|
|
312
|
+
slack: this.slack,
|
|
313
|
+
thickness: this.thickness,
|
|
314
|
+
inertia: this.inertia,
|
|
315
|
+
drag: this.drag,
|
|
316
|
+
substeps: this.substeps,
|
|
317
|
+
iterations: this.iterations,
|
|
318
|
+
flags: this.flags
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* @param {object} json
|
|
324
|
+
*/
|
|
325
|
+
fromJSON(json) {
|
|
326
|
+
this.#assign(json);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
toString() {
|
|
330
|
+
return `ClothDynamics${JSON.stringify(this.toJSON())}`;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* @readonly
|
|
336
|
+
* @type {boolean}
|
|
337
|
+
*/
|
|
338
|
+
ClothDynamics.prototype.isClothDynamics = true;
|
|
339
|
+
|
|
340
|
+
ClothDynamics.typeName = "ClothDynamics";
|