@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.
Files changed (482) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/binary/BitSet.d.ts +16 -0
  4. package/src/core/binary/BitSet.d.ts.map +1 -1
  5. package/src/core/binary/BitSet.js +159 -49
  6. package/src/core/binary/allocator/OffsetAllocator.d.ts +48 -0
  7. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  8. package/src/core/binary/allocator/OffsetAllocator.js +208 -9
  9. package/src/core/binary/compression/compress_bytes.d.ts +20 -0
  10. package/src/core/binary/compression/compress_bytes.d.ts.map +1 -0
  11. package/src/core/binary/compression/compress_bytes.js +35 -0
  12. package/src/core/binary/compression/decompress_bytes_into.d.ts +30 -0
  13. package/src/core/binary/compression/decompress_bytes_into.d.ts.map +1 -0
  14. package/src/core/binary/compression/decompress_bytes_into.js +87 -0
  15. package/src/core/binary/compression/deflate_decompress_bound.d.ts +27 -0
  16. package/src/core/binary/compression/deflate_decompress_bound.d.ts.map +1 -0
  17. package/src/core/binary/compression/deflate_decompress_bound.js +32 -0
  18. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts +24 -0
  19. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts.map +1 -0
  20. package/src/core/geom/3d/quadric/quadric_attribute_add.js +31 -0
  21. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts +46 -0
  22. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts.map +1 -0
  23. package/src/core/geom/3d/quadric/quadric_attribute_reduce.js +104 -0
  24. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts +62 -0
  25. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts.map +1 -0
  26. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.js +158 -0
  27. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts +21 -0
  28. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts.map +1 -0
  29. package/src/core/geom/3d/quadric/quadric_attribute_size.js +24 -0
  30. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts +34 -0
  31. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts.map +1 -0
  32. package/src/core/geom/3d/quadric/quadric_attribute_solve.js +55 -0
  33. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts +28 -0
  34. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts.map +1 -0
  35. package/src/core/geom/3d/quadric/quadric_attribute_sub.js +35 -0
  36. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +15 -0
  37. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
  38. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +35 -0
  39. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts +93 -0
  40. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts.map +1 -0
  41. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.js +128 -0
  42. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts +38 -0
  43. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -0
  44. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +113 -0
  45. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +47 -1
  46. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  47. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +677 -8
  48. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts +22 -0
  49. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts.map +1 -0
  50. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.js +46 -0
  51. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts +19 -0
  52. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts.map +1 -0
  53. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.js +49 -0
  54. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts +63 -0
  55. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts.map +1 -0
  56. package/src/core/graph/layout/layered/BoxLayoutOptions.js +80 -0
  57. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.d.ts +35 -0
  58. package/src/core/graph/layout/layered/LayoutBoxGraph.d.ts.map +1 -0
  59. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.js +53 -1
  60. package/src/core/graph/layout/layered/layout_assign_coordinates.d.ts.map +1 -0
  61. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.js +72 -68
  62. package/src/core/graph/layout/layered/layout_assign_layers.d.ts.map +1 -0
  63. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.js +4 -2
  64. package/src/core/graph/layout/layered/layout_break_cycles.d.ts.map +1 -0
  65. package/src/core/graph/layout/layered/layout_insert_lanes.d.ts.map +1 -0
  66. package/src/core/graph/layout/layered/layout_order_layers.d.ts.map +1 -0
  67. package/src/core/graph/layout/layered/layout_orient_links.d.ts.map +1 -0
  68. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +7 -51
  69. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  70. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +8 -69
  71. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +1 -1
  72. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +6 -6
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.js +1 -1
  74. package/src/engine/graphics3/DebugDrawSystem.d.ts +7 -5
  75. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  76. package/src/engine/graphics3/DebugDrawSystem.js +206 -203
  77. package/src/engine/graphics3/DecalSystem.d.ts +4 -5
  78. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  79. package/src/engine/graphics3/DecalSystem.js +5 -5
  80. package/src/engine/graphics3/FogOfWarSystem.d.ts +7 -12
  81. package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
  82. package/src/engine/graphics3/FogOfWarSystem.js +8 -12
  83. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -230
  84. package/src/shade/RENDERER_CONTRACT.md +12 -7
  85. package/src/shade/playground/caldera/README.md +529 -0
  86. package/src/shade/playground/caldera/caldera_format.d.ts +151 -0
  87. package/src/shade/playground/caldera/caldera_format.d.ts.map +1 -0
  88. package/src/shade/playground/caldera/caldera_format.js +241 -0
  89. package/src/shade/playground/caldera/index.html +126 -0
  90. package/src/shade/playground/caldera/main.d.ts.map +1 -0
  91. package/src/shade/playground/caldera/main.js +1565 -0
  92. package/src/shade/playground/mesh_row_ceiling/README.md +85 -0
  93. package/src/shade/playground/mesh_row_ceiling/index.html +31 -0
  94. package/src/shade/playground/mesh_row_ceiling/main.d.ts +2 -0
  95. package/src/shade/playground/mesh_row_ceiling/main.d.ts.map +1 -0
  96. package/src/shade/playground/mesh_row_ceiling/main.js +389 -0
  97. package/src/shade/playground/vgeo_runtime/README.md +5 -3
  98. package/src/shade/playground/vgeo_runtime/main.js +3 -2
  99. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +3 -3
  100. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -1
  101. package/src/shade/playground/vgeo_runtime/sample_asset.js +3 -3
  102. package/src/shade/playground/vgeo_scene/README.md +103 -24
  103. package/src/shade/playground/vgeo_scene/main.js +525 -24
  104. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  105. package/src/shade/renderer/GraphicsContext.js +6 -0
  106. package/src/shade/renderer/Renderer.d.ts +2 -0
  107. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  108. package/src/shade/renderer/Renderer.js +23 -0
  109. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  110. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +100 -8
  111. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +69 -33
  112. package/src/shade/renderer/extension/RenderExtension.d.ts +15 -18
  113. package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
  114. package/src/shade/renderer/extension/RenderExtension.js +15 -19
  115. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts +5 -5
  116. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts.map +1 -1
  117. package/src/shade/renderer/extension/RenderExtensionRegistry.js +29 -166
  118. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  119. package/src/shade/renderer/geometry/GPUGeometryManager.js +73 -16
  120. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  121. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +18 -3
  122. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +663 -0
  123. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +100 -5
  124. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  125. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +688 -81
  126. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +540 -0
  127. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +155 -64
  128. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +30 -13
  129. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +3 -3
  130. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +358 -0
  131. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +57 -7
  132. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  133. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +63 -9
  134. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts +40 -0
  135. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts.map +1 -0
  136. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js +24 -0
  137. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts +91 -0
  138. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts.map +1 -0
  139. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.js +91 -0
  140. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts +24 -0
  141. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts.map +1 -0
  142. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.js +25 -0
  143. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts +77 -0
  144. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts.map +1 -0
  145. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.js +84 -0
  146. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +19 -6
  147. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -1
  148. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.js +20 -7
  149. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts +19 -0
  150. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts.map +1 -0
  151. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.js +58 -0
  152. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts +18 -0
  153. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts.map +1 -0
  154. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.js +116 -0
  155. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts +18 -0
  156. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -0
  157. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +545 -0
  158. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts +16 -0
  159. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -0
  160. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +110 -0
  161. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +2 -27
  162. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -1
  163. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.js +120 -1564
  164. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts +26 -0
  165. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts.map +1 -0
  166. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js +123 -0
  167. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts +26 -0
  168. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts.map +1 -0
  169. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js +78 -0
  170. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts +24 -0
  171. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -0
  172. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +337 -0
  173. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts +29 -0
  174. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -0
  175. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +147 -0
  176. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts +37 -0
  177. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts.map +1 -0
  178. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.js +243 -0
  179. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts +29 -0
  180. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -0
  181. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +117 -0
  182. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts +46 -0
  183. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts.map +1 -0
  184. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.js +45 -0
  185. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +64 -0
  186. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -0
  187. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +68 -0
  188. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +12 -7
  189. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -1
  190. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.js +33 -11
  191. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts +58 -0
  192. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts.map +1 -0
  193. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js +79 -0
  194. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts +39 -0
  195. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts.map +1 -0
  196. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js +68 -0
  197. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts +53 -0
  198. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts.map +1 -0
  199. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js +243 -0
  200. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +24 -8
  201. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -1
  202. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +250 -25
  203. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +12 -8
  204. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -1
  205. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js +58 -50
  206. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +8 -1
  207. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -1
  208. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.js +18 -3
  209. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts +38 -0
  210. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts.map +1 -0
  211. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.js +81 -0
  212. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +23 -5
  213. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -1
  214. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.js +28 -21
  215. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.js +1 -1
  216. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
  217. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +224 -60
  218. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +15 -0
  219. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -1
  220. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.js +17 -0
  221. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +17 -0
  222. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -1
  223. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.js +19 -0
  224. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +10 -1
  225. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -1
  226. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.js +103 -9
  227. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +14 -2
  228. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -1
  229. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js +38 -14
  230. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts +6 -2
  231. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  232. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +28 -5
  233. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts +32 -0
  234. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts.map +1 -0
  235. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.js +93 -0
  236. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +20 -6
  237. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  238. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +22 -8
  239. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts +16 -0
  240. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts.map +1 -0
  241. package/src/shade/renderer/geometry/virtual/format/attribute/{vgeo_layers_copy_vertex.js → vgeo_layers_copy_corner.js} +8 -8
  242. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts +18 -7
  243. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts.map +1 -1
  244. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +19 -8
  245. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.d.ts +3 -3
  246. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +3 -3
  247. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts +27 -0
  248. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts.map +1 -0
  249. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.js +97 -0
  250. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts +7 -3
  251. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts.map +1 -1
  252. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +21 -11
  253. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts +21 -0
  254. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts.map +1 -0
  255. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.js +41 -0
  256. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +19 -1
  257. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  258. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +20 -1
  259. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts +25 -0
  260. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts.map +1 -0
  261. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.js +24 -0
  262. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts +5 -0
  263. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts.map +1 -1
  264. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +5 -0
  265. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.d.ts.map +1 -1
  266. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +5 -0
  267. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts +10 -3
  268. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts.map +1 -1
  269. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +37 -3
  270. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +21 -13
  271. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  272. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +37 -13
  273. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts +8 -2
  274. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts.map +1 -1
  275. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +14 -2
  276. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +18 -0
  277. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  278. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +19 -1
  279. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +6 -0
  280. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts +21 -0
  281. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts.map +1 -0
  282. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.js +20 -0
  283. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts +9 -0
  284. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts.map +1 -1
  285. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +10 -1
  286. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +1 -2
  287. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +10 -3
  288. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts +20 -0
  289. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts.map +1 -0
  290. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.js +43 -0
  291. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +4 -2
  292. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  293. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +8 -4
  294. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  295. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +2 -2
  296. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts +6 -4
  297. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts.map +1 -1
  298. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.js +6 -4
  299. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +13 -2
  300. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  301. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +13 -2
  302. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +5 -1
  303. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -1
  304. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +14 -1
  305. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -1
  306. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +1 -0
  307. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts +4 -1
  308. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts.map +1 -1
  309. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.js +53 -11
  310. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  311. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +7 -3
  312. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts +12 -2
  313. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  314. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +111 -33
  315. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts +6 -2
  316. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  317. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +112 -42
  318. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts +2 -2
  319. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  320. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +51 -21
  321. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +385 -0
  322. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
  323. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +9 -0
  324. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  325. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +34 -0
  326. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -1
  327. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +18 -0
  328. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  329. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +47 -19
  330. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +1 -0
  331. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +22 -4
  332. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +7 -2
  333. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -1
  334. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +8 -3
  335. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  336. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +10 -0
  337. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  338. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +13 -11
  339. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -1
  340. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +13 -11
  341. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  342. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +4 -0
  343. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  344. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -4
  345. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +6 -2
  346. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  347. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +90 -12
  348. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts +22 -0
  349. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts.map +1 -0
  350. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.js +21 -0
  351. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  352. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +13 -8
  353. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  354. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -6
  355. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  356. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +4 -12
  357. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  358. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  359. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +4 -5
  360. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  361. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +5 -3
  362. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.d.ts.map +1 -1
  363. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js +11 -4
  364. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  365. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +4 -3
  366. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  367. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +3 -0
  368. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
  369. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +94 -90
  370. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  371. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +13 -5
  372. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
  373. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +96 -89
  374. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  375. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +3 -1
  376. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
  377. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +4 -1
  378. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
  379. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +100 -89
  380. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
  381. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +31 -7
  382. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  383. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +1 -7
  384. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
  385. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +161 -153
  386. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  387. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +2 -7
  388. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  389. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +4 -8
  390. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  391. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +5 -8
  392. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +25 -0
  393. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts.map +1 -0
  394. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +24 -0
  395. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +10 -0
  396. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  397. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +30 -21
  398. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +0 -1
  399. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +0 -1
  400. package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +0 -1
  401. package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +0 -1
  402. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +0 -1
  403. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +0 -1
  404. package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +0 -1
  405. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts +0 -61
  406. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +0 -1
  407. package/src/shade/playground/vgeo_viewer/main.d.ts.map +0 -1
  408. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts +0 -18
  409. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +0 -1
  410. package/src/shade/playground/vgeo_viewer/select_cut.d.ts +0 -173
  411. package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +0 -1
  412. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts +0 -52
  413. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts.map +0 -1
  414. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts +0 -24
  415. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts.map +0 -1
  416. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts +0 -32
  417. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts.map +0 -1
  418. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts +0 -59
  419. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts.map +0 -1
  420. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts +0 -44
  421. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts.map +0 -1
  422. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts +0 -20
  423. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts.map +0 -1
  424. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts +0 -73
  425. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts.map +0 -1
  426. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +0 -13
  427. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +0 -1
  428. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts +0 -12
  429. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts.map +0 -1
  430. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts +0 -36
  431. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts.map +0 -1
  432. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts +0 -13
  433. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts.map +0 -1
  434. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts +0 -19
  435. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts.map +0 -1
  436. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts +0 -29
  437. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts.map +0 -1
  438. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts +0 -31
  439. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts.map +0 -1
  440. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts +0 -18
  441. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts.map +0 -1
  442. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts +0 -14
  443. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts.map +0 -1
  444. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts +0 -12
  445. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts.map +0 -1
  446. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts +0 -14
  447. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts.map +0 -1
  448. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts +0 -11
  449. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts.map +0 -1
  450. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts +0 -46
  451. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts.map +0 -1
  452. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +0 -22
  453. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +0 -1
  454. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts +0 -29
  455. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts.map +0 -1
  456. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts +0 -9
  457. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts.map +0 -1
  458. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts +0 -10
  459. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts.map +0 -1
  460. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts +0 -15
  461. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts.map +0 -1
  462. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts +0 -16
  463. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts.map +0 -1
  464. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts +0 -10
  465. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts.map +0 -1
  466. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +0 -17
  467. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +0 -1
  468. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts +0 -3
  469. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts.map +0 -1
  470. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts +0 -8
  471. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +0 -1
  472. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.d.ts +0 -0
  473. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.d.ts +0 -0
  474. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.d.ts +0 -0
  475. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.js +0 -0
  476. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.d.ts +0 -0
  477. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.js +0 -0
  478. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.d.ts +0 -0
  479. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.js +0 -0
  480. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.d.ts +0 -0
  481. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.js +0 -0
  482. /package/src/shade/playground/{vgeo_viewer → caldera}/main.d.ts +0 -0
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Which vertices a group must not move, and which boundary edges must survive its simplification.
3
+ *
4
+ * A vertex is locked when any face outside the group touches it — not merely when it sits on a
5
+ * shared *edge*. The weaker rule leaks: two groups can meet at a single non-manifold vertex with no
6
+ * edge between them, and each would then move that vertex somewhere else, tearing the surface at a
7
+ * point no boundary walk would have flagged.
8
+ *
9
+ * "Outside" includes frontier clusters this round left alone, which is what keeps a band's seam with
10
+ * the rest of the frontier from opening.
11
+ *
12
+ * @param {BinaryTopology} topology
13
+ * @param {number[]} group_face_ids
14
+ * @param {Int32Array} group_of_face one entry per face slot, holding the group each face belongs to
15
+ * @param {number} group_index
16
+ * @returns {{locked: Set<number>, polyline: number[][]}} locked vertex ids, and the `[v1, v2]` pairs
17
+ * of every edge this group shares with the outside
18
+ *
19
+ * @author Alex Goldring
20
+ * @copyright Company Named Limited (c) 2026
21
+ */
22
+ export function vgeo_compute_group_boundary(topology: BinaryTopology, group_face_ids: number[], group_of_face: Int32Array, group_index: number): {
23
+ locked: Set<number>;
24
+ polyline: number[][];
25
+ };
26
+ //# sourceMappingURL=vgeo_compute_group_boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_compute_group_boundary.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js"],"names":[],"mappings":"AAiEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,sFATW,MAAM,EAAE,iBACR,UAAU,eACV,MAAM,GACJ;IAAC,MAAM,EAAE,IAAI,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAA;CAAC,CA0CvD"}
@@ -0,0 +1,123 @@
1
+ import { NULL_POINTER } from "../../../../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
2
+
3
+ /**
4
+ * Does any face outside this group use the edge?
5
+ *
6
+ * @param {BinaryTopology} topology
7
+ * @param {number} edge
8
+ * @param {Int32Array} group_of_face
9
+ * @param {number} group_index
10
+ * @returns {boolean}
11
+ */
12
+ function edge_touches_outside(topology, edge, group_of_face, group_index) {
13
+ const first_loop = topology.edge_read_loop(edge);
14
+
15
+ if (first_loop === NULL_POINTER) {
16
+ return false;
17
+ }
18
+
19
+ let loop = first_loop;
20
+
21
+ do {
22
+ const face = topology.loop_read_face(loop);
23
+
24
+ if (face !== NULL_POINTER && group_of_face[face] !== group_index) {
25
+ return true;
26
+ }
27
+
28
+ loop = topology.loop_read_radial_next(loop);
29
+ } while (loop !== first_loop && loop !== NULL_POINTER);
30
+
31
+ return false;
32
+ }
33
+
34
+ /**
35
+ * Does any face outside this group use the vertex? Walks the vertex's disk cycle and each edge's
36
+ * radial cycle, so the answer is local to the vertex rather than a scan of the frontier.
37
+ *
38
+ * @param {BinaryTopology} topology
39
+ * @param {number} vertex
40
+ * @param {Int32Array} group_of_face
41
+ * @param {number} group_index
42
+ * @returns {boolean}
43
+ */
44
+ function vertex_touches_outside(topology, vertex, group_of_face, group_index) {
45
+ const first_edge = topology.vertex_read_edge(vertex);
46
+
47
+ if (first_edge === NULL_POINTER) {
48
+ return false;
49
+ }
50
+
51
+ let edge = first_edge;
52
+
53
+ do {
54
+ if (edge_touches_outside(topology, edge, group_of_face, group_index)) {
55
+ return true;
56
+ }
57
+
58
+ edge = (topology.edge_read_vertex1(edge) === vertex)
59
+ ? topology.edge_read_v1_disk_next(edge)
60
+ : topology.edge_read_v2_disk_next(edge);
61
+ } while (edge !== first_edge && edge !== NULL_POINTER);
62
+
63
+ return false;
64
+ }
65
+
66
+ /**
67
+ * Which vertices a group must not move, and which boundary edges must survive its simplification.
68
+ *
69
+ * A vertex is locked when any face outside the group touches it — not merely when it sits on a
70
+ * shared *edge*. The weaker rule leaks: two groups can meet at a single non-manifold vertex with no
71
+ * edge between them, and each would then move that vertex somewhere else, tearing the surface at a
72
+ * point no boundary walk would have flagged.
73
+ *
74
+ * "Outside" includes frontier clusters this round left alone, which is what keeps a band's seam with
75
+ * the rest of the frontier from opening.
76
+ *
77
+ * @param {BinaryTopology} topology
78
+ * @param {number[]} group_face_ids
79
+ * @param {Int32Array} group_of_face one entry per face slot, holding the group each face belongs to
80
+ * @param {number} group_index
81
+ * @returns {{locked: Set<number>, polyline: number[][]}} locked vertex ids, and the `[v1, v2]` pairs
82
+ * of every edge this group shares with the outside
83
+ *
84
+ * @author Alex Goldring
85
+ * @copyright Company Named Limited (c) 2026
86
+ */
87
+ export function vgeo_compute_group_boundary(topology, group_face_ids, group_of_face, group_index) {
88
+ const vertices = new Set();
89
+ const edges = new Set();
90
+
91
+ for (const face of group_face_ids) {
92
+ const first_loop = topology.face_read_loop(face);
93
+
94
+ let loop = first_loop;
95
+
96
+ do {
97
+ vertices.add(topology.loop_read_vertex(loop));
98
+ edges.add(topology.loop_read_edge(loop));
99
+
100
+ loop = topology.loop_read_next(loop);
101
+ } while (loop !== first_loop);
102
+ }
103
+
104
+ const locked = new Set();
105
+
106
+ for (const vertex of vertices) {
107
+ if (vertex_touches_outside(topology, vertex, group_of_face, group_index)) {
108
+ locked.add(vertex);
109
+ }
110
+ }
111
+
112
+ const polyline = [];
113
+
114
+ for (const edge of edges) {
115
+ if (!edge_touches_outside(topology, edge, group_of_face, group_index)) {
116
+ continue;
117
+ }
118
+
119
+ polyline.push([topology.edge_read_vertex1(edge), topology.edge_read_vertex2(edge)]);
120
+ }
121
+
122
+ return { locked, polyline };
123
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The bands a round tries, in the order it tries them.
3
+ *
4
+ * Each is one error *octave*: `[e, e · growth]` for each distinct error the frontier holds, finest
5
+ * first. An octave rather than a running threshold is what bounds how far apart two clusters in one
6
+ * group can be — a group shares a single parent error, so merging a nearly-exact cluster with a
7
+ * badly-approximated one drags the exact one up to the other's error for nothing. It is also what
8
+ * lets a cluster *wait*: geometry outside the octave is simply not this round's business.
9
+ *
10
+ * The last band is the whole frontier. It is the escape hatch, not the plan: a frontier of two
11
+ * clusters an order of magnitude apart in error has no octave holding both, and merging them at a
12
+ * wide error span still beats never reaching a root.
13
+ *
14
+ * @param {number[]} errors the frontier's cluster errors, ascending
15
+ * @param {number} growth
16
+ * @param {number} min_fraction least share of the frontier a band may cover
17
+ * @returns {{start: number, end: number}[]} half-open ranges into the error order, deduplicated
18
+ *
19
+ * @author Alex Goldring
20
+ * @copyright Company Named Limited (c) 2026
21
+ */
22
+ export function vgeo_error_bands(errors: number[], growth: number, min_fraction: number): {
23
+ start: number;
24
+ end: number;
25
+ }[];
26
+ //# sourceMappingURL=vgeo_error_bands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_error_bands.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,yCARW,MAAM,EAAE,UACR,MAAM,gBACN,MAAM,GACJ;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,EAAE,CA6D1C"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The bands a round tries, in the order it tries them.
3
+ *
4
+ * Each is one error *octave*: `[e, e · growth]` for each distinct error the frontier holds, finest
5
+ * first. An octave rather than a running threshold is what bounds how far apart two clusters in one
6
+ * group can be — a group shares a single parent error, so merging a nearly-exact cluster with a
7
+ * badly-approximated one drags the exact one up to the other's error for nothing. It is also what
8
+ * lets a cluster *wait*: geometry outside the octave is simply not this round's business.
9
+ *
10
+ * The last band is the whole frontier. It is the escape hatch, not the plan: a frontier of two
11
+ * clusters an order of magnitude apart in error has no octave holding both, and merging them at a
12
+ * wide error span still beats never reaching a root.
13
+ *
14
+ * @param {number[]} errors the frontier's cluster errors, ascending
15
+ * @param {number} growth
16
+ * @param {number} min_fraction least share of the frontier a band may cover
17
+ * @returns {{start: number, end: number}[]} half-open ranges into the error order, deduplicated
18
+ *
19
+ * @author Alex Goldring
20
+ * @copyright Company Named Limited (c) 2026
21
+ */
22
+ export function vgeo_error_bands(errors, growth, min_fraction) {
23
+ /**
24
+ * @param {number} value
25
+ * @returns {number} first position whose error exceeds `value`
26
+ */
27
+ function upper_bound(value) {
28
+ let low = 0;
29
+ let high = errors.length;
30
+
31
+ while (low < high) {
32
+ const middle = (low + high) >> 1;
33
+
34
+ if (errors[middle] <= value) {
35
+ low = middle + 1;
36
+ } else {
37
+ high = middle;
38
+ }
39
+ }
40
+
41
+ return low;
42
+ }
43
+
44
+ const result = [];
45
+ const seen = new Set();
46
+
47
+ /**
48
+ * @param {number} start
49
+ * @param {number} end
50
+ */
51
+ function add(start, end) {
52
+ const key = `${start}:${end}`;
53
+
54
+ if (end - start < 2 || seen.has(key)) {
55
+ return;
56
+ }
57
+
58
+ seen.add(key);
59
+
60
+ result.push({ start, end });
61
+ }
62
+
63
+ const minimum = Math.max(2, Math.ceil(errors.length * min_fraction));
64
+
65
+ let cursor = 0;
66
+
67
+ while (cursor < errors.length) {
68
+ const low = errors[cursor];
69
+
70
+ add(cursor, Math.max(upper_bound(low * growth), Math.min(errors.length, cursor + minimum)));
71
+
72
+ cursor = upper_bound(low);
73
+ }
74
+
75
+ add(0, errors.length);
76
+
77
+ return result;
78
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Partition a band of the frontier into groups of roughly `group_size`.
3
+ *
4
+ * The partition runs **inside each connected component** of the cluster graph, not across the band as
5
+ * a whole. Partitioning globally and splitting the disconnected parts afterwards looks equivalent and
6
+ * is not: a scene assembled from thousands of separate shells has a cluster graph in thousands of
7
+ * pieces, and a balanced global partition draws each part from several of them, so the connectivity
8
+ * split then shreds nearly every group down to a single cluster.
9
+ *
10
+ * What is left over after that — every cluster alone in its component — is bundled by proximity
11
+ * instead, because for those clusters there is no adjacency left to respect and no other way to the
12
+ * root.
13
+ *
14
+ * @param {VGeoFrontier} frontier
15
+ * @param {number[]} band cluster indices this round may consume, ascending
16
+ * @param {object} cluster_graph as {@link vgeo_build_cluster_graph} returns
17
+ * @param {number} group_size
18
+ * @returns {number[][]} groups of at least two clusters each; clusters left out stay in the frontier
19
+ *
20
+ * @author Alex Goldring
21
+ * @copyright Company Named Limited (c) 2026
22
+ */
23
+ export function vgeo_partition_into_groups(frontier: VGeoFrontier, band: number[], cluster_graph: object, group_size: number): number[][];
24
+ //# sourceMappingURL=vgeo_partition_into_groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_partition_into_groups.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js"],"names":[],"mappings":"AA0MA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,yEARW,MAAM,EAAE,iBACR,MAAM,cACN,MAAM,GACJ,MAAM,EAAE,EAAE,CAqHtB"}
@@ -0,0 +1,337 @@
1
+ import { assert } from "../../../../../../core/assert.js";
2
+ import { aabb3_from_v3_array } from "../../../../../../core/geom/3d/aabb/aabb3_from_v3_array.js";
3
+ import { v3_morton_encode_bounded } from "../../../../../../core/geom/3d/morton/v3_morton_encode_bounded.js";
4
+ import { VGEO_MAX_CLUSTER_TRIANGLE_COUNT } from "../../format/cluster/VGEO_MAX_CLUSTER_TRIANGLE_COUNT.js";
5
+ import { VGEO_MAX_CLUSTER_VERTEX_COUNT } from "../../format/cluster/VGEO_MAX_CLUSTER_VERTEX_COUNT.js";
6
+ import { VGEO_MAX_GROUP_CLUSTER_COUNT } from "../../format/page/VGEO_MAX_GROUP_CLUSTER_COUNT.js";
7
+ import { vgeo_graph_components } from "../partition/vgeo_graph_components.js";
8
+ import { vgeo_partition_subgraph } from "../partition/vgeo_partition_subgraph.js";
9
+
10
+ /**
11
+ * Fixed so that the same frontier always groups the same way.
12
+ * @readonly
13
+ * @type {number}
14
+ */
15
+ const GROUP_SEED = 0x6D05;
16
+
17
+ /**
18
+ * Bundle clusters that have no one to merge with along a Morton curve.
19
+ *
20
+ * A cluster alone in its connected component cannot be coarsened: halving its triangles leaves one
21
+ * cluster where there was one cluster, and the DAG stands still. The only way it ever reaches a root
22
+ * is bundled with geometry it shares no edge with, and the only thing left to choose them by is
23
+ * where they are. That is a real cost — a cluster spanning two islands carries a sphere containing
24
+ * both — which is why this is the fallback and adjacency is the rule.
25
+ *
26
+ * @param {VGeoFrontier} frontier
27
+ * @param {number[]} loose cluster indices, each alone in its component
28
+ * @param {number} group_size
29
+ * @returns {number[][]} groups of at least two; a single leftover is returned to the frontier
30
+ */
31
+ function bundle_loose_clusters(frontier, loose, group_size) {
32
+ if (loose.length < 2) {
33
+ return [];
34
+ }
35
+
36
+ // Gathered rather than read through the cluster list twice: the bounds and the codes are the
37
+ // same points, and this is the shape `vgeo_split_face_set_packed` already packs in.
38
+ const centres = new Float32Array(loose.length * 3);
39
+
40
+ loose.forEach((cluster, index) => {
41
+ const sphere = frontier.clusters[cluster].bounds_sphere;
42
+
43
+ centres[index * 3] = sphere[0];
44
+ centres[index * 3 + 1] = sphere[1];
45
+ centres[index * 3 + 2] = sphere[2];
46
+ });
47
+
48
+ const bounds = new Float32Array(6);
49
+
50
+ aabb3_from_v3_array(bounds, centres, centres.length);
51
+
52
+ /**
53
+ * @type {Map<number, number>}
54
+ */
55
+ const codes = new Map();
56
+
57
+ loose.forEach((cluster, index) => {
58
+ codes.set(cluster, v3_morton_encode_bounded(
59
+ centres[index * 3], centres[index * 3 + 1], centres[index * 3 + 2], bounds
60
+ ));
61
+ });
62
+
63
+ const order = loose.slice();
64
+
65
+ order.sort((a, b) => (codes.get(a) - codes.get(b)) || (a - b));
66
+
67
+ const result = [];
68
+
69
+ let bundle = [];
70
+ let triangles = 0;
71
+ let vertices = 0;
72
+ let packable = true;
73
+
74
+ for (const index of order) {
75
+ const cluster = frontier.clusters[index];
76
+
77
+ // Leaves small enough to end up in one cluster between them are worth bundling past the
78
+ // group size: what happens to them is a re-cut at no error, not a simplification, so a
79
+ // bigger bundle costs nothing in fidelity and is the difference between a scene of small
80
+ // parts filling its clusters and running them at a tenth of capacity. Anything else stops at
81
+ // the group size, where the size is a real trade against LOD lockstep.
82
+ const packs = packable
83
+ && cluster.child_group === undefined
84
+ && triangles + cluster.triangle_count <= VGEO_MAX_CLUSTER_TRIANGLE_COUNT
85
+ && vertices + cluster.vertex_count <= VGEO_MAX_CLUSTER_VERTEX_COUNT;
86
+
87
+ if (bundle.length >= group_size && !packs) {
88
+ result.push(bundle);
89
+
90
+ bundle = [];
91
+ triangles = 0;
92
+ vertices = 0;
93
+ packable = true;
94
+ }
95
+
96
+ bundle.push(index);
97
+
98
+ triangles += cluster.triangle_count;
99
+ vertices += cluster.vertex_count;
100
+
101
+ packable = packable && cluster.child_group === undefined;
102
+ }
103
+
104
+ if (bundle.length === 1 && result.length > 0) {
105
+ // A bundle of one merges nothing. Handing it to the bundle before it costs one cluster of
106
+ // spatial spread and is the difference between the frontier shrinking and it standing still.
107
+ result[result.length - 1].push(bundle[0]);
108
+ } else if (bundle.length > 1) {
109
+ result.push(bundle);
110
+ }
111
+
112
+ return result.filter((group) => group.length >= 2);
113
+ }
114
+
115
+ /**
116
+ * Fold every one-cluster piece into the adjacent piece it shares the most boundary with.
117
+ *
118
+ * The partitioner produces these constantly — it optimizes cut, not contiguity, so splitting its
119
+ * parts into connected pieces routinely leaves a cluster standing on its own. Such a cluster is not
120
+ * out of options, though: it sits inside a component that has plenty of neighbours, and the right
121
+ * answer is the nearest of them, not the proximity pool. Letting it fall through to the pool is how
122
+ * a lone shell sixty metres away ends up merged with a fragment of something else entirely.
123
+ *
124
+ * One forward pass is enough. Folding only ever grows a piece and empties the one it came from, so
125
+ * it cannot turn a piece of two into a piece of one — the singletons are exactly the ones present
126
+ * when the pass starts, and a singleton that has already absorbed another is no longer one.
127
+ *
128
+ * @param {number[][]} pieces of a single connected component of the band, each non-empty; every
129
+ * cluster in a singleton piece therefore has a neighbour in some other piece here
130
+ * @param {object} cluster_graph as {@link vgeo_build_cluster_graph} returns
131
+ * @returns {number[][]} non-empty pieces, with no singletons
132
+ */
133
+ function absorb_singleton_pieces(pieces, cluster_graph) {
134
+ if (pieces.length < 2) {
135
+ return pieces;
136
+ }
137
+
138
+ /**
139
+ * `cluster -> index of the piece holding it`.
140
+ * @type {Map<number, number>}
141
+ */
142
+ const piece_of = new Map();
143
+
144
+ const alive = pieces.map((piece) => piece.slice());
145
+
146
+ alive.forEach((piece, index) => {
147
+ for (const cluster of piece) {
148
+ piece_of.set(cluster, index);
149
+ }
150
+ });
151
+
152
+ for (let index = 0; index < alive.length; index++) {
153
+ if (alive[index].length !== 1) {
154
+ continue;
155
+ }
156
+
157
+ const cluster = alive[index][0];
158
+
159
+ /**
160
+ * `piece index -> boundary shared with this cluster`.
161
+ * @type {Map<number, number>}
162
+ */
163
+ const shared = new Map();
164
+
165
+ for (let i = cluster_graph.edge_addresses[cluster]; i < cluster_graph.edge_addresses[cluster + 1]; i++) {
166
+ const target = piece_of.get(cluster_graph.adjacency[i]);
167
+
168
+ if (target === undefined || target === index) {
169
+ continue;
170
+ }
171
+
172
+ shared.set(target, (shared.get(target) ?? 0) + cluster_graph.edge_weights[i]);
173
+ }
174
+
175
+ let best = -1;
176
+ let best_weight = -1;
177
+
178
+ // Sorted, so that two pieces sharing the same boundary length resolve the same way every
179
+ // time rather than however the adjacency happened to be walked.
180
+ for (const [target, weight] of Array.from(shared.entries()).sort((a, b) => a[0] - b[0])) {
181
+ if (weight > best_weight) {
182
+ best = target;
183
+ best_weight = weight;
184
+ }
185
+ }
186
+
187
+ assert.notEqual(
188
+ best, -1,
189
+ 'a lone cluster inside a connected component must border another piece of it'
190
+ );
191
+
192
+ alive[best].push(cluster);
193
+ alive[best].sort((a, b) => a - b);
194
+
195
+ piece_of.set(cluster, best);
196
+
197
+ alive[index] = [];
198
+ }
199
+
200
+ return alive.filter((piece) => piece.length > 0);
201
+ }
202
+
203
+ /**
204
+ * Partition a band of the frontier into groups of roughly `group_size`.
205
+ *
206
+ * The partition runs **inside each connected component** of the cluster graph, not across the band as
207
+ * a whole. Partitioning globally and splitting the disconnected parts afterwards looks equivalent and
208
+ * is not: a scene assembled from thousands of separate shells has a cluster graph in thousands of
209
+ * pieces, and a balanced global partition draws each part from several of them, so the connectivity
210
+ * split then shreds nearly every group down to a single cluster.
211
+ *
212
+ * What is left over after that — every cluster alone in its component — is bundled by proximity
213
+ * instead, because for those clusters there is no adjacency left to respect and no other way to the
214
+ * root.
215
+ *
216
+ * @param {VGeoFrontier} frontier
217
+ * @param {number[]} band cluster indices this round may consume, ascending
218
+ * @param {object} cluster_graph as {@link vgeo_build_cluster_graph} returns
219
+ * @param {number} group_size
220
+ * @returns {number[][]} groups of at least two clusters each; clusters left out stay in the frontier
221
+ *
222
+ * @author Alex Goldring
223
+ * @copyright Company Named Limited (c) 2026
224
+ */
225
+ export function vgeo_partition_into_groups(frontier, band, cluster_graph, group_size) {
226
+ const membership = new Int32Array(frontier.clusters.length).fill(-1);
227
+
228
+ /**
229
+ * Dense rather than a `Map`, and hoisted out of the component loop so it is one allocation per
230
+ * level. See {@link vgeo_partition_subgraph} for why the density is load-bearing rather than a
231
+ * micro-optimisation.
232
+ * @type {Uint32Array}
233
+ */
234
+ const local_index = new Uint32Array(frontier.clusters.length);
235
+
236
+ for (const cluster of band) {
237
+ membership[cluster] = 0;
238
+ }
239
+
240
+ const components = vgeo_graph_components(
241
+ cluster_graph.edge_addresses, cluster_graph.adjacency, band, membership, 0
242
+ );
243
+
244
+ const result = [];
245
+
246
+ /**
247
+ * Clusters with nobody adjacent to merge with.
248
+ * @type {number[]}
249
+ */
250
+ const loose = [];
251
+
252
+ let token = 0;
253
+
254
+ /**
255
+ * @param {number[]} piece
256
+ */
257
+ function accept(piece) {
258
+ if (piece.length < 2) {
259
+ loose.push(piece[0]);
260
+
261
+ return;
262
+ }
263
+
264
+ // The format caps a group at 4096 clusters. Nothing the size policy produces comes near it,
265
+ // but the cap is hard, so the chunking is here rather than assumed away.
266
+ for (let start = 0; start < piece.length; start += VGEO_MAX_GROUP_CLUSTER_COUNT) {
267
+ const chunk = piece.slice(start, start + VGEO_MAX_GROUP_CLUSTER_COUNT);
268
+
269
+ if (chunk.length < 2) {
270
+ loose.push(chunk[0]);
271
+
272
+ continue;
273
+ }
274
+
275
+ result.push(chunk);
276
+ }
277
+ }
278
+
279
+ for (const component of components) {
280
+ if (component.length < 2) {
281
+ // Alone in its component: no adjacency left anywhere, so proximity is the only rule that
282
+ // can still place it.
283
+ loose.push(component[0]);
284
+
285
+ continue;
286
+ }
287
+
288
+ if (component.length <= group_size) {
289
+ accept(component);
290
+
291
+ continue;
292
+ }
293
+
294
+ /**
295
+ * @type {number[][]}
296
+ */
297
+ const pieces = [];
298
+
299
+ const part_count = Math.ceil(component.length / group_size);
300
+
301
+ token++;
302
+
303
+ for (const cluster of component) {
304
+ membership[cluster] = token;
305
+ }
306
+
307
+ const parts = vgeo_partition_subgraph(
308
+ cluster_graph, component, membership, token, part_count, GROUP_SEED, local_index
309
+ );
310
+
311
+ for (const part of parts) {
312
+ token++;
313
+
314
+ for (const cluster of part) {
315
+ membership[cluster] = token;
316
+ }
317
+
318
+ for (const piece of vgeo_graph_components(
319
+ cluster_graph.edge_addresses, cluster_graph.adjacency, part, membership, token
320
+ )) {
321
+ pieces.push(piece);
322
+ }
323
+ }
324
+
325
+ for (const piece of absorb_singleton_pieces(pieces, cluster_graph)) {
326
+ accept(piece);
327
+ }
328
+ }
329
+
330
+ for (const bundle of bundle_loose_clusters(frontier, loose, group_size)) {
331
+ result.push(bundle);
332
+ }
333
+
334
+ result.sort((a, b) => a[0] - b[0]);
335
+
336
+ return result;
337
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * One round: pick a band, group it, simplify each group, and report what it produced.
3
+ *
4
+ * Every group is speculative and judged on its own. One that comes back with no fewer clusters than
5
+ * it consumed is simply dropped — its clusters return to the frontier, to be grouped differently by
6
+ * a later round — rather than failing the round for everyone else. A group that cannot be
7
+ * simplified is no different in kind from a group that could not be formed, and the frontier already
8
+ * knows what to do with those: nothing, for now.
9
+ *
10
+ * The round as a whole is accepted only when it *strictly* shrinks the frontier. Failing that it
11
+ * widens the band, and failing that it grows the group — small groups starve the simplifier, and a
12
+ * wider band gives a fine region coarser neighbours to merge with.
13
+ *
14
+ * @param {VGeoFrontier} frontier
15
+ * @param {number} level of the parents this round would produce
16
+ * @param {VGeoLevelOptions} options
17
+ * @returns {{steps: VGeoGroupStep[], repacks: VGeoGroupRepack[], merged: Set<number>}|undefined}
18
+ * what to commit and which frontier clusters it consumed; `undefined` when nothing this round
19
+ * could try made the frontier smaller
20
+ *
21
+ * @author Alex Goldring
22
+ * @copyright Company Named Limited (c) 2026
23
+ */
24
+ export function vgeo_run_round(frontier: VGeoFrontier, level: number, options: VGeoLevelOptions): {
25
+ steps: VGeoGroupStep[];
26
+ repacks: VGeoGroupRepack[];
27
+ merged: Set<number>;
28
+ } | undefined;
29
+ //# sourceMappingURL=vgeo_run_round.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_run_round.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,8DATW,MAAM,8BAEJ;IAAC,KAAK,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,IAAI,MAAM,CAAC,CAAA;CAAC,GAAC,SAAS,CAyG/F"}