@woosh/meep-engine 3.27.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 (648) 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/mat4/m4_linear_determinant.d.ts +15 -0
  19. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts.map +1 -0
  20. package/src/core/geom/3d/mat4/m4_linear_determinant.js +24 -0
  21. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts +4 -2
  22. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts.map +1 -1
  23. package/src/core/geom/3d/mat4/m4_normal_matrix3.js +21 -11
  24. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts +24 -0
  25. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts.map +1 -0
  26. package/src/core/geom/3d/quadric/quadric_attribute_add.js +31 -0
  27. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts +46 -0
  28. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts.map +1 -0
  29. package/src/core/geom/3d/quadric/quadric_attribute_reduce.js +104 -0
  30. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts +62 -0
  31. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts.map +1 -0
  32. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.js +158 -0
  33. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts +21 -0
  34. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts.map +1 -0
  35. package/src/core/geom/3d/quadric/quadric_attribute_size.js +24 -0
  36. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts +34 -0
  37. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts.map +1 -0
  38. package/src/core/geom/3d/quadric/quadric_attribute_solve.js +55 -0
  39. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts +28 -0
  40. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts.map +1 -0
  41. package/src/core/geom/3d/quadric/quadric_attribute_sub.js +35 -0
  42. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +15 -0
  43. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
  44. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +35 -0
  45. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts +93 -0
  46. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts.map +1 -0
  47. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.js +128 -0
  48. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts +38 -0
  49. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -0
  50. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +113 -0
  51. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +47 -1
  52. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  53. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +677 -8
  54. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts +22 -0
  55. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts.map +1 -0
  56. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.js +46 -0
  57. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts +19 -0
  58. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts.map +1 -0
  59. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.js +49 -0
  60. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts +63 -0
  61. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts.map +1 -0
  62. package/src/core/graph/layout/layered/BoxLayoutOptions.js +80 -0
  63. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.d.ts +35 -0
  64. package/src/core/graph/layout/layered/LayoutBoxGraph.d.ts.map +1 -0
  65. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.js +53 -1
  66. package/src/core/graph/layout/layered/layout_assign_coordinates.d.ts.map +1 -0
  67. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.js +72 -68
  68. package/src/core/graph/layout/layered/layout_assign_layers.d.ts.map +1 -0
  69. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.js +4 -2
  70. package/src/core/graph/layout/layered/layout_break_cycles.d.ts.map +1 -0
  71. package/src/core/graph/layout/layered/layout_insert_lanes.d.ts.map +1 -0
  72. package/src/core/graph/layout/layered/layout_order_layers.d.ts.map +1 -0
  73. package/src/core/graph/layout/layered/layout_orient_links.d.ts.map +1 -0
  74. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +7 -51
  75. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  76. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +8 -69
  77. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +1 -1
  78. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +6 -6
  79. package/src/core/model/node-graph/visual/layout/route_grid_build.js +1 -1
  80. package/src/engine/Engine.d.ts.map +1 -1
  81. package/src/engine/Engine.js +38 -1
  82. package/src/engine/graphics3/DebugDrawSystem.d.ts +7 -5
  83. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  84. package/src/engine/graphics3/DebugDrawSystem.js +206 -203
  85. package/src/engine/graphics3/DecalSystem.d.ts +4 -5
  86. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  87. package/src/engine/graphics3/DecalSystem.js +5 -5
  88. package/src/engine/graphics3/FogOfWarSystem.d.ts +7 -12
  89. package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
  90. package/src/engine/graphics3/FogOfWarSystem.js +8 -12
  91. package/src/engine/graphics3/GraphicsEngine.d.ts +5 -1
  92. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  93. package/src/engine/graphics3/GraphicsEngine.js +834 -830
  94. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -230
  95. package/src/shade/RENDERER_CONTRACT.md +31 -17
  96. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +1 -1
  97. package/src/shade/playground/caldera/README.md +529 -0
  98. package/src/shade/playground/caldera/caldera_format.d.ts +151 -0
  99. package/src/shade/playground/caldera/caldera_format.d.ts.map +1 -0
  100. package/src/shade/playground/caldera/caldera_format.js +241 -0
  101. package/src/shade/playground/caldera/index.html +126 -0
  102. package/src/shade/playground/caldera/main.d.ts.map +1 -0
  103. package/src/shade/playground/caldera/main.js +1565 -0
  104. package/src/shade/playground/mesh_row_ceiling/README.md +85 -0
  105. package/src/shade/playground/mesh_row_ceiling/index.html +31 -0
  106. package/src/shade/playground/mesh_row_ceiling/main.d.ts +2 -0
  107. package/src/shade/playground/mesh_row_ceiling/main.d.ts.map +1 -0
  108. package/src/shade/playground/mesh_row_ceiling/main.js +389 -0
  109. package/src/shade/playground/vgeo_runtime/README.md +32 -16
  110. package/src/shade/playground/vgeo_runtime/main.js +21 -7
  111. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.d.ts +3 -3
  112. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -0
  113. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.js +12 -11
  114. package/src/shade/playground/vgeo_scene/README.md +487 -0
  115. package/src/shade/playground/vgeo_scene/index.html +144 -0
  116. package/src/shade/playground/vgeo_scene/main.d.ts +2 -0
  117. package/src/shade/playground/vgeo_scene/main.d.ts.map +1 -0
  118. package/src/shade/playground/vgeo_scene/main.js +2217 -0
  119. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  120. package/src/shade/renderer/GraphicsContext.js +6 -0
  121. package/src/shade/renderer/Renderer.d.ts +6 -1
  122. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  123. package/src/shade/renderer/Renderer.js +28 -2
  124. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  125. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +100 -8
  126. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +70 -35
  127. package/src/shade/renderer/extension/RenderExtension.d.ts +15 -18
  128. package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
  129. package/src/shade/renderer/extension/RenderExtension.js +15 -19
  130. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts +5 -5
  131. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts.map +1 -1
  132. package/src/shade/renderer/extension/RenderExtensionRegistry.js +29 -166
  133. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  134. package/src/shade/renderer/geometry/GPUGeometryManager.js +73 -16
  135. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  136. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +18 -3
  137. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +663 -0
  138. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +100 -5
  139. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +688 -81
  141. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  142. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +3 -29
  143. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts +22 -0
  144. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts.map +1 -0
  145. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.js +49 -0
  146. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +540 -0
  147. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +159 -66
  148. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +40 -21
  149. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +15 -14
  150. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +358 -0
  151. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +58 -8
  152. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  153. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +64 -10
  154. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.d.ts.map +1 -1
  155. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +5 -9
  156. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts +40 -0
  157. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts.map +1 -0
  158. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js +24 -0
  159. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts +91 -0
  160. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts.map +1 -0
  161. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.js +91 -0
  162. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts +24 -0
  163. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts.map +1 -0
  164. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.js +25 -0
  165. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts +77 -0
  166. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts.map +1 -0
  167. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.js +84 -0
  168. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts.map +1 -0
  169. package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.d.ts → level/VGeoLevelOptions.d.ts} +19 -6
  170. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -0
  171. package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.js → level/VGeoLevelOptions.js} +20 -7
  172. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts.map +1 -0
  173. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts +19 -0
  174. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts.map +1 -0
  175. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.js +58 -0
  176. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts +18 -0
  177. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts.map +1 -0
  178. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.js +116 -0
  179. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts +18 -0
  180. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -0
  181. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +545 -0
  182. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts +16 -0
  183. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -0
  184. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +110 -0
  185. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +11 -0
  186. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -0
  187. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.js +308 -0
  188. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.d.ts → level/vgeo_build_root_group.d.ts} +1 -1
  189. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts.map +1 -0
  190. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.js → level/vgeo_build_root_group.js} +1 -1
  191. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts +26 -0
  192. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts.map +1 -0
  193. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js +123 -0
  194. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts +26 -0
  195. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts.map +1 -0
  196. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js +78 -0
  197. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts +24 -0
  198. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -0
  199. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +337 -0
  200. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts +29 -0
  201. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -0
  202. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +147 -0
  203. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts +37 -0
  204. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts.map +1 -0
  205. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.js +243 -0
  206. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts +29 -0
  207. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -0
  208. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +117 -0
  209. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts +46 -0
  210. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts.map +1 -0
  211. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.js +45 -0
  212. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +64 -0
  213. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -0
  214. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +68 -0
  215. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.d.ts → mesh/VirtualGeometryMesh.d.ts} +13 -8
  216. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -0
  217. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.js → mesh/VirtualGeometryMesh.js} +40 -18
  218. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts +58 -0
  219. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts.map +1 -0
  220. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js +79 -0
  221. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts +39 -0
  222. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts.map +1 -0
  223. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js +68 -0
  224. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts +53 -0
  225. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts.map +1 -0
  226. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js +243 -0
  227. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +45 -0
  228. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -0
  229. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +300 -0
  230. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_tangents.d.ts → mesh/vgeo_compute_vertex_tangents.d.ts} +12 -8
  231. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -0
  232. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js +151 -0
  233. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.d.ts → mesh/vgeo_normalize_source.d.ts} +8 -1
  234. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -0
  235. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.js → mesh/vgeo_normalize_source.js} +27 -12
  236. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts +38 -0
  237. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts.map +1 -0
  238. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.js +81 -0
  239. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.d.ts → page/vgeo_assemble_pages.d.ts} +1 -1
  240. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts.map +1 -0
  241. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.js → page/vgeo_assemble_pages.js} +9 -9
  242. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.d.ts → page/vgeo_build_page_nodes.d.ts} +1 -1
  243. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts.map +1 -0
  244. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.js → page/vgeo_build_page_nodes.js} +4 -4
  245. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts.map +1 -0
  246. package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.js → page/vgeo_page_node_count.js} +2 -2
  247. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.d.ts → partition/VGeoFaceGraph.d.ts} +23 -5
  248. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -0
  249. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.js → partition/VGeoFaceGraph.js} +28 -21
  250. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -0
  251. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts.map +1 -0
  252. package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.js → partition/vgeo_partition_graph.js} +2 -2
  253. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts +41 -0
  254. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts.map +1 -0
  255. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.js +92 -0
  256. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts.map +1 -0
  257. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.js → partition/vgeo_split_face_set.js} +13 -56
  258. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -0
  259. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +371 -0
  260. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts.map +1 -0
  261. package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.js → sphere/vgeo_bounding_sphere.js} +3 -3
  262. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts.map +1 -0
  263. package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.js → sphere/vgeo_containing_sphere.js} +3 -3
  264. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts.map +1 -0
  265. package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.js → sphere/vgeo_sphere_inflate_to_contain.js} +1 -1
  266. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +39 -0
  267. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -0
  268. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.js +42 -0
  269. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +37 -0
  270. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -0
  271. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.js +39 -0
  272. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +23 -0
  273. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -0
  274. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.js +135 -0
  275. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +24 -0
  276. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -0
  277. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js +95 -0
  278. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts.map +1 -0
  279. package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.js → submesh/vgeo_narrow_indices.js} +3 -3
  280. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts +6 -2
  281. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  282. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +37 -16
  283. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts +32 -0
  284. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts.map +1 -0
  285. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.js +93 -0
  286. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +20 -6
  287. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  288. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +22 -8
  289. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts +8 -2
  290. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts.map +1 -1
  291. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +8 -2
  292. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts +16 -0
  293. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts.map +1 -0
  294. package/src/shade/renderer/geometry/virtual/format/attribute/{vgeo_layers_copy_vertex.js → vgeo_layers_copy_corner.js} +8 -8
  295. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts +18 -7
  296. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts.map +1 -1
  297. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +19 -8
  298. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.d.ts +3 -3
  299. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +3 -3
  300. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts +27 -0
  301. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts.map +1 -0
  302. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.js +97 -0
  303. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts +7 -3
  304. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts.map +1 -1
  305. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +21 -11
  306. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts +21 -0
  307. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts.map +1 -0
  308. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.js +41 -0
  309. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +19 -1
  310. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  311. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +20 -1
  312. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts +25 -0
  313. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts.map +1 -0
  314. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.js +24 -0
  315. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts +5 -0
  316. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts.map +1 -1
  317. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +5 -0
  318. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.d.ts.map +1 -1
  319. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +5 -0
  320. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts +10 -3
  321. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts.map +1 -1
  322. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +37 -3
  323. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +21 -13
  324. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  325. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +37 -13
  326. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts +8 -2
  327. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts.map +1 -1
  328. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +14 -2
  329. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +18 -0
  330. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  331. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +19 -1
  332. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +6 -0
  333. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts +21 -0
  334. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts.map +1 -0
  335. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.js +20 -0
  336. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts +9 -0
  337. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts.map +1 -1
  338. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +10 -1
  339. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts +15 -0
  340. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts.map +1 -0
  341. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js +15 -0
  342. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +1 -2
  343. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +10 -3
  344. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts +20 -0
  345. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts.map +1 -0
  346. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.js +43 -0
  347. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +32 -2
  348. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  349. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +15 -7
  350. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  351. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +2 -2
  352. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts +6 -4
  353. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts.map +1 -1
  354. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.js +6 -4
  355. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +13 -2
  356. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  357. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +13 -2
  358. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +5 -1
  359. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -1
  360. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +14 -1
  361. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -1
  362. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +1 -0
  363. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts +4 -1
  364. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts.map +1 -1
  365. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.js +53 -11
  366. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  367. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +7 -3
  368. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts +12 -2
  369. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  370. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +120 -37
  371. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts +6 -2
  372. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  373. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +130 -47
  374. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts +2 -2
  375. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  376. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +60 -22
  377. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +385 -0
  378. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +21 -2
  379. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +52 -2
  380. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  381. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +97 -1
  382. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +4 -4
  383. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  384. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +10 -0
  385. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
  386. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +9 -0
  387. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
  388. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +59 -34
  389. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +8 -8
  390. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  391. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +45 -88
  392. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts +19 -0
  393. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -0
  394. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +116 -0
  395. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts +31 -0
  396. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -0
  397. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +99 -0
  398. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts +17 -0
  399. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts.map +1 -0
  400. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js +39 -0
  401. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -1
  402. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +7 -63
  403. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
  404. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +13 -30
  405. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  406. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +53 -71
  407. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +1 -0
  408. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +22 -4
  409. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +7 -2
  410. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -1
  411. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +8 -3
  412. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  413. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +10 -0
  414. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  415. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +13 -11
  416. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -1
  417. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +13 -11
  418. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  419. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +4 -0
  420. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  421. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -4
  422. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +6 -2
  423. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  424. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +90 -12
  425. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts +22 -0
  426. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts.map +1 -0
  427. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.js +21 -0
  428. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  429. package/src/shade/renderer/loader/gltf/load_gltf.js +0 -19
  430. package/src/shade/renderer/material/chunk_material_draw_side.d.ts +14 -0
  431. package/src/shade/renderer/material/chunk_material_draw_side.d.ts.map +1 -0
  432. package/src/shade/renderer/material/chunk_material_draw_side.js +34 -0
  433. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  434. package/src/shade/renderer/material/standard/fragment_gbuffer.js +8 -1
  435. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  436. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +13 -8
  437. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  438. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -6
  439. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  440. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +13 -1
  441. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +19 -5
  442. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
  443. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +23 -5
  444. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.d.ts.map +1 -1
  445. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.js +12 -5
  446. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  447. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +4 -12
  448. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts +22 -0
  449. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts.map +1 -0
  450. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js +36 -0
  451. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  452. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  453. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +4 -5
  454. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +15 -0
  455. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -0
  456. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +35 -0
  457. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  458. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +5 -3
  459. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.d.ts.map +1 -1
  460. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js +11 -4
  461. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  462. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +4 -3
  463. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts +10 -1
  464. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
  465. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +38 -29
  466. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts +5 -0
  467. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts.map +1 -1
  468. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js +63 -55
  469. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  470. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +3 -0
  471. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
  472. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +94 -90
  473. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  474. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +13 -5
  475. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
  476. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +96 -89
  477. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  478. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +3 -1
  479. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
  480. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +4 -1
  481. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  482. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +1 -0
  483. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
  484. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +100 -89
  485. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
  486. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +31 -7
  487. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  488. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +1 -7
  489. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
  490. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +161 -153
  491. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  492. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +2 -7
  493. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  494. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +44 -53
  495. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  496. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -2
  497. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  498. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -2
  499. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -1
  500. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js +19 -2
  501. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +7 -4
  502. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  503. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -2
  504. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.d.ts.map +1 -1
  505. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.js +15 -4
  506. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  507. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +16 -5
  508. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.d.ts.map +1 -1
  509. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +16 -5
  510. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  511. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +2 -1
  512. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.d.ts.map +1 -1
  513. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.js +4 -0
  514. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  515. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +16 -7
  516. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  517. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +81 -95
  518. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  519. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +26 -39
  520. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  521. package/src/shade/renderer/scene/GPUSceneContext.js +2 -0
  522. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +19 -0
  523. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts.map +1 -1
  524. package/src/shade/renderer/scene/NODE3D_STRUCT.js +34 -0
  525. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts +9 -0
  526. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts.map +1 -0
  527. package/src/shade/renderer/scene/chunk_node3d_flags.js +23 -0
  528. package/src/shade/renderer/scene/chunk_scene_database_access.d.ts.map +1 -1
  529. package/src/shade/renderer/scene/chunk_scene_database_access.js +15 -1
  530. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  531. package/src/shade/renderer/scene/rows/GPUSceneRows.js +9 -1
  532. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts +7 -0
  533. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map +1 -1
  534. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js +16 -4
  535. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts +12 -0
  536. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts.map +1 -0
  537. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js +18 -0
  538. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts +24 -0
  539. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts.map +1 -0
  540. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js +33 -0
  541. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +25 -0
  542. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts.map +1 -0
  543. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +24 -0
  544. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +10 -0
  545. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  546. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +30 -21
  547. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +0 -1
  548. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +0 -1
  549. package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +0 -1
  550. package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +0 -1
  551. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +0 -1
  552. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +0 -1
  553. package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +0 -1
  554. package/src/shade/playground/vgeo_viewer/README.md +0 -150
  555. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts +0 -61
  556. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +0 -1
  557. package/src/shade/playground/vgeo_viewer/cut_geometry.js +0 -460
  558. package/src/shade/playground/vgeo_viewer/index.html +0 -77
  559. package/src/shade/playground/vgeo_viewer/main.d.ts.map +0 -1
  560. package/src/shade/playground/vgeo_viewer/main.js +0 -1343
  561. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +0 -1
  562. package/src/shade/playground/vgeo_viewer/select_cut.d.ts +0 -173
  563. package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +0 -1
  564. package/src/shade/playground/vgeo_viewer/select_cut.js +0 -481
  565. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts.map +0 -1
  566. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts +0 -24
  567. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts.map +0 -1
  568. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.js +0 -25
  569. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts.map +0 -1
  570. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts.map +0 -1
  571. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts.map +0 -1
  572. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts +0 -20
  573. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts.map +0 -1
  574. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.js +0 -20
  575. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts.map +0 -1
  576. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +0 -1
  577. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts.map +0 -1
  578. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts +0 -36
  579. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts.map +0 -1
  580. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.js +0 -1786
  581. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts.map +0 -1
  582. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts.map +0 -1
  583. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts +0 -29
  584. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts.map +0 -1
  585. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.js +0 -75
  586. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts.map +0 -1
  587. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.js +0 -143
  588. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts.map +0 -1
  589. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts +0 -14
  590. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts.map +0 -1
  591. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.js +0 -41
  592. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts +0 -12
  593. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts.map +0 -1
  594. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.js +0 -71
  595. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts.map +0 -1
  596. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts.map +0 -1
  597. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts.map +0 -1
  598. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +0 -1
  599. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts.map +0 -1
  600. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts.map +0 -1
  601. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts.map +0 -1
  602. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts.map +0 -1
  603. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.js +0 -207
  604. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts +0 -16
  605. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts.map +0 -1
  606. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +0 -258
  607. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +0 -1
  608. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +0 -49
  609. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
  610. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts +0 -10
  611. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts.map +0 -1
  612. package/src/shade/renderer/loader/gltf/fix_up_material_sides.js +0 -109
  613. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +0 -17
  614. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +0 -1
  615. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +0 -78
  616. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts +0 -3
  617. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts.map +0 -1
  618. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +0 -100
  619. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts +0 -8
  620. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +0 -1
  621. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.js +0 -26
  622. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts +0 -3
  623. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts.map +0 -1
  624. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.d.ts +0 -0
  625. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.d.ts +0 -0
  626. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.d.ts +0 -0
  627. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.js +0 -0
  628. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.d.ts +0 -0
  629. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.js +0 -0
  630. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.d.ts +0 -0
  631. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.js +0 -0
  632. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.d.ts +0 -0
  633. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.js +0 -0
  634. /package/src/shade/playground/{vgeo_viewer → caldera}/main.d.ts +0 -0
  635. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.d.ts → level/VGeoLevel.d.ts} +0 -0
  636. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.js → level/VGeoLevel.js} +0 -0
  637. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.d.ts → level/VGeoLevelSummary.d.ts} +0 -0
  638. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.js → level/VGeoLevelSummary.js} +0 -0
  639. /package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.d.ts → page/vgeo_page_node_count.d.ts} +0 -0
  640. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.d.ts → partition/vgeo_graph_components.d.ts} +0 -0
  641. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.js → partition/vgeo_graph_components.js} +0 -0
  642. /package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.d.ts → partition/vgeo_partition_graph.d.ts} +0 -0
  643. /package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.d.ts → partition/vgeo_split_face_set.d.ts} +0 -0
  644. /package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set_packed.d.ts → partition/vgeo_split_face_set_packed.d.ts} +0 -0
  645. /package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.d.ts → sphere/vgeo_bounding_sphere.d.ts} +0 -0
  646. /package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.d.ts → sphere/vgeo_containing_sphere.d.ts} +0 -0
  647. /package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.d.ts → sphere/vgeo_sphere_inflate_to_contain.d.ts} +0 -0
  648. /package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.d.ts → submesh/vgeo_narrow_indices.d.ts} +0 -0
