@woosh/meep-engine 3.28.0 → 3.29.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/BitSet.d.ts +16 -0
- package/src/core/binary/BitSet.d.ts.map +1 -1
- package/src/core/binary/BitSet.js +159 -49
- package/src/core/binary/allocator/OffsetAllocator.d.ts +48 -0
- package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
- package/src/core/binary/allocator/OffsetAllocator.js +208 -9
- package/src/core/binary/compression/compress_bytes.d.ts +20 -0
- package/src/core/binary/compression/compress_bytes.d.ts.map +1 -0
- package/src/core/binary/compression/compress_bytes.js +35 -0
- package/src/core/binary/compression/decompress_bytes_into.d.ts +30 -0
- package/src/core/binary/compression/decompress_bytes_into.d.ts.map +1 -0
- package/src/core/binary/compression/decompress_bytes_into.js +87 -0
- package/src/core/binary/compression/deflate_decompress_bound.d.ts +27 -0
- package/src/core/binary/compression/deflate_decompress_bound.d.ts.map +1 -0
- package/src/core/binary/compression/deflate_decompress_bound.js +32 -0
- package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts +24 -0
- package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_add.js +31 -0
- package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts +46 -0
- package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_reduce.js +104 -0
- package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts +62 -0
- package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.js +158 -0
- package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts +21 -0
- package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_size.js +24 -0
- package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts +34 -0
- package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_solve.js +55 -0
- package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts +28 -0
- package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_sub.js +35 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +15 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +35 -0
- package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts +93 -0
- package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.js +128 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts +38 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +113 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +47 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +677 -8
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts +22 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.js +46 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts +19 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.js +49 -0
- package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts +63 -0
- package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts.map +1 -0
- package/src/core/graph/layout/layered/BoxLayoutOptions.js +80 -0
- package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.d.ts +35 -0
- package/src/core/graph/layout/layered/LayoutBoxGraph.d.ts.map +1 -0
- package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.js +53 -1
- package/src/core/graph/layout/layered/layout_assign_coordinates.d.ts.map +1 -0
- package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.js +72 -68
- package/src/core/graph/layout/layered/layout_assign_layers.d.ts.map +1 -0
- package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.js +4 -2
- package/src/core/graph/layout/layered/layout_break_cycles.d.ts.map +1 -0
- package/src/core/graph/layout/layered/layout_insert_lanes.d.ts.map +1 -0
- package/src/core/graph/layout/layered/layout_order_layers.d.ts.map +1 -0
- package/src/core/graph/layout/layered/layout_orient_links.d.ts.map +1 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +7 -51
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +8 -69
- package/src/core/model/node-graph/visual/layout/layout_build_problem.js +1 -1
- package/src/core/model/node-graph/visual/layout/layout_node_graph.js +6 -6
- package/src/core/model/node-graph/visual/layout/route_grid_build.js +1 -1
- package/src/engine/graphics3/DebugDrawSystem.d.ts +7 -5
- package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DebugDrawSystem.js +206 -203
- package/src/engine/graphics3/DecalSystem.d.ts +4 -5
- package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DecalSystem.js +5 -5
- package/src/engine/graphics3/FogOfWarSystem.d.ts +7 -12
- package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
- package/src/engine/graphics3/FogOfWarSystem.js +8 -12
- package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -230
- package/src/shade/RENDERER_CONTRACT.md +12 -7
- package/src/shade/playground/caldera/README.md +529 -0
- package/src/shade/playground/caldera/caldera_format.d.ts +151 -0
- package/src/shade/playground/caldera/caldera_format.d.ts.map +1 -0
- package/src/shade/playground/caldera/caldera_format.js +241 -0
- package/src/shade/playground/caldera/index.html +126 -0
- package/src/shade/playground/caldera/main.d.ts.map +1 -0
- package/src/shade/playground/caldera/main.js +1565 -0
- package/src/shade/playground/mesh_row_ceiling/README.md +85 -0
- package/src/shade/playground/mesh_row_ceiling/index.html +31 -0
- package/src/shade/playground/mesh_row_ceiling/main.d.ts +2 -0
- package/src/shade/playground/mesh_row_ceiling/main.d.ts.map +1 -0
- package/src/shade/playground/mesh_row_ceiling/main.js +389 -0
- package/src/shade/playground/vgeo_runtime/README.md +5 -3
- package/src/shade/playground/vgeo_runtime/main.js +3 -2
- package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +3 -3
- package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -1
- package/src/shade/playground/vgeo_runtime/sample_asset.js +3 -3
- package/src/shade/playground/vgeo_scene/README.md +103 -24
- package/src/shade/playground/vgeo_scene/main.js +525 -24
- package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
- package/src/shade/renderer/GraphicsContext.js +6 -0
- package/src/shade/renderer/Renderer.d.ts +2 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +23 -0
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +100 -8
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +69 -33
- package/src/shade/renderer/extension/RenderExtension.d.ts +15 -18
- package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
- package/src/shade/renderer/extension/RenderExtension.js +15 -19
- package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts +5 -5
- package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts.map +1 -1
- package/src/shade/renderer/extension/RenderExtensionRegistry.js +29 -166
- package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/GPUGeometryManager.js +73 -16
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +18 -3
- package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +663 -0
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +100 -5
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +688 -81
- package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +540 -0
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +155 -64
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +30 -13
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +3 -3
- package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +358 -0
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +57 -7
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +63 -9
- package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts +40 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js +24 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts +91 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.js +91 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts +24 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.js +25 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts +77 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.js +84 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +19 -6
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.js +20 -7
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts +19 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.js +58 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.js +116 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +545 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts +16 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +110 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +2 -27
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.js +120 -1564
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts +26 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js +123 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts +26 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js +78 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts +24 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +337 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +147 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts +37 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.js +243 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +117 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts +46 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.js +45 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +64 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +68 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +12 -7
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.js +33 -11
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts +58 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js +79 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts +39 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js +68 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts +53 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js +243 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +24 -8
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +250 -25
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +12 -8
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js +58 -50
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +8 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.js +18 -3
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts +38 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.js +81 -0
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +23 -5
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.js +28 -21
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.js +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +224 -60
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.js +17 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.js +19 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +10 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.js +103 -9
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +14 -2
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js +38 -14
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts +6 -2
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +28 -5
- package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts +32 -0
- package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.js +93 -0
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +20 -6
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +22 -8
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts +16 -0
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/attribute/{vgeo_layers_copy_vertex.js → vgeo_layers_copy_corner.js} +8 -8
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts +18 -7
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +19 -8
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.d.ts +3 -3
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +3 -3
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts +27 -0
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.js +97 -0
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts +7 -3
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +21 -11
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts +21 -0
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.js +41 -0
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +19 -1
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +20 -1
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts +25 -0
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.js +24 -0
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts +5 -0
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +5 -0
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +5 -0
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts +10 -3
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +37 -3
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +21 -13
- 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 +37 -13
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts +8 -2
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +14 -2
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +18 -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 +19 -1
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +6 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts +21 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.js +20 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +10 -1
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +1 -2
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +10 -3
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.js +43 -0
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +4 -2
- 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 +8 -4
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +2 -2
- package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts +6 -4
- package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.js +6 -4
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +13 -2
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +13 -2
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +5 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +14 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts +4 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.js +53 -11
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +7 -3
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts +12 -2
- 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 +111 -33
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts +6 -2
- 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 +112 -42
- package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts +2 -2
- 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 +51 -21
- package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +385 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +9 -0
- 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 +34 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +18 -0
- 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 +47 -19
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +22 -4
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +7 -2
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +8 -3
- 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 +10 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +13 -11
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +13 -11
- 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 +4 -0
- 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 +3 -4
- package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +6 -2
- package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +90 -12
- package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts +22 -0
- package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.js +21 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +13 -8
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -6
- 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 +4 -12
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
- 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 +4 -5
- 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 +5 -3
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js +11 -4
- 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 +4 -3
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +3 -0
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +94 -90
- 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 +13 -5
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +96 -89
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +3 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +4 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +100 -89
- package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +31 -7
- 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 +1 -7
- package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +161 -153
- 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 +2 -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 +4 -8
- 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 +5 -8
- package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +25 -0
- package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts.map +1 -0
- package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +24 -0
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +10 -0
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +30 -21
- package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +0 -1
- package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts +0 -61
- package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +0 -1
- package/src/shade/playground/vgeo_viewer/main.d.ts.map +0 -1
- package/src/shade/playground/vgeo_viewer/sample_asset.d.ts +0 -18
- package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +0 -1
- package/src/shade/playground/vgeo_viewer/select_cut.d.ts +0 -173
- package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts +0 -52
- package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts +0 -24
- package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts +0 -32
- package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts +0 -59
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts +0 -44
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts +0 -20
- package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts +0 -73
- package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +0 -13
- package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts +0 -12
- package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts +0 -36
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts +0 -13
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts +0 -19
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts +0 -29
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts +0 -31
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts +0 -18
- package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts +0 -14
- package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts +0 -12
- package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts +0 -14
- package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts +0 -11
- package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts +0 -46
- package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +0 -22
- package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts +0 -29
- package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts +0 -9
- package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts +0 -10
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts +0 -15
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts +0 -16
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts.map +0 -1
- package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts +0 -10
- package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +0 -17
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts +0 -3
- package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts +0 -8
- package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +0 -1
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.js +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.js +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.js +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.js +0 -0
- /package/src/shade/playground/{vgeo_viewer → caldera}/main.d.ts +0 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
# Wedges — plan, 2026-09-18
|
|
2
|
+
|
|
3
|
+
`ATTRIBUTE_PLAN_2026_09_18.md` §7, taken up. That plan fixed *how a coarse vertex is given its
|
|
4
|
+
shading values*; this one fixes the fact that a vertex can only hold **one set of them**, so every
|
|
5
|
+
hard edge and every texture seam in a source is destroyed before the builder has done anything at
|
|
6
|
+
all.
|
|
7
|
+
|
|
8
|
+
## 1. The defect, restated with its measurement
|
|
9
|
+
|
|
10
|
+
`BinaryTopology` carries one attribute record per vertex, and `bt_merge_vertices_by_distance` says
|
|
11
|
+
plainly what it does with that: *"Only considers distance, no other attributes are accounted for."*
|
|
12
|
+
`bt_vertex_replace` re-points references and orphans the victim's record.
|
|
13
|
+
|
|
14
|
+
Measured on a hard-edged, UV-charted subdivided box pushed through `vgeo_normalize_source`: 1,734
|
|
15
|
+
source vertices become 1,538, the 196 splits along the twelve cube edges are gone, and **six distinct
|
|
16
|
+
normals survive, every one of them axis-aligned** — the master's record won outright and nothing was
|
|
17
|
+
blended. Every hard edge now carries a normal 90° wrong for half the triangles using it, and each UV
|
|
18
|
+
chart bleeds across its seam. Before a single collapse.
|
|
19
|
+
|
|
20
|
+
The weld itself is not the defect and is not going anywhere. `vgeo_normalize_source` says why: without
|
|
21
|
+
it *"two triangles welded along a seam still look unrelated to every query downstream, and the
|
|
22
|
+
clusterer shreds the mesh along every UV seam it has."* Connectivity wants the weld. Appearance does
|
|
23
|
+
not.
|
|
24
|
+
|
|
25
|
+
**Second consequence, and it is the visible one on Zorah.** A source that authors no normals gets them
|
|
26
|
+
synthesized by area-weighted averaging with no crease rule, because there is nowhere to put a second
|
|
27
|
+
value at a corner. At LOD 0 the angle between a vertex's normal and its own face's normal runs to a
|
|
28
|
+
mean of 8.6°, a p99 of 37.7° and a **max of 179.9°**. That is the soft gradient smeared across flat
|
|
29
|
+
panels, and no amount of work above the leaf can undo it.
|
|
30
|
+
|
|
31
|
+
## 2. Loops are where this belongs, and the codebase already says so
|
|
32
|
+
|
|
33
|
+
`BinaryTopology` has had per-loop storage since it was written — `loop_data`, `loop_data_add_layer` —
|
|
34
|
+
and it has one real consumer, whose own documentation is the argument:
|
|
35
|
+
|
|
36
|
+
> UVs live on loops rather than vertices so that one geometric vertex shared by several charts carries
|
|
37
|
+
> a distinct UV per chart — which is exactly how a seam is represented.
|
|
38
|
+
> — `bt_loop_uv.js`
|
|
39
|
+
|
|
40
|
+
`bt_mesh_compact` already compacts loop data with everything else. So this is a mechanism to *use*,
|
|
41
|
+
not one to invent.
|
|
42
|
+
|
|
43
|
+
Two facts make it work through simplification:
|
|
44
|
+
|
|
45
|
+
- **Loop identity survives a collapse.** `bt_vertex_replace` re-points a surviving loop to the
|
|
46
|
+
survivor vertex and leaves the loop itself alone, so whatever a loop carries travels with it for
|
|
47
|
+
free. Loops of killed faces die, which is also correct — their corners no longer exist.
|
|
48
|
+
- **The payload encoder is already generic over it.** `vgeo_encode_cluster_payload(positions,
|
|
49
|
+
indices, vertex_ids, layers)` only ever does `layers[attribute].read(…, vertex_ids[v])`. Hand it
|
|
50
|
+
loop ids and loop layers and it is unchanged. The parameter is misnamed for that use and gets
|
|
51
|
+
renamed; nothing else about the encoder, the format, or the runtime moves.
|
|
52
|
+
|
|
53
|
+
## 3. The representation
|
|
54
|
+
|
|
55
|
+
A **wedge** is a maximal set of loops at one vertex that carry the same appearance. Three pieces:
|
|
56
|
+
|
|
57
|
+
| what | where | indexed by |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| attribute values | loop data layers | loop |
|
|
60
|
+
| wedge id | a `u32` loop data layer | loop |
|
|
61
|
+
| attribute quadrics | a flat `Float64Array` | wedge |
|
|
62
|
+
|
|
63
|
+
**The invariant, and it is what the specs hold:** every loop with the same wedge id carries
|
|
64
|
+
byte-identical attribute values. That makes the wedge id a *cache* of an equivalence that the values
|
|
65
|
+
themselves define, which is checkable rather than trusted.
|
|
66
|
+
|
|
67
|
+
> **What it became.** There is no `u32` loop layer, because a cache that can go stale is worse than
|
|
68
|
+
> the thing it caches and this one did not need to exist. The partition is *decided* in exactly one
|
|
69
|
+
> place — `vgeo_mesh_wedges`, at the leaf, reading byte equality of each corner's whole record, which
|
|
70
|
+
> is the invariant above applied directly — and **everywhere else it travels by provenance**, the way
|
|
71
|
+
> `source_vertex_ids` always has: the submesh gets its wedge ids from the frontier's, the stitch
|
|
72
|
+
> hands out the next frontier's, and an accumulated quadric crosses each seam by an id map. A
|
|
73
|
+
> `BtWedgeSet` holds a wedge id per *loop* that is never rewritten, a union-find that resolves it
|
|
74
|
+
> after a merge, and one intrusive list per vertex. Byte equality rather than a tolerance because an
|
|
75
|
+
> equivalence relation has to be transitive: a tolerance is not, so grouping by one would depend on
|
|
76
|
+
> the order the corners were walked in and two runs over the same mesh could disagree about it.
|
|
77
|
+
|
|
78
|
+
Why values per loop rather than per wedge with an indirection: the gather and the encoder both want a
|
|
79
|
+
value per corner, the duplication is bounded (`3F` records against `V`, so about six times, ~108 MB on
|
|
80
|
+
a million-triangle primitive against the 3.7 GB the build already peaks at), and an indirection at
|
|
81
|
+
that seam would have to be threaded through every consumer for nothing. Why quadrics per wedge rather
|
|
82
|
+
than per loop: a per-loop quadric only ever accumulates its own triangle, and a fit from one triangle
|
|
83
|
+
is exact and says nothing. The quadric's whole value is the history, and the history belongs to the
|
|
84
|
+
wedge.
|
|
85
|
+
|
|
86
|
+
**Geometric quadrics stay per vertex.** They are about position, position is the vertex's, and
|
|
87
|
+
`ATTRIBUTE_PLAN` §3's units guard depends on that set staying untouched.
|
|
88
|
+
|
|
89
|
+
## 4. What a collapse does
|
|
90
|
+
|
|
91
|
+
Today: the survivor's attribute record is fitted from its accumulated quadric at the new position.
|
|
92
|
+
|
|
93
|
+
With wedges, the same, once per wedge — plus the one new decision:
|
|
94
|
+
|
|
95
|
+
**When the victim's loops arrive at the survivor, which of them join a wedge that is already there?**
|
|
96
|
+
|
|
97
|
+
> **This section's answer is wrong, and the implementation does not use it.** Matching on attribute
|
|
98
|
+
> equality within a tolerance says that two wedges merge when their *values* agree — and two
|
|
99
|
+
> neighbours on a smoothly curved surface have genuinely different normals, so on a sphere it would
|
|
100
|
+
> refuse to merge almost every collapse and invent a crease at each one. The wedge count would grow
|
|
101
|
+
> without bound on exactly the content that has no seams in it at all.
|
|
102
|
+
>
|
|
103
|
+
> **What decides it is a live face.** Each face on the collapsing edge holds one corner at each
|
|
104
|
+
> endpoint and is about to die into the survivor, so those two corners are one corner's worth of
|
|
105
|
+
> surface afterwards; everything else the pair carries stays apart. Topological, exact, no tolerance
|
|
106
|
+
> anywhere, and it keeps every property listed below — on a smooth mesh every edge has its faces and
|
|
107
|
+
> every collapse merges the pair, so the whole thing still degenerates to the old behaviour exactly.
|
|
108
|
+
> A faceless edge is a fuse of two points rather than a simplification of a surface and is treated as
|
|
109
|
+
> one group; rare, and measured rather than assumed, at 6 of 6,195 collapses over a
|
|
110
|
+
> 12,288-triangle sphere's whole DAG.
|
|
111
|
+
>
|
|
112
|
+
> The **wedge count cannot grow** under that rule, which is what made the tolerance unnecessary
|
|
113
|
+
> rather than merely wrong. A vertex's wedges are the fans its creases cut its ring into; a manifold
|
|
114
|
+
> edge's two faces merge one pair each, so a smooth pair goes 1+1−1 = 1, a crease-to-crease pair
|
|
115
|
+
> 2+2−2 = 2, and a crease-to-smooth pair 2+1−1 = 2. The fan structure of the source is the ceiling,
|
|
116
|
+
> and the DAG still reaches one root because a cluster's triangle count keeps falling whatever its
|
|
117
|
+
> wedge count does.
|
|
118
|
+
|
|
119
|
+
Attribute equality, within a tolerance. Two wedges that describe the same appearance are one wedge;
|
|
120
|
+
two that do not stay two. This is Nanite's rule (`MeshSimplifier` matches corners by attribute
|
|
121
|
+
equality on a collapse) and it has the properties that matter:
|
|
122
|
+
|
|
123
|
+
- On a smooth mesh every wedge at a vertex is equal to every other, so there is exactly one, and the
|
|
124
|
+
whole thing degenerates to today's behaviour **exactly**. That is §6's first gate.
|
|
125
|
+
- A hard edge stays split as long as its two sides genuinely differ.
|
|
126
|
+
- It stays split *only* that long. Wedges that have converged merge, which is what stops the wedge
|
|
127
|
+
count from being a floor under how far the DAG can coarsen — and the builder has to reach a single
|
|
128
|
+
128-triangle root.
|
|
129
|
+
|
|
130
|
+
The tolerance is per channel and has precedent in this package:
|
|
131
|
+
`geometry_simplify_redundant_topology` already carries `normal_cosine_tolerance = 1e-3` and
|
|
132
|
+
`attribute_tolerance = 1e-5` for the same question asked of a different pass.
|
|
133
|
+
|
|
134
|
+
**Merging two wedges adds their quadrics**, which is the same operation a survivor already performs
|
|
135
|
+
on a victim's and needs nothing new.
|
|
136
|
+
|
|
137
|
+
## 5. Seam constraint planes
|
|
138
|
+
|
|
139
|
+
An attribute seam is a place where sliding *along* the surface destroys something the face-plane
|
|
140
|
+
quadric cannot see — which is the same situation an open boundary is in, and the same situation
|
|
141
|
+
`bt_mesh_compute_vertex_quadrics` already handles:
|
|
142
|
+
|
|
143
|
+
> for each open edge, add the plane through it perpendicular to its face
|
|
144
|
+
> — `add_boundary_constraints`, at `BOUNDARY_WEIGHT = 3`
|
|
145
|
+
|
|
146
|
+
An edge whose two loops on one side belong to a different wedge than the two on the other is a seam,
|
|
147
|
+
and it wants that same plane. This is the "boundary-plane-penalty mechanism" `VIRTUAL_GEOMETRY_DESIGN`
|
|
148
|
+
§2 named, reused rather than invented. It lands in §8's third stage, because it is an improvement to
|
|
149
|
+
where a seam vertex goes rather than a requirement for the seam to exist.
|
|
150
|
+
|
|
151
|
+
> **Not taken, and the reason is that it would be a second answer to a question already answered.**
|
|
152
|
+
> `ATTRIBUTE_PLAN_2026_09_18.md` put the attribute quadric's *reduction* into the placement solve and
|
|
153
|
+
> into the cost, so a collapse that would smear a seam is already both moved away from it and priced
|
|
154
|
+
> for it — in the metric, where it belongs, rather than as a penalty bolted onto the geometry. Adding
|
|
155
|
+
> planes to the **geometric** quadric would also inflate what `r_e` reports, and `r_e` is the one
|
|
156
|
+
> number the runtime's cut rule depends on; §3's units guard exists precisely to keep that set
|
|
157
|
+
> untouched by anything the attributes do. If a seam is later measured to drift, this is where to
|
|
158
|
+
> start — but it should be measured first.
|
|
159
|
+
|
|
160
|
+
## 6. Staging
|
|
161
|
+
|
|
162
|
+
Three stages, each with a gate that can fail.
|
|
163
|
+
|
|
164
|
+
### 6.1 — Attributes move to loops, one wedge per vertex — **DONE**
|
|
165
|
+
|
|
166
|
+
A pure refactor. Wedge id is derived from the vertex, so every vertex has exactly one wedge and
|
|
167
|
+
nothing about the output can change.
|
|
168
|
+
|
|
169
|
+
- `VirtualGeometryMesh.layers` are declared on `loop_data`.
|
|
170
|
+
- `vgeo_layers_declare` / `_like` / `_copy_vertex` become the loop-indexed equivalents.
|
|
171
|
+
- `vgeo_gather_faces` dedupes on `(vertex, wedge)` and returns a representative loop per output
|
|
172
|
+
vertex; `vgeo_encode_cluster_payload`'s third parameter is renamed to what it is.
|
|
173
|
+
- `vgeo_attribute_vector_{read,write}`, `bt_mesh_compute_vertex_attribute_quadrics` and the
|
|
174
|
+
simplifier index by wedge.
|
|
175
|
+
|
|
176
|
+
**Gate: the DAG is byte-identical**, and it very nearly is. `vgeo_build` is already proved
|
|
177
|
+
deterministic, so the container built before and after was hashed on five fixtures. A derived-attribute
|
|
178
|
+
sphere, a torus, a grid, **and a grid with authored normals and UVs** all match byte for byte. Zorah's
|
|
179
|
+
whole 450-primitive smoke run comes to the same 92.1 MiB it did before.
|
|
180
|
+
|
|
181
|
+
The one fixture that moves is a sphere whose source disagrees with *itself* — the wrap seam and the
|
|
182
|
+
poles, where two coincident vertices carry different UVs. There the weld picks an arbitrary winner
|
|
183
|
+
either way, and its choice moved. There was never a non-arbitrary one to preserve; that is the defect
|
|
184
|
+
§6.2 removes. **The seamless authored grid is what makes that claim precise rather than convenient**:
|
|
185
|
+
it has every channel, it goes through the same code, and it does not move.
|
|
186
|
+
|
|
187
|
+
Cost, measured on a 400,008-triangle Zorah primitive: **11.4 s to 11.9 s and 857 MiB to 934**. The
|
|
188
|
+
`3F` records against `V` is about six times the channel storage, arriving as 9% of a build that is
|
|
189
|
+
mostly not channels.
|
|
190
|
+
|
|
191
|
+
#### What it turned out to cost, that this plan did not foresee
|
|
192
|
+
|
|
193
|
+
Three things, each found by a gate rather than by reading:
|
|
194
|
+
|
|
195
|
+
1. **A pinned vertex is *written* now, and writing it is what keeps it pinned.** Pinning meant "leave
|
|
196
|
+
it alone", and under per-vertex storage leaving it alone left its value alone. Under corner
|
|
197
|
+
storage it does not: a collapse re-points the victim's corners onto the survivor and they arrive
|
|
198
|
+
carrying the victim's appearance. So the carried value goes back over every corner, pinned or not,
|
|
199
|
+
and what pinning now means is that nothing is *derived* — no renormalize, no re-orthogonalize.
|
|
200
|
+
2. **The tangent's handedness needed a vector of its own.** It is a flag no fit touches and no
|
|
201
|
+
derivation replaces, so a donated corner simply kept the one it arrived with. `vgeo_cut.spec.js`
|
|
202
|
+
caught it: one vertex of a cube-sphere came out of a cut with two different tangents in two
|
|
203
|
+
payloads. It now travels in a second, *verbatim* vector that the simplifier is never handed, so a
|
|
204
|
+
survivor's flag stays a survivor's. §4's "the survivor's flag is kept" was a sentence; it is now
|
|
205
|
+
a data structure.
|
|
206
|
+
3. **A byte-identity gate cannot see a quadratic.** Reading a vertex's appearance means naming one of
|
|
207
|
+
its corners, finding one means a pass over the loop pool, and `vgeo_extract_submesh` did that per
|
|
208
|
+
extraction — a pass over the whole frontier repeated once per part of it. 11.4 s became 47.7 s
|
|
209
|
+
with the output byte-identical throughout. The frontier holds the map now
|
|
210
|
+
(`vgeo_frontier_loop_of_vertex`). **Every stage below needs a timing reading, not only a
|
|
211
|
+
correctness one.**
|
|
212
|
+
|
|
213
|
+
### 6.2 — The source's splits become wedges — **DONE**
|
|
214
|
+
|
|
215
|
+
`vgeo_normalize_source` stops destroying them. The weld still runs and still welds *positions*; the
|
|
216
|
+
corners it re-points keep the values they arrived with, so a vertex the source split comes out of
|
|
217
|
+
normalization still split. `vgeo_layers_unify_corners` — the module written the day before purely so
|
|
218
|
+
the defect had a name and a line to delete — is deleted.
|
|
219
|
+
|
|
220
|
+
No loop has to remember which source vertex it came from, as this section supposed: it carries the
|
|
221
|
+
*values*, and `vgeo_mesh_wedges` reads the partition back off them.
|
|
222
|
+
|
|
223
|
+
- **Gate:** a box ships six normals and not a gradient. Every shipped corner normal on a subdivided
|
|
224
|
+
cube is within **2 degrees of a coordinate axis, at every level of the DAG**; take the split away
|
|
225
|
+
and it reads **54.7**, which is the diagonal of three faces averaged into one. That one number
|
|
226
|
+
separates the two behaviours without needing to know which face a vertex belongs to.
|
|
227
|
+
- **Gate:** a UV-charted box keeps each chart's coordinates on its own side of every seam — its
|
|
228
|
+
twelve triangles over eight points ship **24 vertices**, three per corner, one per chart. The
|
|
229
|
+
fixture needed fixing before it said that: with each face charted `0..1`, two of a corner's three
|
|
230
|
+
charts hand it the *same* coordinate, they are genuinely one wedge, and the answer is 20. Each face
|
|
231
|
+
into its own sixth of an atlas, as a real one would be, and it is 24.
|
|
232
|
+
- **Gate:** a smooth source produces exactly one wedge per vertex, asserted directly on a torus, and
|
|
233
|
+
6.1's byte-identity gate still passes on four of its five fixtures.
|
|
234
|
+
|
|
235
|
+
### 6.3 — Wedges merge through the collapse
|
|
236
|
+
|
|
237
|
+
§4's rule, plus §5's seam planes.
|
|
238
|
+
|
|
239
|
+
**6.2 and 6.3 have to land together.** Separately, 6.2 is a regression: the leaf would keep its splits
|
|
240
|
+
and the first group step would throw them away again, because the simplifier carries one value per
|
|
241
|
+
*vertex* and writes it over every corner. A DAG whose LOD 0 has hard edges and whose LOD 1 does not is
|
|
242
|
+
worse than one that never had them, and there is no honest place to stop between.
|
|
243
|
+
|
|
244
|
+
#### The shape the merge wants, sharpened by 6.1
|
|
245
|
+
|
|
246
|
+
- **Wedge ids are a `u32` loop layer**, assigned densely at the leaf by grouping each vertex's corners
|
|
247
|
+
on attribute equality. Values and quadrics are indexed by wedge.
|
|
248
|
+
- **Merging is per collapse, not a pass between them.** A pass at the end of a step would leave every
|
|
249
|
+
collapse *within* the step fitting from a quadric that never absorbed its victim's — the survivor's
|
|
250
|
+
wedge and the victim's would stay separate for thousands of collapses, and "conformance to the
|
|
251
|
+
source" is exactly the property that history carries.
|
|
252
|
+
- **Union-find over wedge ids** is what makes that cheap: merging is a union, the loop layer is never
|
|
253
|
+
rewritten, and lookups go through `find`. No corner has to be located to be re-pointed.
|
|
254
|
+
- **A `wedges_of_vertex` list per vertex** is what the collapse iterates: survivor's list against
|
|
255
|
+
victim's, matching on value within tolerance. **For a smooth mesh every list has length one**, so
|
|
256
|
+
the hot loop costs one comparison — which is what makes this affordable on content like Zorah,
|
|
257
|
+
where the wedge machinery has nothing to do.
|
|
258
|
+
- The tolerance has precedent in this package already: `geometry_simplify_redundant_topology` carries
|
|
259
|
+
`normal_cosine_tolerance = 1e-3` and `attribute_tolerance = 1e-5` for the same question asked of a
|
|
260
|
+
different pass.
|
|
261
|
+
|
|
262
|
+
Two passes stop being re-indexable and have to be **rewritten** rather than adjusted, and both say so
|
|
263
|
+
in their own source today: `vgeo_compute_vertex_tangents` (Lengyel's solve is per vertex and does not
|
|
264
|
+
become per corner by reading corners) and `vgeo_compute_vertex_normals` (which is where crease-angle
|
|
265
|
+
splitting goes, and is the whole of §1's second consequence).
|
|
266
|
+
|
|
267
|
+
- **Gate:** a hard-edged box converges to a single root — no wedge floor. It does, in 6 levels.
|
|
268
|
+
- **Gate:** it keeps its creases while it does — the 2-degree bound above is over *every* level, not
|
|
269
|
+
only the leaf.
|
|
270
|
+
- **Gate:** the crease-angle synthesis this unlocks. `vgeo_compute_vertex_normals` averages per
|
|
271
|
+
corner group, where a group is the connected run of faces a crease does not interrupt, and
|
|
272
|
+
`VGEO_CREASE_ANGLE` (also `VGeoBuildOptions#crease_angle`) is the threshold. It reproduces
|
|
273
|
+
`bt_mesh_compute_vertex_normals` step for step — Newell's normal out of a float32 scratch, summed
|
|
274
|
+
face-then-corner, scaled by a reciprocal — so a mesh **without** a crease comes out bit for bit
|
|
275
|
+
what it always did. That is not fastidiousness: without it every smooth fixture moved, for nothing,
|
|
276
|
+
and the gate could no longer tell a real change from a rounding one.
|
|
277
|
+
- **Gate:** `ATTRIBUTE_PLAN` §3's invariants all still hold. The seam identity test keys on
|
|
278
|
+
*position*, which is exact while every vertex has one wedge and is the wrong question the moment
|
|
279
|
+
one does not — a creased mesh ships two frames at one point **on purpose**. Its creased form is a
|
|
280
|
+
bound instead: a point of a box ships at most one frame per plane it touches, over the whole DAG,
|
|
281
|
+
so a fit that drifted or a level that disagreed with the level below shows up as a fourth.
|
|
282
|
+
|
|
283
|
+
#### What it cost
|
|
284
|
+
|
|
285
|
+
**Measured, on Zorah's 203 primitives of at most 5,000 triangles, every one of which built and
|
|
286
|
+
validated before and after.** 12.1 MiB stored becomes 13.0 (+7.4%), 14.1 MiB decoded becomes 16.5
|
|
287
|
+
(+17%), and the conversion runs 13.5 s against 15.3. That is the price of a hard edge and it is not
|
|
288
|
+
an overhead: a shipped vertex is a *wedge*, and small architectural props are mostly creases.
|
|
289
|
+
|
|
290
|
+
The clearest statement of it is the scattered-cube fixture. A cube is eight vertices and **twenty-four
|
|
291
|
+
shading vertices**, so 200 of them cut into 40 leaves where they cut into a dozen before — 4,800
|
|
292
|
+
wedges against a 128-vertex meshlet ceiling cannot be fewer than 38 clusters however well they are
|
|
293
|
+
packed. The DAG still closes, in 7 levels over 9 pages.
|
|
294
|
+
|
|
295
|
+
Against the *level loop* alone, with no channels changed, there is nothing to pay: paired A/B over an
|
|
296
|
+
81,920-triangle sphere, alternating which tree runs first, is 2,697 ms before and 2,664 after.
|
|
297
|
+
|
|
298
|
+
## 7. What does not change
|
|
299
|
+
|
|
300
|
+
- **The container format.** No new fields, no version move. A wedge is a builder concept; what ships
|
|
301
|
+
is what has always shipped, a value per cluster-local vertex.
|
|
302
|
+
- **The runtime.** Nothing on the device knows what a wedge is.
|
|
303
|
+
- **The cut rule and `r_e`.** Geometric quadrics stay per vertex and stay the only thing an error is
|
|
304
|
+
reported from.
|
|
305
|
+
- **The weld.** Positions still fuse at `weld_ratio`; connectivity is what that is for.
|
|
306
|
+
- **Vertex counts in the *topology*.** A wedge does not add a vertex. It adds an output vertex at
|
|
307
|
+
gather time, which is where a seam has always cost one.
|
|
308
|
+
|
|
309
|
+
## 8. Rejected
|
|
310
|
+
|
|
311
|
+
- **Stop welding attribute-distinct vertices.** The obvious move and the wrong one:
|
|
312
|
+
`vgeo_normalize_source` already records what it costs — the clusterer shreds the mesh along every
|
|
313
|
+
seam, because face adjacency is read off radial cycles and two triangles across an unfused seam
|
|
314
|
+
look unrelated. Weld for connectivity; split for appearance. They are different questions and the
|
|
315
|
+
answer has to be different.
|
|
316
|
+
- **A per-vertex list of wedges with a loop→index.** The same thing as a wedge id on the loop, with an
|
|
317
|
+
extra structure to keep in step and nothing bought.
|
|
318
|
+
- **Wedges fixed at the leaf, never merged.** No tolerance to choose, and a floor under the DAG at
|
|
319
|
+
whatever the source's seam count happens to be. The builder must reach one root.
|
|
320
|
+
- **Deduping only at gather, with no wedge in the simplifier.** Values would travel correctly and the
|
|
321
|
+
quadrics would not: each loop would accumulate its own triangle and nothing else, and a fit from one
|
|
322
|
+
triangle is exact and worthless.
|
|
323
|
+
|
|
324
|
+
## 9. Review ledger
|
|
325
|
+
|
|
326
|
+
### 6.1
|
|
327
|
+
|
|
328
|
+
| # | finding | resolution |
|
|
329
|
+
|---|---|---|
|
|
330
|
+
| 1 | Moving the channels onto corners cost 4.2x the build time — `vgeo_extract_submesh` scanned the whole frontier's loop pool once per group | The frontier holds the map. 47.7 s back to 11.9. **The output was byte-identical the whole time**, which is the finding behind the finding: correctness gates are blind to this and every later stage needs a timing reading of its own. |
|
|
331
|
+
| 2 | A pinned vertex's corners could be a collapse's donations, so "leave it alone" stopped meaning "leave its value alone" | It is written, with the value it already had; what pinning means is that nothing is *derived* for it. |
|
|
332
|
+
| 3 | The tangent's handedness is fitted by nothing and derived by nothing, so a donated corner kept the flag it arrived with — and a cut disagreed with itself | A second, verbatim vector the simplifier is never handed. Caught by `vgeo_cut.spec.js`, which existed. |
|
|
333
|
+
| 4 | `vgeo_layers_unify_corners` claimed two call sites | One. The collapse path stopped needing it when 2 landed, and the doc had not caught up. |
|
|
334
|
+
| 5 | The layer-declaration comment still talked about vertices | Loops, and three records per triangle rather than one per vertex. |
|
|
335
|
+
| 6 | `vgeo_stitch_frontier`'s comment claimed "a handful of topologies" | One per group plus the frontier, which sums to a pass over the round. The cost was right; the description was not. |
|
|
336
|
+
|
|
337
|
+
`check-types` at budget: declarations emit clean, the consumer program reports 19, all in the
|
|
338
|
+
documented set, none in a file this touched. Zorah's smoke: 450 of 450, every container audited,
|
|
339
|
+
92.1 MiB — the same byte count as before.
|
|
340
|
+
|
|
341
|
+
### 6.2 and 6.3
|
|
342
|
+
|
|
343
|
+
| # | finding | resolution |
|
|
344
|
+
|---|---|---|
|
|
345
|
+
| 1 | §4's merge rule is wrong. Matching wedges on **attribute equality within a tolerance** means two neighbours on a curved surface — whose normals genuinely differ — refuse to merge, so a sphere would gain a crease at every collapse and the wedge count would grow without bound on content with no seams at all | A live face decides it instead: each face on the collapsing edge holds one corner at each endpoint and is about to die into the survivor, so those two are one corner's worth of surface. Topological, exact, no tolerance anywhere. And it made the tolerance *unnecessary* as well as wrong — the fan arithmetic in §4 shows the wedge count cannot grow, which was the thing the tolerance was there to prevent. |
|
|
346
|
+
| 2 | §3's `u32` wedge-id loop layer is a cache of the values, and a cache that can go stale | Deleted before it was written. The partition is decided in exactly one place, from the values themselves, and travels by provenance everywhere else — the way `source_vertex_ids` always has. Byte equality rather than a tolerance, because an equivalence relation must be transitive or the partition depends on the order corners were walked in. |
|
|
347
|
+
| 3 | **A set that is not maintained is a set whose ids go stale.** The wedge set lived inside the `attributes` bundle, so a mesh with no channels carried none, and a victim's loops arrived at the survivor still naming the victim's wedge | It is its own argument to the simplifier and is merged whether or not values ride on it. **The byte-identity gate saw nothing**: the containers matched throughout, and what caught it was an unrelated ceiling assertion — clusters of 132 vertices against a cap of 128. |
|
|
348
|
+
| 4 | Two ceilings counted the wrong thing. `VGeoFaceGraph.count_unique_vertices` and the bin packer's `unique_vertices` both fed the meshlet's 128-vertex limit a count of **mesh vertices**, where a meshlet carries one record per wedge | Both count wedges. Found by a hard-edged fixture at 240 against 128 — and the two had to be fixed separately, because the second is the packer's own and the first only bounds the pieces going into it. |
|
|
349
|
+
| 5 | The crease pass reimplemented the face normal as a cross product, so every smooth fixture moved for no reason and the gate could no longer tell a real change from a rounding one | It reproduces `bt_mesh_compute_vertex_normals` step for step: Newell's normal out of a float32 scratch, summed face-then-corner, scaled by a reciprocal rather than divided. Four of the five fixtures went back to byte-identical, and the one that moves is the one with a real seam in it. |
|
|
350
|
+
| 6 | The UV-chart gate asserted 24 shipped vertices and got 20 | The fixture, not the builder. With every face charted `0..1`, two of a corner's three charts hand it the same coordinate — they *are* one wedge and 20 is right. Each face into its own sixth of an atlas, as a real one would be. |
|
|
351
|
+
| 7 | The seam identity test keys on position, which a creased mesh is entitled to break: two frames at one point is what a hard edge **is** | Said so where the test is, and asked the creased form of the question separately — a point of a box ships at most one frame per plane it touches, over the whole DAG. |
|
|
352
|
+
| 8 | The scattered-cube test expected fewer than 40 leaves and got exactly 40 | Not a regression to hide: a cube is eight vertices and twenty-four shading vertices, and 4,800 wedges cannot pack below 38 clusters. The expectation carries the arithmetic now. |
|
|
353
|
+
| 9 | **A third place counting the wrong thing**, found by going looking for it after the first two: `vgeo_build_group_step`'s overshoot heuristic divides `topology.vertices.count()` by the meshlet vertex ceiling to decide how far to tighten its target | `bt_wedges_live_count`. Only a heuristic — the gate is the re-cut's own cluster count — but one that reads low at every crease, so the step aims at a target it has already missed and can give up a group it could have simplified. The lesson is the pattern rather than the line: **every ceiling that says "vertices" means wedges**, and there were three. |
|
|
354
|
+
| 10 | The cost model and the collapse disagreed about a faceless edge. `reduce_pair_attributes` unioned *everything* into one group; `carry_wedges` merged only the victim's wedges into the survivor's first, leaving the survivor's others alone | The cost model follows the collapse. It is 0.1% of collapses and a heuristic either way, but a price that is not the price of the collapse that happens is a bug waiting for someone to trust it. |
|
|
355
|
+
| 11 | **A timing harness read a 1.57x regression that did not exist.** It built its sphere by hand and never called `vgeo_normalize_source`, so the mesh kept its raw wrap seam and its degenerate poles — and the two trees then built *different DAGs*, 39 levels against 19. It was comparing two different builds and reporting the difference as a cost | Through the real path: **13 levels and 1,710 clusters on both**, median 2,294 ms against 2,405, and identical retained heap. Which is the same +3 to 5% the Zorah conversion measures over 3,095,102 triangles. The rule the §6.1 review wrote — take a timing reading at every stage — needs a second half: *take it through the pipeline the asset goes through*, or the reading is of something else. |
|
|
356
|
+
|
|
357
|
+
`check-types` at budget: declarations emit clean, the consumer program reports 19, all in the
|
|
358
|
+
documented set, none in a file this touched.
|
|
@@ -6,20 +6,36 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export class VGeoBuildOptions {
|
|
8
8
|
/**
|
|
9
|
-
* Which codec page blobs are stored under — {@link VGEO_CODEC_RAW}
|
|
10
|
-
* Compressed by default, and there is no case where turning it off
|
|
11
|
-
* encoder stores a page raw whenever compressing it would not shrink
|
|
9
|
+
* Which codec page blobs are stored under — {@link VGEO_CODEC_RAW}, {@link VGEO_CODEC_LZ4} or
|
|
10
|
+
* {@link VGEO_CODEC_DEFLATE}. Compressed by default, and there is no case where turning it off
|
|
11
|
+
* makes a file smaller: the encoder stores a page raw whenever compressing it would not shrink
|
|
12
|
+
* it, per page.
|
|
12
13
|
*
|
|
13
|
-
* What it costs a reader is one
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* What it costs a reader is one block decode per page installed, into the buffer the page was
|
|
15
|
+
* going to be copied into anyway. What it saves is transfer and disk on every fetch of every
|
|
16
|
+
* page, forever.
|
|
17
|
+
*
|
|
18
|
+
* **Deflate, because a build happens once and a fetch happens forever.** It is the denser of
|
|
19
|
+
* the two compressing codecs — 1.369x against LZ4's 1.295x over the pages of a 240x120 torus,
|
|
20
|
+
* 1.48x against 1.38x over a 6,016-triangle sphere — and the bytes it saves are saved on every
|
|
21
|
+
* fetch of every page by every client, for the life of the asset. What it costs is decode:
|
|
22
|
+
* 126 MB/s of decoded output against LZ4's 562, about four and a half times, and that lands on
|
|
23
|
+
* the residency path where it is the arrival cost of a page. `VGEO_CODEC_LZ4` is the setting for a
|
|
24
|
+
* container whose pages arrive while someone is looking at it, and it is one line away.
|
|
25
|
+
*
|
|
26
|
+
* Choosing it here is a choice about *readers*, not about the format: a codec id is a per-asset
|
|
27
|
+
* capability gate (`VGEO_FORMAT.md` §5), so a container built under this default opens only in
|
|
28
|
+
* a reader that carries the deflate decoder. `format_version` does not move, and an older
|
|
29
|
+
* reader refuses the asset rather than misreading it.
|
|
16
30
|
*
|
|
17
31
|
* @type {number}
|
|
18
32
|
*/
|
|
19
33
|
codec: number;
|
|
20
34
|
/**
|
|
21
35
|
* How hard the codec looks for matches, from {@link LZ4_LEVEL}. Nine by default, which is the
|
|
22
|
-
* top of the reference's hash-chain levels.
|
|
36
|
+
* top of the reference's hash-chain levels. **LZ4 only, and the default codec is not LZ4** —
|
|
37
|
+
* `CompressionStream` exposes no level, so this does nothing at all unless {@link codec} was
|
|
38
|
+
* set to {@link VGEO_CODEC_LZ4}.
|
|
23
39
|
*
|
|
24
40
|
* **It changes nothing about the file.** Every level writes the same LZ4 block format, so a
|
|
25
41
|
* container built at any of them reads in every build of the reader that exists; the level is
|
|
@@ -65,6 +81,19 @@ export class VGeoBuildOptions {
|
|
|
65
81
|
* @type {number}
|
|
66
82
|
*/
|
|
67
83
|
weld_ratio: number;
|
|
84
|
+
/**
|
|
85
|
+
* How far two triangles may turn across a shared edge before a **synthesized** normal is split
|
|
86
|
+
* there rather than averaged, in degrees. See {@link VGEO_CREASE_ANGLE}, which is where the
|
|
87
|
+
* default and the measurement behind it live.
|
|
88
|
+
*
|
|
89
|
+
* A build option rather than only a constant because it is the one number in this work that is a
|
|
90
|
+
* judgement about content rather than a consequence of arithmetic: a source of hard-surface
|
|
91
|
+
* props and a source of organic scans want different answers, and a conversion should be able to
|
|
92
|
+
* say which it has.
|
|
93
|
+
*
|
|
94
|
+
* @type {number}
|
|
95
|
+
*/
|
|
96
|
+
crease_angle: number;
|
|
68
97
|
/**
|
|
69
98
|
* Decoded bytes per page, as a **hard cap**: no page of the asset exceeds it, and the container
|
|
70
99
|
* says so with a feature bit a runtime can require (`VGEO_FORMAT.md` §11.14). That is what makes
|
|
@@ -81,6 +110,27 @@ export class VGeoBuildOptions {
|
|
|
81
110
|
* @type {number}
|
|
82
111
|
*/
|
|
83
112
|
nominal_page_size: number;
|
|
113
|
+
/**
|
|
114
|
+
* How much a full unit of each shading channel is worth in object-space position error, as a
|
|
115
|
+
* **fraction of the geometry's own bounding-box diagonal** — one entry per
|
|
116
|
+
* {@link VGEO_ATTRIBUTES} channel, position's ignored.
|
|
117
|
+
*
|
|
118
|
+
* This is the number that makes the simplifier's metric mean anything. An attribute's gradient
|
|
119
|
+
* is *attribute per length*, so the error it contributes is dimensionless while the geometric
|
|
120
|
+
* error beside it is a squared length; adding them without saying how they compare would let the
|
|
121
|
+
* arbitrary range a channel happens to use decide how much the surface is allowed to move. The
|
|
122
|
+
* weight is that statement, and {@link vgeo_resolve_attribute_weights} is where it is made.
|
|
123
|
+
*
|
|
124
|
+
* A ratio rather than a distance for the same reason {@link weld_ratio} is: a conversion is many
|
|
125
|
+
* geometries at many sizes, and a fixed distance right for a doorknob is wrong for a cathedral.
|
|
126
|
+
*
|
|
127
|
+
* The defaults are {@link VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS}, which says what they were
|
|
128
|
+
* measured against. Raising one buys fidelity in that channel at the price of geometric error,
|
|
129
|
+
* and the exchange rate is exactly what the number says it is.
|
|
130
|
+
*
|
|
131
|
+
* @type {number[]}
|
|
132
|
+
*/
|
|
133
|
+
attribute_weight_ratios: number[];
|
|
84
134
|
/**
|
|
85
135
|
* @type {VGeoLevelOptions}
|
|
86
136
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VGeoBuildOptions.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VGeoBuildOptions.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH;IACI;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,OAFU,MAAM,CAEW;IAE3B;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAFU,MAAM,CAEmB;IAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,YAFU,MAAM,CAEE;IAElB;;;;;;;;;;;OAWG;IACH,cAFU,MAAM,CAEiB;IAEjC;;;;;;;;;;;;;;OAcG;IACH,mBAFU,MAAM,CAE2B;IAE3C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,yBAFU,MAAM,EAAE,CAEqD;IAEvE;;OAEG;IACH,eAFU,gBAAgB,CAEa;CAC1C;iCAjJgC,6BAA6B"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { VGEO_CREASE_ANGLE } from "./mesh/VGEO_CREASE_ANGLE.js";
|
|
1
2
|
import { LZ4_LEVEL } from "../../../../../core/binary/lz4/LZ4_LEVEL.js";
|
|
2
|
-
import {
|
|
3
|
+
import { VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS } from "./mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js";
|
|
4
|
+
import { VGEO_CODEC_DEFLATE } from "../format/frame/VGEO_CODEC_DEFLATE.js";
|
|
3
5
|
import { VGEO_DEFAULT_PAGE_SIZE } from "../format/page/VGEO_DEFAULT_PAGE_SIZE.js";
|
|
4
6
|
import { VGeoLevelOptions } from "./level/VGeoLevelOptions.js";
|
|
5
7
|
|
|
@@ -11,21 +13,37 @@ import { VGeoLevelOptions } from "./level/VGeoLevelOptions.js";
|
|
|
11
13
|
*/
|
|
12
14
|
export class VGeoBuildOptions {
|
|
13
15
|
/**
|
|
14
|
-
* Which codec page blobs are stored under — {@link VGEO_CODEC_RAW}
|
|
15
|
-
* Compressed by default, and there is no case where turning it off
|
|
16
|
-
* encoder stores a page raw whenever compressing it would not shrink
|
|
16
|
+
* Which codec page blobs are stored under — {@link VGEO_CODEC_RAW}, {@link VGEO_CODEC_LZ4} or
|
|
17
|
+
* {@link VGEO_CODEC_DEFLATE}. Compressed by default, and there is no case where turning it off
|
|
18
|
+
* makes a file smaller: the encoder stores a page raw whenever compressing it would not shrink
|
|
19
|
+
* it, per page.
|
|
17
20
|
*
|
|
18
|
-
* What it costs a reader is one
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
+
* What it costs a reader is one block decode per page installed, into the buffer the page was
|
|
22
|
+
* going to be copied into anyway. What it saves is transfer and disk on every fetch of every
|
|
23
|
+
* page, forever.
|
|
24
|
+
*
|
|
25
|
+
* **Deflate, because a build happens once and a fetch happens forever.** It is the denser of
|
|
26
|
+
* the two compressing codecs — 1.369x against LZ4's 1.295x over the pages of a 240x120 torus,
|
|
27
|
+
* 1.48x against 1.38x over a 6,016-triangle sphere — and the bytes it saves are saved on every
|
|
28
|
+
* fetch of every page by every client, for the life of the asset. What it costs is decode:
|
|
29
|
+
* 126 MB/s of decoded output against LZ4's 562, about four and a half times, and that lands on
|
|
30
|
+
* the residency path where it is the arrival cost of a page. `VGEO_CODEC_LZ4` is the setting for a
|
|
31
|
+
* container whose pages arrive while someone is looking at it, and it is one line away.
|
|
32
|
+
*
|
|
33
|
+
* Choosing it here is a choice about *readers*, not about the format: a codec id is a per-asset
|
|
34
|
+
* capability gate (`VGEO_FORMAT.md` §5), so a container built under this default opens only in
|
|
35
|
+
* a reader that carries the deflate decoder. `format_version` does not move, and an older
|
|
36
|
+
* reader refuses the asset rather than misreading it.
|
|
21
37
|
*
|
|
22
38
|
* @type {number}
|
|
23
39
|
*/
|
|
24
|
-
codec =
|
|
40
|
+
codec = VGEO_CODEC_DEFLATE;
|
|
25
41
|
|
|
26
42
|
/**
|
|
27
43
|
* How hard the codec looks for matches, from {@link LZ4_LEVEL}. Nine by default, which is the
|
|
28
|
-
* top of the reference's hash-chain levels.
|
|
44
|
+
* top of the reference's hash-chain levels. **LZ4 only, and the default codec is not LZ4** —
|
|
45
|
+
* `CompressionStream` exposes no level, so this does nothing at all unless {@link codec} was
|
|
46
|
+
* set to {@link VGEO_CODEC_LZ4}.
|
|
29
47
|
*
|
|
30
48
|
* **It changes nothing about the file.** Every level writes the same LZ4 block format, so a
|
|
31
49
|
* container built at any of them reads in every build of the reader that exists; the level is
|
|
@@ -73,6 +91,20 @@ export class VGeoBuildOptions {
|
|
|
73
91
|
*/
|
|
74
92
|
weld_ratio = 1e-5;
|
|
75
93
|
|
|
94
|
+
/**
|
|
95
|
+
* How far two triangles may turn across a shared edge before a **synthesized** normal is split
|
|
96
|
+
* there rather than averaged, in degrees. See {@link VGEO_CREASE_ANGLE}, which is where the
|
|
97
|
+
* default and the measurement behind it live.
|
|
98
|
+
*
|
|
99
|
+
* A build option rather than only a constant because it is the one number in this work that is a
|
|
100
|
+
* judgement about content rather than a consequence of arithmetic: a source of hard-surface
|
|
101
|
+
* props and a source of organic scans want different answers, and a conversion should be able to
|
|
102
|
+
* say which it has.
|
|
103
|
+
*
|
|
104
|
+
* @type {number}
|
|
105
|
+
*/
|
|
106
|
+
crease_angle = VGEO_CREASE_ANGLE;
|
|
107
|
+
|
|
76
108
|
/**
|
|
77
109
|
* Decoded bytes per page, as a **hard cap**: no page of the asset exceeds it, and the container
|
|
78
110
|
* says so with a feature bit a runtime can require (`VGEO_FORMAT.md` §11.14). That is what makes
|
|
@@ -90,6 +122,28 @@ export class VGeoBuildOptions {
|
|
|
90
122
|
*/
|
|
91
123
|
nominal_page_size = VGEO_DEFAULT_PAGE_SIZE;
|
|
92
124
|
|
|
125
|
+
/**
|
|
126
|
+
* How much a full unit of each shading channel is worth in object-space position error, as a
|
|
127
|
+
* **fraction of the geometry's own bounding-box diagonal** — one entry per
|
|
128
|
+
* {@link VGEO_ATTRIBUTES} channel, position's ignored.
|
|
129
|
+
*
|
|
130
|
+
* This is the number that makes the simplifier's metric mean anything. An attribute's gradient
|
|
131
|
+
* is *attribute per length*, so the error it contributes is dimensionless while the geometric
|
|
132
|
+
* error beside it is a squared length; adding them without saying how they compare would let the
|
|
133
|
+
* arbitrary range a channel happens to use decide how much the surface is allowed to move. The
|
|
134
|
+
* weight is that statement, and {@link vgeo_resolve_attribute_weights} is where it is made.
|
|
135
|
+
*
|
|
136
|
+
* A ratio rather than a distance for the same reason {@link weld_ratio} is: a conversion is many
|
|
137
|
+
* geometries at many sizes, and a fixed distance right for a doorknob is wrong for a cathedral.
|
|
138
|
+
*
|
|
139
|
+
* The defaults are {@link VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS}, which says what they were
|
|
140
|
+
* measured against. Raising one buys fidelity in that channel at the price of geometric error,
|
|
141
|
+
* and the exchange rate is exactly what the number says it is.
|
|
142
|
+
*
|
|
143
|
+
* @type {number[]}
|
|
144
|
+
*/
|
|
145
|
+
attribute_weight_ratios = VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.slice();
|
|
146
|
+
|
|
93
147
|
/**
|
|
94
148
|
* @type {VGeoLevelOptions}
|
|
95
149
|
*/
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One cluster's geometry expressed against the frontier it came out of, which is what lets the next
|
|
3
|
+
* frontier be stitched from a mixture of freshly simplified clusters and untouched ones.
|
|
4
|
+
*
|
|
5
|
+
* Produced by `vgeo_try_repack`, `vgeo_build_group_step` and `vgeo_build_levels` — the last for
|
|
6
|
+
* the clusters a round left alone — and consumed by `vgeo_stitch_frontier`, which is the only
|
|
7
|
+
* thing that ever reads one.
|
|
8
|
+
*/
|
|
9
|
+
type VGeoContribution = {
|
|
10
|
+
positions: Float32Array;
|
|
11
|
+
/**
|
|
12
|
+
* local to {@link positions }
|
|
13
|
+
*/
|
|
14
|
+
indices: Uint32Array;
|
|
15
|
+
/**
|
|
16
|
+
* ids in the mesh {@link topology } belongs to; not
|
|
17
|
+
* unique, because there is one entry per *wedge* and a seam vertex is several
|
|
18
|
+
*/
|
|
19
|
+
local_vertex_ids: Uint32Array;
|
|
20
|
+
/**
|
|
21
|
+
* the same vertices, named in the frontier's mesh
|
|
22
|
+
*/
|
|
23
|
+
source_vertex_ids: Uint32Array;
|
|
24
|
+
/**
|
|
25
|
+
* one corner of {@link topology } per entry, which is where
|
|
26
|
+
* that entry's appearance is read from — a vertex alone does not address it
|
|
27
|
+
*/
|
|
28
|
+
attribute_ids: Uint32Array;
|
|
29
|
+
/**
|
|
30
|
+
* the wedge each entry is, named in the frontier's mesh,
|
|
31
|
+
* which is how its accumulated attribute quadric follows it across the seam
|
|
32
|
+
*/
|
|
33
|
+
source_wedge_ids: Uint32Array;
|
|
34
|
+
/**
|
|
35
|
+
* the mesh {@link local_vertex_ids } name vertices of, whose
|
|
36
|
+
* loop data block holds their attributes
|
|
37
|
+
*/
|
|
38
|
+
topology: BinaryTopology;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=VGeoContribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VGeoContribution.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js"],"names":[],"mappings":";;;;;;;;;eASc,YAAY;;;;aACZ,WAAW;;;;;sBACX,WAAW;;;;uBAEX,WAAW;;;;;mBACX,WAAW;;;;;sBAEX,WAAW"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One cluster's geometry expressed against the frontier it came out of, which is what lets the next
|
|
3
|
+
* frontier be stitched from a mixture of freshly simplified clusters and untouched ones.
|
|
4
|
+
*
|
|
5
|
+
* Produced by `vgeo_try_repack`, `vgeo_build_group_step` and `vgeo_build_levels` — the last for
|
|
6
|
+
* the clusters a round left alone — and consumed by `vgeo_stitch_frontier`, which is the only
|
|
7
|
+
* thing that ever reads one.
|
|
8
|
+
*
|
|
9
|
+
* @typedef {object} VGeoContribution
|
|
10
|
+
* @property {Float32Array} positions
|
|
11
|
+
* @property {Uint32Array} indices local to {@link positions}
|
|
12
|
+
* @property {Uint32Array} local_vertex_ids ids in the mesh {@link topology} belongs to; not
|
|
13
|
+
* unique, because there is one entry per *wedge* and a seam vertex is several
|
|
14
|
+
* @property {Uint32Array} source_vertex_ids the same vertices, named in the frontier's mesh
|
|
15
|
+
* @property {Uint32Array} attribute_ids one corner of {@link topology} per entry, which is where
|
|
16
|
+
* that entry's appearance is read from — a vertex alone does not address it
|
|
17
|
+
* @property {Uint32Array} source_wedge_ids the wedge each entry is, named in the frontier's mesh,
|
|
18
|
+
* which is how its accumulated attribute quadric follows it across the seam
|
|
19
|
+
* @property {BinaryTopology} topology the mesh {@link local_vertex_ids} name vertices of, whose
|
|
20
|
+
* loop data block holds their attributes
|
|
21
|
+
*
|
|
22
|
+
* @author Alex Goldring
|
|
23
|
+
* @copyright Company Named Limited (c) 2026
|
|
24
|
+
*/
|