@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,243 @@
|
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
2
|
+
import { build_tangent_from_normal } from "../../../normals/build_tangent_from_normal.js";
|
|
3
|
+
import { VGEO_ATTRIBUTE } from "../../format/attribute/VGEO_ATTRIBUTE.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* One vertex's widest channel record on its way into a layer.
|
|
7
|
+
* @type {Float32Array}
|
|
8
|
+
*/
|
|
9
|
+
const scratch_record = new Float32Array(4);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The normal the tangent of the same vertex is squared up against.
|
|
13
|
+
* @type {Float32Array}
|
|
14
|
+
*/
|
|
15
|
+
const scratch_normal = new Float32Array(3);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Frisvad's basis, when the carried tangent has degenerated.
|
|
19
|
+
* @type {Float32Array}
|
|
20
|
+
*/
|
|
21
|
+
const scratch_fallback = new Float32Array(4);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Put the simplifier's vector back into the mesh's layers, and square up the frame it describes.
|
|
25
|
+
*
|
|
26
|
+
* **Nothing is *derived* for a pinned vertex.** That is the whole of what pinning means here and it
|
|
27
|
+
* is what lets a cut place two levels of detail side by side: a vertex two groups share must carry
|
|
28
|
+
* byte-identical values in both payloads, or the seam that is watertight in geometry shades as a
|
|
29
|
+
* crease (`ATTRIBUTE_PLAN_2026_09_18.md` §3, invariant 2).
|
|
30
|
+
*
|
|
31
|
+
* Its corners are still *written*, with what the vector says it already had, and that is not a
|
|
32
|
+
* loophole — it is the same guarantee under corner storage. A collapse re-points the victim's corners
|
|
33
|
+
* onto the survivor and they arrive carrying the victim's appearance, so leaving a pinned vertex
|
|
34
|
+
* alone no longer means leaving its value alone. The write is exact: those float32 records are where
|
|
35
|
+
* the vector was read from.
|
|
36
|
+
*
|
|
37
|
+
* Two channels need more than a copy:
|
|
38
|
+
*
|
|
39
|
+
* - **The normal** is renormalized. A blend of two unit vectors is not one, and a normal that is
|
|
40
|
+
* not unit is not a normal. Two exactly opposing normals blend to nothing, which has no direction
|
|
41
|
+
* to report and so keeps whatever the vertex already carried, the same answer
|
|
42
|
+
* {@link bt_mesh_compute_vertex_normals} gives for a vertex whose faces cancel.
|
|
43
|
+
* - **The colour** is clamped to `[0, 1]`. The value a collapse carries is a *fit*, not an average,
|
|
44
|
+
* and a fit extrapolates — which is right for a texture coordinate and wrong for a channel with a
|
|
45
|
+
* range. The encoder saturates anyway, so what this stops is not a corrupt word but the drift:
|
|
46
|
+
* an out-of-range value left in the layer is what the next level's field is fitted from, and it
|
|
47
|
+
* would walk further out at every round.
|
|
48
|
+
* - **The tangent** is re-orthogonalized against that normal and renormalized, and its fourth
|
|
49
|
+
* component — handedness, a discrete `±1` — is left exactly as the survivor had it, because it is
|
|
50
|
+
* a flag rather than a quantity and there is no average of `+1` and `-1`. A tangent that has
|
|
51
|
+
* blended its way onto the normal has no perpendicular component left to keep, and falls back to
|
|
52
|
+
* Frisvad's basis rather than to a zero vector the octahedral encoder cannot represent.
|
|
53
|
+
*
|
|
54
|
+
* @param {VirtualGeometryMesh} mesh mutated in place
|
|
55
|
+
* @param {{components: number, channels: {attribute: number, offset: number, count: number}[]}} layout
|
|
56
|
+
* from {@link vgeo_attribute_vector_layout}, the same one {@link vgeo_attribute_vector_read} used
|
|
57
|
+
* @param {Float64Array} values indexed by wedge id, as the simplifier left it
|
|
58
|
+
* @param {Float64Array|null} verbatim indexed by wedge id, as it was read — the simplifier does not
|
|
59
|
+
* take it and has nothing to say about it. `null` where the layout has no such component, which
|
|
60
|
+
* is every mesh whose tangent is derived rather than carried.
|
|
61
|
+
* @param {Set<number>} pinned vertex ids nothing may be *derived* for
|
|
62
|
+
* @param {BtWedgeSet} wedges which corners of each vertex shade as one, as the simplifier left it
|
|
63
|
+
*
|
|
64
|
+
* @author Alex Goldring
|
|
65
|
+
* @copyright Company Named Limited (c) 2026
|
|
66
|
+
*/
|
|
67
|
+
export function vgeo_attribute_vector_write(mesh, layout, values, verbatim, pinned, wedges) {
|
|
68
|
+
assert.greaterThan(layout.components, 0, 'layout.components');
|
|
69
|
+
|
|
70
|
+
const topology = mesh.topology;
|
|
71
|
+
|
|
72
|
+
const components = layout.components;
|
|
73
|
+
const channels = layout.channels;
|
|
74
|
+
|
|
75
|
+
const normal_layer = mesh.layers[VGEO_ATTRIBUTE.NORMAL];
|
|
76
|
+
|
|
77
|
+
const carries_tangent = channels.some(
|
|
78
|
+
(channel) => channel.attribute === VGEO_ATTRIBUTE.TANGENT
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
/*
|
|
82
|
+
Over corners. The value is decided per *wedge* and stored per corner, so every corner of a wedge
|
|
83
|
+
gets the same one — and the frame fixups below, being functions of that value, agree corner for
|
|
84
|
+
corner without having to be told to. Two corners of one vertex in different wedges get different
|
|
85
|
+
ones, which is a hard edge, and is the entire point.
|
|
86
|
+
*/
|
|
87
|
+
const loop_pool = topology.loops;
|
|
88
|
+
|
|
89
|
+
for (let loop = 0; loop < loop_pool.size; loop++) {
|
|
90
|
+
if (!loop_pool.is_allocated(loop)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const vertex = topology.loop_read_vertex(loop);
|
|
95
|
+
|
|
96
|
+
/*
|
|
97
|
+
A pinned vertex IS written, and writing it is what keeps it pinned. The vector holds what it
|
|
98
|
+
had -- nothing in the simplifier touches a restricted survivor's entry -- while its *corners*
|
|
99
|
+
do not, because a collapse re-points the victim's onto it and those arrive carrying the
|
|
100
|
+
victim's appearance. Writing the vector back over all of them is what puts that right, and it
|
|
101
|
+
is exact: the value came out of these same float32 records and goes back into them unchanged.
|
|
102
|
+
|
|
103
|
+
What it must not do is *derive* anything for a pinned vertex, so the fixups below are the
|
|
104
|
+
one thing that stays behind the flag.
|
|
105
|
+
*/
|
|
106
|
+
const restore = pinned.has(vertex);
|
|
107
|
+
|
|
108
|
+
const wedge = wedges.find(wedges.of_loop[loop]);
|
|
109
|
+
|
|
110
|
+
const base = wedge * components;
|
|
111
|
+
|
|
112
|
+
for (const channel of channels) {
|
|
113
|
+
const layer = mesh.layers[channel.attribute];
|
|
114
|
+
|
|
115
|
+
// Read first: a channel the vector carries only part of — the tangent, whose handedness
|
|
116
|
+
// stays with the survivor — keeps the rest of its record this way.
|
|
117
|
+
layer.read(scratch_record, 0, loop);
|
|
118
|
+
|
|
119
|
+
for (let component = 0; component < channel.count; component++) {
|
|
120
|
+
const value = values[base + channel.offset + component];
|
|
121
|
+
|
|
122
|
+
assert.isFinite(value, 'carried attribute component');
|
|
123
|
+
|
|
124
|
+
scratch_record[channel.source + component] = value;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (restore) {
|
|
128
|
+
layer.write(loop, scratch_record, 0);
|
|
129
|
+
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (channel.attribute === VGEO_ATTRIBUTE.NORMAL) {
|
|
134
|
+
normalize_in_place(scratch_record, layer, loop);
|
|
135
|
+
} else if (channel.attribute === VGEO_ATTRIBUTE.COLOR) {
|
|
136
|
+
for (let component = 0; component < channel.count; component++) {
|
|
137
|
+
scratch_record[component] = Math.min(1, Math.max(0, scratch_record[component]));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
layer.write(loop, scratch_record, 0);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// After the loop rather than inside it, so the normal it squares up against is the one just
|
|
145
|
+
// written rather than whichever order the channel list happens to be in.
|
|
146
|
+
if (carries_tangent && !restore) {
|
|
147
|
+
orthogonalize_tangent(mesh, normal_layer, loop);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/*
|
|
151
|
+
Last, and over every corner whether the vertex is pinned or not. These components never
|
|
152
|
+
travelled through the fit and never will -- they are the survivor's, and putting them back
|
|
153
|
+
is what stops a corner a collapse donated from keeping the flag it arrived with.
|
|
154
|
+
*/
|
|
155
|
+
if (verbatim === null) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const verbatim_base = wedge * layout.verbatim_components;
|
|
160
|
+
|
|
161
|
+
for (const channel of layout.verbatim) {
|
|
162
|
+
const layer = mesh.layers[channel.attribute];
|
|
163
|
+
|
|
164
|
+
layer.read(scratch_record, 0, loop);
|
|
165
|
+
|
|
166
|
+
for (let component = 0; component < channel.count; component++) {
|
|
167
|
+
scratch_record[channel.source + component] =
|
|
168
|
+
verbatim[verbatim_base + channel.offset + component];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
layer.write(loop, scratch_record, 0);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Scale a channel record's first three components to unit length, leaving them alone when there is
|
|
178
|
+
* no direction there to scale.
|
|
179
|
+
*
|
|
180
|
+
* @param {Float32Array} record
|
|
181
|
+
* @param {BinaryDataLayer} layer the record came from, read again when the blend cancelled
|
|
182
|
+
* @param {number} loop
|
|
183
|
+
*/
|
|
184
|
+
function normalize_in_place(record, layer, loop) {
|
|
185
|
+
const length = Math.hypot(record[0], record[1], record[2]);
|
|
186
|
+
|
|
187
|
+
if (length === 0) {
|
|
188
|
+
layer.read(record, 0, loop);
|
|
189
|
+
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
record[0] /= length;
|
|
194
|
+
record[1] /= length;
|
|
195
|
+
record[2] /= length;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Square one vertex's tangent up against its normal.
|
|
200
|
+
*
|
|
201
|
+
* @param {VirtualGeometryMesh} mesh
|
|
202
|
+
* @param {BinaryDataLayer} normal_layer
|
|
203
|
+
* @param {number} loop
|
|
204
|
+
*/
|
|
205
|
+
function orthogonalize_tangent(mesh, normal_layer, loop) {
|
|
206
|
+
const tangent_layer = mesh.layers[VGEO_ATTRIBUTE.TANGENT];
|
|
207
|
+
|
|
208
|
+
normal_layer.read(scratch_normal, 0, loop);
|
|
209
|
+
tangent_layer.read(scratch_record, 0, loop);
|
|
210
|
+
|
|
211
|
+
const nx = scratch_normal[0];
|
|
212
|
+
const ny = scratch_normal[1];
|
|
213
|
+
const nz = scratch_normal[2];
|
|
214
|
+
|
|
215
|
+
const dot = nx * scratch_record[0] + ny * scratch_record[1] + nz * scratch_record[2];
|
|
216
|
+
|
|
217
|
+
const tx = scratch_record[0] - nx * dot;
|
|
218
|
+
const ty = scratch_record[1] - ny * dot;
|
|
219
|
+
const tz = scratch_record[2] - nz * dot;
|
|
220
|
+
|
|
221
|
+
const length = Math.hypot(tx, ty, tz);
|
|
222
|
+
|
|
223
|
+
if (length === 0) {
|
|
224
|
+
// Nothing perpendicular survived: the carried tangent had blended its way onto the normal.
|
|
225
|
+
build_tangent_from_normal(nx, ny, nz, 0, scratch_fallback);
|
|
226
|
+
|
|
227
|
+
scratch_record[0] = scratch_fallback[0];
|
|
228
|
+
scratch_record[1] = scratch_fallback[1];
|
|
229
|
+
scratch_record[2] = scratch_fallback[2];
|
|
230
|
+
} else {
|
|
231
|
+
scratch_record[0] = tx / length;
|
|
232
|
+
scratch_record[1] = ty / length;
|
|
233
|
+
scratch_record[2] = tz / length;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// A frame the shading model cannot use and the octahedral encoder cannot represent would reach
|
|
237
|
+
// the asset as a silently wrong word.
|
|
238
|
+
assert.isFinite(scratch_record[0], 'tangent x');
|
|
239
|
+
assert.isFinite(scratch_record[1], 'tangent y');
|
|
240
|
+
assert.isFinite(scratch_record[2], 'tangent z');
|
|
241
|
+
|
|
242
|
+
tangent_layer.write(loop, scratch_record, 0);
|
|
243
|
+
}
|
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Area-weighted
|
|
2
|
+
* Area-weighted normals of a mesh, split at its creases, written into its normal channel.
|
|
3
3
|
*
|
|
4
4
|
* The geometry a mesh actually has is the answer for that mesh: carrying a surviving vertex's
|
|
5
5
|
* original normal through a dozen collapses shades a coarse level by whichever vertices happened to
|
|
6
6
|
* win, which is visibly wrong.
|
|
7
7
|
*
|
|
8
|
+
* **Per corner group, not per vertex.** Averaging every face around a vertex is right for a surface
|
|
9
|
+
* and wrong for a corner. Two faces sharing an edge belong to the same group when the surface turns
|
|
10
|
+
* less than {@link VGEO_CREASE_ANGLE} across it; groups are the connected components that leaves,
|
|
11
|
+
* and each gets its own area-weighted average. A vertex on a smooth surface has exactly one, and
|
|
12
|
+
* this is then the pass it has always been. A box corner has three, and the eight vertices of a cube
|
|
13
|
+
* stop carrying a normal that is ninety degrees wrong for every face using it.
|
|
14
|
+
*
|
|
15
|
+
* Area weighting falls out of the arithmetic rather than being applied: Newell's normal *is* the
|
|
16
|
+
* face normal scaled by twice the area, so summing the raw face normals is the area-weighted sum.
|
|
17
|
+
* Which is the same thing {@link bt_mesh_compute_vertex_normals} does, one level down, for the whole
|
|
18
|
+
* vertex — and this reproduces its arithmetic step for step, down to the float32 face scratch and
|
|
19
|
+
* the reciprocal it scales by, so that a mesh without a crease in it comes out bit for bit the same
|
|
20
|
+
* as it did before any of this existed.
|
|
21
|
+
*
|
|
22
|
+
* An edge with anything other than two live triangles on it — a mesh boundary, a non-manifold fin —
|
|
23
|
+
* joins nothing. There is no pair of faces to ask the question of, and splitting is the conservative
|
|
24
|
+
* answer: it keeps each side's own normal rather than inventing an average across a join the mesh
|
|
25
|
+
* itself does not make.
|
|
26
|
+
*
|
|
8
27
|
* **Except where the vertex was pinned.** A pinned vertex is one the step was forbidden to move, and
|
|
9
28
|
* every group that touches it carries it — which is exactly what lets a cut place two levels of
|
|
10
29
|
* detail side by side without a crack. That guarantee has to cover what the vertex *carries*, not
|
|
@@ -13,17 +32,14 @@
|
|
|
13
32
|
* would disagree by however much the surface turns. So a pinned vertex keeps what it had, exactly
|
|
14
33
|
* as it keeps where it was, and the frame stays continuous across every cut the DAG admits.
|
|
15
34
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* which is where the encoder reads from.
|
|
19
|
-
*
|
|
20
|
-
* @param {VirtualGeometryMesh} mesh whose normal layer is sized by the vertex pool and so carries a
|
|
21
|
-
* slot for every live vertex by construction
|
|
35
|
+
* @param {VirtualGeometryMesh} mesh whose normal layer is sized by the loop pool and so carries a
|
|
36
|
+
* slot for every live corner by construction
|
|
22
37
|
* @param {Set<number>} pinned vertex ids to leave exactly as they are; empty for a mesh nothing has
|
|
23
38
|
* locked yet
|
|
39
|
+
* @param {number} [crease_angle] degrees; see {@link VGEO_CREASE_ANGLE}
|
|
24
40
|
*
|
|
25
41
|
* @author Alex Goldring
|
|
26
42
|
* @copyright Company Named Limited (c) 2026
|
|
27
43
|
*/
|
|
28
|
-
export function vgeo_compute_vertex_normals(mesh: VirtualGeometryMesh, pinned: Set<number
|
|
44
|
+
export function vgeo_compute_vertex_normals(mesh: VirtualGeometryMesh, pinned: Set<number>, crease_angle?: number): void;
|
|
29
45
|
//# sourceMappingURL=vgeo_compute_vertex_normals.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vgeo_compute_vertex_normals.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vgeo_compute_vertex_normals.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js"],"names":[],"mappings":"AA0BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,+EAPW,IAAI,MAAM,CAAC,iBAEX,MAAM,QA4MhB"}
|
|
@@ -1,22 +1,55 @@
|
|
|
1
1
|
import { assert } from "../../../../../../core/assert.js";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "../../../../../../core/geom/3d/topology/struct/binary/
|
|
3
|
+
NULL_POINTER
|
|
4
|
+
} from "../../../../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
|
|
5
|
+
import {
|
|
6
|
+
bt_face_compute_newell_normal
|
|
7
|
+
} from "../../../../../../core/geom/3d/topology/struct/binary/query/bt_face_compute_newell_normal.js";
|
|
5
8
|
import { VGEO_ATTRIBUTE } from "../../format/attribute/VGEO_ATTRIBUTE.js";
|
|
9
|
+
import { VGEO_CREASE_ANGLE } from "./VGEO_CREASE_ANGLE.js";
|
|
6
10
|
|
|
7
11
|
/**
|
|
8
|
-
* One
|
|
12
|
+
* One corner's normal, on its way into the format's channel.
|
|
9
13
|
* @type {Float32Array}
|
|
10
14
|
*/
|
|
11
15
|
const scratch_normal = new Float32Array(3);
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
18
|
+
* One face's normal, scaled by twice its area.
|
|
19
|
+
*
|
|
20
|
+
* Float32 because {@link bt_mesh_compute_vertex_normals} accumulates from a float32 scratch, and
|
|
21
|
+
* this pass has to reproduce that sum exactly: on a mesh with no crease it *is* that pass, and the
|
|
22
|
+
* whole claim below is that only geometry with a crease or a seam in it moves.
|
|
23
|
+
* @type {Float32Array}
|
|
24
|
+
*/
|
|
25
|
+
const scratch_face = new Float32Array(3);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Area-weighted normals of a mesh, split at its creases, written into its normal channel.
|
|
15
29
|
*
|
|
16
30
|
* The geometry a mesh actually has is the answer for that mesh: carrying a surviving vertex's
|
|
17
31
|
* original normal through a dozen collapses shades a coarse level by whichever vertices happened to
|
|
18
32
|
* win, which is visibly wrong.
|
|
19
33
|
*
|
|
34
|
+
* **Per corner group, not per vertex.** Averaging every face around a vertex is right for a surface
|
|
35
|
+
* and wrong for a corner. Two faces sharing an edge belong to the same group when the surface turns
|
|
36
|
+
* less than {@link VGEO_CREASE_ANGLE} across it; groups are the connected components that leaves,
|
|
37
|
+
* and each gets its own area-weighted average. A vertex on a smooth surface has exactly one, and
|
|
38
|
+
* this is then the pass it has always been. A box corner has three, and the eight vertices of a cube
|
|
39
|
+
* stop carrying a normal that is ninety degrees wrong for every face using it.
|
|
40
|
+
*
|
|
41
|
+
* Area weighting falls out of the arithmetic rather than being applied: Newell's normal *is* the
|
|
42
|
+
* face normal scaled by twice the area, so summing the raw face normals is the area-weighted sum.
|
|
43
|
+
* Which is the same thing {@link bt_mesh_compute_vertex_normals} does, one level down, for the whole
|
|
44
|
+
* vertex — and this reproduces its arithmetic step for step, down to the float32 face scratch and
|
|
45
|
+
* the reciprocal it scales by, so that a mesh without a crease in it comes out bit for bit the same
|
|
46
|
+
* as it did before any of this existed.
|
|
47
|
+
*
|
|
48
|
+
* An edge with anything other than two live triangles on it — a mesh boundary, a non-manifold fin —
|
|
49
|
+
* joins nothing. There is no pair of faces to ask the question of, and splitting is the conservative
|
|
50
|
+
* answer: it keeps each side's own normal rather than inventing an average across a join the mesh
|
|
51
|
+
* itself does not make.
|
|
52
|
+
*
|
|
20
53
|
* **Except where the vertex was pinned.** A pinned vertex is one the step was forbidden to move, and
|
|
21
54
|
* every group that touches it carries it — which is exactly what lets a cut place two levels of
|
|
22
55
|
* detail side by side without a crack. That guarantee has to cover what the vertex *carries*, not
|
|
@@ -25,51 +58,243 @@ const scratch_normal = new Float32Array(3);
|
|
|
25
58
|
* would disagree by however much the surface turns. So a pinned vertex keeps what it had, exactly
|
|
26
59
|
* as it keeps where it was, and the frame stays continuous across every cut the DAG admits.
|
|
27
60
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* which is where the encoder reads from.
|
|
31
|
-
*
|
|
32
|
-
* @param {VirtualGeometryMesh} mesh whose normal layer is sized by the vertex pool and so carries a
|
|
33
|
-
* slot for every live vertex by construction
|
|
61
|
+
* @param {VirtualGeometryMesh} mesh whose normal layer is sized by the loop pool and so carries a
|
|
62
|
+
* slot for every live corner by construction
|
|
34
63
|
* @param {Set<number>} pinned vertex ids to leave exactly as they are; empty for a mesh nothing has
|
|
35
64
|
* locked yet
|
|
65
|
+
* @param {number} [crease_angle] degrees; see {@link VGEO_CREASE_ANGLE}
|
|
36
66
|
*
|
|
37
67
|
* @author Alex Goldring
|
|
38
68
|
* @copyright Company Named Limited (c) 2026
|
|
39
69
|
*/
|
|
40
|
-
export function vgeo_compute_vertex_normals(mesh, pinned) {
|
|
70
|
+
export function vgeo_compute_vertex_normals(mesh, pinned, crease_angle = VGEO_CREASE_ANGLE) {
|
|
41
71
|
const normals = mesh.layers[VGEO_ATTRIBUTE.NORMAL];
|
|
42
72
|
|
|
43
73
|
assert.notNull(normals, 'mesh normal channel');
|
|
44
74
|
|
|
45
75
|
const topology = mesh.topology;
|
|
46
76
|
|
|
47
|
-
|
|
77
|
+
const face_pool = topology.faces;
|
|
78
|
+
const loop_pool = topology.loops;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Each face's normal scaled by twice its area, which is Newell's as it comes.
|
|
82
|
+
* @type {Float64Array}
|
|
83
|
+
*/
|
|
84
|
+
const face_normal = new Float64Array(face_pool.size * 3);
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Its length, so the angle test does not recompute one.
|
|
88
|
+
* @type {Float64Array}
|
|
89
|
+
*/
|
|
90
|
+
const face_length = new Float64Array(face_pool.size);
|
|
91
|
+
|
|
92
|
+
for (let face = 0; face < face_pool.size; face++) {
|
|
93
|
+
if (!face_pool.is_allocated(face)) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (topology.face_read_loop(face) === NULL_POINTER) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
bt_face_compute_newell_normal(scratch_face, 0, topology, face);
|
|
102
|
+
|
|
103
|
+
const nx = scratch_face[0];
|
|
104
|
+
const ny = scratch_face[1];
|
|
105
|
+
const nz = scratch_face[2];
|
|
106
|
+
|
|
107
|
+
face_normal[face * 3] = nx;
|
|
108
|
+
face_normal[face * 3 + 1] = ny;
|
|
109
|
+
face_normal[face * 3 + 2] = nz;
|
|
48
110
|
|
|
49
|
-
|
|
111
|
+
face_length[face] = Math.sqrt(nx * nx + ny * ny + nz * nz);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Union-find over corners: two corners of one vertex share a root when the surface between them
|
|
116
|
+
* never turned far enough to be a crease.
|
|
117
|
+
* @type {Uint32Array}
|
|
118
|
+
*/
|
|
119
|
+
const group = new Uint32Array(loop_pool.size);
|
|
120
|
+
|
|
121
|
+
for (let loop = 0; loop < loop_pool.size; loop++) {
|
|
122
|
+
group[loop] = loop;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const smooth_cosine = Math.cos((crease_angle * Math.PI) / 180);
|
|
126
|
+
|
|
127
|
+
const edge_pool = topology.edges;
|
|
50
128
|
|
|
51
|
-
for (let
|
|
52
|
-
if (!
|
|
53
|
-
// a released slot's normal is whatever the vertex that used to live there left behind
|
|
129
|
+
for (let edge = 0; edge < edge_pool.size; edge++) {
|
|
130
|
+
if (!edge_pool.is_allocated(edge)) {
|
|
54
131
|
continue;
|
|
55
132
|
}
|
|
56
133
|
|
|
57
|
-
|
|
134
|
+
const first_loop = topology.edge_read_loop(edge);
|
|
135
|
+
|
|
136
|
+
if (first_loop === NULL_POINTER) {
|
|
58
137
|
continue;
|
|
59
138
|
}
|
|
60
139
|
|
|
61
|
-
|
|
140
|
+
let left = NULL_POINTER;
|
|
141
|
+
let right = NULL_POINTER;
|
|
142
|
+
let live = 0;
|
|
143
|
+
|
|
144
|
+
let loop = first_loop;
|
|
145
|
+
|
|
146
|
+
do {
|
|
147
|
+
const face = topology.loop_read_face(loop);
|
|
148
|
+
|
|
149
|
+
if (face !== NULL_POINTER && face_pool.is_allocated(face) && face_length[face] > 0) {
|
|
150
|
+
live++;
|
|
151
|
+
|
|
152
|
+
if (live === 1) {
|
|
153
|
+
left = loop;
|
|
154
|
+
} else if (live === 2) {
|
|
155
|
+
right = loop;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
62
158
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const z = scratch_normal[2];
|
|
159
|
+
loop = topology.loop_read_radial_next(loop);
|
|
160
|
+
} while (loop !== first_loop && loop !== NULL_POINTER);
|
|
66
161
|
|
|
67
|
-
if (
|
|
68
|
-
// An isolated or fully degenerate vertex has no surface to take a normal from; leave
|
|
69
|
-
// whatever it carried rather than inventing a direction.
|
|
162
|
+
if (live !== 2) {
|
|
70
163
|
continue;
|
|
71
164
|
}
|
|
72
165
|
|
|
73
|
-
|
|
166
|
+
const left_face = topology.loop_read_face(left);
|
|
167
|
+
const right_face = topology.loop_read_face(right);
|
|
168
|
+
|
|
169
|
+
const cosine = (
|
|
170
|
+
face_normal[left_face * 3] * face_normal[right_face * 3]
|
|
171
|
+
+ face_normal[left_face * 3 + 1] * face_normal[right_face * 3 + 1]
|
|
172
|
+
+ face_normal[left_face * 3 + 2] * face_normal[right_face * 3 + 2]
|
|
173
|
+
) / (face_length[left_face] * face_length[right_face]);
|
|
174
|
+
|
|
175
|
+
if (cosine < smooth_cosine) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/*
|
|
180
|
+
A loop's edge runs from its own vertex to the next loop's, so on an edge's loop those two
|
|
181
|
+
are the edge's endpoints. Matching them up by vertex is what pairs the corner of one face
|
|
182
|
+
with the corner of the other *at the same point* -- the two faces may be wound oppositely,
|
|
183
|
+
which is exactly when the naive pairing would join the wrong ends.
|
|
184
|
+
*/
|
|
185
|
+
const left_next = topology.loop_read_next(left);
|
|
186
|
+
const right_next = topology.loop_read_next(right);
|
|
187
|
+
|
|
188
|
+
if (topology.loop_read_vertex(left) === topology.loop_read_vertex(right)) {
|
|
189
|
+
join(group, left, right);
|
|
190
|
+
join(group, left_next, right_next);
|
|
191
|
+
} else {
|
|
192
|
+
join(group, left, right_next);
|
|
193
|
+
join(group, left_next, right);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Each group's area-weighted sum, accumulated at its root.
|
|
199
|
+
* @type {Float64Array}
|
|
200
|
+
*/
|
|
201
|
+
const accumulated = new Float64Array(loop_pool.size * 3);
|
|
202
|
+
|
|
203
|
+
/*
|
|
204
|
+
Over faces and then their corners, which is the order `bt_mesh_compute_vertex_normals` sums in.
|
|
205
|
+
The order of a float64 sum is part of its answer, and reproducing it is what makes a mesh with
|
|
206
|
+
no crease byte-identical rather than merely equivalent.
|
|
207
|
+
*/
|
|
208
|
+
for (let face = 0; face < face_pool.size; face++) {
|
|
209
|
+
if (!face_pool.is_allocated(face)) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const first_loop = topology.face_read_loop(face);
|
|
214
|
+
|
|
215
|
+
if (first_loop === NULL_POINTER) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const nx = face_normal[face * 3];
|
|
220
|
+
const ny = face_normal[face * 3 + 1];
|
|
221
|
+
const nz = face_normal[face * 3 + 2];
|
|
222
|
+
|
|
223
|
+
let loop = first_loop;
|
|
224
|
+
|
|
225
|
+
do {
|
|
226
|
+
const root = find(group, loop) * 3;
|
|
227
|
+
|
|
228
|
+
accumulated[root] += nx;
|
|
229
|
+
accumulated[root + 1] += ny;
|
|
230
|
+
accumulated[root + 2] += nz;
|
|
231
|
+
|
|
232
|
+
loop = topology.loop_read_next(loop);
|
|
233
|
+
} while (loop !== first_loop);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
for (let loop = 0; loop < loop_pool.size; loop++) {
|
|
237
|
+
if (!loop_pool.is_allocated(loop)) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (pinned.has(topology.loop_read_vertex(loop))) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const root = find(group, loop) * 3;
|
|
246
|
+
|
|
247
|
+
const x = accumulated[root];
|
|
248
|
+
const y = accumulated[root + 1];
|
|
249
|
+
const z = accumulated[root + 2];
|
|
250
|
+
|
|
251
|
+
const length = Math.sqrt(x * x + y * y + z * z);
|
|
252
|
+
|
|
253
|
+
if (length === 0) {
|
|
254
|
+
// An isolated corner, or a group whose faces cancel: no surface to take a normal from,
|
|
255
|
+
// so leave whatever it carried rather than inventing a direction.
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Scaled by the reciprocal rather than divided, because that is what
|
|
260
|
+
// `bt_mesh_compute_vertex_normals` does and `x * (1 / l)` is not `x / l`.
|
|
261
|
+
const scale = 1 / length;
|
|
262
|
+
|
|
263
|
+
scratch_normal[0] = x * scale;
|
|
264
|
+
scratch_normal[1] = y * scale;
|
|
265
|
+
scratch_normal[2] = z * scale;
|
|
266
|
+
|
|
267
|
+
normals.write(loop, scratch_normal, 0);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* @param {Uint32Array} group
|
|
273
|
+
* @param {number} index
|
|
274
|
+
* @returns {number}
|
|
275
|
+
*/
|
|
276
|
+
function find(group, index) {
|
|
277
|
+
let root = index;
|
|
278
|
+
|
|
279
|
+
while (group[root] !== root) {
|
|
280
|
+
group[root] = group[group[root]];
|
|
281
|
+
|
|
282
|
+
root = group[root];
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return root;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* @param {Uint32Array} group
|
|
290
|
+
* @param {number} a
|
|
291
|
+
* @param {number} b
|
|
292
|
+
*/
|
|
293
|
+
function join(group, a, b) {
|
|
294
|
+
const root_a = find(group, a);
|
|
295
|
+
const root_b = find(group, b);
|
|
296
|
+
|
|
297
|
+
if (root_a !== root_b) {
|
|
298
|
+
group[root_b] = root_a;
|
|
74
299
|
}
|
|
75
300
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Tangents of a mesh, written into its tangent channel.
|
|
3
3
|
*
|
|
4
4
|
* A tangent is a direction *in the texture parameterization*, so where the mesh carries a `UV0` this
|
|
5
|
-
* is Lengyel's per-triangle solve accumulated per
|
|
5
|
+
* is Lengyel's per-triangle solve accumulated per **wedge** and orthogonalized against the normal —
|
|
6
6
|
* {@link geometry_build_tangents}, the same pass {@link Geometry#computeTangents} runs, so an asset
|
|
7
7
|
* that goes through the virtual-geometry builder gets the frame it would have got anywhere else.
|
|
8
8
|
* Where the mesh carries no UVs there is no parameterization to be tangent to, and the frame becomes
|
|
@@ -12,20 +12,24 @@
|
|
|
12
12
|
* the format's flat default, which is parallel to the normal over a whole band of any closed
|
|
13
13
|
* surface and degenerates the frame there.
|
|
14
14
|
*
|
|
15
|
+
* **Per wedge, and that is not a re-indexing of a per-vertex solve.** Lengyel's accumulation is over
|
|
16
|
+
* the triangles that share a value, and at a chart boundary the two sides do not: their UVs run in
|
|
17
|
+
* different directions and averaging them gives a tangent that is tangent to neither. So the solve
|
|
18
|
+
* is fed a mesh whose *vertices are the wedges* — the same substitution the cluster gather makes,
|
|
19
|
+
* and for the same reason — and the answer comes back one per wedge, which is then written to every
|
|
20
|
+
* corner of it.
|
|
21
|
+
*
|
|
15
22
|
* `pinned` carries the same meaning and the same reason as it does for
|
|
16
23
|
* {@link vgeo_compute_vertex_normals}: a vertex two groups share must carry byte-identical values in
|
|
17
24
|
* both, or the seam a cut is allowed to put between them shades as a crease.
|
|
18
25
|
*
|
|
19
|
-
*
|
|
20
|
-
* slots needs no compaction and no remap — a released slot is simply a triangle corner nothing
|
|
21
|
-
* names.
|
|
22
|
-
*
|
|
23
|
-
* @param {VirtualGeometryMesh} mesh whose tangent and normal layers are sized by the vertex pool
|
|
26
|
+
* @param {VirtualGeometryMesh} mesh whose tangent and normal layers are sized by the loop pool
|
|
24
27
|
* @param {Set<number>} pinned vertex ids to leave exactly as they are; empty for a mesh nothing has
|
|
25
28
|
* locked yet
|
|
29
|
+
* @param {BtWedgeSet} wedges which corners of each vertex shade as one
|
|
26
30
|
*
|
|
27
31
|
* @author Alex Goldring
|
|
28
32
|
* @copyright Company Named Limited (c) 2026
|
|
29
33
|
*/
|
|
30
|
-
export function vgeo_compute_vertex_tangents(mesh: VirtualGeometryMesh, pinned: Set<number
|
|
34
|
+
export function vgeo_compute_vertex_tangents(mesh: VirtualGeometryMesh, pinned: Set<number>, wedges: BtWedgeSet): void;
|
|
31
35
|
//# sourceMappingURL=vgeo_compute_vertex_tangents.d.ts.map
|
package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vgeo_compute_vertex_tangents.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vgeo_compute_vertex_tangents.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,gFAPW,IAAI,MAAM,CAAC,4BA2GrB"}
|