@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
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { CLOTH_STEP_PARAM_STRIDE } from "../solver/cloth_step_instance.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* # The command region, and what is *not* in it
|
|
5
|
+
*
|
|
6
|
+
* Layout of the {@link WorkerSystem} command region used by
|
|
7
|
+
* {@link WorkerClothSystem}: a count, then one {@link ClothStepParam} block per
|
|
8
|
+
* cloth to step this tick.
|
|
9
|
+
*
|
|
10
|
+
* §12 asks for exactly this shape — "the command region names which instances
|
|
11
|
+
* are live this step, so sleeping (P5) and culled (§12.1) instances cost nothing
|
|
12
|
+
* but their absence from a list" — and for `ClothDynamics` to travel with it,
|
|
13
|
+
* "written every step … cheaper than tracking dirtiness, and it keeps
|
|
14
|
+
* `cloth.dynamics.slack = 0.2` working live". Both hold. What changed on the way
|
|
15
|
+
* to being built is that the per-cloth words are not a serialization of
|
|
16
|
+
* `ClothDynamics` but the **step's own parameter block** — `dt`, local gravity, a
|
|
17
|
+
* retention, a clamp — because a cloth's dynamics have already been mapped
|
|
18
|
+
* through `cloth_dynamics_map.js` by the time the step can use them, and mapping
|
|
19
|
+
* them on the far side would be a second copy of that mapping with no way to
|
|
20
|
+
* prove it agreed. `MEASUREMENTS.md` §38.
|
|
21
|
+
*
|
|
22
|
+
* The consequence is the useful one: the same block the worker reads is the
|
|
23
|
+
* block {@link ClothSystem} fills in a private scratch array, so the two systems
|
|
24
|
+
* do not agree on the numbers, they *share* them.
|
|
25
|
+
*
|
|
26
|
+
* ## What travels on the cold plane instead
|
|
27
|
+
*
|
|
28
|
+
* A cloth's `ClothState` — the particles, the rows, the duals, the collider
|
|
29
|
+
* table, the pair list. That is a `SharedArrayBuffer` per cloth, registered once
|
|
30
|
+
* when the cloth seeds and again whenever a re-seed replaces it, and nothing of
|
|
31
|
+
* it is ever copied: the worker cuts its own views over the same bytes
|
|
32
|
+
* (`ClothState.fromSharedDescriptor`). §12 asked for one buffer for the whole
|
|
33
|
+
* cloth world; `MEASUREMENTS.md` §39 is why it is one per cloth.
|
|
34
|
+
*
|
|
35
|
+
* @author Alex Goldring
|
|
36
|
+
* @copyright Company Named Limited (c) 2026
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Header words of the command region.
|
|
41
|
+
*
|
|
42
|
+
* @readonly
|
|
43
|
+
* @enum {number}
|
|
44
|
+
*/
|
|
45
|
+
export const ClothCommand = {
|
|
46
|
+
/**
|
|
47
|
+
* How many {@link ClothStepParam} blocks follow.
|
|
48
|
+
*/
|
|
49
|
+
CLOTH_COUNT: 0
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Command words consumed before the first cloth's block.
|
|
54
|
+
* @type {number}
|
|
55
|
+
*/
|
|
56
|
+
export const CLOTH_COMMAND_HEADER_WORDS = 1;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* First word of the `index`-th cloth's parameter block.
|
|
60
|
+
*
|
|
61
|
+
* @param {number} index
|
|
62
|
+
* @returns {number}
|
|
63
|
+
*/
|
|
64
|
+
export function cloth_command_offset(index) {
|
|
65
|
+
return CLOTH_COMMAND_HEADER_WORDS + index * CLOTH_STEP_PARAM_STRIDE;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Size the command region for a ceiling on simultaneously stepped cloths. The
|
|
70
|
+
* region is allocated once at startup and cannot grow, which is what makes that
|
|
71
|
+
* ceiling a constructor argument rather than something discovered at runtime.
|
|
72
|
+
*
|
|
73
|
+
* @param {number} max_cloth_count
|
|
74
|
+
* @returns {number} `Float64` words
|
|
75
|
+
*/
|
|
76
|
+
export function cloth_command_word_count(max_cloth_count) {
|
|
77
|
+
return cloth_command_offset(max_cloth_count);
|
|
78
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloth_write_back.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_write_back.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH;;;;;;GAMG;AACH,wFAFa,IAAI,
|
|
1
|
+
{"version":3,"file":"cloth_write_back.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_write_back.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH;;;;;;GAMG;AACH,wFAFa,IAAI,CA2DhB;AAyBD;;;;;;;;;GASG;AACH,0FAJW,MAAM,UACN,MAAM,GACJ,IAAI,CA4BhB"}
|
|
@@ -76,16 +76,24 @@ export function cloth_write_back(instance, ecd) {
|
|
|
76
76
|
const blended = instance.blended_position;
|
|
77
77
|
const reconstructed = instance.blended_rotation;
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
// The anchor pose the particles were carried into **this step**, not the
|
|
80
|
+
// live component. For `ClothSystem` those are the same value, because the
|
|
81
|
+
// step happened between them. For `WorkerClothSystem` they are not: it
|
|
82
|
+
// writes step T−1 back at the top of tick T, by which time the anchor has
|
|
83
|
+
// moved on, and composing last step's shape against this tick's anchor
|
|
84
|
+
// produces a world pose that describes neither. Nothing rendered can tell —
|
|
85
|
+
// the attachment cascade re-derives position from the anchor and the local
|
|
86
|
+
// transforms either way (§4.1) — but a **nested** cloth reads this pose as
|
|
87
|
+
// its own anchor, and then the two systems hand it different numbers.
|
|
88
|
+
// `MEASUREMENTS.md` §56.
|
|
89
|
+
const ax = instance.anchor_translation[0];
|
|
90
|
+
const ay = instance.anchor_translation[1];
|
|
91
|
+
const az = instance.anchor_translation[2];
|
|
92
|
+
|
|
93
|
+
const aqx = instance.anchor_rotation[0];
|
|
94
|
+
const aqy = instance.anchor_rotation[1];
|
|
95
|
+
const aqz = instance.anchor_rotation[2];
|
|
96
|
+
const aqw = instance.anchor_rotation[3];
|
|
89
97
|
|
|
90
98
|
const parent = instance.node_parent;
|
|
91
99
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn the cloth solver worker.
|
|
3
|
+
*
|
|
4
|
+
* Isolated in its own module on purpose: `import.meta` is a syntax error under
|
|
5
|
+
* the CommonJS transform the test runner uses, so any module containing it
|
|
6
|
+
* cannot be imported by a spec — even transitively. Keeping the expression here
|
|
7
|
+
* lets {@link WorkerClothSystem} stay testable while application code gets a
|
|
8
|
+
* one-import default.
|
|
9
|
+
*
|
|
10
|
+
* The `new Worker(new URL(...), { type: "module" })` form is what webpack 5
|
|
11
|
+
* detects statically, so the worker is emitted as a real chunk with its full
|
|
12
|
+
* dependency graph rather than being assembled at runtime.
|
|
13
|
+
*
|
|
14
|
+
* @returns {Worker}
|
|
15
|
+
*/
|
|
16
|
+
export function makeClothWorker(): Worker;
|
|
17
|
+
//# sourceMappingURL=makeClothWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"makeClothWorker.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/makeClothWorker.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,mCAFa,MAAM,CAIlB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn the cloth solver worker.
|
|
3
|
+
*
|
|
4
|
+
* Isolated in its own module on purpose: `import.meta` is a syntax error under
|
|
5
|
+
* the CommonJS transform the test runner uses, so any module containing it
|
|
6
|
+
* cannot be imported by a spec — even transitively. Keeping the expression here
|
|
7
|
+
* lets {@link WorkerClothSystem} stay testable while application code gets a
|
|
8
|
+
* one-import default.
|
|
9
|
+
*
|
|
10
|
+
* The `new Worker(new URL(...), { type: "module" })` form is what webpack 5
|
|
11
|
+
* detects statically, so the worker is emitted as a real chunk with its full
|
|
12
|
+
* dependency graph rather than being assembled at runtime.
|
|
13
|
+
*
|
|
14
|
+
* @returns {Worker}
|
|
15
|
+
*/
|
|
16
|
+
export function makeClothWorker() {
|
|
17
|
+
return new Worker(new URL("./cloth.worker.js", import.meta.url), { type: "module" });
|
|
18
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
npm run dev --workspace @woosh/meep-engine
|
|
5
5
|
```
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Five pages, one directory, one layer of the system each. (Vite takes the next
|
|
8
8
|
free port if 5173 is busy — the terminal says which.)
|
|
9
9
|
|
|
10
10
|
| | |
|
|
@@ -13,10 +13,16 @@ free port if 5173 is busy — the terminal says which.)
|
|
|
13
13
|
| [`rig.html`](./rig.html) | **the entity subtree, M1.** A real `EntityManager`, real entities, `ClothSystem` walking and writing back. |
|
|
14
14
|
| [`collide.html`](./collide.html) | **collision, M2.** The solver again, with a packed collider table in the argument list. |
|
|
15
15
|
| [`garment.html`](./garment.html) | **skinned garments, M3, and self-collision, M4.** A skeleton of entities, a `Skin`, and a `Cloth` + `ClothRig` driving some of its joints. |
|
|
16
|
+
| [`wind.html`](./wind.html) | **wind, M6.** A banner hanging in a real `FluidSimulator`'s wake, reading it through `ClothFluidWind`. |
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
All are at
|
|
18
19
|
`http://localhost:5173/src/engine/physics/cloth/playground/<page>`.
|
|
19
20
|
|
|
21
|
+
There is no M5 page, and that is deliberate: a `SharedArrayBuffer` needs a
|
|
22
|
+
cross-origin isolated page and `vite.config.mjs` sends no `COOP`/`COEP`
|
|
23
|
+
(`MEASUREMENTS.md` §44). The worker bridge is tested by
|
|
24
|
+
`SystemWorkerLoopback` instead, more precisely than a page could.
|
|
25
|
+
|
|
20
26
|
---
|
|
21
27
|
|
|
22
28
|
# The solver page — `index.html`
|
|
@@ -337,3 +343,68 @@ has the numbers, because it cost an hour to diagnose the first time.
|
|
|
337
343
|
step_once, draw, scene }`. `rebuild` returns a promise, because
|
|
338
344
|
`EntityManager#startup` does and an entity created before it resolves is never
|
|
339
345
|
linked.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
# The wind page — `wind.html`
|
|
350
|
+
|
|
351
|
+
## What it is
|
|
352
|
+
|
|
353
|
+
§10's argument made watchable, and the word that matters is **simulated**. There
|
|
354
|
+
is no wind model on this page. There is a `FluidField`, a `FluidSimulator`, a
|
|
355
|
+
`GlobalFluidEffector` in its prevailing-wind regime, and a solid post standing in
|
|
356
|
+
the flow; the banner reads the result through exactly the `ClothFluidWind` and
|
|
357
|
+
`cloth_sample_air` a scene uses. The blue threads are the air on a horizontal
|
|
358
|
+
slice through the banner's waist, the red squares are the post.
|
|
359
|
+
|
|
360
|
+
The cloth is driven like the solver and collision pages — `cloth_step` in
|
|
361
|
+
process, no `EntityManager` — because what is being shown is the air rather than
|
|
362
|
+
the ECS wiring, and `ecs/cloth_wind.spec.js` covers that more precisely.
|
|
363
|
+
|
|
364
|
+
## Three things to watch rather than read
|
|
365
|
+
|
|
366
|
+
- **Turn the flow to 90° on `ambient only`.** The banner goes limp at the same
|
|
367
|
+
wind speed: the *drag accel* readout falls from 43 m/s² to 0.08, and the mean
|
|
368
|
+
facing factor from 0.221 to 0.000. That is §10's normal-facing factor, and it
|
|
369
|
+
is the sharpest single result in M6.
|
|
370
|
+
- **Do the same on `fluid field + ambient`, and it does not go limp.** 0.216 at
|
|
371
|
+
0°, 0.280 at 90°. A wake has velocity in every direction, so no orientation of
|
|
372
|
+
a banner is edge-on to one — which is something the simulation knows and a wind
|
|
373
|
+
zone could not have told it.
|
|
374
|
+
- **Take the post away.** The air at the banner goes from 6.0 m/s to 8.7. That
|
|
375
|
+
31% deficit is the incompressible projection's answer to a solid standing in a
|
|
376
|
+
flow, and there is no authored falloff anywhere in it.
|
|
377
|
+
|
|
378
|
+
## The readout
|
|
379
|
+
|
|
380
|
+
- **cloth step** — `cloth_wind_accelerate` plus `cloth_step`, against §17's 2 ms
|
|
381
|
+
bar. The wind's own share of it is about one per cent (`MEASUREMENTS.md` §49);
|
|
382
|
+
everything else on that bar is the solver.
|
|
383
|
+
- **fluid step** — the `FluidSimulator`, which at the default grid is several
|
|
384
|
+
times the cloth. It is on the page to be honest about where the frame goes: the
|
|
385
|
+
simulation is the expensive half and cloth is renting it.
|
|
386
|
+
- **air sample** and **sampled** — `cloth_sample_air`. Switch the source to
|
|
387
|
+
`ambient only` and watch it drop by a factor of twenty-five as "per particle"
|
|
388
|
+
becomes "once for the cloth". That is §10's "a cloth outside every fluid field's
|
|
389
|
+
bounds skips it entirely", and it is the reason the fallback is affordable.
|
|
390
|
+
- **drag accel, mean** — the external acceleration with gravity taken back out:
|
|
391
|
+
the facing factor as a number.
|
|
392
|
+
|
|
393
|
+
## What it does not show
|
|
394
|
+
|
|
395
|
+
**A shedding street.** At the grids this page can afford the wake is a *steady*
|
|
396
|
+
velocity deficit — measured at 18, 26 and 34 cells across, with damping and
|
|
397
|
+
vorticity confinement at both ends of their range, the air behind the post varies
|
|
398
|
+
by under 0.03 m/s. The banner's free corner moves twelve times as far per step
|
|
399
|
+
with the post as without, and both of those are settled rather than fluttering.
|
|
400
|
+
That is the fluid solver's answer at this scale rather than the cloth's, and
|
|
401
|
+
`MEASUREMENTS.md` §51 records it so the page is not read as promising something
|
|
402
|
+
it does not do.
|
|
403
|
+
|
|
404
|
+
## Notes
|
|
405
|
+
|
|
406
|
+
`globalThis.cloth_wind_playground` exposes `{ control, camera, rebuild,
|
|
407
|
+
step_once, refresh_post, cloth, tunnel, wind, air_centre, sampled_per_particle,
|
|
408
|
+
mean_drag, tripwire, timings }`. Changing `control.yaw` needs a `refresh_post()`
|
|
409
|
+
after it, because the post stands upstream along the flow and only moves when it
|
|
410
|
+
is asked to.
|
|
@@ -173,7 +173,7 @@ function step_once() {
|
|
|
173
173
|
|
|
174
174
|
const started = performance.now();
|
|
175
175
|
|
|
176
|
-
contact_rows = cloth_contact_find(state, colliders.table, colliders.keys, colliders.count);
|
|
176
|
+
contact_rows = cloth_contact_find(state, colliders.table, colliders.keys, colliders.count, FIXED_STEP);
|
|
177
177
|
|
|
178
178
|
cloth_step(
|
|
179
179
|
state, FIXED_STEP, 0, -9.81, 0,
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>meep — cloth wind (M6)</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: 288px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#readout table { border-collapse: collapse; width: 100%; }
|
|
47
|
+
#readout td { padding: 1px 0; white-space: nowrap; }
|
|
48
|
+
#readout td:last-child { text-align: right; padding-left: 18px; }
|
|
49
|
+
#readout td:first-child { color: var(--dim); }
|
|
50
|
+
|
|
51
|
+
#budget { height: 4px; margin-top: 7px; background: #22262d; position: relative; overflow: hidden; }
|
|
52
|
+
#budget > i { display: block; height: 100%; background: var(--good); width: 0; }
|
|
53
|
+
#budget.over > i { background: var(--bad); }
|
|
54
|
+
|
|
55
|
+
aside {
|
|
56
|
+
width: 300px; flex: none;
|
|
57
|
+
border-left: 1px solid var(--line);
|
|
58
|
+
background: var(--panel);
|
|
59
|
+
overflow-y: auto;
|
|
60
|
+
padding: 12px 14px 40px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
h1 { font-size: 13px; margin: 0 0 2px; }
|
|
64
|
+
h2 {
|
|
65
|
+
font-size: 11px; margin: 18px 0 6px; color: var(--dim);
|
|
66
|
+
text-transform: uppercase; letter-spacing: 0.08em; font-weight: normal;
|
|
67
|
+
border-bottom: 1px solid var(--line); padding-bottom: 4px;
|
|
68
|
+
}
|
|
69
|
+
p.blurb { color: var(--dim); margin: 0 0 6px; }
|
|
70
|
+
a { color: #6fa8dc; }
|
|
71
|
+
|
|
72
|
+
label { display: flex; align-items: center; gap: 8px; margin: 5px 0; }
|
|
73
|
+
label > span:first-child { flex: none; width: 96px; color: var(--dim); }
|
|
74
|
+
label > input[type=range] { flex: 1; min-width: 0; height: 16px; }
|
|
75
|
+
label > output { flex: none; width: 62px; text-align: right; }
|
|
76
|
+
label > select {
|
|
77
|
+
flex: 1; min-width: 0; background: #0d0f12; color: var(--ink);
|
|
78
|
+
border: 1px solid var(--line); font: inherit; padding: 2px 4px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.buttons { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
|
82
|
+
button {
|
|
83
|
+
background: #1b1f26; color: var(--ink); border: 1px solid var(--line);
|
|
84
|
+
font: inherit; padding: 4px 10px; cursor: pointer;
|
|
85
|
+
}
|
|
86
|
+
button:hover { background: #232832; }
|
|
87
|
+
button.on { border-color: var(--warn); color: var(--warn); }
|
|
88
|
+
|
|
89
|
+
#tripwire.bad { color: var(--bad); }
|
|
90
|
+
#tripwire.good { color: var(--good); }
|
|
91
|
+
</style>
|
|
92
|
+
</head>
|
|
93
|
+
<body>
|
|
94
|
+
|
|
95
|
+
<div id="stage">
|
|
96
|
+
<canvas id="view"></canvas>
|
|
97
|
+
|
|
98
|
+
<div id="readout">
|
|
99
|
+
<table>
|
|
100
|
+
<tr><td>cloth step</td><td><b id="ms">—</b> ms</td></tr>
|
|
101
|
+
<tr><td>fluid step</td><td><span id="fluid_ms">—</span> ms</td></tr>
|
|
102
|
+
<tr><td>air sample</td><td><span id="sample_us">—</span> µs</td></tr>
|
|
103
|
+
<tr><td>sampled</td><td id="sample_mode">—</td></tr>
|
|
104
|
+
<tr><td>particles / rows</td><td id="counts">—</td></tr>
|
|
105
|
+
<tr><td>air at the banner</td><td id="air">—</td></tr>
|
|
106
|
+
<tr><td>drag accel, mean</td><td id="drag_accel">—</td></tr>
|
|
107
|
+
<tr><td>state</td><td id="tripwire" class="good">ok</td></tr>
|
|
108
|
+
</table>
|
|
109
|
+
<div id="budget"><i></i></div>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<div id="hint">drag to orbit · wheel to zoom · shift-drag to pan · the blue threads are the air, the red squares the post</div>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<aside>
|
|
116
|
+
<h1>Cloth wind — M6</h1>
|
|
117
|
+
<p class="blurb">
|
|
118
|
+
§10's argument, made watchable: there is no wind model here. A real
|
|
119
|
+
<code>FluidField</code>, a real <code>FluidSimulator</code>, a solid post standing in the
|
|
120
|
+
flow, and a banner reading the result through <code>ClothFluidWind</code> — the same path a
|
|
121
|
+
scene uses. The other pages are
|
|
122
|
+
<a href="./index.html">index</a>, <a href="./rig.html">rig</a>,
|
|
123
|
+
<a href="./collide.html">collide</a> and <a href="./garment.html">garment</a>.
|
|
124
|
+
</p>
|
|
125
|
+
|
|
126
|
+
<h2>Banner</h2>
|
|
127
|
+
<label><span>fabric</span><select id="fabric"></select></label>
|
|
128
|
+
<label><span>size</span><input id="size" type="range" min="6" max="28" step="1"><output id="size_out"></output></label>
|
|
129
|
+
<label><span>spacing</span><input id="spacing" type="range" min="0.02" max="0.09" step="0.005"><output id="spacing_out"></output></label>
|
|
130
|
+
<label><span>drag</span><input id="drag" type="range" min="0" max="1" step="0.01"><output id="drag_out"></output></label>
|
|
131
|
+
<label><span>substeps</span><input id="substeps" type="range" min="1" max="6" step="1"><output id="substeps_out"></output></label>
|
|
132
|
+
<label><span>iterations</span><input id="iterations" type="range" min="1" max="12" step="1"><output id="iterations_out"></output></label>
|
|
133
|
+
|
|
134
|
+
<h2>Air</h2>
|
|
135
|
+
<p class="blurb">
|
|
136
|
+
On <em>ambient only</em>, turn the flow to 90° and the banner goes limp at the same wind
|
|
137
|
+
speed — <em>drag accel</em> falls from 43 to 0.08. That is §10's normal-facing factor.
|
|
138
|
+
On the <em>fluid field</em> it does not go limp: a wake has velocity in every direction,
|
|
139
|
+
so nothing is edge-on to one. Take the post away and the air at the banner goes from
|
|
140
|
+
6.0 to 8.7 m/s — that deficit is the projection's answer, not an authored falloff.
|
|
141
|
+
</p>
|
|
142
|
+
<label><span>source</span><select id="source">
|
|
143
|
+
<option value="field">fluid field + ambient</option>
|
|
144
|
+
<option value="ambient">ambient only</option>
|
|
145
|
+
</select></label>
|
|
146
|
+
<label><span>wind</span><input id="speed" type="range" min="0" max="20" step="0.5"><output id="speed_out"></output></label>
|
|
147
|
+
<label><span>flow angle</span><input id="yaw" type="range" min="0" max="90" step="5"><output id="yaw_out"></output></label>
|
|
148
|
+
<label><span>ambient gust</span><input id="gust" type="range" min="0" max="6" step="0.1"><output id="gust_out"></output></label>
|
|
149
|
+
<label><span>grid</span><input id="resolution" type="range" min="8" max="28" step="2"><output id="resolution_out"></output></label>
|
|
150
|
+
|
|
151
|
+
<div class="buttons">
|
|
152
|
+
<button id="post">post</button>
|
|
153
|
+
<button id="show_field">show the air</button>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<h2>Run</h2>
|
|
157
|
+
<div class="buttons">
|
|
158
|
+
<button id="pause">pause</button>
|
|
159
|
+
<button id="single">step once</button>
|
|
160
|
+
<button id="reset">rebuild</button>
|
|
161
|
+
</div>
|
|
162
|
+
</aside>
|
|
163
|
+
|
|
164
|
+
<script type="module" src="./wind_main.js"></script>
|
|
165
|
+
</body>
|
|
166
|
+
</html>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # The wind tunnel the banner hangs in
|
|
3
|
+
*
|
|
4
|
+
* A real {@link FluidField} stepped by a real {@link FluidSimulator}, with a
|
|
5
|
+
* real {@link GlobalFluidEffector} driving the flow and a solid post standing in
|
|
6
|
+
* it — which is the whole of §10's argument made visible. Nothing here is a
|
|
7
|
+
* wind model: the wake behind the post is the incompressible projection's
|
|
8
|
+
* answer, and the cloth reads it through the same {@link FluidComponent} an
|
|
9
|
+
* ordinary scene would.
|
|
10
|
+
*
|
|
11
|
+
* At the grid a sixty-hertz page can afford the wake is a **steady** velocity
|
|
12
|
+
* deficit rather than a shedding street — measured at 18, 26 and 34 cells
|
|
13
|
+
* across, with and without damping and confinement, the air a banner's width
|
|
14
|
+
* downstream varies by under 0.03 m/s. That is the fluid solver's answer at
|
|
15
|
+
* this scale rather than the cloth's, and `MEASUREMENTS.md` §49 records it so
|
|
16
|
+
* the page is not read as promising something it does not do.
|
|
17
|
+
*
|
|
18
|
+
* The post is written straight into `FluidField#solid` rather than voxelised by
|
|
19
|
+
* `FluidObstacle`, because the page has no ECS to hang a `Collider` on and the
|
|
20
|
+
* obstacle is not what is being demonstrated. `FluidSimulator#step` refreshes
|
|
21
|
+
* the derived masks itself, so writing the cells is the whole of it.
|
|
22
|
+
*
|
|
23
|
+
* @author Alex Goldring
|
|
24
|
+
* @copyright Company Named Limited (c) 2026
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {object} WindTunnel
|
|
28
|
+
* @property {FluidComponent} component the volume, placed in world space
|
|
29
|
+
* @property {FluidSimulator} simulator
|
|
30
|
+
* @property {GlobalFluidEffector} effector the prevailing flow
|
|
31
|
+
* @property {Float32Array} world_to_grid
|
|
32
|
+
* @property {number} cell_size
|
|
33
|
+
* @property {number[]} resolution
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* @param {object} options
|
|
37
|
+
* @param {number} options.cell_size metres
|
|
38
|
+
* @param {number[]} options.resolution cells along x, y, z
|
|
39
|
+
* @param {number[]} options.origin world position of cell (0,0,0)'s centre
|
|
40
|
+
* @returns {WindTunnel}
|
|
41
|
+
*/
|
|
42
|
+
export function build_wind_tunnel({ cell_size, resolution, origin }: {
|
|
43
|
+
cell_size: number;
|
|
44
|
+
resolution: number[];
|
|
45
|
+
origin: number[];
|
|
46
|
+
}): WindTunnel;
|
|
47
|
+
/**
|
|
48
|
+
* Stand a solid post across the flow, upstream of the banner.
|
|
49
|
+
*
|
|
50
|
+
* @param {WindTunnel} tunnel
|
|
51
|
+
* @param {object} options
|
|
52
|
+
* @param {boolean} options.present
|
|
53
|
+
* @param {number} options.x world x of the post's centre
|
|
54
|
+
* @param {number} options.z world z of the post's centre
|
|
55
|
+
* @param {number} options.radius metres
|
|
56
|
+
* @returns {void}
|
|
57
|
+
*/
|
|
58
|
+
export function place_wind_post(tunnel: WindTunnel, { present, x, z, radius }: {
|
|
59
|
+
present: boolean;
|
|
60
|
+
x: number;
|
|
61
|
+
z: number;
|
|
62
|
+
radius: number;
|
|
63
|
+
}): void;
|
|
64
|
+
export type WindTunnel = {
|
|
65
|
+
/**
|
|
66
|
+
* the volume, placed in world space
|
|
67
|
+
*/
|
|
68
|
+
component: FluidComponent;
|
|
69
|
+
simulator: FluidSimulator;
|
|
70
|
+
/**
|
|
71
|
+
* the prevailing flow
|
|
72
|
+
*/
|
|
73
|
+
effector: GlobalFluidEffector;
|
|
74
|
+
world_to_grid: Float32Array;
|
|
75
|
+
cell_size: number;
|
|
76
|
+
resolution: number[];
|
|
77
|
+
};
|
|
78
|
+
import { FluidComponent } from "../../fluid/ecs/FluidComponent.js";
|
|
79
|
+
import { FluidSimulator } from "../../fluid/FluidSimulator.js";
|
|
80
|
+
import { GlobalFluidEffector } from "../../fluid/effector/GlobalFluidEffector.js";
|
|
81
|
+
//# sourceMappingURL=wind_build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wind_build.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/playground/wind_build.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;GAQG;AAEH;;;;;;GAMG;AACH;IAL2B,SAAS,EAAzB,MAAM;IACY,UAAU,EAA5B,MAAM,EAAE;IACU,MAAM,EAAxB,MAAM,EAAE;IACN,UAAU,CA2CtB;AAED;;;;;;;;;;GAUG;AACH,wCARW,UAAU;IAEO,OAAO,EAAxB,OAAO;IACS,CAAC,EAAjB,MAAM;IACU,CAAC,EAAjB,MAAM;IACU,MAAM,EAAtB,MAAM;IACJ,IAAI,CAwChB;;;;;eA3Ga,cAAc;eACd,cAAc;;;;cACd,mBAAmB;mBACnB,YAAY;eACZ,MAAM;gBACN,MAAM,EAAE;;+BAnCS,mCAAmC;+BAFnC,+BAA+B;oCAC1B,6CAA6C"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { FluidField } from "../../fluid/FluidField.js";
|
|
2
|
+
import { FluidSimulator } from "../../fluid/FluidSimulator.js";
|
|
3
|
+
import { GlobalFluidEffector } from "../../fluid/effector/GlobalFluidEffector.js";
|
|
4
|
+
import { FluidComponent } from "../../fluid/ecs/FluidComponent.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* # The wind tunnel the banner hangs in
|
|
8
|
+
*
|
|
9
|
+
* A real {@link FluidField} stepped by a real {@link FluidSimulator}, with a
|
|
10
|
+
* real {@link GlobalFluidEffector} driving the flow and a solid post standing in
|
|
11
|
+
* it — which is the whole of §10's argument made visible. Nothing here is a
|
|
12
|
+
* wind model: the wake behind the post is the incompressible projection's
|
|
13
|
+
* answer, and the cloth reads it through the same {@link FluidComponent} an
|
|
14
|
+
* ordinary scene would.
|
|
15
|
+
*
|
|
16
|
+
* At the grid a sixty-hertz page can afford the wake is a **steady** velocity
|
|
17
|
+
* deficit rather than a shedding street — measured at 18, 26 and 34 cells
|
|
18
|
+
* across, with and without damping and confinement, the air a banner's width
|
|
19
|
+
* downstream varies by under 0.03 m/s. That is the fluid solver's answer at
|
|
20
|
+
* this scale rather than the cloth's, and `MEASUREMENTS.md` §49 records it so
|
|
21
|
+
* the page is not read as promising something it does not do.
|
|
22
|
+
*
|
|
23
|
+
* The post is written straight into `FluidField#solid` rather than voxelised by
|
|
24
|
+
* `FluidObstacle`, because the page has no ECS to hang a `Collider` on and the
|
|
25
|
+
* obstacle is not what is being demonstrated. `FluidSimulator#step` refreshes
|
|
26
|
+
* the derived masks itself, so writing the cells is the whole of it.
|
|
27
|
+
*
|
|
28
|
+
* @author Alex Goldring
|
|
29
|
+
* @copyright Company Named Limited (c) 2026
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @typedef {object} WindTunnel
|
|
34
|
+
* @property {FluidComponent} component the volume, placed in world space
|
|
35
|
+
* @property {FluidSimulator} simulator
|
|
36
|
+
* @property {GlobalFluidEffector} effector the prevailing flow
|
|
37
|
+
* @property {Float32Array} world_to_grid
|
|
38
|
+
* @property {number} cell_size
|
|
39
|
+
* @property {number[]} resolution
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {object} options
|
|
44
|
+
* @param {number} options.cell_size metres
|
|
45
|
+
* @param {number[]} options.resolution cells along x, y, z
|
|
46
|
+
* @param {number[]} options.origin world position of cell (0,0,0)'s centre
|
|
47
|
+
* @returns {WindTunnel}
|
|
48
|
+
*/
|
|
49
|
+
export function build_wind_tunnel({ cell_size, resolution, origin }) {
|
|
50
|
+
const component = new FluidComponent();
|
|
51
|
+
|
|
52
|
+
component.cell_size = cell_size;
|
|
53
|
+
component.origin = origin.slice();
|
|
54
|
+
|
|
55
|
+
const field = new FluidField();
|
|
56
|
+
|
|
57
|
+
field.setResolution(resolution[0], resolution[1], resolution[2]);
|
|
58
|
+
field.build();
|
|
59
|
+
|
|
60
|
+
component.field = field;
|
|
61
|
+
|
|
62
|
+
const simulator = new FluidSimulator();
|
|
63
|
+
|
|
64
|
+
// A little damping so a gust decays rather than accumulating forever, and a
|
|
65
|
+
// little confinement so the wake keeps its eddies at this cell count. Both
|
|
66
|
+
// are the simulator's own documented knobs.
|
|
67
|
+
simulator.velocity_damping = 0.2;
|
|
68
|
+
simulator.vorticity_confinement = 0.35;
|
|
69
|
+
|
|
70
|
+
const effector = new GlobalFluidEffector();
|
|
71
|
+
|
|
72
|
+
// Wind plus drag is `GlobalFluidEffector`'s "prevailing wind" regime: the
|
|
73
|
+
// air relaxes toward `wind`, so the volume's far field *is* the ambient the
|
|
74
|
+
// cloth reads outside it, and a garment carried out of the volume does not
|
|
75
|
+
// walk into still air.
|
|
76
|
+
// Six per second, so the volume reaches nine tenths of the driving wind
|
|
77
|
+
// within a second and the slider means roughly what it says. Measured on
|
|
78
|
+
// this grid: 8.7 m/s of a 9 m/s wind in the free stream, and 3.1 m/s
|
|
79
|
+
// directly behind the post, which is the wake the banner hangs in.
|
|
80
|
+
effector.drag = 6;
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
component,
|
|
84
|
+
simulator,
|
|
85
|
+
effector,
|
|
86
|
+
world_to_grid: new Float32Array(16),
|
|
87
|
+
cell_size,
|
|
88
|
+
resolution: resolution.slice()
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Stand a solid post across the flow, upstream of the banner.
|
|
94
|
+
*
|
|
95
|
+
* @param {WindTunnel} tunnel
|
|
96
|
+
* @param {object} options
|
|
97
|
+
* @param {boolean} options.present
|
|
98
|
+
* @param {number} options.x world x of the post's centre
|
|
99
|
+
* @param {number} options.z world z of the post's centre
|
|
100
|
+
* @param {number} options.radius metres
|
|
101
|
+
* @returns {void}
|
|
102
|
+
*/
|
|
103
|
+
export function place_wind_post(tunnel, { present, x, z, radius }) {
|
|
104
|
+
const field = tunnel.component.field;
|
|
105
|
+
|
|
106
|
+
const solid = field.solid;
|
|
107
|
+
|
|
108
|
+
solid.fill(0);
|
|
109
|
+
|
|
110
|
+
if (!present) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const [res_x, res_y, res_z] = tunnel.resolution;
|
|
115
|
+
|
|
116
|
+
const cell_size = tunnel.cell_size;
|
|
117
|
+
|
|
118
|
+
const origin = tunnel.component.origin;
|
|
119
|
+
|
|
120
|
+
const radius_squared = radius * radius;
|
|
121
|
+
|
|
122
|
+
for (let k = 0; k < res_z; k++) {
|
|
123
|
+
const world_z = origin[2] + k * cell_size;
|
|
124
|
+
|
|
125
|
+
const dz = world_z - z;
|
|
126
|
+
|
|
127
|
+
for (let i = 0; i < res_x; i++) {
|
|
128
|
+
const dx = origin[0] + i * cell_size - x;
|
|
129
|
+
|
|
130
|
+
// A round post: solid where the cell centre is inside the circle in
|
|
131
|
+
// the flow's own plane, spanning the whole height.
|
|
132
|
+
if (dx * dx + dz * dz > radius_squared) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
for (let j = 0; j < res_y; j++) {
|
|
137
|
+
solid[k * res_x * res_y + j * res_x + i] = 1;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wind_main.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/playground/wind_main.js"],"names":[],"mappings":""}
|