@woosh/meep-engine 3.27.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/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/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/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 +27 -13
- package/src/shade/playground/vgeo_runtime/main.js +18 -5
- 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 +9 -8
- 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/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/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 +4 -2
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +10 -8
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +12 -11
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +1 -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} +9 -9
- 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_build.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +9 -11
- 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/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/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/vgeo_read_page.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +9 -4
- 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 +18 -5
- 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 +9 -1
- package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +21 -2
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +52 -2
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +97 -1
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +4 -4
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +10 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +59 -34
- 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 -88
- 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_reseed.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +7 -63
- 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 +13 -30
- 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 +6 -52
- 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/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/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/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/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/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/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/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/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 +78 -88
- 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 +21 -31
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +2 -0
- 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/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/VGeoResidencyOptions.d.ts +0 -49
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
- 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/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/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
|
@@ -1,481 +0,0 @@
|
|
|
1
|
-
import { assert } from "../../../core/assert.js";
|
|
2
|
-
import { DEG_TO_RAD } from "../../../core/math/DEG_TO_RAD.js";
|
|
3
|
-
import {
|
|
4
|
-
VGeoPageWant
|
|
5
|
-
} from "../../renderer/geometry/virtual/format/read/VGeoPageWant.js";
|
|
6
|
-
import { VGEO_NO_CHILD } from "../../renderer/geometry/virtual/format/cluster/VGEO_NO_CHILD.js";
|
|
7
|
-
import { VGEO_SAME_PAGE } from "../../renderer/geometry/virtual/format/cluster/VGEO_SAME_PAGE.js";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Selecting a cut from a partially resident container.
|
|
11
|
-
*
|
|
12
|
-
* The traversal itself is the runtime's rule, not a debug approximation of it: descend the page
|
|
13
|
-
* graph from the root's parentless groups, refine a cluster whose error projects above τ, take it
|
|
14
|
-
* when it does not. What this file adds is the part a whole-file reader never has to think about —
|
|
15
|
-
* what to do when the page a refinement wants is not here.
|
|
16
|
-
*
|
|
17
|
-
* The answer is the format's (`VGEO_FORMAT.md` §10): **draw the coarser cluster and say so**. The
|
|
18
|
-
* result is a genuine surface — watertight, correct, merely coarser in that region — and the want it
|
|
19
|
-
* records carries the exact byte range that would refine it. That is what makes streaming safe in
|
|
20
|
-
* any arrival order, and it is why this file's most interesting number is `clamped`.
|
|
21
|
-
*
|
|
22
|
-
* "Not here" is `VGeoContainerReader.is_selectable`, not `is_resident`, and the difference is the
|
|
23
|
-
* one thing about this traversal that is not obvious: a group is refined into only once every page
|
|
24
|
-
* holding one of its *parents* is installed. Residency alone lets a group be entered through the
|
|
25
|
-
* parents that arrived while a coarse cluster still covers the one that did not, and then both are
|
|
26
|
-
* drawn over the same surface. §10 calls that out by name — "no holes **and no double-draw**, in any
|
|
27
|
-
* arrival order" — and the second half is the one that fails silently.
|
|
28
|
-
*
|
|
29
|
-
* @author Alex Goldring
|
|
30
|
-
* @copyright Company Named Limited (c) 2026
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The view a cut is selected for. `VIRTUAL_GEOMETRY_DESIGN.md` §4: a cut is selected at one camera's
|
|
35
|
-
* distances and pixel budget, and is the wrong cut for any other.
|
|
36
|
-
*/
|
|
37
|
-
export class VGeoCutView {
|
|
38
|
-
/**
|
|
39
|
-
* Camera position, object space — the viewer draws at identity, so world and object agree.
|
|
40
|
-
* @type {Float32Array}
|
|
41
|
-
*/
|
|
42
|
-
eye = new Float32Array(3);
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Pixels of permitted error. The one quality dial.
|
|
46
|
-
* @type {number}
|
|
47
|
-
*/
|
|
48
|
-
tau = 1;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Height of the render target, in pixels — the projection's numerator.
|
|
52
|
-
* @type {number}
|
|
53
|
-
*/
|
|
54
|
-
screen_height = 1080;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* @type {number}
|
|
58
|
-
*/
|
|
59
|
-
fov_y = 60 * DEG_TO_RAD;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @type {boolean}
|
|
63
|
-
*/
|
|
64
|
-
cull_enabled = false;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Six normalized world-space planes, as {@link Camera.frustum} holds them.
|
|
68
|
-
* @type {Float32Array}
|
|
69
|
-
*/
|
|
70
|
-
frustum = new Float32Array(24);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* What one traversal came to, including what it had to look at to get there and what it could not
|
|
75
|
-
* reach.
|
|
76
|
-
*
|
|
77
|
-
* A cut holds the {@link VGeoPage} objects it selected from rather than page indices, so it stays
|
|
78
|
-
* drawable across an eviction: the bytes it needs are reachable from the cut itself. Nothing here
|
|
79
|
-
* goes stale because residency moved under it.
|
|
80
|
-
*/
|
|
81
|
-
export class VGeoCut {
|
|
82
|
-
/**
|
|
83
|
-
* The page each selected cluster came from, parallel to {@link clusters}.
|
|
84
|
-
* @type {VGeoPage[]}
|
|
85
|
-
*/
|
|
86
|
-
pages = [];
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Selected clusters, as indices within the page at the same position of {@link pages}. There is
|
|
90
|
-
* no global cluster id in the format and none in the reader; a cluster is a page and an index.
|
|
91
|
-
* @type {number[]}
|
|
92
|
-
*/
|
|
93
|
-
clusters = [];
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @type {number}
|
|
97
|
-
*/
|
|
98
|
-
triangle_count = 0;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* @type {number}
|
|
102
|
-
*/
|
|
103
|
-
vertex_count = 0;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @type {number}
|
|
107
|
-
*/
|
|
108
|
-
groups_visited = 0;
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* @type {number}
|
|
112
|
-
*/
|
|
113
|
-
clusters_tested = 0;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Clusters whose subtree the frustum threw away, which is a whole region rather than one
|
|
117
|
-
* cluster — the reason culling belongs in the traversal and not after it.
|
|
118
|
-
* @type {number}
|
|
119
|
-
*/
|
|
120
|
-
culled = 0;
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Clusters that projected above τ and were drawn anyway, because the page holding their
|
|
124
|
-
* refinement is not resident.
|
|
125
|
-
*
|
|
126
|
-
* **This is the number that says a cut is still arriving.** Zero means the cut on screen is the
|
|
127
|
-
* one the container's own metric selects for this view; anything above it means part of the
|
|
128
|
-
* surface is standing in for something finer, and {@link wants} says exactly what to fetch to
|
|
129
|
-
* fix it.
|
|
130
|
-
*
|
|
131
|
-
* @type {number}
|
|
132
|
-
*/
|
|
133
|
-
clamped = 0;
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Of those, the ones whose child group's page is **here** and merely not selectable yet, because
|
|
137
|
-
* a page holding one of that group's other parents is not.
|
|
138
|
-
*
|
|
139
|
-
* They carry no want: there is nothing to fetch from a cluster that already has the bytes it
|
|
140
|
-
* points at. What unblocks them is elsewhere in the same cut — the cluster clamped directly
|
|
141
|
-
* against the missing page — so this number is not a second streaming frontier, it is how much
|
|
142
|
-
* of the coarseness on screen is the ancestor rule holding a group back rather than bandwidth.
|
|
143
|
-
*
|
|
144
|
-
* @type {number}
|
|
145
|
-
*/
|
|
146
|
-
clamped_on_activation = 0;
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Which clusters those were, keyed `page · 65536 + cluster`. What the panel counts, a display
|
|
150
|
-
* can paint — so the regions still waiting on bytes are visible as regions.
|
|
151
|
-
* @type {Set<number>}
|
|
152
|
-
*/
|
|
153
|
-
clamped_keys = new Set();
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Clusters whose `child_ref` names an entry outside their page's child table.
|
|
157
|
-
*
|
|
158
|
-
* Impossible in a file the validator accepts, and reachable here precisely because validation is
|
|
159
|
-
* off by default — so it is counted and the cluster is drawn as a leaf, rather than read out of
|
|
160
|
-
* bounds or thrown out of a traversal that was two thirds of the way to a picture.
|
|
161
|
-
*
|
|
162
|
-
* @type {number}
|
|
163
|
-
*/
|
|
164
|
-
broken_child_refs = 0;
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* The pages this cut would need to stop being clamped, one entry per page, most wanted first.
|
|
168
|
-
* @type {VGeoPageWant[]}
|
|
169
|
-
*/
|
|
170
|
-
wants = [];
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Distinct pages the traversal read from.
|
|
174
|
-
* @type {number}
|
|
175
|
-
*/
|
|
176
|
-
pages_touched = 0;
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* @type {number}
|
|
180
|
-
*/
|
|
181
|
-
duration_ms = 0;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* `VIRTUAL_GEOMETRY_DESIGN.md` §4: `err_px = r_e · screen_height / (2 · tan(fov_y / 2) · d)`, with
|
|
186
|
-
* `d` the distance to the *closest point* of the sphere.
|
|
187
|
-
*
|
|
188
|
-
* A zero error projects to zero unconditionally — otherwise a leaf, whose error is exactly zero,
|
|
189
|
-
* would become undrawable the moment the camera entered its sphere.
|
|
190
|
-
*
|
|
191
|
-
* @param {number} error object-space `r_e`; `+Infinity` for a root's parent
|
|
192
|
-
* @param {Float32Array} spheres
|
|
193
|
-
* @param {number} base index of the sphere's first component
|
|
194
|
-
* @param {Float32Array} eye
|
|
195
|
-
* @param {number} k `screen_height / (2 · tan(fov_y / 2))`, hoisted out of the loop
|
|
196
|
-
* @returns {number} pixels
|
|
197
|
-
*/
|
|
198
|
-
function project_error(error, spheres, base, eye, k) {
|
|
199
|
-
if (error === 0) {
|
|
200
|
-
return 0;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const dx = eye[0] - spheres[base];
|
|
204
|
-
const dy = eye[1] - spheres[base + 1];
|
|
205
|
-
const dz = eye[2] - spheres[base + 2];
|
|
206
|
-
|
|
207
|
-
const distance = Math.sqrt(dx * dx + dy * dy + dz * dz) - spheres[base + 3];
|
|
208
|
-
|
|
209
|
-
if (distance <= 0) {
|
|
210
|
-
// camera inside the sphere; the projection is unbounded and the cluster must refine
|
|
211
|
-
return Number.POSITIVE_INFINITY;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return (error * k) / distance;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Whether a sphere is entirely outside the frustum.
|
|
219
|
-
*
|
|
220
|
-
* Only the five finite planes are tested. The projection is infinite reverse-Z, so the far plane's
|
|
221
|
-
* row is degenerate and normalizing it produces nothing a test can use.
|
|
222
|
-
*
|
|
223
|
-
* @param {Float32Array} frustum
|
|
224
|
-
* @param {Float32Array} spheres
|
|
225
|
-
* @param {number} base
|
|
226
|
-
* @returns {boolean}
|
|
227
|
-
*/
|
|
228
|
-
function sphere_outside_frustum(frustum, spheres, base) {
|
|
229
|
-
const x = spheres[base];
|
|
230
|
-
const y = spheres[base + 1];
|
|
231
|
-
const z = spheres[base + 2];
|
|
232
|
-
const radius = spheres[base + 3];
|
|
233
|
-
|
|
234
|
-
for (let plane = 0; plane < 5; plane++) {
|
|
235
|
-
const o = plane * 4;
|
|
236
|
-
|
|
237
|
-
const distance = frustum[o] * x + frustum[o + 1] * y + frustum[o + 2] * z + frustum[o + 3];
|
|
238
|
-
|
|
239
|
-
if (distance < -radius) {
|
|
240
|
-
return true;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
return false;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Select the cut for a view from whatever the reader currently holds.
|
|
249
|
-
*
|
|
250
|
-
* A traversal rather than a flat pass over every cluster, per design §4 — and it gets the cut rule's
|
|
251
|
-
* first half for free. The rule is `project(parent) > τ AND project(self) ≤ τ`; a group is only ever
|
|
252
|
-
* reached by descending *through* the cluster whose step consumed it, and that descent happened
|
|
253
|
-
* precisely because the step projected above τ. Every cluster of a group shares that step's sphere
|
|
254
|
-
* and error, so the parent test is satisfied by the act of arriving.
|
|
255
|
-
*
|
|
256
|
-
* The residency clamp is the live one here, and it is the reason a cut can be taken at all before
|
|
257
|
-
* the file has finished arriving: a cluster that wants a page nobody has is drawn as it stands.
|
|
258
|
-
*
|
|
259
|
-
* @param {VGeoContainerReader} reader
|
|
260
|
-
* @param {VGeoCutView} view
|
|
261
|
-
* @returns {VGeoCut}
|
|
262
|
-
*/
|
|
263
|
-
export function vgeo_select_cut(reader, view) {
|
|
264
|
-
assert.defined(reader.root, 'reader.root — the container must be open');
|
|
265
|
-
|
|
266
|
-
const started = performance.now();
|
|
267
|
-
|
|
268
|
-
const cut = new VGeoCut();
|
|
269
|
-
|
|
270
|
-
const k = view.screen_height / (2 * Math.tan(view.fov_y * 0.5));
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Groups already queued, keyed `page · 65536 + group`. A group is referenced by every sibling
|
|
274
|
-
* cluster of the step that consumed it, so without this the traversal would expand it once per
|
|
275
|
-
* parent and the cut would carry duplicates.
|
|
276
|
-
*
|
|
277
|
-
* Multiplied rather than shifted: a page index is a u32, and `<<` would wrap it at the sixteenth
|
|
278
|
-
* page of a large asset.
|
|
279
|
-
*
|
|
280
|
-
* @type {Set<number>}
|
|
281
|
-
*/
|
|
282
|
-
const queued = new Set();
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* @type {Set<number>}
|
|
286
|
-
*/
|
|
287
|
-
const touched = new Set();
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Wants by page index, so that many clamped clusters wanting one page produce one entry — which
|
|
291
|
-
* is also where {@link VGeoPageWant.reference_count} comes from.
|
|
292
|
-
* @type {Map<number, VGeoPageWant>}
|
|
293
|
-
*/
|
|
294
|
-
const wants = new Map();
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Page and group index, interleaved.
|
|
298
|
-
* @type {number[]}
|
|
299
|
-
*/
|
|
300
|
-
const stack = [];
|
|
301
|
-
|
|
302
|
-
const root = reader.root;
|
|
303
|
-
|
|
304
|
-
for (let group = 0; group < root.group_parent_count.length; group++) {
|
|
305
|
-
// no cluster anywhere refines into this group, so it is the top of the DAG and selectable
|
|
306
|
-
// with nothing above it
|
|
307
|
-
if (root.group_parent_count[group] === 0) {
|
|
308
|
-
queued.add(group);
|
|
309
|
-
stack.push(0, group);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
while (stack.length > 0) {
|
|
314
|
-
const group = stack.pop();
|
|
315
|
-
const page_index = stack.pop();
|
|
316
|
-
|
|
317
|
-
const page = reader.page(page_index);
|
|
318
|
-
|
|
319
|
-
if (page === undefined) {
|
|
320
|
-
// Evicted between being queued and being reached. Nothing here fetches, so the subtree
|
|
321
|
-
// is simply not selected; the clusters above it were already taken by whoever queued it.
|
|
322
|
-
continue;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
cut.groups_visited++;
|
|
326
|
-
touched.add(page_index);
|
|
327
|
-
|
|
328
|
-
const first = page.group_cluster_first[group];
|
|
329
|
-
const count = page.group_cluster_count[group];
|
|
330
|
-
|
|
331
|
-
for (let i = 0; i < count; i++) {
|
|
332
|
-
const id = first + i;
|
|
333
|
-
|
|
334
|
-
cut.clusters_tested++;
|
|
335
|
-
|
|
336
|
-
/*
|
|
337
|
-
Culling on `self_sphere` rather than on the tight `bounds_sphere`, because this decides
|
|
338
|
-
the subtree as well as the cluster: monotonicity makes a cluster's self sphere contain
|
|
339
|
-
every descendant's geometry, so a self sphere outside the frustum means nothing under
|
|
340
|
-
it can be on screen either.
|
|
341
|
-
*/
|
|
342
|
-
if (view.cull_enabled
|
|
343
|
-
&& sphere_outside_frustum(view.frustum, page.self_sphere, id * 4)) {
|
|
344
|
-
cut.culled++;
|
|
345
|
-
continue;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const child_ref = page.child_ref[id];
|
|
349
|
-
|
|
350
|
-
const self_px = project_error(
|
|
351
|
-
page.self_error[id], page.self_sphere, id * 4, view.eye, k
|
|
352
|
-
);
|
|
353
|
-
|
|
354
|
-
if (self_px <= view.tau || child_ref === VGEO_NO_CHILD) {
|
|
355
|
-
select(cut, page, id);
|
|
356
|
-
continue;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
if (child_ref !== VGEO_SAME_PAGE && child_ref >= page.child_page_index.length) {
|
|
360
|
-
cut.broken_child_refs++;
|
|
361
|
-
|
|
362
|
-
select(cut, page, id);
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
const child_page = child_ref === VGEO_SAME_PAGE
|
|
367
|
-
? page_index
|
|
368
|
-
: page.child_page_index[child_ref];
|
|
369
|
-
|
|
370
|
-
const child_group = page.child_group[id];
|
|
371
|
-
|
|
372
|
-
/*
|
|
373
|
-
*Selectable*, not resident — §10, and the difference is the whole of this file's
|
|
374
|
-
correctness. A group's parents are made by one simplification step but grouped for the
|
|
375
|
-
next one separately, so they can end up in different pages; refining into a group
|
|
376
|
-
because its own page arrived, while a page holding one of its other parents has not,
|
|
377
|
-
draws it underneath the coarse cluster still standing in for that parent. Both cover the
|
|
378
|
-
same surface and the depth buffer picks between them at random. `is_selectable` is the
|
|
379
|
-
counter that says the group's entire ancestor cone is here.
|
|
380
|
-
|
|
381
|
-
`SAME_PAGE` is asked the same question. Being in this page settles where the bytes are
|
|
382
|
-
and nothing about where the group's other parents live.
|
|
383
|
-
*/
|
|
384
|
-
if (reader.is_selectable(child_page, child_group)) {
|
|
385
|
-
push(stack, queued, child_page, child_group);
|
|
386
|
-
continue;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/*
|
|
390
|
-
The clamp. Drawing this cluster is not a fallback for a missing one — it is the correct
|
|
391
|
-
coarser surface over exactly the region the missing page would have refined, which is
|
|
392
|
-
what makes an arriving cut watertight at every moment rather than only at the end.
|
|
393
|
-
*/
|
|
394
|
-
cut.clamped++;
|
|
395
|
-
cut.clamped_keys.add(page_index * 65536 + id);
|
|
396
|
-
|
|
397
|
-
select(cut, page, id);
|
|
398
|
-
|
|
399
|
-
if (reader.is_resident(child_page)) {
|
|
400
|
-
/*
|
|
401
|
-
§10: a want naming a page that is already installed is an activation recheck, never
|
|
402
|
-
a fetch. There is nothing to ask for *here* — what this group is waiting on is a
|
|
403
|
-
page holding one of its other parents, and the format stores parent counts rather
|
|
404
|
-
than parent references precisely so that nobody has to name it. Another cluster in
|
|
405
|
-
this same traversal is clamped directly against that page and wants it, because
|
|
406
|
-
monotonicity puts every ancestor of a cluster projecting above τ above τ as well.
|
|
407
|
-
*/
|
|
408
|
-
cut.clamped_on_activation++;
|
|
409
|
-
continue;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
want(wants, page, child_ref, child_page, self_px);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
cut.wants = Array.from(wants.values()).sort((a, b) => b.priority - a.priority);
|
|
417
|
-
cut.pages_touched = touched.size;
|
|
418
|
-
cut.duration_ms = performance.now() - started;
|
|
419
|
-
|
|
420
|
-
return cut;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* @param {VGeoCut} cut
|
|
425
|
-
* @param {VGeoPage} page
|
|
426
|
-
* @param {number} cluster index within `page`
|
|
427
|
-
*/
|
|
428
|
-
function select(cut, page, cluster) {
|
|
429
|
-
cut.pages.push(page);
|
|
430
|
-
cut.clusters.push(cluster);
|
|
431
|
-
|
|
432
|
-
cut.triangle_count += page.triangle_count[cluster];
|
|
433
|
-
cut.vertex_count += page.vertex_count[cluster];
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* @param {number[]} stack
|
|
438
|
-
* @param {Set<number>} queued
|
|
439
|
-
* @param {number} page_index
|
|
440
|
-
* @param {number} group
|
|
441
|
-
*/
|
|
442
|
-
function push(stack, queued, page_index, group) {
|
|
443
|
-
const key = page_index * 65536 + group;
|
|
444
|
-
|
|
445
|
-
if (queued.has(key)) {
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
queued.add(key);
|
|
450
|
-
stack.push(page_index, group);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
/**
|
|
454
|
-
* Record — or reinforce — a want for the page a clamped cluster could not reach.
|
|
455
|
-
*
|
|
456
|
-
* Everything the fetch needs comes out of the child table of the page that is already here, which is
|
|
457
|
-
* the property (§5) that lets refinement cost one round trip and no metadata request.
|
|
458
|
-
*
|
|
459
|
-
* @param {Map<number, VGeoPageWant>} wants
|
|
460
|
-
* @param {VGeoPage} page the resident page holding the clamped cluster
|
|
461
|
-
* @param {number} child_ref index into that page's child table
|
|
462
|
-
* @param {number} child_page
|
|
463
|
-
* @param {number} projected pixels the clamped cluster's error came to
|
|
464
|
-
*/
|
|
465
|
-
function want(wants, page, child_ref, child_page, projected) {
|
|
466
|
-
let record = wants.get(child_page);
|
|
467
|
-
|
|
468
|
-
if (record === undefined) {
|
|
469
|
-
record = new VGeoPageWant();
|
|
470
|
-
|
|
471
|
-
record.page_index = child_page;
|
|
472
|
-
record.frame_offset = page.child_frame_offset[child_ref];
|
|
473
|
-
record.fetch_size = page.child_fetch_size[child_ref];
|
|
474
|
-
record.decoded_size = page.child_decoded_size[child_ref];
|
|
475
|
-
|
|
476
|
-
wants.set(child_page, record);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
record.reference_count++;
|
|
480
|
-
record.priority = Math.max(record.priority, projected);
|
|
481
|
-
}
|