@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,284 @@
|
|
|
1
|
+
import { cloth_contact_find } from "./cloth_contact_find.js";
|
|
2
|
+
import { cloth_self_find } from "./cloth_self_find.js";
|
|
3
|
+
import { cloth_step } from "./cloth_step.js";
|
|
4
|
+
import { cloth_wind_accelerate } from "./cloth_wind_accelerate.js";
|
|
5
|
+
import { ClothStepResult } from "./ClothState.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* # One cloth, one step, over nothing but memory
|
|
9
|
+
*
|
|
10
|
+
* Everything between the broadphase and the write-back: the velocity damping,
|
|
11
|
+
* the contact search, the self-collision pair search, the solve, and the
|
|
12
|
+
* velocity clamp. It reads a {@link ClothState} and a block of \`Float64\`
|
|
13
|
+
* parameters and it writes the state and three result words. It touches no
|
|
14
|
+
* component, no entity, no index, and no clock.
|
|
15
|
+
*
|
|
16
|
+
* **That is the whole of what crosses to the worker**, and the parameters are a
|
|
17
|
+
* block of words rather than a dozen arguments for exactly that reason: the
|
|
18
|
+
* block *is* the command region. \`ClothSystem\` fills a private copy of it and
|
|
19
|
+
* calls this inline; \`WorkerClothSystem\` fills a slice of the shared command
|
|
20
|
+
* region and the worker calls this with the same words. The two paths cannot
|
|
21
|
+
* drift because there is one function and one layout — which is what §12's
|
|
22
|
+
* bit-parity gate asks for, expressed as code rather than as a test.
|
|
23
|
+
*
|
|
24
|
+
* \`Float64\` throughout the block, and that is load-bearing rather than
|
|
25
|
+
* incidental. Every number here — \`dt\`, the local gravity, the retention, the
|
|
26
|
+
* clamp — is computed on the main thread in double and consumed here in double,
|
|
27
|
+
* so the round trip through shared memory is exact. An \`f32\` command region
|
|
28
|
+
* would round the clamp, and a clamp that rounds is a velocity that rounds, and
|
|
29
|
+
* a velocity that rounds is a cloth that diverges over six hundred steps.
|
|
30
|
+
*
|
|
31
|
+
* ## What is deliberately *not* here
|
|
32
|
+
*
|
|
33
|
+
* The leash centres (they come from the animated pose, which lives on the
|
|
34
|
+
* instance), the collider gather (it needs the world's index), the frame move
|
|
35
|
+
* (it needs the anchor's pose), and — M6 — the **air sample**, which needs a
|
|
36
|
+
* fluid field and a world position. Those are §12's "arbitrary user-facing
|
|
37
|
+
* work" and they stay on the main thread in both systems.
|
|
38
|
+
*
|
|
39
|
+
* What is *here* is the aerodynamic term itself, which is the M6 decision worth
|
|
40
|
+
* naming: the air crosses as three floats a particle in the state's own buffer,
|
|
41
|
+
* and everything built from it — the relative flow, the normal-facing factor,
|
|
42
|
+
* the acceleration — is computed on this side, by this function, once. Putting
|
|
43
|
+
* the drag arithmetic on the main thread instead would have given back a share
|
|
44
|
+
* of what M5 bought and would have made the wind a parameter each system
|
|
45
|
+
* computed for itself, which is exactly the shape `MEASUREMENTS.md` §40 says
|
|
46
|
+
* breaks the parity gate. It is one per cent of a step
|
|
47
|
+
* (\`MEASUREMENTS.md\` §49).
|
|
48
|
+
*
|
|
49
|
+
* What is left here either way is the part the budget is spent on:
|
|
50
|
+
* \`MEASUREMENTS.md\` §7 puts 69% of a frame in the stretch rows alone.
|
|
51
|
+
*
|
|
52
|
+
* @author Alex Goldring
|
|
53
|
+
* @copyright Company Named Limited (c) 2026
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Words of one cloth's parameter block.
|
|
58
|
+
*
|
|
59
|
+
* @readonly
|
|
60
|
+
* @enum {number}
|
|
61
|
+
*/
|
|
62
|
+
export const ClothStepParam = {
|
|
63
|
+
/**
|
|
64
|
+
* Which cloth this block is for. Meaningless to the step itself — the
|
|
65
|
+
* worker reads it to find the state, and it lives in the block rather than
|
|
66
|
+
* in a parallel list so that one stride is the whole per-cloth record.
|
|
67
|
+
*/
|
|
68
|
+
ID: 0,
|
|
69
|
+
/**
|
|
70
|
+
* Seconds of the fixed step.
|
|
71
|
+
*/
|
|
72
|
+
DT: 1,
|
|
73
|
+
/**
|
|
74
|
+
* Gravity, already rotated into the cloth's local frame.
|
|
75
|
+
*/
|
|
76
|
+
GRAVITY_X: 2,
|
|
77
|
+
GRAVITY_Y: 3,
|
|
78
|
+
GRAVITY_Z: 4,
|
|
79
|
+
/**
|
|
80
|
+
* `ClothDynamics#substeps`.
|
|
81
|
+
*/
|
|
82
|
+
SUBSTEPS: 5,
|
|
83
|
+
/**
|
|
84
|
+
* `ClothDynamics#iterations`.
|
|
85
|
+
*/
|
|
86
|
+
ITERATIONS: 6,
|
|
87
|
+
/**
|
|
88
|
+
* Per-step velocity retention in `[0, 1]`, from `ClothDynamics#damping`.
|
|
89
|
+
*/
|
|
90
|
+
RETENTION: 7,
|
|
91
|
+
/**
|
|
92
|
+
* Speed ceiling in m/s, §7 P1's clamp — already scaled by whatever is left
|
|
93
|
+
* of a stabilisation window, because the ramp is the caller's bookkeeping
|
|
94
|
+
* and the clamp is only the number.
|
|
95
|
+
*/
|
|
96
|
+
VELOCITY_LIMIT: 8,
|
|
97
|
+
/**
|
|
98
|
+
* `ClothDynamics#thickness`, metres.
|
|
99
|
+
*/
|
|
100
|
+
CONTACT_RADIUS: 9,
|
|
101
|
+
/**
|
|
102
|
+
* The self-collision row's radius, metres. Read only when
|
|
103
|
+
* {@link ClothStepParam.SELF_COLLISION} is set — a cloth with the flag
|
|
104
|
+
* clear keeps whatever radius it last had, because the row that would read
|
|
105
|
+
* it does not run.
|
|
106
|
+
*/
|
|
107
|
+
SELF_RADIUS: 10,
|
|
108
|
+
/**
|
|
109
|
+
* Live records in the state's collider table, as the gather left it.
|
|
110
|
+
*/
|
|
111
|
+
COLLIDER_COUNT: 11,
|
|
112
|
+
/**
|
|
113
|
+
* Non-zero when `ClothDynamicsFlags.SelfCollision` is set.
|
|
114
|
+
*/
|
|
115
|
+
SELF_COLLISION: 12,
|
|
116
|
+
/**
|
|
117
|
+
* §10's aerodynamic coupling, as the **per-step response**
|
|
118
|
+
* `(1 − e^(−rate·dt))/dt` in 1/s rather than as a rate — see
|
|
119
|
+
* `cloth_wind_accelerate` for why that form cannot overshoot at any `dt`.
|
|
120
|
+
*
|
|
121
|
+
* Zero means there is no air to feel: no fabric drag, or an ambient of
|
|
122
|
+
* exactly nothing. The step then skips the aerodynamic term altogether and
|
|
123
|
+
* takes `cloth_step`'s uniform-gravity path, which is the path M0 through
|
|
124
|
+
* M5 measured.
|
|
125
|
+
*/
|
|
126
|
+
DRAG_RESPONSE: 13
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* `Float64` words one cloth's parameter block occupies.
|
|
131
|
+
* @type {number}
|
|
132
|
+
*/
|
|
133
|
+
export const CLOTH_STEP_PARAM_STRIDE = 14;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Step one cloth.
|
|
137
|
+
*
|
|
138
|
+
* @param {ClothState} state the cloth, with its collider table already gathered
|
|
139
|
+
* @param {{offset: Int32Array, partner: Int32Array}|null} self_exclusions pairs
|
|
140
|
+
* a persistent row already governs; `null` when the cloth never self-collides
|
|
141
|
+
* @param {Float64Array} params
|
|
142
|
+
* @param {number} offset first word of this cloth's block in `params`
|
|
143
|
+
* @returns {void}
|
|
144
|
+
*/
|
|
145
|
+
export function cloth_step_instance(state, self_exclusions, params, offset) {
|
|
146
|
+
const dt = params[offset + ClothStepParam.DT];
|
|
147
|
+
|
|
148
|
+
const collider_count = params[offset + ClothStepParam.COLLIDER_COUNT];
|
|
149
|
+
|
|
150
|
+
const gravity_x = params[offset + ClothStepParam.GRAVITY_X];
|
|
151
|
+
const gravity_y = params[offset + ClothStepParam.GRAVITY_Y];
|
|
152
|
+
const gravity_z = params[offset + ClothStepParam.GRAVITY_Z];
|
|
153
|
+
|
|
154
|
+
const drag_response = params[offset + ClothStepParam.DRAG_RESPONSE];
|
|
155
|
+
|
|
156
|
+
state.contact_radius = params[offset + ClothStepParam.CONTACT_RADIUS];
|
|
157
|
+
state.collider_count = collider_count;
|
|
158
|
+
|
|
159
|
+
damp(state, params[offset + ClothStepParam.RETENTION]);
|
|
160
|
+
|
|
161
|
+
const contact_count = cloth_contact_find(
|
|
162
|
+
state, state.collider_table, state.collider_key, collider_count, dt
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
let self_pairs = 0;
|
|
166
|
+
|
|
167
|
+
if (params[offset + ClothStepParam.SELF_COLLISION] !== 0) {
|
|
168
|
+
state.self_radius = params[offset + ClothStepParam.SELF_RADIUS];
|
|
169
|
+
|
|
170
|
+
self_pairs = cloth_self_find(state, self_exclusions);
|
|
171
|
+
} else {
|
|
172
|
+
state.self_count = 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let external = null;
|
|
176
|
+
|
|
177
|
+
if (drag_response !== 0) {
|
|
178
|
+
// §10, and once per step rather than once per iteration. The air itself
|
|
179
|
+
// was sampled on the main thread into `state.air_velocity`; what is
|
|
180
|
+
// left is arithmetic over positions and velocities this state already
|
|
181
|
+
// holds, so it runs here with the rest of the arithmetic and neither
|
|
182
|
+
// system computes it separately.
|
|
183
|
+
cloth_wind_accelerate(state, drag_response, gravity_x, gravity_y, gravity_z);
|
|
184
|
+
|
|
185
|
+
external = state.external_acceleration;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
cloth_step(
|
|
189
|
+
state, dt,
|
|
190
|
+
gravity_x, gravity_y, gravity_z,
|
|
191
|
+
params[offset + ClothStepParam.SUBSTEPS],
|
|
192
|
+
params[offset + ClothStepParam.ITERATIONS],
|
|
193
|
+
state.collider_table, collider_count,
|
|
194
|
+
undefined,
|
|
195
|
+
external
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
const result = state.result;
|
|
199
|
+
|
|
200
|
+
result[ClothStepResult.SPEED] = clamp_velocity(state, params[offset + ClothStepParam.VELOCITY_LIMIT]);
|
|
201
|
+
result[ClothStepResult.CONTACT_COUNT] = contact_count;
|
|
202
|
+
result[ClothStepResult.SELF_PAIRS] = self_pairs;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Scale every particle's velocity, which is §7 P5's other half.
|
|
207
|
+
*
|
|
208
|
+
* The multiplier decay `α·γ` bleeds accumulated force out of a **hard** row,
|
|
209
|
+
* and a soft row has no multiplier to decay — M0 measured a soft cloth landing
|
|
210
|
+
* in a bounded limit cycle that 2,000 further steps do not move. This is what
|
|
211
|
+
* reaches it, and it is why `ClothDynamics#damping` is part of the correctness
|
|
212
|
+
* argument rather than a taste control. `MEASUREMENTS.md` §6.
|
|
213
|
+
*
|
|
214
|
+
* @param {ClothState} state
|
|
215
|
+
* @param {number} retention `[0, 1]`
|
|
216
|
+
* @private
|
|
217
|
+
*/
|
|
218
|
+
function damp(state, retention) {
|
|
219
|
+
if (retention >= 1) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const velocity = state.velocity;
|
|
224
|
+
|
|
225
|
+
for (let i = 0; i < velocity.length; i++) {
|
|
226
|
+
velocity[i] *= retention;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Hold every particle's speed under the limit derived from
|
|
232
|
+
* `ClothDynamics#thickness`, and report the largest speed left afterwards so
|
|
233
|
+
* the sleep test has something to read.
|
|
234
|
+
*
|
|
235
|
+
* §7 P1 names this clamp and M0 deliberately left it out, because a clamp would
|
|
236
|
+
* have masked the property M0 existed to measure. It is here rather than inside
|
|
237
|
+
* `cloth_step` for the same reason: the solver's stability is still its own.
|
|
238
|
+
*
|
|
239
|
+
* Speed rather than displacement is what the sleep test reads, because
|
|
240
|
+
* `position_previous` after a multi-substep step holds the start of the *last*
|
|
241
|
+
* substep rather than the start of the step, and a motion measure that quietly
|
|
242
|
+
* divides by the substep count is a sleep threshold that means something
|
|
243
|
+
* different for every fabric.
|
|
244
|
+
*
|
|
245
|
+
* @param {ClothState} state
|
|
246
|
+
* @param {number} limit m/s
|
|
247
|
+
* @returns {number} largest particle speed after clamping, m/s
|
|
248
|
+
* @private
|
|
249
|
+
*/
|
|
250
|
+
function clamp_velocity(state, limit) {
|
|
251
|
+
const particle_count = state.particle_count;
|
|
252
|
+
|
|
253
|
+
const velocity = state.velocity;
|
|
254
|
+
|
|
255
|
+
const limit_squared = limit * limit;
|
|
256
|
+
|
|
257
|
+
let worst_squared = 0;
|
|
258
|
+
|
|
259
|
+
for (let i = 0; i < particle_count; i++) {
|
|
260
|
+
const p = i * 3;
|
|
261
|
+
|
|
262
|
+
const vx = velocity[p];
|
|
263
|
+
const vy = velocity[p + 1];
|
|
264
|
+
const vz = velocity[p + 2];
|
|
265
|
+
|
|
266
|
+
let speed_squared = vx * vx + vy * vy + vz * vz;
|
|
267
|
+
|
|
268
|
+
if (speed_squared > limit_squared) {
|
|
269
|
+
const scale = limit / Math.sqrt(speed_squared);
|
|
270
|
+
|
|
271
|
+
velocity[p] = vx * scale;
|
|
272
|
+
velocity[p + 1] = vy * scale;
|
|
273
|
+
velocity[p + 2] = vz * scale;
|
|
274
|
+
|
|
275
|
+
speed_squared = limit_squared;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (speed_squared > worst_squared) {
|
|
279
|
+
worst_squared = speed_squared;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return Math.sqrt(worst_squared);
|
|
284
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write the whole external acceleration — gravity plus §10's aerodynamic drag —
|
|
3
|
+
* into {@link ClothState#external_acceleration}.
|
|
4
|
+
*
|
|
5
|
+
* @param {ClothState} state with {@link ClothState#air_velocity} already filled
|
|
6
|
+
* in the cloth's own frame
|
|
7
|
+
* @param {number} response `(1 − e^(−rate·dt))/dt`, 1/s; `0` means no wind and
|
|
8
|
+
* this function should not have been called
|
|
9
|
+
* @param {number} gravity_x cloth-local gravity, m/s²
|
|
10
|
+
* @param {number} gravity_y
|
|
11
|
+
* @param {number} gravity_z
|
|
12
|
+
* @returns {void}
|
|
13
|
+
*/
|
|
14
|
+
export function cloth_wind_accelerate(state: ClothState, response: number, gravity_x: number, gravity_y: number, gravity_z: number): void;
|
|
15
|
+
/**
|
|
16
|
+
* How much of a unit flow the particle's own incident rows cannot let past,
|
|
17
|
+
* `[0, 1]`. The table in this module's header is what the three cases mean.
|
|
18
|
+
*
|
|
19
|
+
* Exported because it is the whole of what M6 added to the physics and a spec
|
|
20
|
+
* that can only reach it through a step is a spec measuring six other things at
|
|
21
|
+
* once.
|
|
22
|
+
*
|
|
23
|
+
* @param {Float32Array} position particle positions, 3 each
|
|
24
|
+
* @param {Int32Array} offset `ClothState#stretch_adjacency_offset`
|
|
25
|
+
* @param {Int32Array} adjacency `ClothState#stretch_adjacency`, `(row << 1) | slot`
|
|
26
|
+
* @param {Int32Array} row_particle `ClothState#stretch_particle`
|
|
27
|
+
* @param {number} particle
|
|
28
|
+
* @param {number} unit_x flow direction, unit length
|
|
29
|
+
* @param {number} unit_y
|
|
30
|
+
* @param {number} unit_z
|
|
31
|
+
* @returns {number}
|
|
32
|
+
*/
|
|
33
|
+
export function cloth_wind_facing(position: Float32Array, offset: Int32Array, adjacency: Int32Array, row_particle: Int32Array, particle: number, unit_x: number, unit_y: number, unit_z: number): number;
|
|
34
|
+
/**
|
|
35
|
+
* # The aerodynamic term, and the factor that makes a flag a flag
|
|
36
|
+
*
|
|
37
|
+
* §10's model: a particle in moving air feels
|
|
38
|
+
*
|
|
39
|
+
* a_drag = response · facing · (u_air − v)
|
|
40
|
+
*
|
|
41
|
+
* where `u_air` is what the main thread sampled into
|
|
42
|
+
* {@link ClothState#air_velocity} and `facing` is how much of the flow the
|
|
43
|
+
* particle's own local geometry cannot let through. Gravity is added to the
|
|
44
|
+
* same word, so what comes out is the **whole** external acceleration and
|
|
45
|
+
* `cloth_step` reads one array instead of a vector plus a special case.
|
|
46
|
+
*
|
|
47
|
+
* Once per particle per **step**, never per iteration, which is §10's own cost
|
|
48
|
+
* rule. A cloth with `response = 0` — no fabric drag, or no air moving — does
|
|
49
|
+
* not run this at all and `cloth_step` takes its uniform-gravity path, so a
|
|
50
|
+
* scene with no wind in it pays nothing and produces the bytes M5 measured.
|
|
51
|
+
*
|
|
52
|
+
* ## `response` rather than a rate, and why it cannot overshoot
|
|
53
|
+
*
|
|
54
|
+
* The caller hands in `(1 − e^(−rate·dt))/dt` rather than `rate`
|
|
55
|
+
* (`cloth_drag_response`), so the velocity change across the step is
|
|
56
|
+
*
|
|
57
|
+
* Δv = a_drag · dt = (1 − e^(−rate·dt)) · facing · (u_air − v)
|
|
58
|
+
*
|
|
59
|
+
* — a fraction of the gap to the air that is **strictly below one** for any
|
|
60
|
+
* `rate`, any `dt` and any `facing ≤ 1`. An explicit drag written as `rate`
|
|
61
|
+
* instead overshoots once `rate·dt > 1` and diverges past 2, which at §1's "not
|
|
62
|
+
* at 5 fps" is a 0.2 s step and a rate of 10. This is the same exact-ODE step
|
|
63
|
+
* `GlobalFluidEffector` takes for the air itself, which is a pleasant symmetry
|
|
64
|
+
* rather than a coincidence: both are relaxations toward a velocity.
|
|
65
|
+
*
|
|
66
|
+
* ## The facing factor: §10 asked for `|n·û|` and a rope has no `n`
|
|
67
|
+
*
|
|
68
|
+
* §10 writes the factor as `|n·û|` — "the difference between a flag and a
|
|
69
|
+
* rope". The normal is the half a **rope** does not have: a chain's particles
|
|
70
|
+
* span a line, every direction perpendicular to it is equally a normal, and any
|
|
71
|
+
* one this code picked would be a fabrication of the kind §7 P4(a) exists to
|
|
72
|
+
* keep out. A rope also wants the *opposite* dependence — it catches the flow
|
|
73
|
+
* across it and slices along it, where a sheet catches it along the normal and
|
|
74
|
+
* slices across.
|
|
75
|
+
*
|
|
76
|
+
* Both are one quantity: **the part of the flow the particle's incident rows
|
|
77
|
+
* cannot let past**. Take the span `T` of the directions to the particle's
|
|
78
|
+
* stretch-row neighbours in the current configuration and the factor is
|
|
79
|
+
* `‖û − proj_T(û)‖`:
|
|
80
|
+
*
|
|
81
|
+
* | rank of `T` | what the particle is | the factor |
|
|
82
|
+
* |---|---|---|
|
|
83
|
+
* | 2 | a point on a surface | `\|û·n‖` with `n = b₁×b₂` — §10's own expression |
|
|
84
|
+
* | 1 | a link of a chain | `√(1 − (û·t)²)` — cross-flow, the rope's answer |
|
|
85
|
+
* | 0 | an isolated particle | `1` — a bead has no preferred direction |
|
|
86
|
+
*
|
|
87
|
+
* One expression, three topologies, no stored normal, no orientation, no sign,
|
|
88
|
+
* and nothing carried between steps — recomputed from the configuration every
|
|
89
|
+
* step, which is exactly what P4(a) asks of a normal. `MEASUREMENTS.md` §46.
|
|
90
|
+
*
|
|
91
|
+
* @author Alex Goldring
|
|
92
|
+
* @copyright Company Named Limited (c) 2026
|
|
93
|
+
*/
|
|
94
|
+
/**
|
|
95
|
+
* How much of a second incident direction has to survive projection out of the
|
|
96
|
+
* first before it counts as spanning a plane with it.
|
|
97
|
+
*
|
|
98
|
+
* A quarter is about fourteen degrees. Below it the two rows describe the same
|
|
99
|
+
* line as far as a normal is concerned, and the cross product of two nearly
|
|
100
|
+
* parallel directions is a normal built almost entirely out of rounding — which
|
|
101
|
+
* on a sheet under tension is every pair of rows on the same edge (the fabric
|
|
102
|
+
* row and the strain-limit row backing it up) and on a chain is every skip row
|
|
103
|
+
* beside the link it skips.
|
|
104
|
+
* @type {number}
|
|
105
|
+
*/
|
|
106
|
+
export const CLOTH_WIND_SPAN_MIN: number;
|
|
107
|
+
//# sourceMappingURL=cloth_wind_accelerate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloth_wind_accelerate.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/solver/cloth_wind_accelerate.js"],"names":[],"mappings":"AA2EA;;;;;;;;;;;;GAYG;AACH,mEAPW,MAAM,aAEN,MAAM,aACN,MAAM,aACN,MAAM,GACJ,IAAI,CA4DhB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,4CAVW,YAAY,UACZ,UAAU,aACV,UAAU,gBACV,UAAU,YACV,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,GACJ,MAAM,CAkGlB;AAtQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH;;;;;;;;;;;GAWG;AACH,kCAFU,MAAM,CAEwB"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # The aerodynamic term, and the factor that makes a flag a flag
|
|
3
|
+
*
|
|
4
|
+
* §10's model: a particle in moving air feels
|
|
5
|
+
*
|
|
6
|
+
* a_drag = response · facing · (u_air − v)
|
|
7
|
+
*
|
|
8
|
+
* where `u_air` is what the main thread sampled into
|
|
9
|
+
* {@link ClothState#air_velocity} and `facing` is how much of the flow the
|
|
10
|
+
* particle's own local geometry cannot let through. Gravity is added to the
|
|
11
|
+
* same word, so what comes out is the **whole** external acceleration and
|
|
12
|
+
* `cloth_step` reads one array instead of a vector plus a special case.
|
|
13
|
+
*
|
|
14
|
+
* Once per particle per **step**, never per iteration, which is §10's own cost
|
|
15
|
+
* rule. A cloth with `response = 0` — no fabric drag, or no air moving — does
|
|
16
|
+
* not run this at all and `cloth_step` takes its uniform-gravity path, so a
|
|
17
|
+
* scene with no wind in it pays nothing and produces the bytes M5 measured.
|
|
18
|
+
*
|
|
19
|
+
* ## `response` rather than a rate, and why it cannot overshoot
|
|
20
|
+
*
|
|
21
|
+
* The caller hands in `(1 − e^(−rate·dt))/dt` rather than `rate`
|
|
22
|
+
* (`cloth_drag_response`), so the velocity change across the step is
|
|
23
|
+
*
|
|
24
|
+
* Δv = a_drag · dt = (1 − e^(−rate·dt)) · facing · (u_air − v)
|
|
25
|
+
*
|
|
26
|
+
* — a fraction of the gap to the air that is **strictly below one** for any
|
|
27
|
+
* `rate`, any `dt` and any `facing ≤ 1`. An explicit drag written as `rate`
|
|
28
|
+
* instead overshoots once `rate·dt > 1` and diverges past 2, which at §1's "not
|
|
29
|
+
* at 5 fps" is a 0.2 s step and a rate of 10. This is the same exact-ODE step
|
|
30
|
+
* `GlobalFluidEffector` takes for the air itself, which is a pleasant symmetry
|
|
31
|
+
* rather than a coincidence: both are relaxations toward a velocity.
|
|
32
|
+
*
|
|
33
|
+
* ## The facing factor: §10 asked for `|n·û|` and a rope has no `n`
|
|
34
|
+
*
|
|
35
|
+
* §10 writes the factor as `|n·û|` — "the difference between a flag and a
|
|
36
|
+
* rope". The normal is the half a **rope** does not have: a chain's particles
|
|
37
|
+
* span a line, every direction perpendicular to it is equally a normal, and any
|
|
38
|
+
* one this code picked would be a fabrication of the kind §7 P4(a) exists to
|
|
39
|
+
* keep out. A rope also wants the *opposite* dependence — it catches the flow
|
|
40
|
+
* across it and slices along it, where a sheet catches it along the normal and
|
|
41
|
+
* slices across.
|
|
42
|
+
*
|
|
43
|
+
* Both are one quantity: **the part of the flow the particle's incident rows
|
|
44
|
+
* cannot let past**. Take the span `T` of the directions to the particle's
|
|
45
|
+
* stretch-row neighbours in the current configuration and the factor is
|
|
46
|
+
* `‖û − proj_T(û)‖`:
|
|
47
|
+
*
|
|
48
|
+
* | rank of `T` | what the particle is | the factor |
|
|
49
|
+
* |---|---|---|
|
|
50
|
+
* | 2 | a point on a surface | `\|û·n‖` with `n = b₁×b₂` — §10's own expression |
|
|
51
|
+
* | 1 | a link of a chain | `√(1 − (û·t)²)` — cross-flow, the rope's answer |
|
|
52
|
+
* | 0 | an isolated particle | `1` — a bead has no preferred direction |
|
|
53
|
+
*
|
|
54
|
+
* One expression, three topologies, no stored normal, no orientation, no sign,
|
|
55
|
+
* and nothing carried between steps — recomputed from the configuration every
|
|
56
|
+
* step, which is exactly what P4(a) asks of a normal. `MEASUREMENTS.md` §46.
|
|
57
|
+
*
|
|
58
|
+
* @author Alex Goldring
|
|
59
|
+
* @copyright Company Named Limited (c) 2026
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* How much of a second incident direction has to survive projection out of the
|
|
64
|
+
* first before it counts as spanning a plane with it.
|
|
65
|
+
*
|
|
66
|
+
* A quarter is about fourteen degrees. Below it the two rows describe the same
|
|
67
|
+
* line as far as a normal is concerned, and the cross product of two nearly
|
|
68
|
+
* parallel directions is a normal built almost entirely out of rounding — which
|
|
69
|
+
* on a sheet under tension is every pair of rows on the same edge (the fabric
|
|
70
|
+
* row and the strain-limit row backing it up) and on a chain is every skip row
|
|
71
|
+
* beside the link it skips.
|
|
72
|
+
* @type {number}
|
|
73
|
+
*/
|
|
74
|
+
export const CLOTH_WIND_SPAN_MIN = 0.25;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Write the whole external acceleration — gravity plus §10's aerodynamic drag —
|
|
78
|
+
* into {@link ClothState#external_acceleration}.
|
|
79
|
+
*
|
|
80
|
+
* @param {ClothState} state with {@link ClothState#air_velocity} already filled
|
|
81
|
+
* in the cloth's own frame
|
|
82
|
+
* @param {number} response `(1 − e^(−rate·dt))/dt`, 1/s; `0` means no wind and
|
|
83
|
+
* this function should not have been called
|
|
84
|
+
* @param {number} gravity_x cloth-local gravity, m/s²
|
|
85
|
+
* @param {number} gravity_y
|
|
86
|
+
* @param {number} gravity_z
|
|
87
|
+
* @returns {void}
|
|
88
|
+
*/
|
|
89
|
+
export function cloth_wind_accelerate(state, response, gravity_x, gravity_y, gravity_z) {
|
|
90
|
+
const particle_count = state.particle_count;
|
|
91
|
+
|
|
92
|
+
const air = state.air_velocity;
|
|
93
|
+
const out = state.external_acceleration;
|
|
94
|
+
const velocity = state.velocity;
|
|
95
|
+
const position = state.position;
|
|
96
|
+
const mass_inverse = state.mass_inverse;
|
|
97
|
+
|
|
98
|
+
const offset = state.stretch_adjacency_offset;
|
|
99
|
+
const adjacency = state.stretch_adjacency;
|
|
100
|
+
const row_particle = state.stretch_particle;
|
|
101
|
+
|
|
102
|
+
for (let i = 0; i < particle_count; i++) {
|
|
103
|
+
const p = i * 3;
|
|
104
|
+
|
|
105
|
+
out[p] = gravity_x;
|
|
106
|
+
out[p + 1] = gravity_y;
|
|
107
|
+
out[p + 2] = gravity_z;
|
|
108
|
+
|
|
109
|
+
if (mass_inverse[i] === 0) {
|
|
110
|
+
// Pinned. `cloth_predict` holds it exactly and never reads its
|
|
111
|
+
// acceleration, so the facing walk would be work for nothing —
|
|
112
|
+
// and a pin is the whole edge of a flag, which is a real share of
|
|
113
|
+
// a banner's particles.
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const flow_x = air[p] - velocity[p];
|
|
118
|
+
const flow_y = air[p + 1] - velocity[p + 1];
|
|
119
|
+
const flow_z = air[p + 2] - velocity[p + 2];
|
|
120
|
+
|
|
121
|
+
const speed = Math.sqrt(flow_x * flow_x + flow_y * flow_y + flow_z * flow_z);
|
|
122
|
+
|
|
123
|
+
if (speed === 0) {
|
|
124
|
+
// Moving exactly with the air. No flow, no direction to face, and
|
|
125
|
+
// the factor would be a division by zero rather than a small
|
|
126
|
+
// number.
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const inverse_speed = 1 / speed;
|
|
131
|
+
|
|
132
|
+
const facing = cloth_wind_facing(
|
|
133
|
+
position, offset, adjacency, row_particle, i,
|
|
134
|
+
flow_x * inverse_speed, flow_y * inverse_speed, flow_z * inverse_speed
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
if (facing === 0) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const scale = response * facing;
|
|
142
|
+
|
|
143
|
+
out[p] += scale * flow_x;
|
|
144
|
+
out[p + 1] += scale * flow_y;
|
|
145
|
+
out[p + 2] += scale * flow_z;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* How much of a unit flow the particle's own incident rows cannot let past,
|
|
151
|
+
* `[0, 1]`. The table in this module's header is what the three cases mean.
|
|
152
|
+
*
|
|
153
|
+
* Exported because it is the whole of what M6 added to the physics and a spec
|
|
154
|
+
* that can only reach it through a step is a spec measuring six other things at
|
|
155
|
+
* once.
|
|
156
|
+
*
|
|
157
|
+
* @param {Float32Array} position particle positions, 3 each
|
|
158
|
+
* @param {Int32Array} offset `ClothState#stretch_adjacency_offset`
|
|
159
|
+
* @param {Int32Array} adjacency `ClothState#stretch_adjacency`, `(row << 1) | slot`
|
|
160
|
+
* @param {Int32Array} row_particle `ClothState#stretch_particle`
|
|
161
|
+
* @param {number} particle
|
|
162
|
+
* @param {number} unit_x flow direction, unit length
|
|
163
|
+
* @param {number} unit_y
|
|
164
|
+
* @param {number} unit_z
|
|
165
|
+
* @returns {number}
|
|
166
|
+
*/
|
|
167
|
+
export function cloth_wind_facing(
|
|
168
|
+
position, offset, adjacency, row_particle, particle,
|
|
169
|
+
unit_x, unit_y, unit_z
|
|
170
|
+
) {
|
|
171
|
+
const p = particle * 3;
|
|
172
|
+
|
|
173
|
+
const x = position[p];
|
|
174
|
+
const y = position[p + 1];
|
|
175
|
+
const z = position[p + 2];
|
|
176
|
+
|
|
177
|
+
const end = offset[particle + 1];
|
|
178
|
+
|
|
179
|
+
let b1x = 0;
|
|
180
|
+
let b1y = 0;
|
|
181
|
+
let b1z = 0;
|
|
182
|
+
|
|
183
|
+
let rank = 0;
|
|
184
|
+
|
|
185
|
+
for (let a = offset[particle]; a < end; a++) {
|
|
186
|
+
const entry = adjacency[a];
|
|
187
|
+
|
|
188
|
+
// `(row << 1) | slot` for a two-particle row, so the partner is the
|
|
189
|
+
// other slot of the same row.
|
|
190
|
+
const other = row_particle[(entry >> 1) * 2 + (1 - (entry & 1))] * 3;
|
|
191
|
+
|
|
192
|
+
let dx = position[other] - x;
|
|
193
|
+
let dy = position[other + 1] - y;
|
|
194
|
+
let dz = position[other + 2] - z;
|
|
195
|
+
|
|
196
|
+
const length = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
197
|
+
|
|
198
|
+
if (length === 0) {
|
|
199
|
+
// Two particles on top of each other. The row itself is degenerate
|
|
200
|
+
// and every other row kind guards it the same way.
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const inverse_length = 1 / length;
|
|
205
|
+
|
|
206
|
+
dx *= inverse_length;
|
|
207
|
+
dy *= inverse_length;
|
|
208
|
+
dz *= inverse_length;
|
|
209
|
+
|
|
210
|
+
if (rank === 0) {
|
|
211
|
+
b1x = dx;
|
|
212
|
+
b1y = dy;
|
|
213
|
+
b1z = dz;
|
|
214
|
+
|
|
215
|
+
rank = 1;
|
|
216
|
+
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Reject the first basis direction and see whether anything is left.
|
|
221
|
+
const along = dx * b1x + dy * b1y + dz * b1z;
|
|
222
|
+
|
|
223
|
+
let rx = dx - along * b1x;
|
|
224
|
+
let ry = dy - along * b1y;
|
|
225
|
+
let rz = dz - along * b1z;
|
|
226
|
+
|
|
227
|
+
const residual = Math.sqrt(rx * rx + ry * ry + rz * rz);
|
|
228
|
+
|
|
229
|
+
if (residual < CLOTH_WIND_SPAN_MIN) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const inverse_residual = 1 / residual;
|
|
234
|
+
|
|
235
|
+
rx *= inverse_residual;
|
|
236
|
+
ry *= inverse_residual;
|
|
237
|
+
rz *= inverse_residual;
|
|
238
|
+
|
|
239
|
+
// `b1 × b2` is a unit normal because the two are orthonormal by
|
|
240
|
+
// construction, so the facing factor needs no second normalise.
|
|
241
|
+
const nx = b1y * rz - b1z * ry;
|
|
242
|
+
const ny = b1z * rx - b1x * rz;
|
|
243
|
+
const nz = b1x * ry - b1y * rx;
|
|
244
|
+
|
|
245
|
+
const facing = unit_x * nx + unit_y * ny + unit_z * nz;
|
|
246
|
+
|
|
247
|
+
return facing < 0 ? -facing : facing;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (rank === 0) {
|
|
251
|
+
// Nothing incident: a bead, and a bead faces every direction equally.
|
|
252
|
+
return 1;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// A line. What it blocks is the flow *across* it, which is the sine of the
|
|
256
|
+
// angle between the two — the rope's answer, and the complement of the
|
|
257
|
+
// sheet's.
|
|
258
|
+
const along = unit_x * b1x + unit_y * b1y + unit_z * b1z;
|
|
259
|
+
|
|
260
|
+
const across = 1 - along * along;
|
|
261
|
+
|
|
262
|
+
return across <= 0 ? 0 : Math.sqrt(across);
|
|
263
|
+
}
|
|
@@ -36,8 +36,15 @@
|
|
|
36
36
|
* garment's own skinned surface — `b` a short way inside along the vertex
|
|
37
37
|
* normal, `r_b` that distance again — and a skinned garment is M3. M2's entity
|
|
38
38
|
* path has a chain rather than a surface, so it has no normal to offer: a rope
|
|
39
|
-
* has no inside. So the row ships with storage
|
|
40
|
-
*
|
|
39
|
+
* has no inside. So the row ships with storage and a spec, and
|
|
40
|
+
* `cloth_proxy_build` is what will fill it.
|
|
41
|
+
*
|
|
42
|
+
* **Nothing drives it in a scene.** This docblock used to say "and a playground
|
|
43
|
+
* demo driving it directly", and no page under `playground/` writes
|
|
44
|
+
* {@link ClothState#backstop_plane} — M3 arrived and filled nothing in either.
|
|
45
|
+
* What holds the row up is `cloth_backstop_row.spec.js` alone, which is the
|
|
46
|
+
* honest status of a row with no author: the arithmetic is gated, the
|
|
47
|
+
* integration is not.
|
|
41
48
|
*
|
|
42
49
|
* ## No trust region, and no geometric stiffness
|
|
43
50
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloth_backstop_row.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js"],"names":[],"mappings":"AAYA
|
|
1
|
+
{"version":3,"file":"cloth_backstop_row.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AAEH;;;;;;;;;;;GAWG;AACH,kDANW,YAAY,GAAC,MAAM,EAAE,mBACrB,MAAM,0BAEN,MAAM,GACJ,MAAM,CAuBlB;AAED;;;;;;GAMG;AACH,uDAJW,YAAY,+BAEZ,MAAM,QA8EhB;AAED;;;;;;;;;;GAUG;AACH,oEANW,MAAM,SACN,MAAM,eACN,MAAM,eACN,MAAM,qBACN,MAAM,QAuChB;AAED;;;;;;;GAOG;AACH,oEAJW,MAAM,eACN,MAAM,qBACN,MAAM,QA2ChB"}
|