@@ -28,8 +28,10 @@ consumer reads it, and `runtime/RUNTIME_PLAN.md` §4.8 says why: at the moment a
28
28
  per-cluster test the cut has already passed is strictly tighter than any page-level test, so the
29
29
  page-level one can never reject anything. Its consumer is prefetch, which is a later campaign.
30
30
 
31
- `shade/playground/vgeo_viewer/` drives the reader end to end, and its `select_cut.js` is a CPU
32
- reference traversal of the cut rule this format was shaped around.
31
+ `shade/playground/vgeo_runtime/` and `shade/playground/vgeo_scene/` drive the reader end to end
32
+ against a device, and `runtime/cut/__fixtures__/vgeo_select_cut.js` is a CPU reference traversal of the
33
+ cut rule this format was shaped around — the oracle the GPU cut is held to, and the only traversal
34
+ of it that is not a kernel.
33
35
 
34
36
  ## 1. Design constraints (inherited, binding)
35
37
 
@@ -116,8 +118,8 @@ All u64/u128 fields are naturally 8-byte aligned.
116
118
  | offset | type | field | notes |
117
119
  |-------:|-----------|--------------------------|-------|
118
120
  | 0 | u32 | magic | `'VGEO'` = 0x4F454756 |
119
- | 4 | u16 | format_version | 4 today; breaking layout changes only |
120
- | 6 | u16 | min_reader_version | 3 today; reader MUST reject if its version is lower |
121
+ | 4 | u16 | format_version | 6 today; breaking layout changes only |
122
+ | 6 | u16 | min_reader_version | 6 today; reader MUST reject if its version is lower |
121
123
  | 8 | u16 | header_size | = 256 |
