@woosh/meep-engine 3.25.0 → 3.27.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/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +542 -0
- package/src/core/binary/lz4/LZ4_LEVEL.d.ts +33 -0
- package/src/core/binary/lz4/LZ4_LEVEL.d.ts.map +1 -0
- package/src/core/binary/lz4/LZ4_LEVEL.js +32 -0
- package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts +33 -0
- package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts.map +1 -0
- package/src/core/binary/lz4/lz4_compress_block_at_level.js +47 -0
- package/src/core/binary/lz4/lz4_compress_block_hc.d.ts +40 -0
- package/src/core/binary/lz4/lz4_compress_block_hc.d.ts.map +1 -0
- package/src/core/binary/lz4/lz4_compress_block_hc.js +1382 -0
- package/src/core/binary/lz4/lz4_decompress_block.d.ts +2 -1
- package/src/core/binary/lz4/lz4_decompress_block.d.ts.map +1 -1
- package/src/core/binary/lz4/lz4_decompress_block.js +31 -6
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +66 -0
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/HeightMapShape3D.js +314 -20
- 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/physics/cloth/MEASUREMENTS.md +582 -0
- package/src/engine/physics/cloth/PLAN.md +330 -49
- 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/ClothInstance.d.ts +65 -7
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +72 -8
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +25 -4
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +75 -8
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +41 -4
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +207 -63
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +10 -0
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +17 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +27 -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 +28 -3
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +75 -10
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +131 -12
- 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_write_back.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back.js +18 -10
- package/src/engine/physics/cloth/playground/collide_main.js +1 -1
- 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 +12 -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 +12 -2
- package/src/engine/physics/cloth/solver/cloth_step_instance.js +1 -1
- 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 +23 -9
- package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/AbstractClothWind.js +23 -9
- package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts +7 -5
- package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/ClothAmbientWind.js +12 -9
- package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/ClothFluidWind.js +5 -2
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +7 -2
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/cloth_sample_air.js +12 -5
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/playground/vgeo_runtime/README.md +167 -22
- package/src/shade/playground/vgeo_runtime/index.html +112 -62
- package/src/shade/playground/vgeo_runtime/main.js +660 -83
- package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +1 -1
- package/src/shade/playground/vgeo_viewer/sample_asset.js +19 -2
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +11 -0
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +16 -8
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +16 -11
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +73 -5
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +26 -15
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +5 -3
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +20 -0
- 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 +56 -9
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +1 -0
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +22 -0
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +24 -0
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +12 -0
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +13 -0
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +8 -1
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +11 -3
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +10 -1
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.js +17 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts +8 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.js +7 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +3 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +16 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts +14 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.js +13 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts +11 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.js +10 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +20 -2
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +4 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +4 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +29 -3
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +81 -122
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +40 -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 +44 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +69 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +236 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +14 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +15 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts +31 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.js +32 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +10 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +21 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.js +84 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts +22 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +96 -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 +55 -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 +202 -13
- 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 +147 -10
- package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +637 -0
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +33 -36
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +109 -193
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +58 -28
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +77 -105
- package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +37 -0
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +105 -22
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +548 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +29 -50
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +47 -489
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts +84 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +393 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts +234 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +1363 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts +81 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.js +89 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +53 -34
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +407 -124
- package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts +100 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.js +219 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.js +47 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.js +19 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +30 -12
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +15 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +18 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +5 -15
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts +3 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.js +77 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts +3 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +186 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +20 -8
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +580 -188
- package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +15 -18
- package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +19 -28
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +45 -25
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +11 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +0 -1
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +12 -10
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +8 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +7 -2
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +8 -3
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +2 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +19 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts +5 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.js +22 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts +14 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.js +13 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.js +16 -0
- package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.js +16 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts +23 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.js +28 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts +2 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.js +13 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +10 -5
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +15 -6
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +6 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +38 -1
- package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +4 -3
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +6 -3
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +6 -3
- 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 +12 -4
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +2 -0
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +58 -57
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +3 -5
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +3 -4
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +3 -4
- package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +7 -7
- package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +83 -78
- 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 +7 -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 +7 -1
- package/src/shade/renderer/scene/GPUSceneContext.d.ts +22 -2
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +59 -4
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +92 -16
- package/src/shade/renderer/view/GPUViewContext.d.ts +5 -0
- package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
- package/src/shade/renderer/view/GPUViewContext.js +21 -0
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +74 -3
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +0 -723
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +0 -50
- package/src/shade/renderer/shader/chunk/jobs/NOTES.md +0 -47
- package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.js +0 -102
|
@@ -12,36 +12,95 @@ proves the DAG, the format and the residency clamp, and by construction it prove
|
|
|
12
12
|
engine. This page proves the engine seam and nothing about the DAG, because the DAG has its own
|
|
13
13
|
tests and its own oracle.
|
|
14
14
|
|
|
15
|
+
And it proves one thing neither the specs nor the viewer can, which is what the surface **looks
|
|
16
|
+
like**. The viewer draws with `cullMode: 'none'` and colours its cut per cluster; this page draws
|
|
17
|
+
through a `Front`-sided standard material with a light on it. That is the difference that caught
|
|
18
|
+
the shared sample torus being wound inside-out — the near surface culled away, the far inner wall
|
|
19
|
+
showing through the hole where it should have been, and normals pointing into the tube so what
|
|
20
|
+
survived was lit from inside. Eighteen thousand specs and a second playground had drawn that
|
|
21
|
+
container without a single one of them being able to notice.
|
|
22
|
+
|
|
23
|
+
## How it is lit, and why that is not decoration
|
|
24
|
+
|
|
25
|
+
A sun and an **environment map** (`load_default_environment`, the same octahedral sky eight other
|
|
26
|
+
playgrounds light themselves with), and **TAA on**.
|
|
27
|
+
|
|
28
|
+
Both are here for the geometry rather than for the picture. A directional light alone puts every
|
|
29
|
+
surface facing away from it at ambient zero, which is precisely the silhouette and the creases —
|
|
30
|
+
the places a cut is worth looking at — and a converted asset arrives with normals and no material
|
|
31
|
+
authoring, so the environment is most of what there is to shade it with. TAA is the other half: a
|
|
32
|
+
cut is re-selected every frame against a threshold in *pixels*, so the seams between two levels of
|
|
33
|
+
detail land on different pixels from one frame to the next, and without a temporal filter every one
|
|
34
|
+
of them is an aliased edge that crawls. The crawl reads as the cut being unstable when it is the
|
|
35
|
+
rasterizer being point-sampled.
|
|
36
|
+
|
|
37
|
+
Neither costs a reading. TAA runs downstream of the G-buffer, long after the cut has been selected
|
|
38
|
+
and drawn, and its sub-pixel jitter does not move the cut: the τ table below is identical with it on
|
|
39
|
+
and off. The environment is not awaited — `test_assets/` is gitignored, so a checkout without it
|
|
40
|
+
gets the sun alone and still draws every triangle the cut selected.
|
|
41
|
+
|
|
42
|
+
**Not the GPU sky, and that is worth writing down.** `renderer/atmosphere/GPUSky.js` and
|
|
43
|
+
`view/GPUViewSkyContext.js` would be the natural source for this and are **not reachable**: nothing
|
|
44
|
+
in the engine constructs either, `GPUSceneContext` has no `sky` for `GPUViewSkyContext.update` to
|
|
45
|
+
ask for, and `Renderer` does not mention the atmosphere at all. Reviving it is not a playground's
|
|
46
|
+
change — the sky produces an already-convolved GPU texture with `SPHERE_PROBE_MIPMAP_LEVELS` mips,
|
|
47
|
+
while `GPULightCollection` builds its environment privately from a CPU `ShadeTexture` and convolves
|
|
48
|
+
a full mip chain itself, so the two do not meet without a new way to hand that class a GPU-side
|
|
49
|
+
environment. That is a lighting change every scene in the engine would take, and it wants its own
|
|
50
|
+
piece of work.
|
|
51
|
+
|
|
15
52
|
## What it shows
|
|
16
53
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
54
|
+
A container is opened holding **only its root page**. Everything else arrives because the cut asked
|
|
55
|
+
for it: a clamped cluster emits a want, the want names the page it was discovered through, the
|
|
56
|
+
feedback readback resolves it to a byte range out of that page's own child table, and the page
|
|
57
|
+
installs. Nothing is prefetched and no directory is read.
|
|
58
|
+
|
|
59
|
+
The one the page loads itself is built in the page, so there is something to look at without a file.
|
|
60
|
+
It is not what the page is *for*: **drop a `.vgeo` on the window**, or open the page at
|
|
61
|
+
`?file=<url>`, and that container is swapped for a real one. A sample torus is thirteen pages and a
|
|
62
|
+
converted asset is thousands, and the claim being made here is about the second.
|
|
21
63
|
|
|
22
|
-
Measured on an nvidia/lovelace adapter, a 128×48 torus at 64 KB pages — 13 pages, built in ~0.
|
|
23
|
-
in-page —
|
|
24
|
-
|
|
25
|
-
|
|
64
|
+
Measured on an nvidia/lovelace adapter, a 128×48 torus at 64 KB pages — 13 pages, built in ~0.4 s
|
|
65
|
+
in-page — at a render target of 978×546. **The viewport is part of the measurement now**: τ is a
|
|
66
|
+
count of render-target pixels, the canvas follows the window, so a row of this table without the
|
|
67
|
+
resolution beside it is half a reading.
|
|
26
68
|
|
|
27
69
|
| τ (px) | drawn clusters | pages visited | clamped | wavefronts | queue remaining |
|
|
28
70
|
|---:|---:|---:|---:|---:|---:|
|
|
29
|
-
| 0.5 |
|
|
30
|
-
| 1 |
|
|
31
|
-
| 2 |
|
|
32
|
-
| 4 |
|
|
33
|
-
| 8 |
|
|
34
|
-
| 16 |
|
|
71
|
+
| 0.5 | 38 | 9 | 0 | 14 | 0 |
|
|
72
|
+
| 1 | 18 | 6 | 0 | 11 | 0 |
|
|
73
|
+
| 2 | 15 | 6 | 0 | 11 | 0 |
|
|
74
|
+
| 4 | 9 | 5 | 0 | 8 | 0 |
|
|
75
|
+
| 8 | 6 | 5 | 0 | 8 | 0 |
|
|
76
|
+
| 16 | 4 | 3 | 0 | 6 | 0 |
|
|
35
77
|
|
|
36
|
-
The last two columns are
|
|
37
|
-
|
|
38
|
-
|
|
78
|
+
The last two columns are what the review's M8 was about: the descent ran fourteen wavefronts at its
|
|
79
|
+
deepest against a budget of 64, and stopped with nothing still queued. A non-zero `queue remaining`
|
|
80
|
+
is the one reading here that means a **hole** rather than a coarser surface.
|
|
39
81
|
|
|
40
82
|
The cut is monotone in τ and it is a *fraction* of the asset at every setting, which is design §1's
|
|
41
83
|
whole claim: rendering cost is a function of the threshold and the resolution, not of the source
|
|
42
|
-
triangle count. Residency settles at 9 of 13 pages and
|
|
84
|
+
triangle count. Residency settles at 9 of 13 pages and 231 KB — the four it never fetches are the
|
|
43
85
|
ones the cut never wanted.
|
|
44
86
|
|
|
87
|
+
The same claim, on the largest container of a converted 2,975-asset set — 920 MB, 17,172 pages,
|
|
88
|
+
27,960,383 source triangles, served over HTTP by range requests at `?file=`:
|
|
89
|
+
|
|
90
|
+
| | |
|
|
91
|
+
|---|---:|
|
|
92
|
+
| drawn clusters | 10,766 |
|
|
93
|
+
| pages resident | 1,691 of 17,172 |
|
|
94
|
+
| bytes read | 87.6 MB of 920.7 MB |
|
|
95
|
+
| clamped | 0 |
|
|
96
|
+
| refused installs | 0 |
|
|
97
|
+
| opened in | 5 ms |
|
|
98
|
+
|
|
99
|
+
Nine and a half per cent of the file, and the container was on screen five milliseconds after its
|
|
100
|
+
first range came back. `clamped` reaching zero is the streaming having finished rather than the
|
|
101
|
+
budget having given up — which is a distinction the panel can now make, because `refused` is beside
|
|
102
|
+
it.
|
|
103
|
+
|
|
45
104
|
Two readings are worth watching for what they say about the loop rather than the picture:
|
|
46
105
|
|
|
47
106
|
- **`clamped` goes to zero.** The first frames draw a coarse, watertight surface because the pages
|
|
@@ -52,11 +111,87 @@ Two readings are worth watching for what they say about the loop rather than the
|
|
|
52
111
|
costs streaming latency and nothing on screen, and a loop that insisted on a reading every frame
|
|
53
112
|
would stall the frame it was reading.
|
|
54
113
|
|
|
114
|
+
## What residency costs, and what it used to
|
|
115
|
+
|
|
116
|
+
The numbers above were taken with the tier nowhere near full. The reading that matters for a
|
|
117
|
+
runtime is the one with the tier full and the camera moving, and until 2026-09-14 it was
|
|
118
|
+
disqualifying: on this same container at 4,096 slots, zoomed in on a rosette, a DevTools trace had
|
|
119
|
+
twenty-four main-thread tasks over 50 ms in five and a half seconds, the longest 637 ms, `refused`
|
|
120
|
+
at 4.1 million and `pages visited` at 4,044 of 4,096 — every resident page touched every frame, so
|
|
121
|
+
nothing could be evicted, while selectability was recomputed over the whole geometry on every
|
|
122
|
+
install and every evict. `RUNTIME_PLAN_2026_09_14.md` in `runtime/` is the diagnosis and the
|
|
123
|
+
rebuild.
|
|
124
|
+
|
|
125
|
+
Measured after it, on an nvidia/lovelace adapter at 1258×646, a tour of eight rosettes held five
|
|
126
|
+
seconds each, twice round, then the rosette at rest:
|
|
127
|
+
|
|
128
|
+
| | before | after |
|
|
129
|
+
|---|---:|---:|
|
|
130
|
+
| main-thread tasks over 50 ms | 24 in 5.5 s, longest 637 ms | 4 in 150 s, longest 115 ms |
|
|
131
|
+
| `refused`, whole run | 4,166,982 | 999, over 3,009 evictions |
|
|
132
|
+
| `clamped` at rest, zoomed in | 1,334 | 0 |
|
|
133
|
+
| `pages visited` zoomed in | 4,044 of 4,096 | 2,000–3,200 of 4,096 |
|
|
134
|
+
| frame time zoomed in | — | p50 8.3 ms, p95 12.6 ms |
|
|
135
|
+
| page fetches on workers | 0 | all of them |
|
|
136
|
+
|
|
137
|
+
The panel's `RAM evicted`, `fetching` and `worker fetches` rows are new with it, and `refused` is
|
|
138
|
+
the reading to keep watching: it climbs only while the tier is full of pages the cut still draws
|
|
139
|
+
from, which is a budget saying no and not a tier scanning.
|
|
140
|
+
|
|
141
|
+
Two things the tour still shows. The four long tasks left are `GPUMeshletManager` compactions —
|
|
142
|
+
a refused allocation with free space behind it rebuilds every batch, which is the one O(resident)
|
|
143
|
+
event the rebuild deferred. And under a vite dev server the first seconds after a container opens
|
|
144
|
+
stall while the four page-fetch workers' module graphs are served; a bundled build does not pay
|
|
145
|
+
that.
|
|
146
|
+
|
|
147
|
+
## Putting an asset in it
|
|
148
|
+
|
|
149
|
+
Drop a `.vgeo` anywhere on the window, or open the page at `?file=/some/asset.vgeo` — a URL source
|
|
150
|
+
reads by `Range` request, so a container is opened out of its header and root page rather than
|
|
151
|
+
downloaded. Either way the asset on screen is retired first: its mesh row, its entity, its VRAM
|
|
152
|
+
pages and its place in the RAM tier's budget all go back, and the camera reframes on the new
|
|
153
|
+
container's own bounding sphere, which is the difference between a torus a unit across and a
|
|
154
|
+
building thirty metres up.
|
|
155
|
+
|
|
156
|
+
Two refusals are worth recognising, because both leave what is on screen exactly as it was and say
|
|
157
|
+
so in the panel rather than clearing the page:
|
|
158
|
+
|
|
159
|
+
- **"this container makes no promise about its own [page size]"** — built before `FORMAT` §11.14, so
|
|
160
|
+
its pages may be over the size its header names, and this tier lays out fixed-stride slots.
|
|
161
|
+
Rebuild it.
|
|
162
|
+
- **"this container's pages are bounded at N and this pool holds pages of 65536"** — right format,
|
|
163
|
+
wrong size. The pool's page size is fixed for the life of the page, because there is no slot-size
|
|
164
|
+
class table; build the asset at 64 KB.
|
|
165
|
+
|
|
166
|
+
The VRAM tier here is built with **4,096 page slots** rather than the engine default of 1,024,
|
|
167
|
+
which is a decision this page takes on its own and worth knowing when reading its numbers against
|
|
168
|
+
another host's. At the default, an asset over a thousand pages fills the tier and `refused` starts
|
|
169
|
+
climbing — and the cut then clamps against a budget instead of against τ, which is the one thing
|
|
170
|
+
this page is not supposed to be showing you. `refused` is in the panel so that when it *is* the
|
|
171
|
+
budget, you can see it is.
|
|
172
|
+
|
|
173
|
+
## Profiling it
|
|
174
|
+
|
|
175
|
+
**`T` records a GPU capture, `T` again stops it and downloads an `.sgpt`** — the same key and the
|
|
176
|
+
same module (`playground/profile_hotkey.js`) the other playgrounds bind, so there is one
|
|
177
|
+
implementation of the drain and the naming rather than one per page. The level is `WORKLOAD`: pass
|
|
178
|
+
spans, the frame graph, and dispatch/draw counts, which measures around 14 KB a frame here.
|
|
179
|
+
|
|
180
|
+
It answers the question the panel cannot. Every reading above is a **count** — clusters drawn, pages
|
|
181
|
+
visited, wavefronts run — and not one of them is a cost. What is worth knowing is how the seed, the
|
|
182
|
+
traverse loop, the collect and the expansion compare against the rasterization they feed, and
|
|
183
|
+
whether the descent's wavefront count shows up as time or disappears into occupancy.
|
|
184
|
+
|
|
185
|
+
The capture's note carries **τ, the asset and the cut it selected**, next to the adapter and the
|
|
186
|
+
resolution, because the same 0.4 ms is a triumph at ten thousand clusters and a scandal at nine. A
|
|
187
|
+
capture without those is a number with nothing to divide it by.
|
|
188
|
+
|
|
55
189
|
## Driving it
|
|
56
190
|
|
|
57
|
-
`__state()` is the whole surface a headless session needs — frames, the cut's counters,
|
|
58
|
-
residency tiers. `__page.runtime.tau` is the threshold
|
|
59
|
-
|
|
191
|
+
`__state()` is the whole surface a headless session needs — frames, the cut's counters, the asset,
|
|
192
|
+
the render target's size, and both residency tiers. `__page.runtime.tau` is the threshold,
|
|
193
|
+
`__load_url(url)` opens a container without a pointer to drop with. The panel shows nothing
|
|
194
|
+
`__state()` does not.
|
|
60
195
|
|
|
61
196
|
```
|
|
62
197
|
npm run dev --workspace @woosh/meep-engine
|
|
@@ -68,7 +203,7 @@ rhetorical claim: 18,569 passing specs did not notice it failing to boot at all,
|
|
|
68
203
|
`scene.add(make_sunlight())` had outlived `Scene.add` and the page threw before defining
|
|
69
204
|
`__state`. Treat a green suite without a drive as unverified.
|
|
70
205
|
|
|
71
|
-
### The headless recipe, and the
|
|
206
|
+
### The headless recipe, and the four things that cost an hour
|
|
72
207
|
|
|
73
208
|
Start the dev server, then launch Chrome with a debugging port and connect over CDP:
|
|
74
209
|
|
|
@@ -88,6 +223,16 @@ chrome --headless=new --enable-unsafe-webgpu --remote-debugging-port=9333 \
|
|
|
88
223
|
`chrome://omnibox-popup` targets as well, and the first entry is routinely not the page. Attaching
|
|
89
224
|
to one of those and asking it for `navigator.gpu` answers `undefined`, which reads exactly like a
|
|
90
225
|
browser without WebGPU.
|
|
226
|
+
- **Resize the window, not the viewport.** `Emulation.setDeviceMetricsOverride` moves `innerWidth`
|
|
227
|
+
and leaves `document.documentElement.clientWidth` where it was, so the page never resizes and the
|
|
228
|
+
override reads as the fix not working. `Browser.getWindowForTarget` then `Browser.setWindowBounds`
|
|
229
|
+
is a real resize and the canvas follows it.
|
|
230
|
+
- **A drop is dispatchable.** `new DataTransfer()`, `items.add(new File([bytes], name))`, then
|
|
231
|
+
`window.dispatchEvent(new DragEvent('drop', { dataTransfer }))` goes through the page's own
|
|
232
|
+
handler — no pointer, and no separate code path to keep honest. `?file=` needs a server that
|
|
233
|
+
answers `Range` with a `206`; vite refuses `/@fs/` outside the workspace, so an asset off the
|
|
234
|
+
tree wants twenty lines of `http.createServer` with `Access-Control-Expose-Headers:
|
|
235
|
+
Content-Range`.
|
|
91
236
|
|
|
92
237
|
Open the page as Chrome's startup URL rather than with `Page.navigate` — the `load` event is not a
|
|
93
238
|
reliable signal here, so poll for `__state` itself. Then set `__page.runtime.tau` and read
|
|
@@ -1,62 +1,112 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>meep — virtual geometry runtime</title>
|
|
6
|
-
|
|
7
|
-
<link rel="icon" href="data:,">
|
|
8
|
-
|
|
9
|
-
<style>
|
|
10
|
-
:root { color-scheme: dark; }
|
|
11
|
-
|
|
12
|
-
html, body { height: 100%; margin: 0; overflow: hidden; background: #070b10; }
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
#panel
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
color: #
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
#panel
|
|
31
|
-
|
|
32
|
-
#panel
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>meep — virtual geometry runtime</title>
|
|
6
|
+
|
|
7
|
+
<link rel="icon" href="data:,">
|
|
8
|
+
|
|
9
|
+
<style>
|
|
10
|
+
:root { color-scheme: dark; }
|
|
11
|
+
|
|
12
|
+
html, body { height: 100%; margin: 0; overflow: hidden; background: #070b10; }
|
|
13
|
+
|
|
14
|
+
/* Placed, not sized. `Renderer` owns both of the canvas's sizes — it writes `width`/`height`
|
|
15
|
+
in device pixels and an **inline** `style.width`/`style.height` in CSS pixels every time
|
|
16
|
+
it configures the context — and an inline style beats a rule in here. So a `width: 100%`
|
|
17
|
+
on this selector would look like it was doing the work while the renderer quietly pinned
|
|
18
|
+
the canvas to whatever it was first told, and `main.js` measures the window rather than
|
|
19
|
+
the canvas for exactly that reason. */
|
|
20
|
+
#view { position: absolute; top: 0; left: 0; display: block; }
|
|
21
|
+
|
|
22
|
+
#panel {
|
|
23
|
+
position: absolute; top: 0; right: 0; width: 320px; max-height: 100vh; overflow-y: auto;
|
|
24
|
+
z-index: 10; padding: 12px 14px; box-sizing: border-box;
|
|
25
|
+
font: 12px/1.45 ui-monospace, "Cascadia Mono", Consolas, monospace;
|
|
26
|
+
color: #dfe6ee; background: rgba(12, 16, 22, 0.88);
|
|
27
|
+
border-left: 1px solid #2b3947;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#panel h1 { margin: 0 0 8px; font-size: 13px; letter-spacing: 0.06em; color: #7fd2ff; }
|
|
31
|
+
|
|
32
|
+
#panel h2 {
|
|
33
|
+
margin: 14px 0 6px; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
|
|
34
|
+
color: #6b7c8d; border-bottom: 1px solid #24313d; padding-bottom: 3px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#panel .row { display: flex; justify-content: space-between; gap: 8px; }
|
|
38
|
+
|
|
39
|
+
/* A dropped file's name is as long as the file's name, and a converter's names are hashes.
|
|
40
|
+
Clipped rather than wrapped so the rows stay one line each, and `min-width: 0` because a
|
|
41
|
+
flex item refuses to shrink below its content without it — which is what put a horizontal
|
|
42
|
+
scrollbar across the whole panel. The full name is in the tooltip. */
|
|
43
|
+
#panel .row span:last-child {
|
|
44
|
+
color: #f2f6fa; text-align: right;
|
|
45
|
+
min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
#panel .row span:first-child { flex: none; }
|
|
49
|
+
#panel .muted { color: #6b7c8d; }
|
|
50
|
+
#panel .bad { color: #ff8a7a; }
|
|
51
|
+
#panel .good { color: #8fe388; }
|
|
52
|
+
#panel input[type=range] { width: 100%; }
|
|
53
|
+
#panel label { display: block; margin: 6px 0 2px; }
|
|
54
|
+
|
|
55
|
+
/* `overflow-wrap` as well as the wrap, because the status carries a URL and a URL has no
|
|
56
|
+
spaces to break at — one `?file=` was enough to push a scrollbar across the panel. */
|
|
57
|
+
#status { white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
58
|
+
#status.error { color: #ff8a7a; }
|
|
59
|
+
|
|
60
|
+
#hint, #profile-note { margin-top: 10px; color: #6b7c8d; }
|
|
61
|
+
|
|
62
|
+
#profile-status { margin-top: 4px; color: #dfe6ee; word-break: break-word; }
|
|
63
|
+
#profile-status.recording { color: #ff8a7a; }
|
|
64
|
+
|
|
65
|
+
/* Shown only while something is being dragged over the window. `inset: 0` rather than the
|
|
66
|
+
canvas's box because a file dropped on the panel is a file dropped on the page. */
|
|
67
|
+
#drop {
|
|
68
|
+
position: absolute; inset: 0; z-index: 20;
|
|
69
|
+
display: none; align-items: center; justify-content: center;
|
|
70
|
+
font: 20px ui-monospace, monospace; color: #7fd2ff;
|
|
71
|
+
background: rgba(6, 12, 20, 0.82); border: 3px dashed #7fd2ff; box-sizing: border-box;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#drop.active { display: flex; }
|
|
75
|
+
</style>
|
|
76
|
+
</head>
|
|
77
|
+
<body tabindex="0">
|
|
78
|
+
|
|
79
|
+
<canvas id="view"></canvas>
|
|
80
|
+
|
|
81
|
+
<div id="drop">drop a .vgeo file</div>
|
|
82
|
+
|
|
83
|
+
<div id="panel">
|
|
84
|
+
<h1>virtual geometry runtime</h1>
|
|
85
|
+
<div id="status" class="muted">starting…</div>
|
|
86
|
+
|
|
87
|
+
<label>threshold τ <span id="tau-value">1.0</span> px</label>
|
|
88
|
+
<input id="tau" type="range" min="0.25" max="16" step="0.25" value="1">
|
|
89
|
+
|
|
90
|
+
<h2>asset</h2>
|
|
91
|
+
<div id="asset"></div>
|
|
92
|
+
|
|
93
|
+
<h2>cut</h2>
|
|
94
|
+
<div id="cut"></div>
|
|
95
|
+
|
|
96
|
+
<h2>residency</h2>
|
|
97
|
+
<div id="residency"></div>
|
|
98
|
+
|
|
99
|
+
<h2>profiling</h2>
|
|
100
|
+
<div id="profile-status">idle · T to record</div>
|
|
101
|
+
<div id="profile-note"><strong>T</strong> starts a GPU capture and <strong>T</strong> again
|
|
102
|
+
stops it and downloads an <code>.sgpt</code>. The capture's note carries τ and the cut it
|
|
103
|
+
selected, because a pass timing here means nothing without them.</div>
|
|
104
|
+
|
|
105
|
+
<div id="hint">drop a <code>.vgeo</code> file anywhere on the page, or open
|
|
106
|
+
<code>?file=/some/asset.vgeo</code></div>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<script type="module" src="./main.js"></script>
|
|
110
|
+
|
|
111
|
+
</body>
|
|
112
|
+
</html>
|