@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,80 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Every array the step touches is a view into a single `ArrayBuffer`: particle
|
|
5
|
-
* state, the constraint tables, the per-particle incidence lists, and the
|
|
6
|
-
* duals. One allocation per cloth, one object to hand across a worker boundary
|
|
7
|
-
* (§12 puts a region per instance inside one shared buffer; this is that region
|
|
8
|
-
* with its views already cut), and no object dereference anywhere in the step.
|
|
9
|
-
* `SolverBodyState` is the same idea for rigid bodies and reads the same way.
|
|
10
|
-
*
|
|
11
|
-
* `Float32` throughout, per §12: the simulation runs in the cloth's local
|
|
12
|
-
* frame, so coordinates are garment-sized rather than world-sized and f32 has
|
|
13
|
-
* ample precision, and the payoff is half the bandwidth in the loop that
|
|
14
|
-
* dominates. JavaScript arithmetic is f64 regardless — only the *storage* is
|
|
15
|
-
* narrow, so a vertex update computes in double and rounds once on the way
|
|
16
|
-
* out.
|
|
17
|
-
*
|
|
18
|
-
* ## Particles are stored in colour order
|
|
19
|
-
*
|
|
20
|
-
* The sweep is "for each colour, for each particle in it" (§5.4). Rather than
|
|
21
|
-
* indirect through a colour membership list every iteration, {@link from}
|
|
22
|
-
* **permutes the particles** so each colour is a contiguous span, rewrites
|
|
23
|
-
* every row's particle indices into the new numbering, and stores one offset
|
|
24
|
-
* per colour. The sweep is then a pair of counted loops over adjacent indices
|
|
25
|
-
* and the runtime never sees a graph. {@link source_of_particle} carries the
|
|
26
|
-
* inverse permutation for a caller that has to map back to the mesh vertex it
|
|
27
|
-
* came from.
|
|
28
|
-
*
|
|
29
|
-
* ## Rows are stored per kind, and reached from the particle
|
|
30
|
-
*
|
|
31
|
-
* §6's row model is one table of `(C, f_min, f_max, stiffness)`, but the rows
|
|
32
|
-
* are *visited from the particle side* — a vertex update needs every row that
|
|
33
|
-
* touches particle `i`, not every row. So each kind carries a CSR incidence
|
|
34
|
-
* list: `*_adjacency_offset[i] .. [i + 1]` indexes into `*_adjacency`, whose
|
|
35
|
-
* entries pack the row index together with which slot of that row the particle
|
|
36
|
-
* occupies. Keeping the kinds in separate lists rather than one polymorphic
|
|
37
|
-
* table is what lets each accumulation loop stay monomorphic; a new row type
|
|
38
|
-
* is a new module and a new pair of arrays, not a branch inside the old loop.
|
|
39
|
-
*
|
|
40
|
-
* M0 carried the two persistent kinds the solver core is proved on — stretch
|
|
41
|
-
* and bend. M1 adds the third, the **leash**: §6's slack row and its tether
|
|
42
|
-
* row, which have the same `C` and differ only in where their centre and
|
|
43
|
-
* radius come from (`cloth_leash_row.js`). §6's strain-limit row needed no new
|
|
44
|
-
* storage at all — it is a stretch row with a longer rest length and a
|
|
45
|
-
* one-sided clamp, which the stretch table already carries. M2 adds the
|
|
46
|
-
* **backstop**, which is a leash against a plane rather than a point.
|
|
47
|
-
*
|
|
48
|
-
* ## Contacts are transient, and they live here anyway
|
|
49
|
-
*
|
|
50
|
-
* §5.4 says contact rows "never enter this structure" and are kept in a
|
|
51
|
-
* per-particle scratch applied Jacobi-style. Half of that is right and half of
|
|
52
|
-
* it is a solution to a problem a *collider* contact does not have.
|
|
53
|
-
*
|
|
54
|
-
* A contact against a collider is **unary** — one particle against a surface
|
|
55
|
-
* that is fixed for the substep — so it couples no two particles, so there is
|
|
56
|
-
* no Gauss-Seidel/Jacobi distinction to make and nothing to keep out of the
|
|
57
|
-
* colouring. It accumulates in the vertex update exactly like a leash row, in
|
|
58
|
-
* colour order, deterministically. What M4's particle-particle rows need is a
|
|
59
|
-
* different question and §9 is where it is answered.
|
|
60
|
-
*
|
|
61
|
-
* What *is* true is that a contact comes and goes, so it cannot be a CSR table
|
|
62
|
-
* sized at build time. It is instead a fixed **{@link CLOTH_CONTACT_SLOTS}
|
|
63
|
-
* slots per particle**, allocated once inside this buffer and rebuilt each
|
|
64
|
-
* step: an occupied slot names a collider, an empty one holds `-1`. That keeps
|
|
65
|
-
* §12's one-allocation property, bounds the worst case — a particle inside
|
|
66
|
-
* thirty colliders gets rows against the four nearest, which is the four that
|
|
67
|
-
* matter — and makes the accumulation a counted loop over adjacent slots
|
|
68
|
-
* rather than an indirection.
|
|
69
|
-
*
|
|
70
|
-
* A leash row is **unary** — one particle against a point — which has two
|
|
71
|
-
* pleasant consequences. It adds no edge to the particle graph, so the
|
|
72
|
-
* colouring is untouched by however many leashes a cloth carries. And its
|
|
73
|
-
* incidence list needs no slot bits: an entry is a row index and nothing else.
|
|
74
|
-
*
|
|
75
|
-
* @author Alex Goldring
|
|
76
|
-
* @copyright Company Named Limited (c) 2026
|
|
2
|
+
* Slots in {@link ClothStateresult } — what one step answers with.
|
|
77
3
|
*/
|
|
4
|
+
export type ClothStepResult = number;
|
|
5
|
+
export namespace ClothStepResult {
|
|
6
|
+
let SPEED: number;
|
|
7
|
+
let CONTACT_COUNT: number;
|
|
8
|
+
let SELF_PAIRS: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* `Float64` words in {@link ClothState#result}.
|
|
12
|
+
* @type {number}
|
|
13
|
+
*/
|
|
14
|
+
export const CLOTH_STEP_RESULT_WORDS: number;
|
|
78
15
|
export class ClothState {
|
|
79
16
|
/**
|
|
80
17
|
* Build a cloth from a rest configuration and its rows.
|
|
@@ -105,9 +42,14 @@ export class ClothState {
|
|
|
105
42
|
* @param {Int32Array|number[]} [description.backstop_particle] the particle each backstop row holds
|
|
106
43
|
* @param {Float32Array|number[]} [description.backstop_radius] backstop radius per row; the planes
|
|
107
44
|
* themselves are written per step rather than here
|
|
45
|
+
* @param {boolean} [description.shared] back the buffer with a
|
|
46
|
+
* {@link SharedArrayBuffer} so a worker can step it in place. Throws where
|
|
47
|
+
* `SharedArrayBuffer` does not exist — a page that is not cross-origin
|
|
48
|
+
* isolated is one where the worker path cannot run, and silently handing
|
|
49
|
+
* back private memory would make both threads mutate copies of it.
|
|
108
50
|
* @returns {ClothState}
|
|
109
51
|
*/
|
|
110
|
-
static from({ position, mass_inverse, stretch_particle, stretch_rest, stretch_stiffness, stretch_force_min, stretch_force_max, bend_particle, bend_weight, bend_stiffness, leash_particle, leash_radius, backstop_particle, backstop_radius }: {
|
|
52
|
+
static from({ position, mass_inverse, stretch_particle, stretch_rest, stretch_stiffness, stretch_force_min, stretch_force_max, bend_particle, bend_weight, bend_stiffness, leash_particle, leash_radius, backstop_particle, backstop_radius, shared }: {
|
|
111
53
|
position: Float32Array | number[];
|
|
112
54
|
mass_inverse: Float32Array | number[];
|
|
113
55
|
stretch_particle?: Int32Array | number[];
|
|
@@ -122,12 +64,43 @@ export class ClothState {
|
|
|
122
64
|
leash_radius?: Float32Array | number[];
|
|
123
65
|
backstop_particle?: Int32Array | number[];
|
|
124
66
|
backstop_radius?: Float32Array | number[];
|
|
67
|
+
shared?: boolean;
|
|
68
|
+
}): ClothState;
|
|
69
|
+
/**
|
|
70
|
+
* Attach to a state built on another thread. The views are cut by the same
|
|
71
|
+
* {@link allocate} the original ran, so the two objects see identical
|
|
72
|
+
* regions at identical offsets — no serialized layout to drift, because
|
|
73
|
+
* there is only one function that knows the layout.
|
|
74
|
+
*
|
|
75
|
+
* Build-time content (rows, adjacency, the colour permutation) is already in
|
|
76
|
+
* the buffer and is not rewritten; only the views are new.
|
|
77
|
+
*
|
|
78
|
+
* @param {{buffer: SharedArrayBuffer, particle_count: number, stretch_count: number,
|
|
79
|
+
* bend_count: number, leash_count: number, backstop_count: number, colour_count: number}} descriptor
|
|
80
|
+
* @returns {ClothState}
|
|
81
|
+
*/
|
|
82
|
+
static fromSharedDescriptor(descriptor: {
|
|
83
|
+
buffer: SharedArrayBuffer;
|
|
84
|
+
particle_count: number;
|
|
85
|
+
stretch_count: number;
|
|
86
|
+
bend_count: number;
|
|
87
|
+
leash_count: number;
|
|
88
|
+
backstop_count: number;
|
|
89
|
+
colour_count: number;
|
|
125
90
|
}): ClothState;
|
|
126
91
|
/**
|
|
127
|
-
* The single allocation every view below is cut from.
|
|
128
|
-
* @
|
|
92
|
+
* The single allocation every view below is cut from. A
|
|
93
|
+
* {@link SharedArrayBuffer} when the cloth was built for a worker, and an
|
|
94
|
+
* ordinary one otherwise — nothing else about the layout changes, which is
|
|
95
|
+
* what makes the worker a deployment choice rather than a second format.
|
|
96
|
+
* @type {ArrayBuffer|SharedArrayBuffer}
|
|
129
97
|
*/
|
|
130
|
-
buffer: ArrayBuffer;
|
|
98
|
+
buffer: ArrayBuffer | SharedArrayBuffer;
|
|
99
|
+
/**
|
|
100
|
+
* What the last step answered — see {@link ClothStepResult}.
|
|
101
|
+
* @type {Float64Array}
|
|
102
|
+
*/
|
|
103
|
+
result: Float64Array;
|
|
131
104
|
/**
|
|
132
105
|
* @type {number}
|
|
133
106
|
*/
|
|
@@ -410,6 +383,33 @@ export class ClothState {
|
|
|
410
383
|
* @type {number}
|
|
411
384
|
*/
|
|
412
385
|
contact_radius: number;
|
|
386
|
+
/**
|
|
387
|
+
* This step's colliders, packed, in the **cloth's own frame** —
|
|
388
|
+
* {@link CLOTH_COLLIDER_SLOTS} records of `CCR_STRIDE` floats, rewritten
|
|
389
|
+
* every step by `cloth_gather_colliders`.
|
|
390
|
+
*
|
|
391
|
+
* §12's table always listed the colliders as a region of the cloth's own
|
|
392
|
+
* area; M2 kept them on {@link ClothInstance} and grew the array on demand,
|
|
393
|
+
* on the grounds that the size is a property of the world rather than of the
|
|
394
|
+
* cloth. Both are true, and the one that decides is the worker: a region
|
|
395
|
+
* inside this buffer needs no second registration when the broadphase
|
|
396
|
+
* happens to return more.
|
|
397
|
+
* @type {Float32Array}
|
|
398
|
+
*/
|
|
399
|
+
collider_table: Float32Array;
|
|
400
|
+
/**
|
|
401
|
+
* The index handle behind each record in {@link collider_table}. A record
|
|
402
|
+
* index is this step's; a handle is the collider's, and it is what a
|
|
403
|
+
* transient contact's multiplier is warm-started on.
|
|
404
|
+
* @type {Int32Array}
|
|
405
|
+
*/
|
|
406
|
+
collider_key: Int32Array;
|
|
407
|
+
/**
|
|
408
|
+
* Live records in {@link collider_table}, at most
|
|
409
|
+
* {@link CLOTH_COLLIDER_SLOTS}.
|
|
410
|
+
* @type {number}
|
|
411
|
+
*/
|
|
412
|
+
collider_count: number;
|
|
413
413
|
/**
|
|
414
414
|
* Which collider each contact slot holds, `CLOTH_CONTACT_SLOTS` per
|
|
415
415
|
* particle. A **record index into the caller's packed collider table**, not
|
|
@@ -522,5 +522,60 @@ export class ClothState {
|
|
|
522
522
|
* @type {Float32Array}
|
|
523
523
|
*/
|
|
524
524
|
contact_anchor: Float32Array;
|
|
525
|
+
/**
|
|
526
|
+
* The air each particle sits in, 3 per particle, **in the cloth's own
|
|
527
|
+
* frame**, metres per second (§10).
|
|
528
|
+
*
|
|
529
|
+
* Written by the main thread — `cloth_sample_air` — and read by the step,
|
|
530
|
+
* which is the whole of M6's answer to "which side of the worker bridge does
|
|
531
|
+
* wind sampling run on". A fluid field is a hundred thousand floats rewritten
|
|
532
|
+
* every step by a solver that may itself be on another worker; the *answer*
|
|
533
|
+
* is three floats a particle. So the field stays where it is and the answer
|
|
534
|
+
* crosses — and it crosses for free, because this is a region of the cloth's
|
|
535
|
+
* own `SharedArrayBuffer` and the main thread writes exactly where the worker
|
|
536
|
+
* reads. `MEASUREMENTS.md` §45.
|
|
537
|
+
*
|
|
538
|
+
* Stale rather than absent when a cloth has no wind: the step skips the
|
|
539
|
+
* aerodynamic term entirely when its drag response is zero, so what this
|
|
540
|
+
* holds is whatever the last windy step left.
|
|
541
|
+
* @type {Float32Array}
|
|
542
|
+
*/
|
|
543
|
+
air_velocity: Float32Array;
|
|
544
|
+
/**
|
|
545
|
+
* Gravity plus §10's aerodynamic drag, 3 per particle, cloth-local, m/s².
|
|
546
|
+
*
|
|
547
|
+
* Built once per step by `cloth_wind_accelerate` and read by `cloth_step`
|
|
548
|
+
* in place of its uniform gravity vector. It is in the buffer rather than in
|
|
549
|
+
* a module scratch for two reasons: §12's one-allocation-per-cloth property,
|
|
550
|
+
* which M5 spent a milestone making true; and the bit-parity gate, which
|
|
551
|
+
* compares this buffer byte for byte and therefore covers the derived
|
|
552
|
+
* acceleration rather than only its inputs.
|
|
553
|
+
* @type {Float32Array}
|
|
554
|
+
*/
|
|
555
|
+
external_acceleration: Float32Array;
|
|
556
|
+
/**
|
|
557
|
+
* @returns {boolean} whether the buffer is shared with a worker.
|
|
558
|
+
*/
|
|
559
|
+
isSharedMemory(): boolean;
|
|
560
|
+
/**
|
|
561
|
+
* Everything a second thread needs to cut the same views over the same
|
|
562
|
+
* bytes: the buffer, and the six counts the layout is a function of.
|
|
563
|
+
*
|
|
564
|
+
* Structured-cloneable, and the buffer inside it is *shared* rather than
|
|
565
|
+
* copied — which is the whole point, and is why {@link isSharedMemory} is
|
|
566
|
+
* asserted here rather than discovered on the far side.
|
|
567
|
+
*
|
|
568
|
+
* @returns {{buffer: SharedArrayBuffer, particle_count: number, stretch_count: number,
|
|
569
|
+
* bend_count: number, leash_count: number, backstop_count: number, colour_count: number}}
|
|
570
|
+
*/
|
|
571
|
+
getSharedDescriptor(): {
|
|
572
|
+
buffer: SharedArrayBuffer;
|
|
573
|
+
particle_count: number;
|
|
574
|
+
stretch_count: number;
|
|
575
|
+
bend_count: number;
|
|
576
|
+
leash_count: number;
|
|
577
|
+
backstop_count: number;
|
|
578
|
+
colour_count: number;
|
|
579
|
+
};
|
|
525
580
|
}
|
|
526
581
|
//# sourceMappingURL=ClothState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClothState.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/ClothState.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ClothState.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/ClothState.js"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { CCR_STRIDE } from "../collider/ClothColliderRecord.js";
|
|
2
3
|
import { cloth_color_order, cloth_color_particles } from "./cloth_color_particles.js";
|
|
4
|
+
import { CLOTH_COLLIDER_SLOTS } from "./cloth_solver_constants.js";
|
|
3
5
|
import { CLOTH_SELF_PAIRS_PER_PARTICLE } from "./cloth_self_find.js";
|
|
4
6
|
import { CLOTH_CONTACT_SLOTS } from "./constraint/cloth_contact_row.js";
|
|
5
7
|
|
|
@@ -77,17 +79,80 @@ import { CLOTH_CONTACT_SLOTS } from "./constraint/cloth_contact_row.js";
|
|
|
77
79
|
* colouring is untouched by however many leashes a cloth carries. And its
|
|
78
80
|
* incidence list needs no slot bits: an entry is a row index and nothing else.
|
|
79
81
|
*
|
|
82
|
+
* ## The air is in here too, and it is the one region the main thread writes
|
|
83
|
+
*
|
|
84
|
+
* M6's wind (§10) samples a fluid field per particle per step, and a fluid field
|
|
85
|
+
* is not a thing that can cross to a cloth worker. So what crosses is the
|
|
86
|
+
* **sampled answer**: {@link ClothState#air_velocity}, written by the main
|
|
87
|
+
* thread into this buffer and read by the step on the far side of it. Every
|
|
88
|
+
* other region here is written by whichever thread runs the step; this one is
|
|
89
|
+
* the direction the buffer was already able to carry and nobody had used.
|
|
90
|
+
*
|
|
91
|
+
* ## The step's scalar results come back in the buffer too
|
|
92
|
+
*
|
|
93
|
+
* Everything above is state the step reads and writes. {@link ClothState#result}
|
|
94
|
+
* is the other direction and the reason it exists is the worker: a step that
|
|
95
|
+
* runs on another thread can only answer through memory both threads hold, and
|
|
96
|
+
* the three things a caller needs back from one — the largest speed left, which
|
|
97
|
+
* the sleep test reads, and the two diagnostic counts — are scalars rather than
|
|
98
|
+
* arrays. They sit in the buffer instead of on the object because a
|
|
99
|
+
* `ClothState` attached over shared memory in a worker is a *different object*
|
|
100
|
+
* over the *same bytes*, so a plain field on it is invisible to the main thread.
|
|
101
|
+
*
|
|
102
|
+
* `Float64` rather than `Float32`, at the head of the buffer where the
|
|
103
|
+
* alignment is free: the speed is compared against a sleep threshold, and an f32
|
|
104
|
+
* round on one side of that comparison and not the other is exactly the kind of
|
|
105
|
+
* divergence §12's bit-parity gate exists to forbid.
|
|
106
|
+
*
|
|
80
107
|
* @author Alex Goldring
|
|
81
108
|
* @copyright Company Named Limited (c) 2026
|
|
82
109
|
*/
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Slots in {@link ClothState#result} — what one step answers with.
|
|
113
|
+
*
|
|
114
|
+
* @readonly
|
|
115
|
+
* @enum {number}
|
|
116
|
+
*/
|
|
117
|
+
export const ClothStepResult = {
|
|
118
|
+
/**
|
|
119
|
+
* Largest particle speed after the velocity clamp, m/s. §7 P1's clamp
|
|
120
|
+
* reports it and §7 P5's sleep test reads it.
|
|
121
|
+
*/
|
|
122
|
+
SPEED: 0,
|
|
123
|
+
/**
|
|
124
|
+
* Contact rows the step created. Diagnostic.
|
|
125
|
+
*/
|
|
126
|
+
CONTACT_COUNT: 1,
|
|
127
|
+
/**
|
|
128
|
+
* Self-collision pairs the step found. Diagnostic.
|
|
129
|
+
*/
|
|
130
|
+
SELF_PAIRS: 2
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* `Float64` words in {@link ClothState#result}.
|
|
135
|
+
* @type {number}
|
|
136
|
+
*/
|
|
137
|
+
export const CLOTH_STEP_RESULT_WORDS = 3;
|
|
138
|
+
|
|
83
139
|
export class ClothState {
|
|
84
140
|
|
|
85
141
|
/**
|
|
86
|
-
* The single allocation every view below is cut from.
|
|
87
|
-
* @
|
|
142
|
+
* The single allocation every view below is cut from. A
|
|
143
|
+
* {@link SharedArrayBuffer} when the cloth was built for a worker, and an
|
|
144
|
+
* ordinary one otherwise — nothing else about the layout changes, which is
|
|
145
|
+
* what makes the worker a deployment choice rather than a second format.
|
|
146
|
+
* @type {ArrayBuffer|SharedArrayBuffer}
|
|
88
147
|
*/
|
|
89
148
|
buffer = null;
|
|
90
149
|
|
|
150
|
+
/**
|
|
151
|
+
* What the last step answered — see {@link ClothStepResult}.
|
|
152
|
+
* @type {Float64Array}
|
|
153
|
+
*/
|
|
154
|
+
result = null;
|
|
155
|
+
|
|
91
156
|
/**
|
|
92
157
|
* @type {number}
|
|
93
158
|
*/
|
|
@@ -415,6 +480,36 @@ export class ClothState {
|
|
|
415
480
|
*/
|
|
416
481
|
contact_radius = 0;
|
|
417
482
|
|
|
483
|
+
/**
|
|
484
|
+
* This step's colliders, packed, in the **cloth's own frame** —
|
|
485
|
+
* {@link CLOTH_COLLIDER_SLOTS} records of `CCR_STRIDE` floats, rewritten
|
|
486
|
+
* every step by `cloth_gather_colliders`.
|
|
487
|
+
*
|
|
488
|
+
* §12's table always listed the colliders as a region of the cloth's own
|
|
489
|
+
* area; M2 kept them on {@link ClothInstance} and grew the array on demand,
|
|
490
|
+
* on the grounds that the size is a property of the world rather than of the
|
|
491
|
+
* cloth. Both are true, and the one that decides is the worker: a region
|
|
492
|
+
* inside this buffer needs no second registration when the broadphase
|
|
493
|
+
* happens to return more.
|
|
494
|
+
* @type {Float32Array}
|
|
495
|
+
*/
|
|
496
|
+
collider_table = null;
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* The index handle behind each record in {@link collider_table}. A record
|
|
500
|
+
* index is this step's; a handle is the collider's, and it is what a
|
|
501
|
+
* transient contact's multiplier is warm-started on.
|
|
502
|
+
* @type {Int32Array}
|
|
503
|
+
*/
|
|
504
|
+
collider_key = null;
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Live records in {@link collider_table}, at most
|
|
508
|
+
* {@link CLOTH_COLLIDER_SLOTS}.
|
|
509
|
+
* @type {number}
|
|
510
|
+
*/
|
|
511
|
+
collider_count = 0;
|
|
512
|
+
|
|
418
513
|
/**
|
|
419
514
|
* Which collider each contact slot holds, `CLOTH_CONTACT_SLOTS` per
|
|
420
515
|
* particle. A **record index into the caller's packed collider table**, not
|
|
@@ -539,6 +634,39 @@ export class ClothState {
|
|
|
539
634
|
*/
|
|
540
635
|
contact_anchor = null;
|
|
541
636
|
|
|
637
|
+
/**
|
|
638
|
+
* The air each particle sits in, 3 per particle, **in the cloth's own
|
|
639
|
+
* frame**, metres per second (§10).
|
|
640
|
+
*
|
|
641
|
+
* Written by the main thread — `cloth_sample_air` — and read by the step,
|
|
642
|
+
* which is the whole of M6's answer to "which side of the worker bridge does
|
|
643
|
+
* wind sampling run on". A fluid field is a hundred thousand floats rewritten
|
|
644
|
+
* every step by a solver that may itself be on another worker; the *answer*
|
|
645
|
+
* is three floats a particle. So the field stays where it is and the answer
|
|
646
|
+
* crosses — and it crosses for free, because this is a region of the cloth's
|
|
647
|
+
* own `SharedArrayBuffer` and the main thread writes exactly where the worker
|
|
648
|
+
* reads. `MEASUREMENTS.md` §45.
|
|
649
|
+
*
|
|
650
|
+
* Stale rather than absent when a cloth has no wind: the step skips the
|
|
651
|
+
* aerodynamic term entirely when its drag response is zero, so what this
|
|
652
|
+
* holds is whatever the last windy step left.
|
|
653
|
+
* @type {Float32Array}
|
|
654
|
+
*/
|
|
655
|
+
air_velocity = null;
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Gravity plus §10's aerodynamic drag, 3 per particle, cloth-local, m/s².
|
|
659
|
+
*
|
|
660
|
+
* Built once per step by `cloth_wind_accelerate` and read by `cloth_step`
|
|
661
|
+
* in place of its uniform gravity vector. It is in the buffer rather than in
|
|
662
|
+
* a module scratch for two reasons: §12's one-allocation-per-cloth property,
|
|
663
|
+
* which M5 spent a milestone making true; and the bit-parity gate, which
|
|
664
|
+
* compares this buffer byte for byte and therefore covers the derived
|
|
665
|
+
* acceleration rather than only its inputs.
|
|
666
|
+
* @type {Float32Array}
|
|
667
|
+
*/
|
|
668
|
+
external_acceleration = null;
|
|
669
|
+
|
|
542
670
|
/**
|
|
543
671
|
* Build a cloth from a rest configuration and its rows.
|
|
544
672
|
*
|
|
@@ -568,6 +696,11 @@ export class ClothState {
|
|
|
568
696
|
* @param {Int32Array|number[]} [description.backstop_particle] the particle each backstop row holds
|
|
569
697
|
* @param {Float32Array|number[]} [description.backstop_radius] backstop radius per row; the planes
|
|
570
698
|
* themselves are written per step rather than here
|
|
699
|
+
* @param {boolean} [description.shared] back the buffer with a
|
|
700
|
+
* {@link SharedArrayBuffer} so a worker can step it in place. Throws where
|
|
701
|
+
* `SharedArrayBuffer` does not exist — a page that is not cross-origin
|
|
702
|
+
* isolated is one where the worker path cannot run, and silently handing
|
|
703
|
+
* back private memory would make both threads mutate copies of it.
|
|
571
704
|
* @returns {ClothState}
|
|
572
705
|
*/
|
|
573
706
|
static from({
|
|
@@ -584,7 +717,8 @@ export class ClothState {
|
|
|
584
717
|
leash_particle = EMPTY_INT32,
|
|
585
718
|
leash_radius = EMPTY_FLOAT32,
|
|
586
719
|
backstop_particle = EMPTY_INT32,
|
|
587
|
-
backstop_radius = EMPTY_FLOAT32
|
|
720
|
+
backstop_radius = EMPTY_FLOAT32,
|
|
721
|
+
shared = false
|
|
588
722
|
}) {
|
|
589
723
|
const particle_count = mass_inverse.length;
|
|
590
724
|
const stretch_count = stretch_rest.length;
|
|
@@ -617,7 +751,11 @@ export class ClothState {
|
|
|
617
751
|
|
|
618
752
|
const state = new ClothState();
|
|
619
753
|
|
|
620
|
-
allocate(
|
|
754
|
+
allocate(
|
|
755
|
+
state,
|
|
756
|
+
particle_count, stretch_count, bend_count, leash_count, backstop_count, colour_count,
|
|
757
|
+
shared ? allocate_shared : allocate_private
|
|
758
|
+
);
|
|
621
759
|
|
|
622
760
|
state.colour_offset.set(colour_offset);
|
|
623
761
|
state.source_of_particle.set(order);
|
|
@@ -729,6 +867,95 @@ export class ClothState {
|
|
|
729
867
|
|
|
730
868
|
return state;
|
|
731
869
|
}
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* @returns {boolean} whether the buffer is shared with a worker.
|
|
873
|
+
*/
|
|
874
|
+
isSharedMemory() {
|
|
875
|
+
return typeof SharedArrayBuffer === "function" && this.buffer instanceof SharedArrayBuffer;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Everything a second thread needs to cut the same views over the same
|
|
880
|
+
* bytes: the buffer, and the six counts the layout is a function of.
|
|
881
|
+
*
|
|
882
|
+
* Structured-cloneable, and the buffer inside it is *shared* rather than
|
|
883
|
+
* copied — which is the whole point, and is why {@link isSharedMemory} is
|
|
884
|
+
* asserted here rather than discovered on the far side.
|
|
885
|
+
*
|
|
886
|
+
* @returns {{buffer: SharedArrayBuffer, particle_count: number, stretch_count: number,
|
|
887
|
+
* bend_count: number, leash_count: number, backstop_count: number, colour_count: number}}
|
|
888
|
+
*/
|
|
889
|
+
getSharedDescriptor() {
|
|
890
|
+
assert.ok(this.isSharedMemory(), 'ClothState.getSharedDescriptor: the state is not shared-memory backed');
|
|
891
|
+
|
|
892
|
+
return {
|
|
893
|
+
buffer: this.buffer,
|
|
894
|
+
particle_count: this.particle_count,
|
|
895
|
+
stretch_count: this.stretch_count,
|
|
896
|
+
bend_count: this.bend_count,
|
|
897
|
+
leash_count: this.leash_count,
|
|
898
|
+
backstop_count: this.backstop_count,
|
|
899
|
+
colour_count: this.colour_count
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Attach to a state built on another thread. The views are cut by the same
|
|
905
|
+
* {@link allocate} the original ran, so the two objects see identical
|
|
906
|
+
* regions at identical offsets — no serialized layout to drift, because
|
|
907
|
+
* there is only one function that knows the layout.
|
|
908
|
+
*
|
|
909
|
+
* Build-time content (rows, adjacency, the colour permutation) is already in
|
|
910
|
+
* the buffer and is not rewritten; only the views are new.
|
|
911
|
+
*
|
|
912
|
+
* @param {{buffer: SharedArrayBuffer, particle_count: number, stretch_count: number,
|
|
913
|
+
* bend_count: number, leash_count: number, backstop_count: number, colour_count: number}} descriptor
|
|
914
|
+
* @returns {ClothState}
|
|
915
|
+
*/
|
|
916
|
+
static fromSharedDescriptor(descriptor) {
|
|
917
|
+
const state = new ClothState();
|
|
918
|
+
|
|
919
|
+
allocate(
|
|
920
|
+
state,
|
|
921
|
+
descriptor.particle_count,
|
|
922
|
+
descriptor.stretch_count,
|
|
923
|
+
descriptor.bend_count,
|
|
924
|
+
descriptor.leash_count,
|
|
925
|
+
descriptor.backstop_count,
|
|
926
|
+
descriptor.colour_count,
|
|
927
|
+
() => descriptor.buffer
|
|
928
|
+
);
|
|
929
|
+
|
|
930
|
+
return state;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* @param {number} byte_length
|
|
936
|
+
* @returns {ArrayBuffer}
|
|
937
|
+
* @private
|
|
938
|
+
*/
|
|
939
|
+
function allocate_private(byte_length) {
|
|
940
|
+
return new ArrayBuffer(byte_length);
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* @param {number} byte_length
|
|
945
|
+
* @returns {SharedArrayBuffer}
|
|
946
|
+
* @private
|
|
947
|
+
*/
|
|
948
|
+
function allocate_shared(byte_length) {
|
|
949
|
+
if (typeof SharedArrayBuffer !== "function") {
|
|
950
|
+
throw new Error(
|
|
951
|
+
"ClothState: SharedArrayBuffer is unavailable, so a worker-backed cloth cannot be built."
|
|
952
|
+
+ " A WorkerClothSystem requires a cross-origin isolated page: serve with"
|
|
953
|
+
+ " 'Cross-Origin-Opener-Policy: same-origin' and 'Cross-Origin-Embedder-Policy: require-corp',"
|
|
954
|
+
+ " or use ClothSystem, which is the same solver on this thread."
|
|
955
|
+
);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
return new SharedArrayBuffer(byte_length);
|
|
732
959
|
}
|
|
733
960
|
|
|
734
961
|
/**
|
|
@@ -744,23 +971,37 @@ const EMPTY_INT32 = new Int32Array(0);
|
|
|
744
971
|
const EMPTY_FLOAT32 = new Float32Array(0);
|
|
745
972
|
|
|
746
973
|
/**
|
|
747
|
-
* Cut every view out of one buffer, in declaration order.
|
|
748
|
-
*
|
|
749
|
-
*
|
|
974
|
+
* Cut every view out of one buffer, in declaration order. Sizes are counted in
|
|
975
|
+
* **4-byte elements**; the one `Float64` region sits first, where the buffer's
|
|
976
|
+
* own alignment already satisfies it, and costs two elements a word.
|
|
977
|
+
*
|
|
978
|
+
* The one function that knows the layout, deliberately: {@link
|
|
979
|
+
* ClothState.fromSharedDescriptor} attaches a second thread to the same bytes by
|
|
980
|
+
* running this again over the buffer it was handed, so there is no serialized
|
|
981
|
+
* description of the layout anywhere that could drift from the layout.
|
|
750
982
|
*
|
|
751
983
|
* @param {ClothState} state
|
|
752
984
|
* @param {number} particle_count
|
|
753
985
|
* @param {number} stretch_count
|
|
754
986
|
* @param {number} bend_count
|
|
755
987
|
* @param {number} leash_count
|
|
988
|
+
* @param {number} backstop_count
|
|
756
989
|
* @param {number} colour_count
|
|
990
|
+
* @param {function(number): (ArrayBuffer|SharedArrayBuffer)} acquire given the
|
|
991
|
+
* byte length, answers the buffer to cut — a fresh private one, a fresh shared
|
|
992
|
+
* one, or an existing one being re-attached
|
|
757
993
|
* @private
|
|
758
994
|
*/
|
|
759
|
-
function allocate(
|
|
995
|
+
function allocate(
|
|
996
|
+
state,
|
|
997
|
+
particle_count, stretch_count, bend_count, leash_count, backstop_count, colour_count,
|
|
998
|
+
acquire
|
|
999
|
+
) {
|
|
760
1000
|
const contact_count = particle_count * CLOTH_CONTACT_SLOTS;
|
|
761
1001
|
const self_capacity = particle_count * CLOTH_SELF_PAIRS_PER_PARTICLE;
|
|
762
1002
|
|
|
763
1003
|
const sizes = [
|
|
1004
|
+
CLOTH_STEP_RESULT_WORDS * 2, // result — Float64, first for its alignment
|
|
764
1005
|
particle_count * 3, // position
|
|
765
1006
|
particle_count * 3, // position_previous
|
|
766
1007
|
particle_count * 3, // velocity
|
|
@@ -799,6 +1040,8 @@ function allocate(state, particle_count, stretch_count, bend_count, leash_count,
|
|
|
799
1040
|
backstop_count, // backstop_penalty
|
|
800
1041
|
particle_count + 1, // backstop_adjacency_offset
|
|
801
1042
|
backstop_count, // backstop_adjacency
|
|
1043
|
+
CLOTH_COLLIDER_SLOTS * CCR_STRIDE, // collider_table
|
|
1044
|
+
CLOTH_COLLIDER_SLOTS, // collider_key
|
|
802
1045
|
contact_count, // contact_collider
|
|
803
1046
|
contact_count, // contact_key
|
|
804
1047
|
contact_count, // contact_lambda
|
|
@@ -808,7 +1051,9 @@ function allocate(state, particle_count, stretch_count, bend_count, leash_count,
|
|
|
808
1051
|
contact_count * 3, // contact_anchor
|
|
809
1052
|
self_capacity * 2, // self_pair
|
|
810
1053
|
particle_count * 3, // self_force
|
|
811
|
-
particle_count * 6
|
|
1054
|
+
particle_count * 6, // self_hessian
|
|
1055
|
+
particle_count * 3, // air_velocity
|
|
1056
|
+
particle_count * 3 // external_acceleration
|
|
812
1057
|
];
|
|
813
1058
|
|
|
814
1059
|
let total = 0;
|
|
@@ -817,18 +1062,20 @@ function allocate(state, particle_count, stretch_count, bend_count, leash_count,
|
|
|
817
1062
|
total += sizes[i];
|
|
818
1063
|
}
|
|
819
1064
|
|
|
820
|
-
const buffer =
|
|
1065
|
+
const buffer = acquire(total * 4);
|
|
1066
|
+
|
|
1067
|
+
assert.equal(buffer.byteLength, total * 4, 'ClothState buffer byte length');
|
|
821
1068
|
|
|
822
1069
|
let cursor = 0;
|
|
823
1070
|
|
|
824
1071
|
/**
|
|
825
|
-
* @param {Float32ArrayConstructor|Int32ArrayConstructor} type
|
|
1072
|
+
* @param {Float32ArrayConstructor|Int32ArrayConstructor|Float64ArrayConstructor} type
|
|
826
1073
|
* @param {number} length
|
|
827
1074
|
*/
|
|
828
1075
|
const cut = (type, length) => {
|
|
829
1076
|
const view = new type(buffer, cursor * 4, length);
|
|
830
1077
|
|
|
831
|
-
cursor += length;
|
|
1078
|
+
cursor += length * (type.BYTES_PER_ELEMENT / 4);
|
|
832
1079
|
|
|
833
1080
|
return view;
|
|
834
1081
|
};
|
|
@@ -841,6 +1088,8 @@ function allocate(state, particle_count, stretch_count, bend_count, leash_count,
|
|
|
841
1088
|
state.backstop_count = backstop_count;
|
|
842
1089
|
state.colour_count = colour_count;
|
|
843
1090
|
|
|
1091
|
+
state.result = cut(Float64Array, CLOTH_STEP_RESULT_WORDS);
|
|
1092
|
+
|
|
844
1093
|
state.position = cut(Float32Array, particle_count * 3);
|
|
845
1094
|
state.position_previous = cut(Float32Array, particle_count * 3);
|
|
846
1095
|
state.velocity = cut(Float32Array, particle_count * 3);
|
|
@@ -884,6 +1133,9 @@ function allocate(state, particle_count, stretch_count, bend_count, leash_count,
|
|
|
884
1133
|
state.backstop_adjacency_offset = cut(Int32Array, particle_count + 1);
|
|
885
1134
|
state.backstop_adjacency = cut(Int32Array, backstop_count);
|
|
886
1135
|
|
|
1136
|
+
state.collider_table = cut(Float32Array, CLOTH_COLLIDER_SLOTS * CCR_STRIDE);
|
|
1137
|
+
state.collider_key = cut(Int32Array, CLOTH_COLLIDER_SLOTS);
|
|
1138
|
+
|
|
887
1139
|
state.contact_collider = cut(Int32Array, contact_count);
|
|
888
1140
|
state.contact_key = cut(Int32Array, contact_count);
|
|
889
1141
|
state.contact_lambda = cut(Float32Array, contact_count);
|
|
@@ -896,6 +1148,15 @@ function allocate(state, particle_count, stretch_count, bend_count, leash_count,
|
|
|
896
1148
|
state.self_force = cut(Float32Array, particle_count * 3);
|
|
897
1149
|
state.self_hessian = cut(Float32Array, particle_count * 6);
|
|
898
1150
|
|
|
1151
|
+
// M6's two, last rather than beside the other per-particle regions, and the
|
|
1152
|
+
// placement is the point. A cloth with no wind never touches them, so
|
|
1153
|
+
// putting them between `inertia_blend` and the row tables would push
|
|
1154
|
+
// twenty-four bytes a particle — twenty-four kilobytes on the §17 workload —
|
|
1155
|
+
// between the sweep and the rows it reads, for a feature that step is not
|
|
1156
|
+
// running. Cold regions go at the cold end.
|
|
1157
|
+
state.air_velocity = cut(Float32Array, particle_count * 3);
|
|
1158
|
+
state.external_acceleration = cut(Float32Array, particle_count * 3);
|
|
1159
|
+
|
|
899
1160
|
assert.equal(cursor, total, 'buffer cursor at end of allocation');
|
|
900
1161
|
}
|
|
901
1162
|
|