122
124
  | 10 | u8 | hash_algo | 0 = xxHash3; readers MUST reject unknown values |
123
125
  | 11 | u8 | reserved | |
@@ -136,8 +138,7 @@ All u64/u128 fields are naturally 8-byte aligned.
136
138
  | 88 | u64 | dir_block_checksums_offset | `ceil(total_pages / 128)` × u64 |
137
139
  | 96 | u32 | nominal_page_size | bytes a decoded page may come to; a **hard bound** when bit 0 of `feature_flags_ignorable` is set (§11.14), advisory otherwise |
138
140
  | 100 | u16 | reserved | |
139
- | 102 | u8 | level_count | levels `0..level_count-1` |
140
- | 103 | u8 | reserved | |
141
+ | 102 | u16 | level_count | levels `0..level_count-1`; ≤ 65,535. A `u8` through version 5, and the byte above it was reserved and written as zero — so little-endian makes this field read identically through either width for any container of 255 levels or fewer |
141
142
  | 104 | u64 | source_vertex_count | vertices of the normalized source mesh (post-weld) the leaves represent |
142
143
  | 112 | u64 | source_face_count | triangles of the normalized source mesh |
143
144
  | 120 | [f32; 4] | object_sphere | object-space minimal bounding sphere (center xyz, radius) of the whole geometry |
