@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
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { assert } from "../../../../../../assert.js";
|
|
2
2
|
import { Uint32Heap } from "../../../../../../collection/heap/Uint32Heap.js";
|
|
3
3
|
import { Quadric3 } from "../../../../quadric/Quadric3.js";
|
|
4
|
+
import { QUADRIC3_SIZE } from "../../../../quadric/QUADRIC3_SIZE.js";
|
|
5
|
+
import { quadric3_add } from "../../../../quadric/quadric3_add.js";
|
|
6
|
+
import { quadric3_evaluate } from "../../../../quadric/quadric3_evaluate.js";
|
|
7
|
+
import { quadric_attribute_add } from "../../../../quadric/quadric_attribute_add.js";
|
|
8
|
+
import { quadric_attribute_reduce } from "../../../../quadric/quadric_attribute_reduce.js";
|
|
9
|
+
import { quadric_attribute_size } from "../../../../quadric/quadric_attribute_size.js";
|
|
10
|
+
import { quadric_attribute_solve } from "../../../../quadric/quadric_attribute_solve.js";
|
|
4
11
|
import { NULL_POINTER } from "../BinaryTopology.js";
|
|
5
12
|
import { bt_edge_collapse_would_fold } from "../query/bt_edge_collapse_would_fold.js";
|
|
6
13
|
import { bt_loop_kill } from "./bt_loop_kill.js";
|
|
@@ -18,6 +25,51 @@ const scratch_coord_b = new Float32Array(3);
|
|
|
18
25
|
const scratch_target = new Float32Array(3);
|
|
19
26
|
const scratch_combined_q = new Quadric3();
|
|
20
27
|
|
|
28
|
+
/**
|
|
29
|
+
* The pair's summed attribute quadric, and its reduction. Grown to whatever channel count the
|
|
30
|
+
* current call carries and reused across every candidate it scores — `evaluate_edge_collapse` runs
|
|
31
|
+
* once per heap insert and again for every neighbour of every collapse, and an allocation there is
|
|
32
|
+
* an allocation per edge per round.
|
|
33
|
+
* @type {Float64Array}
|
|
34
|
+
*/
|
|
35
|
+
let scratch_attribute_sum = new Float64Array(0);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @type {Float64Array}
|
|
39
|
+
*/
|
|
40
|
+
const scratch_attribute_reduced = new Float64Array(QUADRIC3_SIZE);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* One wedge group's reduction, on its way into the sum over groups.
|
|
44
|
+
* @type {Float64Array}
|
|
45
|
+
*/
|
|
46
|
+
const scratch_group_reduced = new Float64Array(QUADRIC3_SIZE);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The wedges of a candidate's two endpoints, the survivor's first, and the local union-find that
|
|
50
|
+
* groups them. Only the multi-wedge path touches these, which on smooth geometry is never.
|
|
51
|
+
* @type {Uint32Array}
|
|
52
|
+
*/
|
|
53
|
+
let scratch_wedge_ids = new Uint32Array(0);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @type {Uint32Array}
|
|
57
|
+
*/
|
|
58
|
+
let scratch_wedge_group = new Uint32Array(0);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The corners of the faces a collapse would destroy, as `(at a, at b)` pairs. Two on a manifold
|
|
62
|
+
* edge, which is why it starts small and grows.
|
|
63
|
+
* @type {Uint32Array}
|
|
64
|
+
*/
|
|
65
|
+
let scratch_dying_loops = new Uint32Array(8);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The fitted attribute record, on its way onto the survivor.
|
|
69
|
+
* @type {Float64Array}
|
|
70
|
+
*/
|
|
71
|
+
let scratch_attribute_values = new Float64Array(0);
|
|
72
|
+
|
|
21
73
|
/**
|
|
22
74
|
* Count the number of still-live faces attached to an edge via its radial loop cycle.
|
|
23
75
|
* Orphan loops (whose face was already killed by a prior collapse) are skipped so
|
|
@@ -60,10 +112,15 @@ function count_edge_faces(mesh, edge_id) {
|
|
|
60
112
|
* @param {number} edge_id
|
|
61
113
|
* @param {Quadric3[]} quadratics
|
|
62
114
|
* @param {Set<number>} restricted_vertices
|
|
115
|
+
* @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null}
|
|
116
|
+
* attributes the channels the collapse carries, or `null` to carry none
|
|
117
|
+
* @param {BtWedgeSet|null} wedges which corners of each vertex shade as one
|
|
63
118
|
* @param {Float32Array|number[]} out_target Target position is written here.
|
|
64
119
|
* @returns {number}
|
|
65
120
|
*/
|
|
66
|
-
function evaluate_edge_collapse(
|
|
121
|
+
function evaluate_edge_collapse(
|
|
122
|
+
mesh, edge_id, quadratics, restricted_vertices, attributes, wedges, out_target
|
|
123
|
+
) {
|
|
67
124
|
const v1 = mesh.edge_read_vertex1(edge_id);
|
|
68
125
|
const v2 = mesh.edge_read_vertex2(edge_id);
|
|
69
126
|
|
|
@@ -89,6 +146,12 @@ function evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices,
|
|
|
89
146
|
return Number.POSITIVE_INFINITY;
|
|
90
147
|
}
|
|
91
148
|
|
|
149
|
+
let attribute_cost = 0;
|
|
150
|
+
|
|
151
|
+
if (attributes !== null) {
|
|
152
|
+
reduce_pair_attributes(mesh, v1, v2, attributes, wedges, scratch_attribute_reduced);
|
|
153
|
+
}
|
|
154
|
+
|
|
92
155
|
if (v1_restricted) {
|
|
93
156
|
mesh.vertex_read_coordinate(out_target, 0, v1);
|
|
94
157
|
} else if (v2_restricted) {
|
|
@@ -97,6 +160,22 @@ function evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices,
|
|
|
97
160
|
scratch_combined_q.copy(q1);
|
|
98
161
|
scratch_combined_q.add(q2);
|
|
99
162
|
|
|
163
|
+
if (attributes !== null) {
|
|
164
|
+
/*
|
|
165
|
+
The channels decide where the vertex goes, and this is where they do it. `A` and `b` of
|
|
166
|
+
the reduced attribute quadric are what is left of them after the exact solve for their
|
|
167
|
+
own values, so a collapse across a crease or a texture seam is pulled away from the
|
|
168
|
+
placement that would smear it.
|
|
169
|
+
|
|
170
|
+
Only `optimize` reads this sum. Its weight slot is now a plane count plus a triangle
|
|
171
|
+
count, which is not a quantity, and nothing downstream takes a distance from it -- the
|
|
172
|
+
cost below is the two pure geometric quadrics, evaluated separately.
|
|
173
|
+
*/
|
|
174
|
+
quadric3_add(
|
|
175
|
+
scratch_combined_q, 0, scratch_combined_q, 0, scratch_attribute_reduced, 0
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
100
179
|
if (!scratch_combined_q.optimize(out_target)) {
|
|
101
180
|
// Singular combined tensor: fall back to the midpoint
|
|
102
181
|
mesh.vertex_read_coordinate(scratch_coord_a, 0, v1);
|
|
@@ -112,8 +191,14 @@ function evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices,
|
|
|
112
191
|
const ty = out_target[1];
|
|
113
192
|
const tz = out_target[2];
|
|
114
193
|
|
|
194
|
+
if (attributes !== null) {
|
|
195
|
+
// What the channels still cost once each has been given its best value at this position --
|
|
196
|
+
// in units of length, because the weights put them there.
|
|
197
|
+
attribute_cost = Math.abs(quadric3_evaluate(scratch_attribute_reduced, 0, tx, ty, tz));
|
|
198
|
+
}
|
|
199
|
+
|
|
115
200
|
// Cost can drift slightly negative for near-zero values due to fp noise.
|
|
116
|
-
return Math.abs(q1.evaluate(tx, ty, tz) + q2.evaluate(tx, ty, tz));
|
|
201
|
+
return Math.abs(q1.evaluate(tx, ty, tz) + q2.evaluate(tx, ty, tz)) + attribute_cost;
|
|
117
202
|
}
|
|
118
203
|
|
|
119
204
|
/**
|
|
@@ -124,9 +209,13 @@ function evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices,
|
|
|
124
209
|
* @param {number} survivor
|
|
125
210
|
* @param {Quadric3[]} quadratics
|
|
126
211
|
* @param {Set<number>} restricted_vertices
|
|
212
|
+
* @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null} attributes
|
|
213
|
+
* @param {BtWedgeSet|null} wedges
|
|
127
214
|
* @param {Uint32Heap} heap
|
|
128
215
|
*/
|
|
129
|
-
function update_neighbor_costs(
|
|
216
|
+
function update_neighbor_costs(
|
|
217
|
+
mesh, survivor, quadratics, restricted_vertices, attributes, wedges, heap
|
|
218
|
+
) {
|
|
130
219
|
let curr_e = mesh.vertex_read_edge(survivor);
|
|
131
220
|
|
|
132
221
|
if (curr_e === NULL_POINTER) {
|
|
@@ -148,7 +237,10 @@ function update_neighbor_costs(mesh, survivor, quadratics, restricted_vertices,
|
|
|
148
237
|
const idx = heap.find_index_by_id(curr_e);
|
|
149
238
|
|
|
150
239
|
if (idx !== -1) {
|
|
151
|
-
const cost = evaluate_edge_collapse(
|
|
240
|
+
const cost = evaluate_edge_collapse(
|
|
241
|
+
mesh, curr_e, quadratics, restricted_vertices, attributes, wedges, scratch_target
|
|
242
|
+
);
|
|
243
|
+
|
|
152
244
|
heap.__update_score_by_index(idx, cost);
|
|
153
245
|
}
|
|
154
246
|
|
|
@@ -156,6 +248,504 @@ function update_neighbor_costs(mesh, survivor, quadratics, restricted_vertices,
|
|
|
156
248
|
} while (curr_e !== start_e && curr_e !== NULL_POINTER);
|
|
157
249
|
}
|
|
158
250
|
|
|
251
|
+
/**
|
|
252
|
+
* The corners of every face a collapse of `(a, b)` would destroy, as pairs — the corner at `a`
|
|
253
|
+
* followed by the corner at `b` — written into {@link scratch_dying_loops}.
|
|
254
|
+
*
|
|
255
|
+
* **The faces a collapse destroys are not only the ones on the edge it names.** They are the ones
|
|
256
|
+
* holding *both* endpoints: the edge's own, the ones on any parallel edge {@link bt_edge_kill_parallels}
|
|
257
|
+
* clears first, and the ones {@link bt_vertex_fuse_duplicate_edges} finds degenerate afterwards. That
|
|
258
|
+
* is {@link collapse_kills_protected_face}'s contract, written down there and true here for the same
|
|
259
|
+
* reason — and a triangle holding both endpoints has an edge between them, so walking the disk cycle
|
|
260
|
+
* for edges to `b` finds all of them.
|
|
261
|
+
*
|
|
262
|
+
* Walking one radial cycle instead would miss the parallel edges, and a wedge whose only dying face
|
|
263
|
+
* is on one of those would be adopted by the survivor rather than merged into it: two corner groups
|
|
264
|
+
* that are one piece of surface, left as two, which is a crease where the mesh has none.
|
|
265
|
+
*
|
|
266
|
+
* @param {BinaryTopology} mesh
|
|
267
|
+
* @param {number} a
|
|
268
|
+
* @param {number} b
|
|
269
|
+
* @returns {number} how many pairs were written
|
|
270
|
+
*/
|
|
271
|
+
function collect_dying_faces(mesh, a, b) {
|
|
272
|
+
let count = 0;
|
|
273
|
+
|
|
274
|
+
let edge = mesh.vertex_read_edge(a);
|
|
275
|
+
|
|
276
|
+
if (edge === NULL_POINTER) {
|
|
277
|
+
return 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const start_edge = edge;
|
|
281
|
+
const face_pool = mesh.faces;
|
|
282
|
+
|
|
283
|
+
do {
|
|
284
|
+
const at_v1 = mesh.edge_read_vertex1(edge) === a;
|
|
285
|
+
|
|
286
|
+
const other = at_v1 ? mesh.edge_read_vertex2(edge) : mesh.edge_read_vertex1(edge);
|
|
287
|
+
|
|
288
|
+
if (other === b) {
|
|
289
|
+
const first_loop = mesh.edge_read_loop(edge);
|
|
290
|
+
|
|
291
|
+
let loop = first_loop;
|
|
292
|
+
|
|
293
|
+
while (loop !== NULL_POINTER) {
|
|
294
|
+
const face = mesh.loop_read_face(loop);
|
|
295
|
+
|
|
296
|
+
if (face !== NULL_POINTER && face_pool.is_allocated(face)) {
|
|
297
|
+
const next_loop = mesh.loop_read_next(loop);
|
|
298
|
+
|
|
299
|
+
const at_a = mesh.loop_read_vertex(loop) === a ? loop : next_loop;
|
|
300
|
+
|
|
301
|
+
if (scratch_dying_loops.length < (count + 1) * 2) {
|
|
302
|
+
const grown = new Uint32Array(Math.max(8, (count + 1) * 4));
|
|
303
|
+
|
|
304
|
+
grown.set(scratch_dying_loops);
|
|
305
|
+
|
|
306
|
+
scratch_dying_loops = grown;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
scratch_dying_loops[count * 2] = at_a;
|
|
310
|
+
scratch_dying_loops[count * 2 + 1] = at_a === loop ? next_loop : loop;
|
|
311
|
+
|
|
312
|
+
count++;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
loop = mesh.loop_read_radial_next(loop);
|
|
316
|
+
|
|
317
|
+
if (loop === first_loop) {
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
edge = at_v1 ? mesh.edge_read_v1_disk_next(edge) : mesh.edge_read_v2_disk_next(edge);
|
|
324
|
+
} while (edge !== start_edge && edge !== NULL_POINTER);
|
|
325
|
+
|
|
326
|
+
return count;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Which wedges of a collapse's two endpoints would become one, and the reduced attribute quadric
|
|
331
|
+
* that follows from it.
|
|
332
|
+
*
|
|
333
|
+
* **A live face is what says two corners shade as one.** Each face on the edge holds one corner at
|
|
334
|
+
* each endpoint, and that face is about to die into the survivor — so whatever those two corners
|
|
335
|
+
* were, they are one corner's worth of surface afterwards. Everything else the two vertices carry
|
|
336
|
+
* stays apart. That rule needs no tolerance and no comparison of values, which matters: two
|
|
337
|
+
* neighbours on a smoothly curved surface have genuinely different normals, so a rule that merged
|
|
338
|
+
* only equal values would invent a crease at every collapse a sphere has.
|
|
339
|
+
*
|
|
340
|
+
* Each resulting group is reduced separately and the reductions summed, because each group solves
|
|
341
|
+
* for its own value ({@link quadric_attribute_reduce} is the substitution of that solve). Summing
|
|
342
|
+
* the quadrics first and reducing once would be the claim that all of them share one value, which
|
|
343
|
+
* is the thing a seam denies.
|
|
344
|
+
*
|
|
345
|
+
* **A collapse with no face to destroy is a fuse of two points, not a simplification of a surface**,
|
|
346
|
+
* and it is treated as one group. Nothing survives to hold the corners apart, and the alternative
|
|
347
|
+
* leaves the victim's accumulated history on a wedge that may have no corners left to carry it. Rare,
|
|
348
|
+
* and measured rather than assumed: 6 of 6,195 collapses over a 12,288-triangle sphere's whole DAG.
|
|
349
|
+
*
|
|
350
|
+
* @param {BinaryTopology} mesh
|
|
351
|
+
* @param {number} v1
|
|
352
|
+
* @param {number} v2
|
|
353
|
+
* @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}} attributes
|
|
354
|
+
* @param {BtWedgeSet} wedges
|
|
355
|
+
* @param {Float64Array} out `QUADRIC3_SIZE` elements, overwritten
|
|
356
|
+
*/
|
|
357
|
+
function reduce_pair_attributes(mesh, v1, v2, attributes, wedges, out) {
|
|
358
|
+
const components = attributes.components;
|
|
359
|
+
const size = quadric_attribute_size(components);
|
|
360
|
+
|
|
361
|
+
const quadrics = attributes.quadrics;
|
|
362
|
+
|
|
363
|
+
const first_1 = wedges.first_of_vertex[v1];
|
|
364
|
+
const first_2 = wedges.first_of_vertex[v2];
|
|
365
|
+
|
|
366
|
+
/*
|
|
367
|
+
One wedge each, which is every vertex of a mesh with no seams and the overwhelming majority of
|
|
368
|
+
one that has them. They can only end up in the same group, so the answer is the sum of the two
|
|
369
|
+
reduced once -- exactly the arithmetic this had before wedges existed, kept on the path that
|
|
370
|
+
runs once per edge per round.
|
|
371
|
+
*/
|
|
372
|
+
if (
|
|
373
|
+
first_1 !== NULL_POINTER && wedges.next_of_wedge[first_1] === NULL_POINTER
|
|
374
|
+
&& first_2 !== NULL_POINTER && wedges.next_of_wedge[first_2] === NULL_POINTER
|
|
375
|
+
) {
|
|
376
|
+
quadric_attribute_add(
|
|
377
|
+
scratch_attribute_sum, 0,
|
|
378
|
+
quadrics, first_1 * size, quadrics, first_2 * size,
|
|
379
|
+
components
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
quadric_attribute_reduce(out, 0, scratch_attribute_sum, 0, components);
|
|
383
|
+
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
let count = 0;
|
|
388
|
+
|
|
389
|
+
for (let w = first_1; w !== NULL_POINTER; w = wedges.next_of_wedge[w]) {
|
|
390
|
+
count++;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
for (let w = first_2; w !== NULL_POINTER; w = wedges.next_of_wedge[w]) {
|
|
394
|
+
count++;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (scratch_wedge_ids.length < count) {
|
|
398
|
+
scratch_wedge_ids = new Uint32Array(count);
|
|
399
|
+
scratch_wedge_group = new Uint32Array(count);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
let n = 0;
|
|
403
|
+
|
|
404
|
+
for (let w = first_1; w !== NULL_POINTER; w = wedges.next_of_wedge[w]) {
|
|
405
|
+
scratch_wedge_ids[n] = w;
|
|
406
|
+
scratch_wedge_group[n] = n;
|
|
407
|
+
n++;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const first_count = n;
|
|
411
|
+
|
|
412
|
+
for (let w = first_2; w !== NULL_POINTER; w = wedges.next_of_wedge[w]) {
|
|
413
|
+
scratch_wedge_ids[n] = w;
|
|
414
|
+
scratch_wedge_group[n] = n;
|
|
415
|
+
n++;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const dying = collect_dying_faces(mesh, v1, v2);
|
|
419
|
+
|
|
420
|
+
for (let pair = 0; pair < dying; pair++) {
|
|
421
|
+
local_union(
|
|
422
|
+
local_index(wedges.find(wedges.of_loop[scratch_dying_loops[pair * 2]]), n),
|
|
423
|
+
local_index(wedges.find(wedges.of_loop[scratch_dying_loops[pair * 2 + 1]]), n)
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (dying === 0 && first_count > 0) {
|
|
428
|
+
/*
|
|
429
|
+
Whatever the second vertex holds joins the first's first wedge, and the first's *other*
|
|
430
|
+
wedges are left alone -- which is exactly what {@link carry_wedges} does when the edge has no
|
|
431
|
+
face, and the two have to agree or the price of a collapse is not the price of the collapse
|
|
432
|
+
that happens. (Which of the pair survives is decided after this runs, so a swapped pair
|
|
433
|
+
scores the mirror of what it will do; the shape of the partition is the same either way and
|
|
434
|
+
this is a heuristic over 0.1% of collapses.)
|
|
435
|
+
*/
|
|
436
|
+
for (let i = first_count; i < n; i++) {
|
|
437
|
+
local_union(0, i);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
out.fill(0, 0, QUADRIC3_SIZE);
|
|
442
|
+
|
|
443
|
+
for (let group = 0; group < n; group++) {
|
|
444
|
+
if (local_find(group) !== group) {
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
let members = 0;
|
|
449
|
+
|
|
450
|
+
for (let i = 0; i < n; i++) {
|
|
451
|
+
if (local_find(i) !== group) {
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const from = scratch_wedge_ids[i] * size;
|
|
456
|
+
|
|
457
|
+
if (members === 0) {
|
|
458
|
+
for (let element = 0; element < size; element++) {
|
|
459
|
+
scratch_attribute_sum[element] = quadrics[from + element];
|
|
460
|
+
}
|
|
461
|
+
} else {
|
|
462
|
+
quadric_attribute_add(
|
|
463
|
+
scratch_attribute_sum, 0, scratch_attribute_sum, 0, quadrics, from, components
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
members++;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
quadric_attribute_reduce(scratch_group_reduced, 0, scratch_attribute_sum, 0, components);
|
|
471
|
+
|
|
472
|
+
quadric3_add(out, 0, out, 0, scratch_group_reduced, 0);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Where a wedge id sits in {@link scratch_wedge_ids}, or `-1`.
|
|
478
|
+
*
|
|
479
|
+
* A scan rather than a map: it is over the wedges of two vertices, which is two on a crease and one
|
|
480
|
+
* on everything else.
|
|
481
|
+
*
|
|
482
|
+
* @param {number} wedge
|
|
483
|
+
* @param {number} count
|
|
484
|
+
* @returns {number}
|
|
485
|
+
*/
|
|
486
|
+
function local_index(wedge, count) {
|
|
487
|
+
for (let i = 0; i < count; i++) {
|
|
488
|
+
if (scratch_wedge_ids[i] === wedge) {
|
|
489
|
+
return i;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return -1;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* @param {number} index
|
|
498
|
+
* @returns {number}
|
|
499
|
+
*/
|
|
500
|
+
function local_find(index) {
|
|
501
|
+
let root = index;
|
|
502
|
+
|
|
503
|
+
while (scratch_wedge_group[root] !== root) {
|
|
504
|
+
root = scratch_wedge_group[root];
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
return root;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* @param {number} a index into {@link scratch_wedge_ids}, or `-1` for a wedge not among them
|
|
512
|
+
* @param {number} b
|
|
513
|
+
*/
|
|
514
|
+
function local_union(a, b) {
|
|
515
|
+
if (a < 0 || b < 0) {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const root_a = local_find(a);
|
|
520
|
+
const root_b = local_find(b);
|
|
521
|
+
|
|
522
|
+
if (root_a !== root_b) {
|
|
523
|
+
scratch_wedge_group[root_b] = root_a;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Move the survivor's attribute record onto the value the pair between them stands for, when there
|
|
529
|
+
* is no field to fit one from.
|
|
530
|
+
*
|
|
531
|
+
* The fallback, not the rule. A vertex whose every incident triangle was a sliver -- or which has
|
|
532
|
+
* none left at all -- has an attribute quadric of no weight, and a quadric of no weight has no field
|
|
533
|
+
* to evaluate. Blending is what is left, and it is a reasonable answer rather than a good one: it is
|
|
534
|
+
* confined to the values that went in, where a fit is not, and it says nothing about where the
|
|
535
|
+
* vertex ended up.
|
|
536
|
+
*
|
|
537
|
+
* Blended by accumulated quadric weight, which is how much source surface each endpoint speaks for:
|
|
538
|
+
* a vertex that a dozen collapses have folded into already represents a dozen vertices' worth of the
|
|
539
|
+
* original, and taking half its word against a vertex that represents one would let whichever side
|
|
540
|
+
* of a merge happened to be shorter of history pull the value across.
|
|
541
|
+
*
|
|
542
|
+
* Two endpoints that have accumulated nothing have no claim over one another, and split it.
|
|
543
|
+
*
|
|
544
|
+
* @param {Float64Array} values indexed by wedge id, `components` elements each
|
|
545
|
+
* @param {number} components
|
|
546
|
+
* @param {number} survivor wedge
|
|
547
|
+
* @param {number} victim wedge
|
|
548
|
+
* @param {number} survivor_weight
|
|
549
|
+
* @param {number} victim_weight
|
|
550
|
+
*/
|
|
551
|
+
function blend_attributes(values, components, survivor, victim, survivor_weight, victim_weight) {
|
|
552
|
+
const total = survivor_weight + victim_weight;
|
|
553
|
+
|
|
554
|
+
const survivor_share = total > 0 ? survivor_weight / total : 0.5;
|
|
555
|
+
const victim_share = 1 - survivor_share;
|
|
556
|
+
|
|
557
|
+
const survivor_base = survivor * components;
|
|
558
|
+
const victim_base = victim * components;
|
|
559
|
+
|
|
560
|
+
for (let component = 0; component < components; component++) {
|
|
561
|
+
values[survivor_base + component] =
|
|
562
|
+
values[survivor_base + component] * survivor_share
|
|
563
|
+
+ values[victim_base + component] * victim_share;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Merge the pair's wedges, and — where there are values riding along — decide what the survivor
|
|
569
|
+
* carries and give it the victim's accumulated fields.
|
|
570
|
+
*
|
|
571
|
+
* **The merge happens whether or not anything is being carried.** A wedge set is a statement about
|
|
572
|
+
* which corners of the result belong together, and a set that stops tracking collapses is a set
|
|
573
|
+
* whose ids go stale: the victim's loops arrive at the survivor still naming the victim's wedge, and
|
|
574
|
+
* every consumer downstream reads a seam where there is none. Measured, because it got past a
|
|
575
|
+
* byte-identity gate and was caught by an unrelated assertion instead: a round over a mesh with no
|
|
576
|
+
* channels at all cut clusters of 132 vertices against a ceiling of 128.
|
|
577
|
+
*
|
|
578
|
+
* Once per **wedge**, because a vertex has one position and not one appearance. The survivor comes
|
|
579
|
+
* out of this holding its own wedges, whichever of the victim's merged into them, and whichever of
|
|
580
|
+
* the victim's did not — those simply move, still carrying what they always did.
|
|
581
|
+
* {@link reduce_pair_attributes} is the rule for which is which, and it is the same walk.
|
|
582
|
+
*
|
|
583
|
+
* Every wedge that ends up on the survivor is fitted afresh, not only the merged ones: the vertex
|
|
584
|
+
* moved, and a field is evaluated *at a position*.
|
|
585
|
+
*
|
|
586
|
+
* A merged wedge's quadric absorbs its partner's first, so the fit it is then asked for is over
|
|
587
|
+
* *everything* the pair has ever stood for — which is what makes the answer a deviation from the
|
|
588
|
+
* source rather than from the step before it, exactly as the geometric quadric's is.
|
|
589
|
+
*
|
|
590
|
+
* Then the value: the position it is being moved to, plugged into the field those accumulated
|
|
591
|
+
* triangles describe. Where there is no field — a wedge every one of whose triangles was a sliver,
|
|
592
|
+
* or which has no triangles left — {@link blend_attributes} is the fallback, applied at the merge so
|
|
593
|
+
* that a wedge with nothing to fit from still ends up between the two values rather than on one of
|
|
594
|
+
* them. A successful fit overwrites it. (Two victim wedges merging into one survivor wedge, which
|
|
595
|
+
* takes a non-manifold edge, blend the second against the first's result; it is a fallback inside a
|
|
596
|
+
* fallback and it is confined to the values that went in either way.)
|
|
597
|
+
*
|
|
598
|
+
* **A restricted survivor is given the victim's fields and none of its values.** Its position does
|
|
599
|
+
* not move, but the fit at that unchanged position would still come out different, because `W`, `G`
|
|
600
|
+
* and `D` under it have grown. That would break the one thing pinning is for: a vertex two groups
|
|
601
|
+
* share must carry byte-identical values in both. It keeps the quadric so that a *later* step, one
|
|
602
|
+
* that is free to move it, fits from the whole history rather than from the fragment it started
|
|
603
|
+
* with. A wedge it *adopts* is a wedge the other group never had, carrying corners that are this
|
|
604
|
+
* group's alone, so it is no exception to that.
|
|
605
|
+
*
|
|
606
|
+
* @param {BinaryTopology} mesh
|
|
607
|
+
* @param {BtWedgeSet} wedges
|
|
608
|
+
* @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null} attributes
|
|
609
|
+
* @param {number} survivor
|
|
610
|
+
* @param {number} victim
|
|
611
|
+
* @param {boolean} survivor_restricted
|
|
612
|
+
* @param {number} survivor_weight geometric quadric weight, for the fallback
|
|
613
|
+
* @param {number} victim_weight
|
|
614
|
+
* @param {Float32Array|number[]} target where the survivor is being moved to
|
|
615
|
+
*/
|
|
616
|
+
function carry_wedges(
|
|
617
|
+
mesh, wedges, attributes, survivor, victim, survivor_restricted,
|
|
618
|
+
survivor_weight, victim_weight, target
|
|
619
|
+
) {
|
|
620
|
+
const dying = collect_dying_faces(mesh, survivor, victim);
|
|
621
|
+
|
|
622
|
+
for (let pair = 0; pair < dying; pair++) {
|
|
623
|
+
absorb_wedge(
|
|
624
|
+
wedges, attributes,
|
|
625
|
+
wedges.find(wedges.of_loop[scratch_dying_loops[pair * 2]]),
|
|
626
|
+
wedges.find(wedges.of_loop[scratch_dying_loops[pair * 2 + 1]]),
|
|
627
|
+
survivor_restricted, survivor_weight, victim_weight
|
|
628
|
+
);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
if (dying === 0 && wedges.first_of_vertex[survivor] !== NULL_POINTER) {
|
|
632
|
+
// A fuse of two points rather than a simplification of a surface; see
|
|
633
|
+
// {@link reduce_pair_attributes}, whose cost model this has to agree with.
|
|
634
|
+
const into = wedges.find(wedges.first_of_vertex[survivor]);
|
|
635
|
+
|
|
636
|
+
for (
|
|
637
|
+
let wedge = wedges.first_of_vertex[victim];
|
|
638
|
+
wedge !== NULL_POINTER;
|
|
639
|
+
wedge = wedges.next_of_wedge[wedge]
|
|
640
|
+
) {
|
|
641
|
+
absorb_wedge(
|
|
642
|
+
wedges, attributes, into, wedges.find(wedge),
|
|
643
|
+
survivor_restricted, survivor_weight, victim_weight
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// The survivor's own list, less whatever merged into something else, then the victim's on top of
|
|
649
|
+
// it. The loops themselves are not touched: a corner's wedge id goes stale and `find` resolves
|
|
650
|
+
// it, which is the whole reason nothing has to go looking for a corner in order to move it.
|
|
651
|
+
relist_wedges(wedges, survivor, survivor);
|
|
652
|
+
relist_wedges(wedges, victim, survivor);
|
|
653
|
+
|
|
654
|
+
if (survivor_restricted || attributes === null) {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
const components = attributes.components;
|
|
659
|
+
|
|
660
|
+
for (
|
|
661
|
+
let wedge = wedges.first_of_vertex[survivor];
|
|
662
|
+
wedge !== NULL_POINTER;
|
|
663
|
+
wedge = wedges.next_of_wedge[wedge]
|
|
664
|
+
) {
|
|
665
|
+
const fitted = quadric_attribute_solve(
|
|
666
|
+
scratch_attribute_values, 0,
|
|
667
|
+
attributes.quadrics, wedge * quadric_attribute_size(components), components,
|
|
668
|
+
attributes.weights,
|
|
669
|
+
target[0], target[1], target[2]
|
|
670
|
+
);
|
|
671
|
+
|
|
672
|
+
if (fitted) {
|
|
673
|
+
attributes.values.set(
|
|
674
|
+
scratch_attribute_values.subarray(0, components), wedge * components
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Make `other` part of `wedge`: its accumulated field, and — for the case where there turns out to
|
|
682
|
+
* be no field to fit from — its value.
|
|
683
|
+
*
|
|
684
|
+
* @param {BtWedgeSet} wedges
|
|
685
|
+
* @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null} attributes
|
|
686
|
+
* @param {number} wedge root that survives, the survivor's
|
|
687
|
+
* @param {number} other root that does not, the victim's
|
|
688
|
+
* @param {boolean} survivor_restricted
|
|
689
|
+
* @param {number} survivor_weight
|
|
690
|
+
* @param {number} victim_weight
|
|
691
|
+
*/
|
|
692
|
+
function absorb_wedge(
|
|
693
|
+
wedges, attributes, wedge, other, survivor_restricted, survivor_weight, victim_weight
|
|
694
|
+
) {
|
|
695
|
+
if (!wedges.merge(wedge, other)) {
|
|
696
|
+
// Already one wedge. A manifold edge's two faces name the same pair twice, which is the
|
|
697
|
+
// common case rather than an oddity, so this is the guard that keeps a quadric from being
|
|
698
|
+
// counted into itself.
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
if (attributes === null) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
const components = attributes.components;
|
|
707
|
+
const size = quadric_attribute_size(components);
|
|
708
|
+
|
|
709
|
+
quadric_attribute_add(
|
|
710
|
+
attributes.quadrics, wedge * size,
|
|
711
|
+
attributes.quadrics, wedge * size,
|
|
712
|
+
attributes.quadrics, other * size,
|
|
713
|
+
components
|
|
714
|
+
);
|
|
715
|
+
|
|
716
|
+
if (!survivor_restricted) {
|
|
717
|
+
blend_attributes(
|
|
718
|
+
attributes.values, components, wedge, other, survivor_weight, victim_weight
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Move every wedge of `from` onto `to`, dropping the ones that are no longer their own root.
|
|
725
|
+
*
|
|
726
|
+
* `from === to` is a compaction in place, which is what the survivor needs: its own wedges can have
|
|
727
|
+
* merged into each other, through a victim wedge that touched both.
|
|
728
|
+
*
|
|
729
|
+
* @param {BtWedgeSet} wedges
|
|
730
|
+
* @param {number} from vertex
|
|
731
|
+
* @param {number} to vertex
|
|
732
|
+
*/
|
|
733
|
+
function relist_wedges(wedges, from, to) {
|
|
734
|
+
let wedge = wedges.first_of_vertex[from];
|
|
735
|
+
|
|
736
|
+
wedges.detach_all(from);
|
|
737
|
+
|
|
738
|
+
while (wedge !== NULL_POINTER) {
|
|
739
|
+
const next = wedges.next_of_wedge[wedge];
|
|
740
|
+
|
|
741
|
+
if (wedges.find(wedge) === wedge) {
|
|
742
|
+
wedges.attach(wedge, to);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
wedge = next;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
159
749
|
/**
|
|
160
750
|
* Would collapsing this edge destroy a face the caller asked to keep?
|
|
161
751
|
*
|
|
@@ -316,7 +906,48 @@ export function bt_mesh_simplify(
|
|
|
316
906
|
* @param {number} target_face_count Desired face count after simplification.
|
|
317
907
|
* @param {Set<number>} restricted_vertices Vertices that must not move or be removed.
|
|
318
908
|
* @param {Set<number>} protected_faces Faces that must not be removed.
|
|
909
|
+
* `attributes` is per-vertex data that travels *through* the collapse rather than being re-derived
|
|
910
|
+
* from the result. Whatever a merged vertex is to carry has to be decided here, from the values
|
|
911
|
+
* being merged: the mesh a collapse leaves behind is a different surface, and a value read off it
|
|
912
|
+
* afterwards describes that one rather than the one the caller started with.
|
|
913
|
+
*
|
|
914
|
+
* It is carried per **wedge** — a set of corners at one vertex that shade as one — so a hard edge
|
|
915
|
+
* or a texture seam survives a collapse instead of being averaged away. Which of the pair's wedges
|
|
916
|
+
* become one is decided by the faces the collapse destroys, in {@link reduce_pair_attributes}; a
|
|
917
|
+
* mesh with no seams has one wedge per vertex, every collapse merges the pair, and all of this is
|
|
918
|
+
* the arithmetic it always was.
|
|
919
|
+
*
|
|
920
|
+
* It is **fitted**, not inherited and not averaged. Each channel varies affinely over a triangle, so
|
|
921
|
+
* every triangle a wedge has ever absorbed says what that channel should be at any position; the
|
|
922
|
+
* survivor takes the value that best explains all of them at once, at the position it is being moved
|
|
923
|
+
* to ({@link quadric_attribute_solve}). Those same accumulated fields also reach the *placement* and
|
|
924
|
+
* the cost, through {@link quadric_attribute_reduce} -- so a collapse that would smear a crease or a
|
|
925
|
+
* texture seam is both moved away from it and priced for it. A vertex with no field to fit from
|
|
926
|
+
* falls back to a weighted blend, and a **restricted** survivor is left exactly as it is, for the
|
|
927
|
+
* same reason its position is.
|
|
928
|
+
*
|
|
929
|
+
* The values themselves mean nothing here. A caller whose record holds a direction or a flag rather
|
|
930
|
+
* than a quantity has to say so afterwards, over the array this leaves behind.
|
|
931
|
+
*
|
|
932
|
+
* What the call **returns** is still the pure geometric quadric's answer, evaluated at wherever the
|
|
933
|
+
* higher-dimensional metric put each vertex. Solving in one metric and reporting in the other is
|
|
934
|
+
* what keeps the number an object-space length (`VIRTUAL_GEOMETRY_DESIGN.md` §3).
|
|
935
|
+
*
|
|
319
936
|
* @param {Quadric3[]} quadratics indexed by vertex id, one per allocated vertex; mutated in place
|
|
937
|
+
* @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null} [attributes]
|
|
938
|
+
* per-wedge records to carry through the collapses, with the attribute quadrics that fit them
|
|
939
|
+
* ({@link bt_mesh_compute_wedge_attribute_quadrics}) and the per-channel weights those were
|
|
940
|
+
* built with. `values` and `quadrics` are indexed by **wedge id**;
|
|
941
|
+
* {@link bt_wedges_per_vertex} is the set where that is the vertex id. `null` to carry nothing,
|
|
942
|
+
* which is what every caller but the virtual-geometry builder does. {@link bt_mesh_simplify_by_error}
|
|
943
|
+
* is not among them at all — it is a separate implementation with its own cost function, and so
|
|
944
|
+
* is untouched by any of this, which matters because it simplifies to a *tolerance* that an
|
|
945
|
+
* attribute term would quietly move.
|
|
946
|
+
* @param {BtWedgeSet|null} [wedges] which corners of each vertex shade as one, **mutated in place**
|
|
947
|
+
* as the collapses merge them. Required when `attributes` is given, and useful without it: a
|
|
948
|
+
* caller that carries no values may still care which corners of the result belong together, and
|
|
949
|
+
* a set that is not maintained is a set whose ids go stale — corners of one vertex would resolve
|
|
950
|
+
* to different wedges and every consumer downstream would see a seam that is not there.
|
|
320
951
|
* @returns {number} object-space distance the surface moved, `0` when no collapse was performed
|
|
321
952
|
*/
|
|
322
953
|
export function bt_mesh_simplify_with_quadrics(
|
|
@@ -324,7 +955,9 @@ export function bt_mesh_simplify_with_quadrics(
|
|
|
324
955
|
target_face_count,
|
|
325
956
|
restricted_vertices,
|
|
326
957
|
protected_faces,
|
|
327
|
-
quadratics
|
|
958
|
+
quadratics,
|
|
959
|
+
attributes = null,
|
|
960
|
+
wedges = null
|
|
328
961
|
) {
|
|
329
962
|
assert.defined(mesh, 'mesh');
|
|
330
963
|
assert.notNull(mesh, 'mesh');
|
|
@@ -345,6 +978,22 @@ export function bt_mesh_simplify_with_quadrics(
|
|
|
345
978
|
return 0;
|
|
346
979
|
}
|
|
347
980
|
|
|
981
|
+
if (attributes !== null) {
|
|
982
|
+
assert.notNull(wedges, 'wedges, which carrying attributes requires');
|
|
983
|
+
|
|
984
|
+
const size = quadric_attribute_size(attributes.components);
|
|
985
|
+
|
|
986
|
+
// Grown, never shrunk: a build is thousands of calls over the same handful of channel
|
|
987
|
+
// counts, and every one of them would otherwise allocate.
|
|
988
|
+
if (scratch_attribute_sum.length < size) {
|
|
989
|
+
scratch_attribute_sum = new Float64Array(size);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
if (scratch_attribute_values.length < attributes.components) {
|
|
993
|
+
scratch_attribute_values = new Float64Array(attributes.components);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
|
|
348
997
|
const edge_pool = mesh.edges;
|
|
349
998
|
const heap = new Uint32Heap(edge_pool.size);
|
|
350
999
|
|
|
@@ -357,7 +1006,9 @@ export function bt_mesh_simplify_with_quadrics(
|
|
|
357
1006
|
continue;
|
|
358
1007
|
}
|
|
359
1008
|
|
|
360
|
-
const cost = evaluate_edge_collapse(
|
|
1009
|
+
const cost = evaluate_edge_collapse(
|
|
1010
|
+
mesh, e, quadratics, restricted_vertices, attributes, wedges, scratch_target
|
|
1011
|
+
);
|
|
361
1012
|
|
|
362
1013
|
if (cost === Number.POSITIVE_INFINITY) {
|
|
363
1014
|
continue;
|
|
@@ -407,7 +1058,9 @@ export function bt_mesh_simplify_with_quadrics(
|
|
|
407
1058
|
continue;
|
|
408
1059
|
}
|
|
409
1060
|
|
|
410
|
-
const cost = evaluate_edge_collapse(
|
|
1061
|
+
const cost = evaluate_edge_collapse(
|
|
1062
|
+
mesh, edge_id, quadratics, restricted_vertices, attributes, wedges, scratch_target
|
|
1063
|
+
);
|
|
411
1064
|
|
|
412
1065
|
if (cost === Number.POSITIVE_INFINITY) {
|
|
413
1066
|
continue;
|
|
@@ -433,6 +1086,20 @@ export function bt_mesh_simplify_with_quadrics(
|
|
|
433
1086
|
const pre_survivor = mesh.edge_read_vertex1(edge_id);
|
|
434
1087
|
const pre_victim = mesh.edge_read_vertex2(edge_id);
|
|
435
1088
|
|
|
1089
|
+
// Before the accumulation below, which is what makes the blend fallback weigh the two
|
|
1090
|
+
// endpoints' own histories rather than the survivor's already carrying the victim's. And
|
|
1091
|
+
// before the topology mutates, which is what lets the faces about to die say which corners
|
|
1092
|
+
// shade as one.
|
|
1093
|
+
if (wedges !== null) {
|
|
1094
|
+
carry_wedges(
|
|
1095
|
+
mesh, wedges, attributes, pre_survivor, pre_victim,
|
|
1096
|
+
restricted_vertices.has(pre_survivor),
|
|
1097
|
+
quadratics[pre_survivor].weight,
|
|
1098
|
+
quadratics[pre_victim].weight,
|
|
1099
|
+
scratch_target
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
|
|
436
1103
|
// Accumulate victim's quadric onto the survivor before the topology mutates.
|
|
437
1104
|
quadratics[pre_survivor].add(quadratics[pre_victim]);
|
|
438
1105
|
quadratics[pre_victim] = null;
|
|
@@ -453,7 +1120,9 @@ export function bt_mesh_simplify_with_quadrics(
|
|
|
453
1120
|
// are still intact.
|
|
454
1121
|
current_face_count -= bt_vertex_fuse_duplicate_edges(mesh, survivor);
|
|
455
1122
|
|
|
456
|
-
update_neighbor_costs(
|
|
1123
|
+
update_neighbor_costs(
|
|
1124
|
+
mesh, survivor, quadratics, restricted_vertices, attributes, wedges, heap
|
|
1125
|
+
);
|
|
457
1126
|
}
|
|
458
1127
|
|
|
459
1128
|
// Measured here, before the cleanup below, because a vertex left behind by a patch that was
|