@woosh/meep-engine 3.26.0 → 3.28.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/build/bundle-worker-terrain.js +1 -1
- 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/mat4/m4_linear_determinant.d.ts +15 -0
- package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_linear_determinant.js +24 -0
- package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts +4 -2
- package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts.map +1 -1
- package/src/core/geom/3d/mat4/m4_normal_matrix3.js +21 -11
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +14 -7
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/HeightMapShape3D.js +87 -78
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +38 -1
- package/src/engine/graphics3/GraphicsEngine.d.ts +5 -1
- package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
- package/src/engine/graphics3/GraphicsEngine.js +834 -830
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/RENDERER_CONTRACT.md +19 -10
- package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +1 -1
- package/src/shade/playground/vgeo_runtime/README.md +186 -27
- package/src/shade/playground/vgeo_runtime/index.html +112 -62
- package/src/shade/playground/vgeo_runtime/main.js +678 -88
- package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +18 -0
- package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -0
- package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.js +23 -5
- package/src/shade/playground/vgeo_scene/README.md +408 -0
- package/src/shade/playground/vgeo_scene/index.html +144 -0
- package/src/shade/playground/vgeo_scene/main.d.ts +2 -0
- package/src/shade/playground/vgeo_scene/main.d.ts.map +1 -0
- package/src/shade/playground/vgeo_scene/main.js +1716 -0
- package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.d.ts +4 -1
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +5 -2
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +1 -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/meshlet/MeshletBatch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +3 -29
- package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts +22 -0
- package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts.map +1 -0
- package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.js +49 -0
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +77 -7
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +36 -23
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +17 -14
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +19 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +21 -1
- package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +5 -9
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts +32 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +59 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts +44 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +36 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_build_levels.js → level/vgeo_build_levels.js} +61 -95
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts +19 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.js → level/vgeo_build_root_group.js} +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +73 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.js → mesh/VirtualGeometryMesh.js} +7 -7
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_normals.js → mesh/vgeo_compute_vertex_normals.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +31 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_tangents.js → mesh/vgeo_compute_vertex_tangents.js} +5 -5
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +46 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.js → mesh/vgeo_normalize_source.js} +9 -9
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts +13 -0
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.js → page/vgeo_assemble_pages.js} +63 -16
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts +13 -0
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.js → page/vgeo_build_page_nodes.js} +4 -4
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts +22 -0
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.js → page/vgeo_page_node_count.js} +2 -2
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +52 -0
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.js → partition/VGeoFaceGraph.js} +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts +14 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.js → partition/vgeo_partition_graph.js} +2 -2
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts +41 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.js +92 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts +10 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.js → partition/vgeo_split_face_set.js} +12 -55
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set_packed.js → partition/vgeo_split_face_set_packed.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts +12 -0
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.js → sphere/vgeo_bounding_sphere.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.js → sphere/vgeo_containing_sphere.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.js → sphere/vgeo_sphere_inflate_to_contain.js} +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +24 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +14 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_extract_submesh.js → submesh/vgeo_extract_submesh.js} +5 -5
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +12 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_gather_faces.js → submesh/vgeo_gather_faces.js} +2 -2
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts +11 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.js → submesh/vgeo_narrow_indices.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +10 -11
- 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/attribute/vgeo_attributes_read.d.ts +8 -2
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +8 -2
- 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_GROUP_OFFSET.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js +15 -0
- 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/payload/vgeo_encode_cluster_payload.d.ts +28 -0
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +7 -3
- 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 +63 -3
- 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 +219 -17
- 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 +156 -11
- package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +656 -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 +109 -29
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +173 -105
- package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +37 -0
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +109 -26
- 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 +55 -487
- 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 +1388 -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 +8 -8
- 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 +11 -73
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts +19 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +98 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts +31 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +99 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js +39 -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 +130 -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 +32 -37
- 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 +576 -230
- 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/load_gltf.d.ts.map +1 -1
- package/src/shade/renderer/loader/gltf/load_gltf.js +0 -19
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/material/chunk_material_draw_side.d.ts +14 -0
- package/src/shade/renderer/material/chunk_material_draw_side.d.ts.map +1 -0
- package/src/shade/renderer/material/chunk_material_draw_side.js +34 -0
- package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
- package/src/shade/renderer/material/standard/fragment_gbuffer.js +8 -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/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +13 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +19 -5
- package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +23 -5
- package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.js +12 -5
- 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/rasterization_opaque_buckets.d.ts +22 -0
- package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js +36 -0
- 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/chunk_triangle_winding_is_reversed.d.ts +15 -0
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +35 -0
- 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/RASTERIZATION_BUCKET_LIMIT.d.ts +10 -1
- package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +38 -29
- package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts +5 -0
- package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js +63 -55
- 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/graph_meshlets_rasterize.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +1 -0
- 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/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +44 -53
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -2
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -2
- package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js +19 -2
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +7 -4
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -2
- package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.js +15 -4
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +16 -5
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +16 -5
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +2 -1
- package/src/shade/renderer/rasterize/native/rasterization_shader_resources.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/rasterization_shader_resources.js +4 -0
- package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +16 -7
- 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 +85 -89
- 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 +28 -32
- 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 +61 -4
- package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +19 -0
- package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/scene/NODE3D_STRUCT.js +34 -0
- package/src/shade/renderer/scene/chunk_node3d_flags.d.ts +9 -0
- package/src/shade/renderer/scene/chunk_node3d_flags.d.ts.map +1 -0
- package/src/shade/renderer/scene/chunk_node3d_flags.js +23 -0
- package/src/shade/renderer/scene/chunk_scene_database_access.d.ts.map +1 -1
- package/src/shade/renderer/scene/chunk_scene_database_access.js +15 -1
- package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
- package/src/shade/renderer/scene/rows/GPUSceneRows.js +9 -1
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts +7 -0
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js +16 -4
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts +12 -0
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js +18 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts +24 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js +33 -0
- 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/playground/vgeo_viewer/README.md +0 -150
- package/src/shade/playground/vgeo_viewer/cut_geometry.js +0 -460
- package/src/shade/playground/vgeo_viewer/index.html +0 -77
- package/src/shade/playground/vgeo_viewer/main.js +0 -1343
- package/src/shade/playground/vgeo_viewer/select_cut.js +0 -481
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +0 -258
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +0 -723
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +0 -49
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +0 -50
- package/src/shade/renderer/loader/gltf/fix_up_material_sides.js +0 -109
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +0 -78
- package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +0 -100
- package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.js +0 -26
- package/src/shade/renderer/shader/chunk/jobs/NOTES.md +0 -47
- package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts +0 -3
- package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts.map +0 -1
- package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.js +0 -102
- /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.js → level/VGeoLevel.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.js → level/VGeoLevelOptions.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.js → level/VGeoLevelSummary.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.js → partition/vgeo_graph_components.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{VGeoGatheredFaces.js → submesh/VGeoGatheredFaces.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{VGeoSubmesh.js → submesh/VGeoSubmesh.js} +0 -0
package/package.json
CHANGED
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
# LZ4_HIGH_COMPRESSION_PLAN — `src/core/binary/lz4`
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-14 · Adds a compression level to the encoder. The format does not change and
|
|
4
|
+
[lz4_decompress_block.js](lz4_decompress_block.js) is not touched.
|
|
5
|
+
|
|
6
|
+
Every number below was measured on this machine on 2026-09-14, against real data. The measurement
|
|
7
|
+
recipes are in §9 so any of it can be re-run.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1 · The question, and the answer
|
|
12
|
+
|
|
13
|
+
> Add a configurable compression level that gets us to the current state-of-the-art maximum, without
|
|
14
|
+
> changing the format.
|
|
15
|
+
|
|
16
|
+
**The state of the art for the LZ4 block format is `lz4hc` level 12, and there is nothing
|
|
17
|
+
meaningful past it.** An encoder built with an *uncapped* match search and a shortest-path parse over
|
|
18
|
+
the whole block — strictly more search than level 12 is allowed — was measured against level 12:
|
|
19
|
+
|
|
20
|
+
| corpus | level 12 | uncapped search + whole-block parse | time |
|
|
21
|
+
|---|---|---|---|
|
|
22
|
+
| 60 real `.vgeo` pages (1.77 MB) | 1,531,612 B | **1,531,612 B** — identical | 1.6× slower |
|
|
23
|
+
| 24 text chunks (1.57 MB) | 356,238 B | 356,233 B — **0.0014% smaller** | 7.9× slower |
|
|
24
|
+
| 18 runs and periodic blocks (74 KB) | 4,225 B | **4,225 B** — identical | 110× slower |
|
|
25
|
+
|
|
26
|
+
Five bytes in a third of a megabyte, for eight times the work — and on repetitive data the uncapped
|
|
27
|
+
parse is 110× level 12 and 3,500× level 9, because dropping the reference's `sufficient_len` early
|
|
28
|
+
exit is exactly what lets a run of zeros cost quadratic time. The ceiling is level 12; the plan is to
|
|
29
|
+
reach it and stop.
|
|
30
|
+
|
|
31
|
+
A JS port of `lz4hc` was written and validated before this plan was drafted: **20,976 blocks over
|
|
32
|
+
1,947 inputs, at every level from 2 to 12, byte for byte identical to liblz4**, first try, including
|
|
33
|
+
runs, periodic data, matches at the far edge of the 64KB window, engine source, glTF JSON and real
|
|
34
|
+
geometry pages. The work is a known quantity, not an experiment.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 2 · What it is worth
|
|
39
|
+
|
|
40
|
+
Corpus: **2,636 decoded pages, 140,268,332 bytes**, taken from 120 of the 2,975 `.vgeo` containers
|
|
41
|
+
the Zorah build wrote on 2026-09-13. These are the exact bytes
|
|
42
|
+
[vgeo_encode_frame_blob.js](../../../shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js)
|
|
43
|
+
is handed in production. Baseline is what [lz4_compress_block.js](lz4_compress_block.js) ships today.
|
|
44
|
+
|
|
45
|
+
| level | ratio | vs. today | JS throughput |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| fast (today) | 0.89470 | — | 412–436 MB/s |
|
|
48
|
+
| 3 | 0.87272 | −2.457% | 51–53 MB/s |
|
|
49
|
+
| 4 | 0.87239 | −2.494% | 51 MB/s |
|
|
50
|
+
| 6 | 0.87214 | −2.522% | 51 MB/s |
|
|
51
|
+
| **9** | **0.87209** | **−2.528%** | **52–55 MB/s** |
|
|
52
|
+
| 10 | 0.87204 | −2.533% | 46 MB/s |
|
|
53
|
+
| 11 | 0.87204 | −2.533% | 45 MB/s |
|
|
54
|
+
| 12 | 0.87202 | −2.535% | 42 MB/s |
|
|
55
|
+
|
|
56
|
+
Two things fall out of that table.
|
|
57
|
+
|
|
58
|
+
**Level 3 already gets 97% of what is available on geometry.** The whole ladder from 3 to 12 is
|
|
59
|
+
0.078 percentage points — 41 MiB on the 51 GiB Zorah build. Meshlet pages are quantised, densely
|
|
60
|
+
packed bytes; the matches that exist are short and near, and a four-deep chain walk finds them.
|
|
61
|
+
|
|
62
|
+
**Level 9 is both smaller and slightly faster than levels 3–6** — repeatably, three paired runs,
|
|
63
|
+
always in the same direction. Level 9 is the only hash-chain level that turns on pattern analysis
|
|
64
|
+
(the reference enables it at `nbSearches > 128`), and on data with runs in it that pays for itself.
|
|
65
|
+
There is no reason to ship 3–8 as the default when 9 dominates them.
|
|
66
|
+
|
|
67
|
+
### It is not the same story for every payload
|
|
68
|
+
|
|
69
|
+
The codec is generic core code, so the ladder has to be there even though vgeo barely uses it.
|
|
70
|
+
Measured on 64KB chunks, same baseline:
|
|
71
|
+
|
|
72
|
+
| payload | fast | level 3 | level 9 | level 12 |
|
|
73
|
+
|---|---|---|---|---|
|
|
74
|
+
| engine source + glTF JSON | 0.30153 | 0.23931 (−20.6%) | 0.23164 (−23.2%) | 0.22972 (−23.8%) |
|
|
75
|
+
| runs and periodic data | 0.05763 | 0.05759 (−0.07%) | 0.05731 (−0.57%) | 0.05731 (−0.57%) |
|
|
76
|
+
| real `.vgeo` pages | 0.89470 | −2.46% | −2.53% | −2.54% |
|
|
77
|
+
|
|
78
|
+
On text the top of the ladder is worth 3.2 points over level 3 and costs 8× the time (113 MB/s at
|
|
79
|
+
level 3, 14 MB/s at level 12). That is the payload class that justifies building levels 10–12 at all.
|
|
80
|
+
|
|
81
|
+
### What it does to a Zorah build
|
|
82
|
+
|
|
83
|
+
From the 2026-09-13 conversion log: pages **51.38 GiB stored, 56.38 GiB decoded**, built in
|
|
84
|
+
**4 h 8 m wall / 17 h 9 m CPU** across ten workers.
|
|
85
|
+
|
|
86
|
+
| level | pages would be | saved | compression CPU | share of build CPU |
|
|
87
|
+
|---|---|---|---|---|
|
|
88
|
+
| fast | 51.38 GiB | — | 2.4 min | 0.2% |
|
|
89
|
+
| 3 | 50.12 GiB | 1.26 GiB | 19.4 min | 1.9% |
|
|
90
|
+
| **9** | **50.08 GiB** | **1.30 GiB** | **18.9 min** | **1.8%** |
|
|
91
|
+
| 12 | 50.08 GiB | 1.30 GiB | 24.0 min | 2.3% |
|
|
92
|
+
|
|
93
|
+
**The whole ladder is free.** Sixteen extra minutes of CPU on a seventeen-hour build, about two
|
|
94
|
+
minutes of wall clock across ten workers, for 1.3 GiB. The interesting decision is not whether to
|
|
95
|
+
pay for high compression — it is which level, and the answer is 9 because 10–12 cost 15–40% more
|
|
96
|
+
time for 0.007 points.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 3 · What it costs the reader
|
|
101
|
+
|
|
102
|
+
The format does not change, so nothing has to be done. But the *shape* of the blocks changes, and
|
|
103
|
+
that is worth saying out loud because it does not go the way one would guess.
|
|
104
|
+
|
|
105
|
+
Measured with [lz4_decompress_block.js](lz4_decompress_block.js) over 250 real pages:
|
|
106
|
+
|
|
107
|
+
| | ratio | sequences | bytes/sequence | decode |
|
|
108
|
+
|---|---|---|---|---|
|
|
109
|
+
| fast | 0.89372 | 208,503 | 61.9 | 1,174 MB/s |
|
|
110
|
+
| level 9 | 0.87087 | 336,176 | 38.4 | 1,059 MB/s |
|
|
111
|
+
| level 12 | 0.87081 | 339,644 | 38.0 | 999 MB/s |
|
|
112
|
+
|
|
113
|
+
On geometry, HC finds **more** matches, not longer ones — 61% more sequences — and the decoder's
|
|
114
|
+
per-sequence cost is a byte loop, so pages decode **10–15% slower**. On text the same measurement
|
|
115
|
+
inverts: 115,657 sequences down to 81,431, and decode goes from 705 to 828 MB/s (**+18%**).
|
|
116
|
+
|
|
117
|
+
This lands in a worker ([vgeo_page_worker_serve.js](../../../shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js)),
|
|
118
|
+
off the main thread, and it buys 2.5% fewer bytes to fetch on every page of every session. It is a
|
|
119
|
+
fair trade as it stands. It is also **entirely recoverable**, for an unrelated reason — see §8.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 4 · What the reference actually is
|
|
124
|
+
|
|
125
|
+
`lz4hc.c` at 1.10.0. The level table is identical in 1.9.4 and 1.10.0 for levels 3–12, so targeting
|
|
126
|
+
that range is version-stable:
|
|
127
|
+
|
|
128
|
+
| level | strategy | chain attempts | sufficient length |
|
|
129
|
+
|---|---|---|---|
|
|
130
|
+
| 3–9 | hash chain, lazy parse | 4, 8, 16, 32, 64, 128, 256 | 16 |
|
|
131
|
+
| 10 | optimal parse | 96 | 64 |
|
|
132
|
+
| 11 | optimal parse | 512 | 128 |
|
|
133
|
+
| 12 | optimal parse, full update | 16,384 | 4,096 |
|
|
134
|
+
|
|
135
|
+
**Level 2 is deliberately not on that list.** 1.9.4 gives it the hash-chain strategy; 1.10.0 gives it
|
|
136
|
+
`lz4mid`, a different compressor added in that release. "Level 2" does not name one thing across
|
|
137
|
+
reference versions, so this encoder will not have one. Levels 1 (fast) and 3–12 are the ladder.
|
|
138
|
+
|
|
139
|
+
Four pieces of the reference are load-bearing and none of them can be dropped:
|
|
140
|
+
|
|
141
|
+
- **The hash chain.** `hashTable` (32,768 × u32) holds the newest position per 4-byte hash;
|
|
142
|
+
`chainTable` (65,536 × u16) holds, per position, the *delta* back to the previous position with the
|
|
143
|
+
same hash, capped at 65,535. Positions are inserted lazily, from `nextToUpdate` up to the current
|
|
144
|
+
position, so nothing is built that is never searched.
|
|
145
|
+
- **Pattern analysis.** When the chain shows consecutive positions (delta 1) and the 4 bytes are a
|
|
146
|
+
repeat of a single byte, the walk jumps straight to the best position in the run instead of
|
|
147
|
+
stepping through thousands of links. Without it, levels 9–12 go quadratic on a page of zeros.
|
|
148
|
+
This is what makes level 9 *faster* than level 6 on real data.
|
|
149
|
+
- **Chain swap.** On a tie, scan the chain deltas inside the match for the largest step and follow
|
|
150
|
+
that instead. Only the optimal parser uses it.
|
|
151
|
+
- **The three-match lazy parse** (levels 3–9) and the **windowed shortest path** (10–12). The price
|
|
152
|
+
model is exact in bytes — a token, a 2-byte offset, and the continuation bytes each length field
|
|
153
|
+
spills into — which is why the parse is a genuine shortest path and not a heuristic.
|
|
154
|
+
|
|
155
|
+
Everything else in `lz4hc.c` is dictionary and streaming support: `extDict`, `dictCtx`,
|
|
156
|
+
`LZ4HC_protectDictEnd`, the pattern rotation across a dictionary boundary, `favorDecSpeed`,
|
|
157
|
+
`fillOutput`. meep compresses one self-contained block with no history. **All of it drops**, and with
|
|
158
|
+
it about half the file. The port that was validated is ~700 lines against the reference's ~1,400.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 5 · Design
|
|
163
|
+
|
|
164
|
+
### 5.1 Files
|
|
165
|
+
|
|
166
|
+
Four new files in this directory. **[lz4_compress_block.js](lz4_compress_block.js) is not edited.**
|
|
167
|
+
|
|
168
|
+
- **`LZ4_LEVEL.js`** — `{ FAST: 1, HC_MIN: 3, HC_DEFAULT: 9, HC_MAX: 12 }`, with the note about 2.
|
|
169
|
+
- **`lz4_compress_block_hc.js`** — the high-compression encoder. Same parameter list as the fast one
|
|
170
|
+
with `level` appended:
|
|
171
|
+
`lz4_compress_block_hc(destination, destination_offset, destination_end, source, source_offset, source_end, level)`.
|
|
172
|
+
- **`lz4_compress_block_at_level.js`** — dispatch. `level <= 1` goes to `lz4_compress_block`,
|
|
173
|
+
anything else to `lz4_compress_block_hc`. This is what callers with a knob call; it is the only
|
|
174
|
+
new thing `vgeo_encode_frame_blob` needs to know about.
|
|
175
|
+
- **`lz4_compress_block_hc.spec.js`** — §6.
|
|
176
|
+
|
|
177
|
+
### 5.2 Why the fast encoder is not touched
|
|
178
|
+
|
|
179
|
+
The obvious tidy — lift `write_token_and_literals` and `write_continuation` out of
|
|
180
|
+
`lz4_compress_block.js` into a module both encoders import — was built and measured. Across five
|
|
181
|
+
paired runs it cost the fast encoder between 0% and 8% of its throughput and never once helped.
|
|
182
|
+
The HC encoder sequences its writes differently anyway (`LZ4HC_encodeSequence` emits token, literals,
|
|
183
|
+
offset and match continuation as one unit, where the fast encoder splits it), so the two are not the
|
|
184
|
+
same function. **The HC module carries its own writers.** The fast encoder's pinned bytes and its
|
|
185
|
+
435 MB/s cannot regress if nothing edits it.
|
|
186
|
+
|
|
187
|
+
### 5.3 Memory, and when it is taken
|
|
188
|
+
|
|
189
|
+
| table | type | bytes | needed from |
|
|
190
|
+
|---|---|---|---|
|
|
191
|
+
| hash | `Int32Array(32768)` | 128 KB | level 3 |
|
|
192
|
+
| chain | `Uint16Array(65536)` | 128 KB | level 3 |
|
|
193
|
+
| price / offset / length / literal-length | 4 × `Int32Array(4099)` | 64 KB | level 10 |
|
|
194
|
+
|
|
195
|
+
320 KB, against the 32 KB the fast encoder holds today. meep ships raw source, so a module-level
|
|
196
|
+
`new Int32Array(1 << 15)` would cost that to every consumer whether or not they ever compress —
|
|
197
|
+
including the runtime, which only ever *decodes*. **Allocate lazily**: the chain tables on the first
|
|
198
|
+
HC call, the parser tables on the first level-10-or-higher call. Module-static after that, like the
|
|
199
|
+
fast encoder's, and safe for the same reason — the encoder is straight-line synchronous code that
|
|
200
|
+
resets its tables on entry.
|
|
201
|
+
|
|
202
|
+
### 5.4 Table lifetime
|
|
203
|
+
|
|
204
|
+
`hash_table.fill(0)` and `chain_table.fill(0xFFFF)` on entry, per call. This looked like the obvious
|
|
205
|
+
thing to optimise — 256 KB of fill for a page that may be 1.4 KB — so it was measured.
|
|
206
|
+
|
|
207
|
+
*Advancing* that bias from call to call so the tables never need clearing at all — which is what the
|
|
208
|
+
reference does across streamed blocks, and which was verified byte-exact over 6,600 fuzz blocks —
|
|
209
|
+
came out at **0.95–1.01×: no gain**, because turning `IDX_BASE` into a mutable module binding costs
|
|
210
|
+
the inner loop more than the fill saves. Dropping only the chain-table clear (which is provably unnecessary here: every position's
|
|
211
|
+
delta is written by the insert before anything can walk to it) also measured as noise.
|
|
212
|
+
|
|
213
|
+
**Ship the plain per-call fill.** It matches the fast encoder's precedent and it is not the cost.
|
|
214
|
+
|
|
215
|
+
### 5.5 Two invariants the port must keep
|
|
216
|
+
|
|
217
|
+
- **Self-contained blocks.** No match may reach before `source_offset`. With an index space biased by
|
|
218
|
+
one window, an empty hash slot reads as "before the block" for free and the existing
|
|
219
|
+
"a block compressed after another does not carry the previous one's positions" test passes without
|
|
220
|
+
a special case.
|
|
221
|
+
- **The output bound is checked, not assumed.** The reference has `limitedOutput`; this codebase
|
|
222
|
+
throws, with message shapes the existing spec asserts (`/needs \d+ bytes, and only \d+ are left/`).
|
|
223
|
+
The HC writers must do the same checks at the same two points — before the token-and-literals run,
|
|
224
|
+
and before the offset-and-match-length. The prototype has neither yet; this is the one piece of the
|
|
225
|
+
port that is not already written.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 6 · Tests
|
|
230
|
+
|
|
231
|
+
Following the idiom already in [lz4_compress_block.spec.js](lz4_compress_block.spec.js): pinned
|
|
232
|
+
reference blocks first, then shapes too large to write down driven through and back.
|
|
233
|
+
|
|
234
|
+
**Pinned vectors.** These are what liblz4's own `LZ4_compress_HC` writes, and the prototype
|
|
235
|
+
reproduces them exactly:
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
// the greedy pass leaves bytes on the table
|
|
239
|
+
// "acddafadcacddaacddafadcacddaacdadcacbddafadcacddaacgdccaafadcacddaacgdadcacdfbeagdda" (84 bytes)
|
|
240
|
+
// fast=47 hc3=42 hc9=42 hc12=42
|
|
241
|
+
// hc3/hc9/hc12: 91 61 63 64 64 61 66 61 64 63 09 00 0d 0e 00 01 0b 00 1a 62 15 00 5a 67 64
|
|
242
|
+
// 63 63 61 11 00 02 0c 00 80 66 62 65 61 67 64 64 61
|
|
243
|
+
|
|
244
|
+
// the optimal parser earns its own row
|
|
245
|
+
// "ffafdfdefafdfdeeahadefehahadefeeahadefehfd" (42 bytes)
|
|
246
|
+
// fast=35 hc3=35 hc9=35 hc12=32
|
|
247
|
+
// hc3/hc9: 83 66 66 61 66 64 66 64 65 07 00 93 65 61 68 61 64 65 66 65 68 08 00 b0 65 61 68
|
|
248
|
+
// 61 64 65 66 65 68 66 64
|
|
249
|
+
// hc12 : 83 66 66 61 66 64 66 64 65 07 00 92 65 61 68 61 64 65 66 65 68 08 00 03 10 00 50
|
|
250
|
+
// 66 65 68 66 64
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The first pins that HC finds matches the greedy pass walks past; the second pins that levels 10–12
|
|
254
|
+
are a different parser and not just a longer search.
|
|
255
|
+
|
|
256
|
+
**Properties, over the existing `CORPUS` at every level:**
|
|
257
|
+
|
|
258
|
+
1. Round trip through `lz4_decompress_block` — bytes back exactly.
|
|
259
|
+
2. The encoder restrictions, using the spec's existing `read_sequences`: last five bytes literal, no
|
|
260
|
+
match starting within twelve bytes of the end, no offset reaching before the block start, the
|
|
261
|
+
block closes with a literals-only sequence.
|
|
262
|
+
3. **Aggregate** monotonicity: summed over the corpus, level *n+1* is never larger than level *n*.
|
|
263
|
+
**Not per block** — 54 non-monotone steps were found across 275 inputs, concentrated at the 9→10
|
|
264
|
+
boundary where the parser changes, the worst being a 64KB JSON chunk going 16,741 → 16,993 bytes.
|
|
265
|
+
Asserting per-block monotonicity would be asserting something false.
|
|
266
|
+
4. A destination one byte short of the block is rejected, at every level, with the same message
|
|
267
|
+
shapes the fast encoder produces.
|
|
268
|
+
5. `source_offset > 0`: the same payload compressed at offsets 0, 7, 32, 33 and 4096 inside buffers
|
|
269
|
+
filled with different padding bytes produces **identical blocks**. This is the real guard on the
|
|
270
|
+
one latent hazard in the port (§7), and it holds today for both encoders — 72 pages × 5 paddings.
|
|
271
|
+
6. Compressing a second block after a first does not carry the first's positions (the existing test,
|
|
272
|
+
extended across levels).
|
|
273
|
+
7. The level argument is validated: 2 and anything outside 1…12 is refused rather than silently
|
|
274
|
+
clamped to something the caller did not ask for.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 7 · What the port has to be careful about
|
|
279
|
+
|
|
280
|
+
Found while building and validating the prototype. None of these are speculative.
|
|
281
|
+
|
|
282
|
+
**The cheap rejection gate can read outside the block.** Before a full compare, the reference tests
|
|
283
|
+
the two bytes at the current best match end: `read16(iLowLimit + longest - 1)` against
|
|
284
|
+
`read16(matchPtr - lookBackLength + longest - 1)`. When the search is allowed to start behind the
|
|
285
|
+
current position — which is exactly what the lazy parser's second and third searches do — the second
|
|
286
|
+
address can fall before `source_offset`, and at `source_offset === 0` before the array. The C reads
|
|
287
|
+
whatever is in the buffer; JS reads `undefined`, which `| 0` turns into a zero. The gate is only a
|
|
288
|
+
heuristic, so either behaviour produces a *valid* block, but they can produce *different* blocks.
|
|
289
|
+
Clamp it explicitly and pin it with test 5 above. Over 72 real pages × 5 paddings, and 1,200 fuzz
|
|
290
|
+
inputs, no divergence was reachable — it is latent, not live, and it should stay that way by
|
|
291
|
+
construction rather than by luck.
|
|
292
|
+
|
|
293
|
+
**The level table, not the levels.** Levels 3–12 map onto `{ attempts, sufficient_length }` pairs and
|
|
294
|
+
a strategy; the strategy boundary at 10 and the pattern-analysis boundary at `attempts > 128` are
|
|
295
|
+
where behaviour changes, not the level numbers. Write the table, not a switch.
|
|
296
|
+
|
|
297
|
+
**`LZ4_MAX_INPUT_SIZE` still applies.** Indices are biased by one window and held in an `Int32Array`,
|
|
298
|
+
which is fine to 2^31, and the existing assert already caps input well below that.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## 8 · Adjacent, and out of scope
|
|
303
|
+
|
|
304
|
+
**The decoder's byte loops.** [lz4_decompress_block.js](lz4_decompress_block.js) copies literals and
|
|
305
|
+
matches one byte at a time. Splicing in `destination.set` for literal runs of 16 or more and
|
|
306
|
+
`copyWithin` for non-overlapping matches of 16 or more — nothing else changed, output verified
|
|
307
|
+
identical — measured on 250 real pages:
|
|
308
|
+
|
|
309
|
+
| | shipped decoder | with bulk copies |
|
|
310
|
+
|---|---|---|
|
|
311
|
+
| fast blocks | 1,206 MB/s | **2,034 MB/s** |
|
|
312
|
+
| level 9 blocks | 1,036 MB/s | **1,361 MB/s** |
|
|
313
|
+
|
|
314
|
+
HC blocks under a bulk-copy decoder (1,361 MB/s) decode **faster than fast blocks do today**
|
|
315
|
+
(1,206 MB/s). The decode cost in §3 is a property of the decoder's inner loop, not of high
|
|
316
|
+
compression. This is a separate change to a file this plan deliberately does not touch, and it is
|
|
317
|
+
worth making on its own merits.
|
|
318
|
+
|
|
319
|
+
**Done, 2026-09-14**, in the commit that added this paragraph. The threshold went in at
|
|
320
|
+
thirty-two rather than sixteen: sweeping both crossovers over 2,267 real pages put the top of the
|
|
321
|
+
curve between twenty-four and thirty-two, and thirty-two is where
|
|
322
|
+
[lz4_compress_block.js](lz4_compress_block.js) had already put its own. Measured the way §10 says
|
|
323
|
+
to, twenty-one interleaved rounds alternating which decoder went first:
|
|
324
|
+
|
|
325
|
+
| | shipped decoder | with bulk copies |
|
|
326
|
+
|---|---|---|
|
|
327
|
+
| fast blocks | 1,205 MB/s | **2,237 MB/s** |
|
|
328
|
+
| level 9 blocks | 1,109 MB/s | **1,592 MB/s** |
|
|
329
|
+
|
|
330
|
+
The claim survives with room to spare: level 9 blocks now decode 32% *faster* than fast blocks
|
|
331
|
+
managed before the change, and 44% faster than they manage today. What does **not** close is the
|
|
332
|
+
gap between the two shapes — bulk copies help fast blocks more, because their literal runs are
|
|
333
|
+
58.8 bytes against level 9's 34.7, so level 9 goes from 8% behind level 1 to 29% behind it. The
|
|
334
|
+
reader ends up far ahead in absolute terms and §3's trade is paid for several times over; the
|
|
335
|
+
*ratio* §3 quoted gets wider, not narrower, and a later reader should not expect otherwise.
|
|
336
|
+
|
|
337
|
+
Output is pinned against the old decoder over **57,938 stored pages of 150 Zorah containers,
|
|
338
|
+
3,489,392,680 decoded bytes, not one byte different**, and over the same 2,267 pages re-encoded at
|
|
339
|
+
both levels. The overlapping match stays a byte loop and has its own vectors in the spec.
|
|
340
|
+
|
|
341
|
+
What the sweep also showed is that the win is the **literal** path, which §3's text figures
|
|
342
|
+
predict but do not say outright. Four fifths of a decoded page is literal runs averaging 34.7
|
|
343
|
+
bytes at level 9, and its matches average 8.7 — so `set` moves 68% of the output and `copyWithin`
|
|
344
|
+
4%. On engine source, where literal runs average 1.1 bytes, the change is a wash at any threshold.
|
|
345
|
+
|
|
346
|
+
**python-lz4 is not a usable reference for the fast encoder.** The 4.4.5 wheel (liblz4 1.9.4) fails
|
|
347
|
+
to find matches whose candidate was recorded during the search loop: `"QabcdXXabcdZZZZZZZZ"` codes
|
|
348
|
+
as all literals, while the same input with the repeat at offset 0 codes the match. Its HC path is
|
|
349
|
+
correct. Consequence: **[lz4_compress_block.js](lz4_compress_block.js) is right and that build is
|
|
350
|
+
wrong** — meep's blocks are 1.43% *smaller* than its `mode='default'` output over the corpus, and a
|
|
351
|
+
line-by-line transliteration of `LZ4_compress_generic`'s `byU16` path agrees with meep on all 152
|
|
352
|
+
inputs tried. Validate HC against python-lz4; validate the fast encoder against the lz4 CLI or a
|
|
353
|
+
transliteration.
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## 9 · The plan
|
|
358
|
+
|
|
359
|
+
Each stage is independently shippable and leaves the tree green.
|
|
360
|
+
|
|
361
|
+
### Stage A — the hash chain, levels 3–9
|
|
362
|
+
|
|
363
|
+
**Files:** `LZ4_LEVEL.js`, `lz4_compress_block_hc.js`, `lz4_compress_block_at_level.js`,
|
|
364
|
+
`lz4_compress_block_hc.spec.js`
|
|
365
|
+
|
|
366
|
+
Port, from `lz4hc.c`, with no dictionary and no streaming: the lazy insert, the match finder with
|
|
367
|
+
pattern analysis, `LZ4HC_countBack`, and the three-match lazy parser. Add the output-bound checks
|
|
368
|
+
(§5.5) and the clamped gate (§7). Levels 10–12 assert as not yet available.
|
|
369
|
+
|
|
370
|
+
**Proves:** −2.53% on vgeo pages, −23.2% on text, at 52 MB/s. That is 97% of everything this plan can
|
|
371
|
+
deliver.
|
|
372
|
+
|
|
373
|
+
**Test:** all of §6 except the level-12 vector and the 9→10 aggregate step.
|
|
374
|
+
|
|
375
|
+
### Stage B — the optimal parser, levels 10–12
|
|
376
|
+
|
|
377
|
+
**Files:** `lz4_compress_block_hc.js` (the parser and its lazily-allocated tables), spec additions.
|
|
378
|
+
|
|
379
|
+
Port `LZ4HC_compress_optimal` with `favorDecSpeed` fixed off: the exact byte price model, the
|
|
380
|
+
4,096-position window, `sufficient_len`, and full update at level 12. Add chain swap to the finder.
|
|
381
|
+
|
|
382
|
+
**Proves:** the ladder reaches the documented maximum, and §1's measurement says there is nothing
|
|
383
|
+
past it.
|
|
384
|
+
|
|
385
|
+
**Test:** the level-12 vector, and aggregate monotonicity across the whole ladder.
|
|
386
|
+
|
|
387
|
+
### Stage C — the level reaches the build
|
|
388
|
+
|
|
389
|
+
**Files:**
|
|
390
|
+
[VGeoBuildOptions.js](../../../shade/renderer/geometry/virtual/build/VGeoBuildOptions.js) ·
|
|
391
|
+
[VGeoWriteOptions.js](../../../shade/renderer/geometry/virtual/format/VGeoWriteOptions.js) ·
|
|
392
|
+
[vgeo_encode_frame_blob.js](../../../shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js) ·
|
|
393
|
+
[vgeo_write_container.js](../../../shade/renderer/geometry/virtual/format/vgeo_write_container.js) ·
|
|
394
|
+
[gltf_to_vgeo.js](../../../../tools/geometry/virtual/gltf_to_vgeo.js)
|
|
395
|
+
|
|
396
|
+
A `codec_level` beside the existing `codec` at each layer, defaulting to `LZ4_LEVEL.HC_DEFAULT` (9),
|
|
397
|
+
and a `--codec-level` flag on the tool. `vgeo_encode_frame_blob` already declines compression per
|
|
398
|
+
page when it would not shrink the page, so the level cannot make a file larger — nothing about that
|
|
399
|
+
contract changes.
|
|
400
|
+
|
|
401
|
+
**Test:** [vgeo_frame_blob.spec.js](../../../shade/renderer/geometry/virtual/format/frame/vgeo_frame_blob.spec.js)
|
|
402
|
+
gains a level case; the container round trip runs at the default.
|
|
403
|
+
|
|
404
|
+
Nothing in the runtime changes. `codec` on the frame is still `VGEO_CODEC_LZ4`, the reader still
|
|
405
|
+
reads it, and a container built at level 12 is readable by every build of the reader that exists.
|
|
406
|
+
|
|
407
|
+
### Stage D — confirm on a real conversion
|
|
408
|
+
|
|
409
|
+
Re-run a Zorah subset at the new default and check the two numbers this plan promised: pages about
|
|
410
|
+
2.5% smaller, build CPU up under 2%. Record it next to the 2026-09-13 log.
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
## 10 · How to re-measure
|
|
415
|
+
|
|
416
|
+
Everything above came from a scratchpad at
|
|
417
|
+
`C:\Users\Alex\AppData\Local\Temp\claude\H--git-CompanyNamed-meep\f41c851a-bc82-447f-be15-80a25e108370\scratchpad`,
|
|
418
|
+
which is session-local and will not survive. The recipes are short:
|
|
419
|
+
|
|
420
|
+
- **Corpus** — walk a `.vgeo` with `vgeo_read_header` + `vgeo_read_directory`, slice each frame at
|
|
421
|
+
`frame_offset`/`fetch_size`, and decode the blob past
|
|
422
|
+
`VGEO_FRAME_HEADER_SIZE + 48 × child_page_count`. Note that `vgeo_read_header` wants more than
|
|
423
|
+
`VGEO_HEADER_SIZE` bytes — the level table follows the header, so hand it 8 KB.
|
|
424
|
+
- **Ground truth** — `python -c "import lz4.block as B; B.compress(data, mode='high_compression', compression=N, store_size=False)"`.
|
|
425
|
+
Python has `lz4` installed here (4.4.5, liblz4 1.9.4). For HC only — see §8.
|
|
426
|
+
- **Timing** — interleave A and B in one process and alternate which runs first; nineteen node
|
|
427
|
+
processes is a normal background load on this machine and a single-shot number means nothing.
|
|
428
|
+
- **Build cost** — `H:\vgeo_scratch\zorah-2026-13-09-console.log` carries the stored/decoded page
|
|
429
|
+
totals and the CPU time the projections in §2 are scaled against.
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## 11 · What it came to
|
|
434
|
+
|
|
435
|
+
Carried out 2026-09-14, in four commits: the encoder and its spec, the plumbing through the build,
|
|
436
|
+
one profiling pass, and this. Every number below was measured on this machine after the work, the
|
|
437
|
+
same way §10 says to measure it.
|
|
438
|
+
|
|
439
|
+
### The port
|
|
440
|
+
|
|
441
|
+
`lz4hc.c` at 1.10.0, with the dictionary and streaming half dropped as §4 said. One thing dropped
|
|
442
|
+
that §4 did not name: **`LZ4HC_protectDictEnd` goes too.** It guards against a candidate whose four
|
|
443
|
+
bytes would run off the end of a dictionary, and with no dictionary every candidate the loop reaches
|
|
444
|
+
already satisfies it — `matchCandidateIdx >= lowestMatchIndex` implies it, and so does every index
|
|
445
|
+
the pattern-analysis branch assigns. 733 lines of code against the reference's 2,192 of file.
|
|
446
|
+
|
|
447
|
+
Byte for byte identical to liblz4 1.9.4's `LZ4_compress_HC` over **26,093 blocks**:
|
|
448
|
+
|
|
449
|
+
| corpus | inputs | levels | blocks |
|
|
450
|
+
|---|---|---|---|
|
|
451
|
+
| synthetic: runs, periods, window edges, structured and small fuzz | 1,182 | 3–12 | 11,820 |
|
|
452
|
+
| the same, capped at 20 KB | 961 | 3–12 | 9,610 |
|
|
453
|
+
| the same, over 20 KB | 221 | 10–12 | 663 |
|
|
454
|
+
| real `.vgeo` pages from the 2026-09-13 Zorah build | 400 | 3–12 | 4,000 |
|
|
455
|
+
|
|
456
|
+
First try, as §1 said it would be. §6's two pinned vectors reproduce exactly, level-12 row included.
|
|
457
|
+
|
|
458
|
+
### The ladder, on 5,802 real pages
|
|
459
|
+
|
|
460
|
+
The pages of a 507-geometry Zorah subset, 190,044,904 bytes decoded — the exact bytes
|
|
461
|
+
`vgeo_encode_frame_blob` was handed:
|
|
462
|
+
|
|
463
|
+
| level | stored | ratio | vs. level 1 | encoder |
|
|
464
|
+
|---|---|---|---|---|
|
|
465
|
+
| 1 | 166,692,697 | 0.87712 | — | 340–390 MB/s |
|
|
466
|
+
| 3 | 162,743,403 | 0.85634 | −2.369% | 44–53 MB/s |
|
|
467
|
+
| **9** | **162,604,364** | **0.85561** | **−2.453%** | **42–50 MB/s** |
|
|
468
|
+
| 12 | 162,586,298 | 0.85552 | −2.463% | 31–38 MB/s |
|
|
469
|
+
|
|
470
|
+
The stored byte counts are exact and repeat to the byte. The throughputs are ranges because that is
|
|
471
|
+
what this machine supports: two best-of-nine runs of the same measurement, minutes apart, came out
|
|
472
|
+
20% apart, which is wider than most of the differences anyone would want to read off the column.
|
|
473
|
+
What *is* stable is the shape within a run — level 1 is about eight times level 9, and level 9 is
|
|
474
|
+
about 5% slower than level 3 — because those are ratios taken between interleaved passes.
|
|
475
|
+
|
|
476
|
+
§2's shape holds exactly: level 3 is 96.2% of everything the ladder has on this payload, and the
|
|
477
|
+
whole run from 3 to 12 is 0.082 percentage points. On a wider sample — the first 25 pages of each of
|
|
478
|
+
120 containers, 2,718 pages and 122,283,932 bytes — the same ladder runs 0.90483 to 0.87733, which
|
|
479
|
+
is **−3.040%**, so 2.5% is the conservative end of what a whole build gets rather than the middle.
|
|
480
|
+
|
|
481
|
+
Throughput came out below §2's 52 MB/s at first. Profiling put 16.3% of all ticks in the guarded
|
|
482
|
+
gate read of §7, which V8 was not inlining: it is called once per link of every chain walked. Taking
|
|
483
|
+
the guard only on addresses that need it, and reading the call's context into locals once rather
|
|
484
|
+
than reloading module bindings inside that loop, bought 15% in a paired in-process comparison and
|
|
485
|
+
left nothing outside the search loop above 14% of the profile.
|
|
486
|
+
|
|
487
|
+
### The two numbers Stage D promised
|
|
488
|
+
|
|
489
|
+
**Pages about 2.5% smaller — confirmed.** The paired conversions, `--max-triangles 30000` on
|
|
490
|
+
`zorah_main_public.v2.gltf`, 507 geometries and 5.25 M triangles, identical in every run:
|
|
491
|
+
|
|
492
|
+
| | pages stored | decoded |
|
|
493
|
+
|---|---|---|
|
|
494
|
+
| level 1 | 159.0 MiB | 181.2 MiB |
|
|
495
|
+
| level 9 | 155.1 MiB | 181.2 MiB |
|
|
496
|
+
|
|
497
|
+
**Build CPU up under 2% — confirmed for the Zorah build, but not for this subset.** Six runs,
|
|
498
|
+
alternating which level went first:
|
|
499
|
+
|
|
500
|
+
| | CPU | wall |
|
|
501
|
+
|---|---|---|
|
|
502
|
+
| level 1 | 139.3 s · 139.7 s · **119.5 s** | 128.8 · 129.4 · **110.8** |
|
|
503
|
+
| level 9 | 143.0 s · 147.6 s · **124.1 s** | 131.6 · 133.8 · **114.9** |
|
|
504
|
+
|
|
505
|
+
The last pair ran back to back on a quiet machine and is the one to read: **+4.6 s of CPU, +3.85%**.
|
|
506
|
+
Measuring the compression alone over the same build's own pages — five interleaved passes, so no
|
|
507
|
+
noise at all — gives 0.51 s against 4.03 s, a delta of **+3.52 s, or +2.95%** of that build.
|
|
508
|
+
|
|
509
|
+
That is over 2%, and it is over 2% *because of what the subset is*. `--max-triangles 30000` selects
|
|
510
|
+
the small geometries, and they are cheap: 190 MB of pages out of 119.5 s of build CPU, which is
|
|
511
|
+
1.59 MB of page bytes per CPU-second. The 2026-09-13 build produced 60,536 MB of pages from 61,740 s
|
|
512
|
+
(17 h 9 m, validation excluded), which is **0.98** — it spends 62% more CPU per page byte, because
|
|
513
|
+
it is building the large meshes too. Scaling this subset's measured delta by that gives **about 2%**
|
|
514
|
+
of the Zorah build's CPU.
|
|
515
|
+
|
|
516
|
+
**About 2% is as fine as this machine resolves it, and the honest answer is that it straddles the
|
|
517
|
+
line.** The three paired conversions give deltas of +3.7 s, +7.9 s and +4.6 s on a build of 190 MB
|
|
518
|
+
of pages, which scale to 1.9%, 4.1% and 2.4% of the Zorah build; the direct compression measurement,
|
|
519
|
+
taken twice on a quiet machine, gives 1.7% and 2.1%. Every one of those is a difference of a few
|
|
520
|
+
seconds measured against a two-minute build on a box whose own run-to-run spread is 20%, so §2's
|
|
521
|
+
1.8% is not *confirmed* so much as *not contradicted*. What can be said without a measurement error
|
|
522
|
+
swallowing it: the level costs a couple of percent of a build and a couple of minutes of wall clock
|
|
523
|
+
across ten workers, and it is about 3% on a build made only of small meshes.
|
|
524
|
+
|
|
525
|
+
### What it costs the reader, re-measured
|
|
526
|
+
|
|
527
|
+
§3 said the blocks change shape and the plan was right about that, on 2,500 real pages:
|
|
528
|
+
|
|
529
|
+
| | ratio | bytes/sequence | decode |
|
|
530
|
+
|---|---|---|---|
|
|
531
|
+
| level 1 | 0.87252 | 55.3 | 1,197 MB/s |
|
|
532
|
+
| level 9 | 0.85228 | 38.4 | 1,080 MB/s |
|
|
533
|
+
| level 12 | 0.85220 | 38.1 | 1,077 MB/s |
|
|
534
|
+
|
|
535
|
+
38.4 bytes a sequence at level 9, which is §3's figure to the decimal, and decode 9.8% slower rather
|
|
536
|
+
than 10–15%. §8's bulk-copy decoder is still the answer to that, and still out of scope here.
|
|
537
|
+
|
|
538
|
+
### And it reads
|
|
539
|
+
|
|
540
|
+
507 Zorah containers built at level 9 pass the tool's whole post-build audit — every build
|
|
541
|
+
invariant, checksum and directory record, in every file — which is the claim that the format does
|
|
542
|
+
not change, made against real geometry rather than argued.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The compression levels {@link lz4_compress_block_at_level} accepts.
|
|
3
|
+
*
|
|
4
|
+
* Level 1 is the format's fast encoder, {@link lz4_compress_block}. Levels 3 to 12 are the
|
|
5
|
+
* high-compression encoder, {@link lz4_compress_block_hc}: 3 to 9 walk a hash chain with a lazy
|
|
6
|
+
* parse of ever more candidates, and 10 to 12 replace that parse with a shortest path over a window
|
|
7
|
+
* of the block. Twelve is the top of the ladder in the reference and, measured against an encoder
|
|
8
|
+
* with an uncapped search and a whole-block parse, the top of what the block format allows at all.
|
|
9
|
+
*
|
|
10
|
+
* **There is no level 2.** The reference gives the number different algorithms in different
|
|
11
|
+
* releases — 1.9.4 compresses it on the hash chain, 1.10.0 hands it to `lz4mid`, a compressor that
|
|
12
|
+
* release added — so "level 2" does not name one thing, and this encoder will not pretend it does.
|
|
13
|
+
*
|
|
14
|
+
* Nine is the default because the ladder above it is not worth its time: on real geometry pages the
|
|
15
|
+
* whole run from 3 to 12 is under a tenth of a percentage point of ratio, and 10 to 12 cost 15-40%
|
|
16
|
+
* more time for the last thousandth of it. Nine is the smallest of the hash-chain levels and costs
|
|
17
|
+
* about 5% more time than 3 — the reference's own claim that 9 comes out *faster* than the levels
|
|
18
|
+
* below it is a property of its eight-byte pattern scan, which JavaScript has no cheap way to do,
|
|
19
|
+
* and it does not reproduce here. The case for 9 over 3 is ratio, and it is a small one.
|
|
20
|
+
*
|
|
21
|
+
* @see https://github.com/lz4/lz4/blob/dev/lib/lz4hc.h — `LZ4HC_CLEVEL_MIN` and friends
|
|
22
|
+
* @type {{FAST: number, HC_MIN: number, HC_DEFAULT: number, HC_MAX: number}}
|
|
23
|
+
*
|
|
24
|
+
* @author Alex Goldring
|
|
25
|
+
* @copyright Company Named Limited (c) 2026
|
|
26
|
+
*/
|
|
27
|
+
export const LZ4_LEVEL: {
|
|
28
|
+
FAST: number;
|
|
29
|
+
HC_MIN: number;
|
|
30
|
+
HC_DEFAULT: number;
|
|
31
|
+
HC_MAX: number;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=LZ4_LEVEL.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LZ4_LEVEL.d.ts","sourceRoot":"","sources":["../../../../../src/core/binary/lz4/LZ4_LEVEL.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBALU;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAU1E"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The compression levels {@link lz4_compress_block_at_level} accepts.
|
|
3
|
+
*
|
|
4
|
+
* Level 1 is the format's fast encoder, {@link lz4_compress_block}. Levels 3 to 12 are the
|
|
5
|
+
* high-compression encoder, {@link lz4_compress_block_hc}: 3 to 9 walk a hash chain with a lazy
|
|
6
|
+
* parse of ever more candidates, and 10 to 12 replace that parse with a shortest path over a window
|
|
7
|
+
* of the block. Twelve is the top of the ladder in the reference and, measured against an encoder
|
|
8
|
+
* with an uncapped search and a whole-block parse, the top of what the block format allows at all.
|
|
9
|
+
*
|
|
10
|
+
* **There is no level 2.** The reference gives the number different algorithms in different
|
|
11
|
+
* releases — 1.9.4 compresses it on the hash chain, 1.10.0 hands it to `lz4mid`, a compressor that
|
|
12
|
+
* release added — so "level 2" does not name one thing, and this encoder will not pretend it does.
|
|
13
|
+
*
|
|
14
|
+
* Nine is the default because the ladder above it is not worth its time: on real geometry pages the
|
|
15
|
+
* whole run from 3 to 12 is under a tenth of a percentage point of ratio, and 10 to 12 cost 15-40%
|
|
16
|
+
* more time for the last thousandth of it. Nine is the smallest of the hash-chain levels and costs
|
|
17
|
+
* about 5% more time than 3 — the reference's own claim that 9 comes out *faster* than the levels
|
|
18
|
+
* below it is a property of its eight-byte pattern scan, which JavaScript has no cheap way to do,
|
|
19
|
+
* and it does not reproduce here. The case for 9 over 3 is ratio, and it is a small one.
|
|
20
|
+
*
|
|
21
|
+
* @see https://github.com/lz4/lz4/blob/dev/lib/lz4hc.h — `LZ4HC_CLEVEL_MIN` and friends
|
|
22
|
+
* @type {{FAST: number, HC_MIN: number, HC_DEFAULT: number, HC_MAX: number}}
|
|
23
|
+
*
|
|
24
|
+
* @author Alex Goldring
|
|
25
|
+
* @copyright Company Named Limited (c) 2026
|
|
26
|
+
*/
|
|
27
|
+
export const LZ4_LEVEL = {
|
|
28
|
+
FAST: 1,
|
|
29
|
+
HC_MIN: 3,
|
|
30
|
+
HC_DEFAULT: 9,
|
|
31
|
+
HC_MAX: 12
|
|
32
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encode one LZ4 block, at whichever level the caller asks for.
|
|
3
|
+
*
|
|
4
|
+
* This is what a caller with a knob calls. The two encoders behind it are not variants of one
|
|
5
|
+
* another — {@link lz4_compress_block} makes a single greedy pass over a table that holds one
|
|
6
|
+
* position per hash, and {@link lz4_compress_block_hc} walks a chain of every position carrying the
|
|
7
|
+
* same hash and parses the matches against each other — so they are two functions, and this is the
|
|
8
|
+
* one line that chooses between them.
|
|
9
|
+
*
|
|
10
|
+
* **Every level writes the same format.** A block is a block: the level changes how long the encoder
|
|
11
|
+
* spent looking for matches, not what a match is coded as. So the level is a build-time decision
|
|
12
|
+
* with no reader consequence at all, and one that can be changed on an existing pipeline without
|
|
13
|
+
* anything downstream knowing.
|
|
14
|
+
*
|
|
15
|
+
* `destination` and `source` must not overlap.
|
|
16
|
+
*
|
|
17
|
+
* @param {Uint8Array} destination
|
|
18
|
+
* @param {number} destination_offset where this block's output starts
|
|
19
|
+
* @param {number} destination_end one past the last byte the block may write; give it
|
|
20
|
+
* {@link lz4_compress_bound} bytes and it cannot run out
|
|
21
|
+
* @param {Uint8Array} source
|
|
22
|
+
* @param {number} source_offset the first byte of input, and the floor a match may reach back to
|
|
23
|
+
* @param {number} source_end one past the last byte of input
|
|
24
|
+
* @param {number} level {@link LZ4_LEVEL.FAST}, or one of 3 to {@link LZ4_LEVEL.HC_MAX} — there is
|
|
25
|
+
* no level 2, and {@link LZ4_LEVEL} says why
|
|
26
|
+
* @returns {number} the offset just past the last byte written
|
|
27
|
+
* @throws {Error} if the block does not fit the space given for it
|
|
28
|
+
*
|
|
29
|
+
* @author Alex Goldring
|
|
30
|
+
* @copyright Company Named Limited (c) 2026
|
|
31
|
+
*/
|
|
32
|
+
export function lz4_compress_block_at_level(destination: Uint8Array, destination_offset: number, destination_end: number, source: Uint8Array, source_offset: number, source_end: number, level: number): number;
|
|
33
|
+
//# sourceMappingURL=lz4_compress_block_at_level.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lz4_compress_block_at_level.d.ts","sourceRoot":"","sources":["../../../../../src/core/binary/lz4/lz4_compress_block_at_level.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,yDAfW,UAAU,sBACV,MAAM,mBACN,MAAM,UAEN,UAAU,iBACV,MAAM,cACN,MAAM,SACN,MAAM,GAEJ,MAAM,CAgBlB"}
|