@@ -154,12 +155,35 @@ version-4 file correctly by ignoring them. In the other direction a version-4 re
154
155
  which is true — so neither direction needs a version test, and nothing has to be rebuilt to stay
155
156
  readable.
156
157
 
158
+ **5 moved both**, which is the pair working the other way. It put `subtree_aabb` in the cluster
159
+ record (§7) over the bytes `bounds_sphere` and `cone_reserved` held, so every field from offset 40
160
+ on shifted: a version-4 reader would take a version-5 `child_ref` out of the middle of a bounding
161
+ box and descend into whatever group that named. There is no ignoring it and no partial reading of
162
+ it, so `min_reader_version` moved with the version, which is what that field is for. A version-5
163
+ reader still reads version-4 records — it branches on the version it is holding — so nothing has to
164
+ be rebuilt to stay readable, only to be culled tightly.
165
+
166
+ **6 widened the level ordinal to `u16`** in all three places it is written down: `level_count`
167
+ here, the page band in the page header (§6.1), and the page band in the directory record (§9). 255
168
+ was a ceiling a real asset reached — the 2026-09-14 Zorah conversion refused a three-million-triangle
169
+ bush at exactly 255 levels with 39 clusters still unmerged, while the other 2,974 geometries of that
170
+ scene, one of them 27 million triangles, converged by 149 — and a ceiling an asset can touch is a
171
+ ceiling in the wrong place. Two of the three cost nothing: this header and the directory record both
172
+ had reserved bytes lying beside the field. The page header had none, and rather than grow the page
173
+ this spends `node_table_offset`, which only ever restated `56 + 8·group_count`. So **a page header
174
+ is still 56 bytes and every other field of every page ever written is still at its old offset** —
175
+ but bytes 4..8 and 20..24 of it now mean different things, and there is no partial reading of that,
176
+ so `min_reader_version` moved. A version-6 reader keeps the older page layout as it keeps the older
177
+ cluster layout, so again nothing has to be rebuilt to stay readable.
178
+
157
179
  ### 4.1 Level table (`level_count` × 32 B, immediately after the header)
158
180
 
159
181
  Statistics per level, at `256 + 32·i`, ending where the root page frame begins. Small —
160
- a hundred levels is 3.2 KB — so a single fetch of the file's head brings the header, the
161
- whole table, and the always-resident root page together, and the table is available before
162
- any page has been decoded.
182
+ a hundred levels is 3.2 KB, and the deepest container yet converted is 149 — so a single
183
+ fetch of the file's head brings the header, the whole table, and the always-resident root
184
+ page together, and the table is available before any page has been decoded. That is a
185
+ statement about what builds produce and not a bound: `level_count` is a `u16`, and a
186
+ reader sizing a head fetch must take the number it finds rather than assume this one.
163
187
 
164
188
  | offset | type | field | notes |
165
189
  |-------:|------|-------------------|-------|
@@ -217,7 +241,7 @@ Every page — root included — is stored as a self-delimiting frame:
217
241
  | offset | type | field | notes |
218
242
  |-------:|------|------------------|-------|
219
243
  | 0 | u32 | magic | `'VGPG'` = 0x47504756 |
220
- | 4 | u8 | codec | 0 = raw, 1 = one LZ4 block; applies to the blob only; readers MUST reject unknown values |
244
+ | 4 | u8 | codec | 0 = raw, 1 = one LZ4 block, 2 = one raw DEFLATE stream; applies to the blob only; readers MUST reject unknown values |
221
245
  | 5 | u8 | flags | 0 |
222
246
  | 6 | u16 | child_page_count | entries in the child table; 0 for all-leaf pages |
223
247
  | 8 | u32 | stored_size | bytes of blob (after the child table) |
@@ -256,26 +280,64 @@ terminator.
256
280
  and an asset may carry a mixture, so a reader that handles the defined codecs handles
257
281
  any file without asking what it was written with. That is what makes "compress unless it
258
282
  would not shrink" expressible — the LZ4 worst case is about one byte in 255 plus a
259
- token, and paying it to store bytes verbatim is a straight loss, so a page that does not
260
- compress is written raw and says so.
283
+ token, deflate's is a stored block that is never smaller than its input, and paying
284
+ either to store bytes verbatim is a straight loss, so a page that does not compress is
285
+ written raw and says so.
261
286
 
262
287
  A new codec id is a **per-asset capability gate, not a format break**, exactly as a new
263
288
  `payload_encoding` is: an older reader meets a codec it has no decoder for and refuses
264
289
  the asset instead of misreading it. `format_version` moves only when the container
265
- layout itself changes, and adding a codec does not change it.
290
+ layout itself changes, and adding a codec does not change it — `2` went in without
291
+ touching `format_version` or `min_reader_version`.
266
292
 
267
- `1` is a **bare LZ4 block**, not an LZ4 frame: LZ4's own framing carries a magic, a
268
- checksum and a content size that this frame already carries better, and `decoded_size`
269
- is what the block is decoded against. Blocks are independent — no match reaches outside
270
- the page — so a page decodes from its own bytes with no other page involved, which is
271
- the same property residency already needs.
293
+ `1` is a **bare LZ4 block**, not an LZ4 frame, and `2` is a **bare DEFLATE stream**
294
+ (RFC 1951), not a zlib or gzip member. Both wrappers carry a magic, a checksum and a
295
+ content size that this frame already carries better, and `decoded_size` is what the blob
296
+ is decoded against. Both codecs are independent per blob — no match reaches outside the
297
+ page — so a page decodes from its own bytes with no other page involved, which is the
298
+ same property residency already needs.
272
299
 
273
300
  `decoded_size` is untrusted input, and readers allocate against it before anything can
274
301
  contradict it. It MUST therefore be checked against what `stored_size` bytes could
275
302
  physically produce under `codec` — exactly `stored_size` for raw, at most
276
- `255·stored_size + 19` for LZ4 — *before* the allocation. A block that then decodes to
277
- anything other than `decoded_size` MUST be rejected: a page truncated to a plausible
278
- prefix is the one corruption that reads as a valid page with geometry missing.
303
+ `255·stored_size + 19` for LZ4, at most `1032·stored_size` for deflate — *before* the
304
+ allocation. A blob that then decodes to anything other than `decoded_size` MUST be
305
+ rejected: a page truncated to a plausible prefix is the one corruption that reads as a
306
+ valid page with geometry missing.
307
+
308
+ Those ceilings are what the *format* permits, and neither compressing one is anything
309
+ like what a page looks like, so a length check alone is a weak guard — deflate's 1032:1 admits a 256 KB blob claiming 264
310
+ MB. A decoder MUST therefore bound its own output as it produces it rather than
311
+ comparing lengths once it is done: the LZ4 decoder is given the end of the page as its
312
+ write limit, and the deflate decoder stops at the first chunk that would pass it. A blob
313
+ that expands further than its header admits then costs one chunk rather than the whole
314
+ expansion.
315
+
316
+ **Which codec, and why deflate is the default.** Measured over the 44 pages of a
317
+ 240×120 torus: LZ4 stores them at **1.295x** and deflate at **1.369x**, and decoding
318
+ every page costs **3.8 ms** under LZ4 against **16.9 ms** under deflate — 562 MB/s of
319
+ decoded output against 126. Deflate buys about seven points of ratio for four and a half
320
+ times the decode.
321
+
322
+ **The builder and the converter write deflate**, because the two sides of that trade are
323
+ not paid the same number of times: an asset is built once and fetched forever, and the
324
+ bytes deflate saves are saved on every fetch of every page by every client. LZ4 is the
325
+ deliberate setting for a container whose pages arrive while someone is looking at it —
326
+ there the decode is a page's *arrival* cost on the residency path, and 126 MB/s is what
327
+ that costs. Neither is a property of the file format: `codec` is a frame field and a
328
+ reader that handles the defined codecs reads either without being told.
329
+
330
+ A *default* codec is a statement about readers rather than about bytes. Under the gate
331
+ above, a container written with deflate opens only in a reader that carries the deflate
332
+ decoder, so the default is what decides which builds of this engine can open a freshly
333
+ converted asset. `format_version` still does not move, and an older reader still refuses
334
+ rather than misreads.
335
+
336
+ Deflate is also the *hosted* codec: `CompressionStream`/`DecompressionStream` are the
337
+ platform's own zlib, so it costs no bytes of library — and the platform offers it only
338
+ as a stream, which is why everything in this reader from the blob decode upwards is
339
+ asynchronous. Nothing in the format requires that; a synchronous inflate would read the
340
+ same files.
279
341
 
280
342
  **What it is worth, measured.** LZ4 over the pages of the Stanford models comes to
281
343
  **1.12x on the bunny, 1.18x on the dragon and 1.14x on the 27M-triangle lucy** — pages
@@ -290,10 +352,11 @@ is worth writing down because it says where the next win is rather than here:
290
352
  The tables compress, and there are not enough of them to matter. The payload does not,
291
353
  because under `SHADE_MESHLET_V1` it is float32 positions and packed attribute words —
292
354
  high-entropy at the byte level, with no repetition for an LZ matcher to find. For
293
- reference, on the same bytes `gzip -9` reaches 1.22x and `xz -9` 1.63x, so this is the
294
- data resisting rather than the codec failing; an entropy coder buys a little more for a
295
- lot more time. **The lever is `payload_encoding`, not `codec`** — quantized positions
296
- (§12) shrink those bytes directly and leave the residue far more compressible.
355
+ reference, on the same bytes `gzip -9` reaches 1.22x — codec `2`'s algorithm, at a level
356
+ the platform API does not expose — and `xz -9` 1.63x, so this is the data resisting
357
+ rather than the codec failing; an entropy coder buys a little more for a lot more time. **The lever is `payload_encoding`, not
358
+ `codec`** — quantized positions (§12) shrink those bytes directly and leave the residue
359
+ far more compressible.
297
360
 
298
361
  What the reader pays is one block decode per page installed, into the buffer the page was
299
362
  going to be copied into anyway: ~350–500 MB/s of decoded output from the JS decoder, so
@@ -307,9 +370,9 @@ about 0.6 ms for a 256 KB page.
307
370
  ```
308
371
 
309
372
  The two parent tables sit between the cluster records and the payload, and that placement is the
310
- reason `min_reader_version` did not move (§4): `node_table_offset`'s `= 56 + 8·group_count` stays
311
- true, every earlier offset is where it was, and both tables hold 4-byte entries over sections that
312
- are already multiples of four, so §11.8's word-aligned payload survives.
373
+ reason `min_reader_version` did not move when version 4 added them (§4): the node table's `= 56 +
374
+ 8·group_count` stays true, every earlier offset is where it was, and both tables hold 4-byte entries
375
+ over sections that are already multiples of four, so §11.8's word-aligned payload survives.
313
376
 
314
377
  PageHeader:
315
378
 
@@ -317,13 +380,13 @@ PageHeader:
317
380
  |-------:|------|-----------------------|-------|
318
381
  | 0 | u16 | group_count | ≥ 1; group table immediately follows the header |
319
382
  | 2 | u16 | cluster_count | ≥ 1 |
320
- | 4 | u8 | min_level | page band; non-root pages span one contiguous band |
321
- | 5 | u8 | max_level | |
322
- | 6 | u16 | node_count | ≥ 1; ≤ 2·`group_count` (§6.1) |
383
+ | 4 | u16 | min_level | page band; non-root pages span one contiguous band. A `u8` at 4 and another at 5 through version 5 |
384
+ | 6 | u16 | max_level | |
323
385
  | 8 | u32 | cluster_table_offset | |
324
386
  | 12 | u32 | payload_offset | |
325
387
  | 16 | u32 | payload_size | |
326
- | 20 | u32 | node_table_offset | = `56 + 8·group_count`; the node table follows the group table |
388
+ | 20 | u16 | node_count | ≥ 1; ≤ 2·`group_count` (§6.1). At 6 through version 5 |
389
+ | 22 | u16 | reserved | what version 5 spent on `node_table_offset`, which said only `56 + 8·group_count` — the group table follows the header and the node table follows the group table, so a reader derives it. MUST be zero |
327
390
  | 24 | u32 | parent_table_offset | start of the parent section — the parent-page table, then the group-parent table. **0 means the page carries neither**, which is what every container written before `format_version` 4 says about itself |
328
391
  | 28 | u16 | parent_entry_count | entries in the group-parent table (§6.3) = Σ `parent_cluster_count` over this page's groups |
329
392
  | 30 | u16 | parent_page_count | entries in the parent-page table (§6.4) |
@@ -433,11 +496,13 @@ decode it. Being a copy, it can drift; §11.11 requires it to match the page's o
433
496
  ## 7. Cluster record (112 bytes)
434
497
 
435
498
  Everything the runtime cut rule, culling, wants, and upload need — denormalized per
436
- cluster so selection reads one record. Two kinds of spheres, deliberately distinct: the
499
+ cluster so selection reads one record. Three kinds of bounds, deliberately distinct: the
437
500
  **LOD-metric pair** (`self_sphere`/`parent_sphere` — shared per group step so all
438
- siblings project identical values, monotonically inflated, never a tight fit) and the
439
- **culling bounds** (`bounds_sphere`/`aabb` — this cluster's own tight fits, never used
440
- in the cut test):
501
+ siblings project identical values, monotonically inflated, never a tight fit), the
502
+ **cluster's own box** (`aabb` — its tight fit, the meshlet metadata's `bounds_box`, culled
503
+ downstream by the HZB), and the **subtree box** (`subtree_aabb` — this cluster's geometry and
504
+ everything reachable below it, and the only one of the three the cut's per-cluster frustum test
505
+ can use, because culling a cluster takes its whole child group out of the descent):
441
506
 
442
507
  | offset | type | field | notes |
443
508
  |-------:|----------|-----------------|-------|
@@ -445,18 +510,23 @@ in the cut test):
445
510
  | 16 | f32 | self_error | object-space `r_e`; leaves: 0 |
446
511
  | 20 | f32 | parent_error | error of the step that consumed it; roots: +∞ |
447
512
  | 24 | [f32; 4] | parent_sphere | LOD-metric sphere of the consuming step; roots: duplicate of self_sphere |
448
- | 40 | [f32; 4] | bounds_sphere | this cluster's own minimal bounding sphere (miniball), object-space — culling |
449
- | 56 | [f32; 6] | aabb | this cluster's object-space AABB — culling, GPU metadata `bounds_box`, and the (future) dequantization grid |
450
- | 80 | u16 | child_ref | index into this frame's child table; `SAME_PAGE` when the child group is in this page; `NO_CHILD` for leaves |
451
- | 82 | u16 | child_group | group index within the child page (or this page, for `SAME_PAGE`); `NO_GROUP` for leaves |
452
- | 84 | u32 | cone_reserved | reserved — **write 0**. Named for a backface-cone cull pass that is now **declined outright** (design §9, plan §5), so no sub-encoding will ever be pinned here. Kept rather than reclaimed: removing it moves `format_version`, a constant-zero column costs nothing after the page codec, and there are ten more reserved bytes beside it at 102 and 104 anyway. A candidate to rename and reuse the next time the version moves for some other reason |
453
- | 88 | u32 | encoding_flags | frozen bit table in §8 |
454
- | 92 | u32 | payload_offset | into this page's payload section; ≡ 0 (mod 4) |
455
- | 96 | u32 | payload_size | bytes; ≡ 0 (mod 4) |
456
- | 100 | u8 | vertex_count | 3 ≤ n ≤ 128 |
457
- | 101 | u8 | triangle_count | 1 ≤ n ≤ 128 |
458
- | 102 | u16 | reserved | |
459
- | 104 | u64 | reserved | |
513
+ | 40 | [f32; 6] | subtree_aabb | object-space AABB of this cluster's vertices **and of every cluster reachable below it** through child groups (§11.17); leaves: equals `aabb`. What the runtime's per-cluster frustum cull reads |
514
+ | 64 | [f32; 6] | aabb | this cluster's own object-space AABB — GPU metadata `bounds_box`, the downstream culls, and the (future) dequantization grid |
515
+ | 88 | u16 | child_ref | index into this frame's child table; `SAME_PAGE` when the child group is in this page; `NO_CHILD` for leaves |
516
+ | 90 | u16 | child_group | group index within the child page (or this page, for `SAME_PAGE`); `NO_GROUP` for leaves |
517
+ | 92 | u32 | encoding_flags | frozen bit table in §8 |
518
+ | 96 | u32 | payload_offset | into this page's payload section; ≡ 0 (mod 4) |
519
+ | 100 | u32 | payload_size | bytes; ≡ 0 (mod 4) |
520
+ | 104 | u8 | vertex_count | 3 ≤ n ≤ 128 |
521
+ | 105 | u8 | triangle_count | 1 ≤ n ≤ 128 |
522
+ | 106 | [u8; 6] | reserved | **write 0** |
523
+
524
+ **What version 5 spent to fit `subtree_aabb` in the same 112 bytes.** `bounds_sphere`, the cluster's
525
+ own miniball, which no runtime ever read — the cut tests the LOD sphere, the HZB and the small-primitive
526
+ cull test `bounds_box`, and the builder keeps its own copy of the sphere for the object bounds and the
527
+ group centroids. And `cone_reserved`, four bytes held for a backface-cone cull that is **declined
528
+ outright** (design §9, plan §5): the earlier note kept it because reclaiming four bytes was not worth
529
+ moving `format_version`, and moving it for twenty-four was.
460
530
 
461
531
  Monotonicity (`parent_error ≥ self_error`, `parent_sphere ⊇ self_sphere`) is a build
462
532
  invariant, not a reader concern. A single-cluster asset is valid: one root page, one
@@ -520,12 +590,12 @@ derivable from the frames (§3) — standard runtime traversal never reads it.
520
590
  | 0 | u64 | frame_offset | absolute; frame per §5 |
521
591
  | 8 | u32 | fetch_size | as in the child table: the exact byte range to fetch is `[frame_offset, frame_offset + fetch_size)` |
522
592
  | 12 | u32 | decoded_size | MUST equal the frame's |
523
- | 16 | u8 | min_level | |
524
- | 17 | u8 | max_level | |
525
- | 18 | u16 | flags | bit 0: root page |
526
- | 20 | u16 | group_count | |
527
- | 22 | u16 | cluster_count | |
528
- | 24 | u64 | reserved | |
593
+ | 16 | u16 | min_level | a `u8` here and another at 17 through version 5, which is what moved the three fields below by two — into bytes this record has always held in reserve |
594
+ | 18 | u16 | max_level | |
595
+ | 20 | u16 | flags | bit 0: root page |
596
+ | 22 | u16 | group_count | |
597
+ | 24 | u16 | cluster_count | |
598
+ | 26 | [u8; 6] | reserved | |
529
599
 
530
600
  **Directory integrity**: `dir_block_checksums` holds one xxh3-64 per 128 directory
531
601
  records (one 4 KB block), seed = `asset_id_high64 XOR block_index`. Readers that use
@@ -746,8 +816,10 @@ clustering and simplification dominate regardless.
746
816
  one, and it is in page 0. Several parentless clusters would be several entry points,
747
817
  and the cut only ever enters at one; it is also what an unconverged build leaves
748
818
  behind, which is the likelier cause. All floats NaN-free.
749
- `bounds_sphere` and `aabb` contain the cluster's decoded vertices; the header's
750
- `object_sphere` and `object_bounds` contain the normalized source mesh.
819
+ `self_sphere`, `aabb` and `subtree_aabb` contain the cluster's decoded vertices; the header's
820
+ `object_sphere` and `object_bounds` contain the normalized source mesh. The `self_sphere` half is
821
+ what makes the LOD sphere usable as a conservative bound at all — the runtime's first frustum test
822
+ is on it, and a reader meeting a pre-5 container stands its cube in for `subtree_aabb`.
751
823
  8. Payload offsets and sizes are 4-byte multiples; every payload decodes/uploads
752
824
  against `payload_encoding` with no external state beyond its own cluster record.
753
825
  A leaf's `self_error` of 0 is only as honest as the simplifier's metric — see design
@@ -762,18 +834,23 @@ clustering and simplification dominate regardless.
762
834
  and the leaves partition the group table — each group reached through exactly one leaf. Each
763
835
  node's metric bounds its whole subtree: its sphere contains every child's, its `min_self_error`
764
836
  is no greater than any child's, its `max_parent_error` no less. The page header's metric equals
765
- the root node's.
837
+ the root node's. The table begins at `56 + 8·group_count` — derived, because the page header
838
+ carries no offset for it since version 6 — and the `u16` at 22 that its offset used to occupy is
839
+ zero.
766
840
  11. Every child-table entry's metric equals the header metric of the page it names. It is a copy
767
841
  read before that page is fetched, so nothing else can catch it having drifted — and a traversal
768
842
  that trusts a stale one skips a page it needed and leaves a hole.
769
843
  12. Every frame names a defined `codec` (§5); a raw frame's `stored_size` equals its
770
844
  `decoded_size`; and no frame's `decoded_size` exceeds what its codec could produce from
771
- `stored_size` bytes. Every blob decodes to exactly `decoded_size` — a short decode is a
772
- truncated page, and a page truncated to a plausible prefix is the one corruption that reads
773
- as valid geometry with pieces missing.
845
+ `stored_size` bytes. Every blob decodes to exactly `decoded_size` — neither short nor long. A
846
+ short decode is a truncated page, and a page truncated to a plausible prefix is the one
847
+ corruption that reads as valid geometry with pieces missing; a long one is a blob that would
848
+ write past what the reader allocated from `decoded_size`, and is stopped while it is producing
849
+ rather than measured afterwards.
774
850
  13. `root_page_offset = align16(256 + 32 · level_count)`; the level table's `cluster_count` and
775
851
  `group_count` columns sum to `total_clusters` and `total_groups`; every level holds at least
776
- one cluster and one group; `min_error ≤ max_error`, both finite and ≥ 0.
852
+ one cluster and one group; `min_error ≤ max_error`, both finite and ≥ 0. `level_count ≥ 1`,
853
+ and no page's `max_level` reaches it.
777
854
  14. **Page size is a bound.** When bit 0 of `feature_flags_ignorable` is set, every page's
778
855
  `decoded_size` is ≤ `nominal_page_size`, and `nominal_page_size` is non-zero. The bit is what a
779
856
  reader checks; unset, `nominal_page_size` is the advisory build parameter it used to be and
@@ -802,13 +879,29 @@ clustering and simplification dominate regardless.
802
879
  the run, rather than carrying a dedup bitmask sized by instances × groups — so the order is
803
880
  load-bearing and not presentation.
804
881
 
882
+ 17. **`subtree_aabb` bounds the subtree.** It contains the cluster's own `aabb` and, for every
883
+ cluster of the group the cluster refines into, that cluster's `subtree_aabb` — so by induction
884
+ it contains every vertex anywhere below the cluster in the DAG. A leaf's equals its `aabb`.
885
+
886
+ **Exact, on the stored values, with no tolerance.** A union of float32 extremes is a float32
887
+ extreme, so unlike the spheres there is nothing here for rounding to eat and nothing to inflate
888
+ against it. That is half of why the runtime cull is a box: the other half is that a subtree of a
889
+ surface is a flat patch, and its AABB is a fraction of the volume of any sphere around it.
890
+
891
+ **Why the subtree and not the cluster.** The runtime's per-cluster frustum test decides whether
892
+ a cluster refines into its child group, so culling it removes that whole group — and everything
893
+ under it — from the cut. A step consumes one group and produces several parents, each naming the
894
+ *whole* consumed group, so what is reachable below a cluster carries its siblings' surface too
895
+ and grows with depth. A bound that covered only the cluster would cull a parent with on-screen
896
+ descendants, and a culled subtree leaves a hole with nothing standing in over it.
897
+
805
898
  ## 12. Open
806
899
 
807
- - Page codec ids beyond raw and LZ4 (§5). LZ4 is the default and is where the cheap
808
- ratio is; a slower, denser codec (meshopt-style over the payload, deflate-family over
809
- the tables) is a per-frame `codec` id away and costs no reader that already handles a
810
- mixture. The quantized-position `payload_encoding` is the other half of the same
811
- question, and would take most of what LZ4 currently finds.
900
+ - ~~Page codec ids beyond raw and LZ4~~ — `2` is raw DEFLATE through the platform's own zlib (§5)
901
+ and is what the builder writes by default: 1.369x against LZ4's 1.295x on the same pages, for four
902
+ and a half times the decode. Still open is a codec that knows what it is compressing —
903
+ meshopt-style over the payload rather than an LZ matcher over its bytes. The quantized-position `payload_encoding` is the other half of the same
904
+ question, and would take most of what either general-purpose codec currently finds.
812
905
  - ~~Default `nominal_page_size`~~ — 64 KiB, `VGEO_DEFAULT_PAGE_SIZE`: one page size rather than
813
906
  Nanite's two, set between hiding fetch latency and paying for it in response time and in VRAM per
814
907
  resident page on a low-end device, with a floor at the largest group a build produces. Provisional
@@ -15,12 +15,14 @@ RAM tier's budget, and `runtime/` is everything §7 describes — the selection
15
15
  pass, the VRAM page pool, the feedback loop, and the seam through which VG instances enter the
16
16
  meshlet pipeline ([runtime/RUNTIME_PLAN.md](./runtime/RUNTIME_PLAN.md)).
17
17
 
18
- Two playgrounds prove two different things and it is worth not confusing them.
19
- `shade/playground/vgeo_viewer/` puts a clamped **CPU** cut of a streaming container on screen
20
- through Shade's direct geometry path — it proves the DAG, the format and the clamp, and by
21
- construction it proves nothing about the engine. `shade/playground/vgeo_runtime/` puts an ordinary
22
- `Mesh` in an ordinary `Scene` and draws it entirely from a **GPU** cut through the meshlet
23
- pipeline — it proves the seam and nothing about the DAG. §10 says which milestone that leaves us
18
+ `shade/playground/vgeo_runtime/` puts an ordinary `Mesh` in an ordinary `Scene` and draws it
19
+ entirely from a **GPU** cut through the meshlet pipeline — it proves the engine seam, and
20
+ `shade/playground/vgeo_scene/` opens a whole converted set at once, where the claim about a *scene*
21
+ is measured. What proves the DAG, the format and the clamp is not a page at all: it is
22
+ `runtime/cut/__fixtures__/vgeo_select_cut.js`, a CPU traversal of the same rule that every cut
23
+ spec is held to. A third playground once drew that traversal on screen through Shade's direct
24
+ geometry path, with its own renderer and its own streaming loop; once the GPU page could show
25
+ everything it showed, it was a second runtime for no gain, and it was retired. §10 says which milestone that leaves us
24
26
  in, and the order the work actually arrived in.
25
27
 
26
28
  ## 1. What and why
@@ -83,7 +85,7 @@ hands-off principle argues for anyway.
83
85
  possible and matter (§3).
84
86
  - **Bounds**: `Miniball` (minimal bounding sphere, iteration-capped). That is the whole list —
85
87
  **normal cones are not part of this design**. Backface cone culling is declined outright (§9,
86
- plan §5), so `cone_reserved` stays zero, and
88
+ plan §5), so `cone_reserved` was reclaimed by `format_version` 5 (format §7), and
87
89
  `bt_face_cluster_compute_normal_bounding_cone` — the `BinaryTopology` port of the old
88
90
  `TopoMesh` cone builder — has no consumer and no prospect of one.
89
91
  - **Renderer formats (the real seam)**: meshlets capped at 128 triangles / 128 vertices
@@ -138,8 +140,9 @@ Pinned:
138
140
  spanning an order of magnitude of error when the cut it takes is a *threshold* on error.
139
141
  The minimum share is not optional: on error spread thinly and continuously — a UV
140
142
  sphere, poles against equator — an octave alone holds a handful of clusters, and the
141
- round count then scales with the cluster count rather than its logarithm, which a u8
142
- `level_count` cannot survive. Measured on a 98k-triangle sphere against a sweep: growth
143
+ round count then scales with the cluster count rather than its logarithm, which no
144
+ `level_count` can survive and which a build refuses outright past
145
+ `VGeoLevelOptions.max_levels`. Measured on a 98k-triangle sphere against a sweep: growth
143
146
  4 cuts clusters-dragged-up by 38% for one extra level; growth 2 cuts it 60% for seven.
144
147
  On geometry of uniform error the band is the whole frontier and this *is* the sweep.
145
148
  - **A level is an ordinal, not a generation.** A group's band ordinal is what orders pages;
@@ -162,6 +165,19 @@ Pinned:
162
165
  group. A build that cannot reach one root **throws** — the runtime starts its cut at the
163
166
  root, and several parentless clusters is not a shape it can start from. The validator
164
167
  enforces it from the bytes: exactly one cluster with `parent_error = +∞`, in page 0.
168
+ - **A step aims at a cluster count, and a cluster is bounded by two numbers.** What the
169
+ simplifier is handed is a triangle target, but a cluster is capped at 128 triangles *and*
170
+ 128 vertices, and on geometry that has come apart — seams, small separate parts, the
171
+ patches a collapse leaves behind once it has eaten the connective tissue — there are two
172
+ or three vertices per triangle rather than a half. Halving the triangles then does not
173
+ halve the vertices, the re-cut needs as many clusters as the group consumed, and the step
174
+ is worth nothing to the round. So the re-cut is *measured* and the target tightened on
175
+ whichever of the two ceilings the attempt broke, until the step strictly shrinks its
176
+ group — tightened by the overshoot rather than by the cluster ratio, because what it
177
+ costs is fidelity and the overshoot is the least it can pay. Measured on the Zorah
178
+ sample: 187 of its 3,163 primitives reached a frontier no grouping could shrink, every
179
+ one of them this, and a 188th ran out of `VGeoLevelOptions.max_levels` inching forward a
180
+ merge a round — the same refusal to merge, spent on depth rather than on a stall.
165
181
  - **Islands merge by proximity, once adjacency has nothing left to offer.** A cluster alone
166
182
  in its connected component can never be coarsened — halving its triangles leaves one
167
183
  cluster where there was one — so a mesh of separate shells has no root at all under
@@ -280,7 +296,7 @@ Pinned:
280
296
  *before* it is fetched. Below page granularity, each page carries a tree over its own groups
281
297
  (format §6.1–6.2). Cost, measured: 0.3%–1.6% of asset size.
282
298
 
283
- *What exists.* `playground/vgeo_viewer/select_cut.js` is this rule on the CPU, against a
299
+ *What exists.* `runtime/cut/__fixtures__/vgeo_select_cut.js` is this rule on the CPU, against a
284
300
  partially resident container: descend from the root's parentless groups, refine where
285
301
  `project(parent) > τ`, take the cluster where it does not, and stop where the child group is
286
302
  not selectable — recording the want that would unblock it. It is the reference the GPU pass
@@ -356,16 +372,19 @@ Pinned:
356
372
  in the file (coarse-first order is topological); non-root pages hold clusters of a
357
373
  single level band. Build-validated.
358
374
  - **Compression must not break random access.** Transparent HTTP compression does not
359
- compose with range requests, so compression is per-page *inside* the container. Two codecs
360
- are defined and both shipped — `raw` and a bare LZ4 block — chosen **per frame** rather than
361
- per file, so a page that would not shrink is stored verbatim and says so. Measured, LZ4 is
362
- worth 1.12x–1.18x on the Stanford models, and the reason it is not more is the reason to stop
363
- here: the payload is float32 positions and packed attribute words, and it does not compress.
364
- Quantization (§2) is the lever, not the codec.
375
+ compose with range requests, so compression is per-page *inside* the container. Three codecs
376
+ are defined and all three shipped — `raw`, a bare LZ4 block, and a bare DEFLATE stream through
377
+ the platform's own zlib — chosen **per frame** rather than per file, so a page that would not
378
+ shrink is stored verbatim and says so. Measured, LZ4 is worth 1.12x–1.18x on the Stanford
379
+ models and deflate about seven points more for four and a half times the decode; deflate is what
380
+ the builder writes, because a build happens once and a fetch happens forever. The reason neither
381
+ is worth more is the reason to stop here: the payload is float32 positions and packed attribute
382
+ words, and it does not compress. Quantization (§2) is the lever, not the codec.
365
383
  - **Coarse-first layout**: pages ordered so a plain prefix read of the file yields a
366
384
  complete coarse asset — progressive load without a feedback loop.
367
385
 
368
- Open: a denser page codec than LZ4, if quantization leaves one worth having;
386
+ Open: a page codec that knows what it is compressing — meshopt-style over the payload rather
387
+ than an LZ matcher over its bytes — if quantization leaves one worth having;
369
388
  per-attribute quantization widths (cluster-local grids); relationship to
370
389
  `MeshletGeometrySerializationAdapter` (extend vs parallel).
371
390
 
@@ -545,7 +564,7 @@ Pinned:
545
564
  `bt_mesh_validate` → level-0 clustering (+ CC split) → the §3 round loop → per-cluster
546
565
  encode → page assignment (level-banded, DAG + spatial locality, acyclicity check) →
547
566
  container emit. The encode is the miniball sphere, the AABB, and `SHADE_MESHLET_V1`
548
- attributes at their shipped widths (format §8): `cone_reserved` is zero because cone culling
567
+ attributes at their shipped widths (format §8): there is no cone field because cone culling
549
568
  is declined (§9), and positions are raw float32 because quantization is a `payload_encoding`
550
569
  that does not exist yet.
551
570
  - **The weld tolerance is scale-relative**, a fraction of each geometry's bounding-box
@@ -591,8 +610,8 @@ canonicalizing them is a preprocessor's job).
591
610
 
592
611
  - **Backface normal-cone culling — declined outright, not deferred.** The two-pass HZB already
593
612
  rejects what a cone would, on evidence rather than on a bound; see plan §5 for the mechanism
594
- and the reports behind it. `cone_reserved` stays a zeroed reserved field (format §7). This is
595
- the one entry here that is not a "v1" qualifier.
613
+ and the reports behind it. `cone_reserved` was a zeroed reserved field until `format_version` 5
614
+ spent it on `subtree_aabb` (format §7). This is the one entry here that is not a "v1" qualifier.
596
615
  - Skinned / morphing / WPO meshes through the VG path (static geometry only).
597
616
  - **Non-opaque VG instances.** The cut runs beside the mesh→meshlet expansion of the *opaque*
598
617
  rasterization paths, and the transparent and alpha-tested bucket path
@@ -629,7 +648,7 @@ is the piece still missing, and M1 is where the work now starts.
629
648
  Acceptance: crack-free under τ sweep and flythrough (incl. group-boundary polyline and
630
649
  flip validation); drawn-triangle count tracks resolution, not source size; §3 build
631
650
  validations green.
632
- **Done**: the builder; a CPU cut (`playground/vgeo_viewer/select_cut.js`) that is a traversal
651
+ **Done**: the builder; a CPU cut (`runtime/cut/__fixtures__/vgeo_select_cut.js`) that is a traversal
633
652
  rather than the flat pass planned here, and that runs against a partially resident container,
634
653
  which was M2's job; τ-sweep watertightness as a spec (`build/vgeo_cut.spec.js` counts edges
635
654
  used by one triangle instead of two, at a spread of thresholds, and wants zero); the
@@ -33,7 +33,7 @@ accepted-and-waiting one.
33
33
  - **Cluster-count simplification target** `[M §2.2]`, and a minimum cluster fill through the
34
34
  generalized leaf repack `[V §3.3]`.
35
35
  - **Compactness-weighted cluster adjacency** `[M §2.3]` — `compactness()` in
36
- `build/vgeo_build_levels.js`.
36
+ `build/level/vgeo_build_levels.js`.
37
37
  - **Speculative groups, rejected individually** `[M §2.4]`.
38
38
  - **Per-level summary table in the file head** `[V §4.1, §6.1]` — VGEO_FORMAT §4.1.
39
39
  - **A traversal metric on the page DAG, and a group tree inside each page** `[V §2.1, §6.3]` —
@@ -72,12 +72,13 @@ accepted-and-waiting one.
72
72
  362 non-root groups have split parents: 355 of 576 camera positions double-drew, up to 10.7%
73
73
  of drawn triangles, before. Zero after. It reads as corrupt geometry rather than as a missing
74
74
  page, which is why the tool that found it could not name it.
75
- - **A CPU cut against a partially resident container** — `playground/vgeo_viewer/`.
76
- `select_cut.js` is the runtime's rule rather than a debug approximation of it; the viewer is
77
- what makes clamping, streaming and eviction watchable, and `__state()` is what makes it
78
- assertable from a headless browser. It draws through Shade's direct geometry path, not the
79
- meshlet pipeline — so it proves the DAG and the format, and proves nothing about the engine
80
- seam.
75
+ - **A CPU cut against a partially resident container** —
76
+ `runtime/cut/__fixtures__/vgeo_select_cut.js`. It is the runtime's rule rather than a debug
77
+ approximation of it, and `vgeo_select_cut.spec.js` holds it to the format's guarantees. A
78
+ `vgeo_viewer` playground used to draw it on screen through Shade's direct geometry path, which is
79
+ what made clamping, streaming and eviction watchable; once `playground/vgeo_runtime/` could show
80
+ all of that through the meshlet pipeline, the page was a second renderer and a second streaming
81
+ loop for no gain, and it was retired. The traversal stayed, because it is the oracle.
81
82
 
82
83
  - **The GPU runtime** — `runtime/`, and [runtime/RUNTIME_PLAN.md](./runtime/RUNTIME_PLAN.md) for the
83
84
  design and the adversarial review that reshaped it. The cut is a wavefront BFS over the page DAG
@@ -95,7 +96,7 @@ accepted-and-waiting one.
95
96
  evaluator does not. §6 states the fact without stating it as a term of the rule, because §4 was
96
97
  written for a traversal.
97
98
  - **Page size decides whether that state is even reachable.** At the 8 KB pages
98
- `select_cut.spec.js` uses, a torus puts exactly one group in every page — so a blocked group is
99
+ `vgeo_select_cut.spec.js` uses, a torus puts exactly one group in every page — so a blocked group is
99
100
  a blocked page, no page is ever mixed, and no page is ever entered twice. Measured: 40 pages
100
101
  withheld one at a time and 60 random residency subsets produced *no* mixed page. At 64 KB the
101
102
  median page holds eight groups and it is ordinary. A spec for anything about mixed selectability
@@ -120,7 +121,7 @@ prefetch.
120
121
  ### 2.1 A partitioning fallback for when METIS fails `[M §3.3]`, `[V §3.2]` — LANDED
121
122
 
122
123
  `core/graph/graph_partition_spectral.js` — recursive spectral bisection over CSR, matrix-free,
123
- signature-compatible with `metis_partition_kway`. `build/vgeo_partition_graph.js` tries METIS
124
+ signature-compatible with `metis_partition_kway`. `build/partition/vgeo_partition_graph.js` tries METIS
124
125
  and falls back to it; both of the builder's partitioning sites go through that wrapper.
125
126
 
126
127
  Notes worth keeping:
@@ -212,7 +213,7 @@ installed page can be re-tested without walking back to its parent.
212
213
  width at the top. This one has *no* paging question by construction: it is inside a page, it
213
214
  ships and evicts with it, and it cannot dangle.
214
215
 
215
- Both landed together; VGEO_FORMAT §6.1–6.2 specifies them, `build/vgeo_build_page_nodes.js`
216
+ Both landed together; VGEO_FORMAT §6.1–6.2 specifies them, `build/page/vgeo_build_page_nodes.js`
216
217
  builds them. Notes worth keeping:
217
218
 
218
219
  - The tree needs no partitioner. A page's groups arrive in Morton order of their centroid, so
@@ -243,7 +244,7 @@ for the first few bands, which are also the cheapest to walk.
243
244
  LOD-metric sphere and error range (VGEO_FORMAT §5, §6.2), and every page carries a fanout-4 tree
244
245
  over its own groups (§6.1). The writer emits them, `vgeo_validate_container` checks them
245
246
  (§11.10–11.11) with corruption tests behind both checks, and **nothing reads either**.
246
- `VGeoPage` records `node_count` and stops; `select_cut.js` descends group by group.
247
+ `VGeoPage` records `node_count` and stops; `vgeo_select_cut` descends group by group.
247
248
 
248
249
  This is not a defect to fix on its own account. Building a consumer for its own sake would fix
249
250
  the interface before the pass that has to live with it, and the CPU traversal does not need the
@@ -451,9 +452,9 @@ attacked:
451
452
  library exposing cone data, and Remedy report the same for Northlight. Taken together with
452
453
  the mechanism above, there is nothing left to measure.
453
454
 
454
- Consequences, so that nobody re-derives them: `cone_reserved` stays a zeroed reserved u32
455
- (format §7) — reclaiming 4 bytes of 112 is not worth a `format_version` move, and the page
456
- codec compresses a constant-zero column away. `bt_face_cluster_compute_normal_bounding_cone`
455
+ Consequences, so that nobody re-derives them: `cone_reserved` was a zeroed reserved u32 until
456
+ `format_version` 5 (format §7) — reclaiming 4 bytes of 112 was never worth a version move on its
457
+ own, and it went when `subtree_aabb` needed 24 and the version moved anyway. `bt_face_cluster_compute_normal_bounding_cone`
457
458
  has no consumer and no prospect of one.
458
459
  - **Fixed-size residency slots** `[M §2.5]`. Micron gives every resident patch one slot of
459
460
  `MICRON_PATCH_SIZE_MAX × 3` vertices with occupancy in a BitSet: no allocator, no